<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <iostream>

#include "ast/DebugVisitor.hpp"

#include "variant.hpp"
#include "assert.hpp"
#include "VisitorUtils.hpp"
#include "Variable.hpp"

using namespace eddic;

namespace {

std::string toStringType(ast::Type type){
    if(auto* ptr = boost::get<ast::SimpleType>(&type)){
        return ptr->type;
    } else if(auto* ptr = boost::get<ast::ArrayType>(&type)){
        return ptr->type + "[]";
    } else {
        ASSERT_PATH_NOT_TAKEN("Unhandled type");
    }
}

struct DebugVisitor : public boost::static_visitor<> {
    mutable int level = 0;

    std::string indent() const {
        std::string acc = "";
        for(int i = 0; i < level; ++i){
            acc += "    ";
        }
        return acc;
    }

    void operator()(ast::SourceFile& program) const {
        std::cout << indent() << "SourceFile" << std::endl;

        ++level;

        visit_each(*this, program.Content->blocks);
    }

    void operator()(ast::Import& import) const {
        std::cout << indent() << "include \"" << import.file << "\"" << std::endl;
    }

    void operator()(ast::StandardImport& import) const {
        std::cout << indent() << "include <" << import.header << ">" << std::endl;
    }

    template<typename Container>
    void print_each_sub(Container& container) const {
        level++;
        visit_each(*this, container);
        level--;
    }

    template<typename Container>
    void print_sub(Container& container) const {
        level++;
        visit(*this, container);
        level--;
    }

    void operator()(ast::FunctionDeclaration& declaration) const {
        std::cout << indent() << "Function " << declaration.Content->functionName << std::endl;
        std::cout << indent() << "Parameters:" << std::endl;
        level++;
        for(auto param : declaration.Content->parameters){
            std::cout << indent() << param.parameterName << std::endl;
        }
        level--;
        std::cout << indent() << "Instructions:" << std::endl;
        print_each_sub(declaration.Content->instructions);
    }

    void operator()(ast::Struct& struct_) const {
        std::cout << indent() << "Structure declaration: " << struct_.Content->name << std::endl;
        level++;
        std::cout << indent() << "Members:" << std::endl;
        level++;
        visit_each_non_variant(*this, struct_.Content->members);
        level--;
        std::cout << indent() << "Functions:" << std::endl;
        level++;
        visit_each_non_variant(*this, struct_.Content->functions);
        level--;
        level--;
    }

    void operator()(ast::MemberDeclaration& declaration) const {
        std::cout << indent() << toStringType(declaration.Content->type)  << " " << declaration.Content->name << std::endl;
    }

    void operator()(ast::GlobalVariableDeclaration&) const {
        std::cout << indent() << "Global Variable" << std::endl;
    }

    void operator()(ast::GlobalArrayDeclaration&) const {
        std::cout << indent() << "Global Array" << std::endl;
    }

    void operator()(ast::For& for_) const {
        std::cout << indent() << "For" << std::endl;
        print_each_sub(for_.Content->instructions);
    }

    void operator()(ast::Foreach& for_) const {
        std::cout << indent() << "Foreach" << std::endl;
        print_each_sub(for_.Content->instructions);
    }

    void operator()(ast::ForeachIn& for_) const {
        std::cout << indent() << "Foreach in " << std::endl;
        print_each_sub(for_.Content->instructions);
    }

    void operator()(ast::Switch& switch_) const {
        std::cout << indent() << "Switch " << std::endl;

        ++level;
        std::cout << indent() << "Value" << std::endl;
        print_sub(switch_.Content->value);
        for(auto& case_ : switch_.Content->cases){
            (*this)(case_);
        }
        if(switch_.Content->default_case){
            (*this)(*switch_.Content->default_case);
        }
        --level;
    }

    void operator()(ast::SwitchCase& switch_case) const {
        std::cout << indent() << "Case" << std::endl;

        ++level;
        std::cout << indent() << "Value" << std::endl;
        print_sub(switch_case.value);
        std::cout << indent() << "Instructions" << std::endl;
        print_each_sub(switch_case.instructions);
        --level;
    }

    void operator()(ast::DefaultCase& default_case) const {
        std::cout << indent() << "Default Case" << std::endl;

        print_each_sub(default_case.instructions);
    }

    void operator()(ast::While& while_) const {
        std::cout << indent() << "While" << std::endl;
        std::cout << indent() << "Condition:" << std::endl;
        print_sub(while_.Content->condition);
        print_each_sub(while_.Content->instructions);
    }

    void operator()(ast::DoWhile& while_) const {
        std::cout << indent() << "Do while" << std::endl;
        std::cout << indent() << "Condition:" << std::endl;
        print_sub(while_.Content->condition);
        std::cout << indent() << "Body:" << std::endl;
        print_each_sub(while_.Content->instructions);
    }

    void operator()(ast::Swap&) const {
        std::cout << indent() << "Swap" << std::endl;
    }

    void operator()(ast::If& if_) const {
        std::cout << indent() << "If" << std::endl;

        std::cout << indent() << "Condition:" << std::endl;
        print_sub(if_.Content->condition);

        std::cout << indent() << "Instructions" << std::endl;
        print_each_sub(if_.Content->instructions);

        for(auto& else_if : if_.Content->elseIfs){
            std::cout << indent() << "ElseIf" << std::endl;

            std::cout << indent() << "Condition:" << std::endl;
            print_sub(else_if.condition);

            std::cout << indent() << "Instructions" << std::endl;
            print_each_sub(else_if.instructions);
        }

        if(if_.Content->else_){
            std::cout << indent() << "Else" << std::endl;

            std::cout << indent() << "Instructions" << std::endl;
            print_each_sub((*if_.Content->else_).instructions);
        }
    }

    void operator()(ast::FunctionCall& call) const {
        std::cout << indent() << "FunctionCall " << call.Content->functionName << std::endl;
        print_each_sub(call.Content->values);
    }

    void operator()(ast::MemberFunctionCall& call) const {
        std::cout << indent() << "Member FunctionCall " << call.Content->object_name << "." << call.Content->function_name << std::endl;
        print_each_sub(call.Content->values);
    }

    void operator()(ast::BuiltinOperator& builtin) const {
        std::cout << indent() << "Builtin Operator " << (int) builtin.Content->type << std::endl;
        print_each_sub(builtin.Content->values);
    }

    void operator()(ast::VariableDeclaration& declaration) const {
        std::cout << indent() << "Variable declaration [" << declaration.Content->variableName << "]" << std::endl;

        if(declaration.Content->value){
            print_sub(*declaration.Content->value);
        }
    }

    void operator()(ast::ArrayDeclaration&) const {
        std::cout << indent() << "Array declaration" << std::endl;
    }

    void operator()(ast::SuffixOperation& op) const {
        std::cout << indent() << op.Content->variableName << "(suffix)" << (int)op.Content->op << std::endl;
    }

    void operator()(ast::PrefixOperation& op) const {
        std::cout << indent() << (int)op.Content->op << "(prefix)" << op.Content->variableName << std::endl;
    }

    void operator()(ast::Assignment& assign) const {
        std::cout << indent() << "Assignment [operator = " << static_cast<int>(assign.Content->op) << " ] " << std::endl;

        std::cout << indent() << "Left Value:" << std::endl;
        print_sub(assign.Content->left_value);

        std::cout << indent() << "Right Value:" << std::endl;
        print_sub(assign.Content->value);
    }

    void operator()(ast::Ternary& ternary) const {
        std::cout << indent() << "Ternary" << std::endl;

        std::cout << indent() << "Condition Value:" << std::endl;
        print_sub(ternary.Content->condition);

        std::cout << indent() << "True Value:" << std::endl;
        print_sub(ternary.Content->true_value);

        std::cout << indent() << "False Value:" << std::endl;
        print_sub(ternary.Content->false_value);
    }

    void operator()(ast::Return& return_) const {
        std::cout << indent() << "Function return" << std::endl;
        print_sub(return_.Content->value);
    }

    void operator()(ast::Litteral& litteral) const {
        std::cout << indent() << "Litteral [" << litteral.value << "]" << std::endl;
    }

    void operator()(ast::Integer& integer) const {
        std::cout << indent() << "Integer [" << integer.value << "]" << std::endl;
    }

    void operator()(ast::IntegerSuffix& integer) const {
        std::cout << indent() << "Float (suffix) [" << integer.value << "f]" << std::endl;
    }

    void operator()(ast::Float& float_) const {
        std::cout << indent() << "Float [" << float_.value << "]" << std::endl;
    }

    void operator()(ast::True&) const {
        std::cout << indent() << "true" << std::endl;
    }

    void operator()(ast::Null&) const {
        std::cout << indent() << "null" << std::endl;
    }

    void operator()(ast::False&) const {
        std::cout << indent() << "false" << std::endl;
    }

    void operator()(ast::VariableValue& value) const {
        std::cout << indent() << "Variable " << value.Content->var->name();

        for(auto& member : value.Content->memberNames){
            std::cout << "." << member;
        }

        std::cout << std::endl;
    }

    void operator()(ast::DereferenceValue& value) const {
        std::cout << indent() << "Dereference Variable Value" << std::endl;;

        std::cout << indent() << "Left Value:" << std::endl;
        print_sub(value.Content->ref);
    }

    void operator()(ast::ArrayValue& value) const {
        std::cout << indent() << "Array value [" << value.Content->arrayName << "]" << std::endl;
        print_sub(value.Content->indexValue);
    }

    void operator()(ast::Expression& value) const {
        std::cout << indent() << "Expression [" << value.Content->operations.size() << "]" << std::endl;
        ++level;
        visit(*this, value.Content->first);
        for(auto& operation : value.Content->operations){
            std::cout << indent() << (int) operation.get<0>() << std::endl;
            visit(*this, operation.get<1>());
        }
        --level;
    }

    void operator()(ast::Unary& value) const {
        std::cout << indent() << "Unary " << static_cast<int>(value.Content->op) << std::endl;
        print_sub(value.Content->value);
    }

    void operator()(ast::Cast& cast) const {
        std::cout << indent() << "Cast " << std::endl;
        std::cout << indent() << "\tType: " << toStringType(cast.Content->type) << std::endl;
        print_sub(cast.Content->value);
    }
};

} //end of anonymous namespace

void ast::Printer::print(SourceFile& program){
    DebugVisitor visitor;
    visit_non_variant(visitor, program);
}
<commit_msg>Some cleanup<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <iostream>

#include "ast/DebugVisitor.hpp"

#include "variant.hpp"
#include "assert.hpp"
#include "VisitorUtils.hpp"
#include "Variable.hpp"

using namespace eddic;

namespace {

std::string toStringType(ast::Type type){
    if(auto* ptr = boost::get<ast::SimpleType>(&type)){
        return ptr->type;
    } else if(auto* ptr = boost::get<ast::ArrayType>(&type)){
        return ptr->type + "[]";
    } else {
        ASSERT_PATH_NOT_TAKEN("Unhandled type");
    }
}

struct DebugVisitor : public boost::static_visitor<> {
    mutable int level = 0;

    std::string indent() const {
        std::string acc = "";
        for(int i = 0; i < level; ++i){
            acc += "    ";
        }
        return acc;
    }

    template<typename Container>
    void print_each_sub(Container& container) const {
        level++;
        visit_each(*this, container);
        level--;
    }

    template<typename Container>
    void print_sub(Container& container) const {
        level++;
        visit(*this, container);
        level--;
    }

    void operator()(ast::SourceFile& program) const {
        std::cout << indent() << "SourceFile" << std::endl;

        print_each_sub(program.Content->blocks);
    }

    void operator()(ast::Import& import) const {
        std::cout << indent() << "include \"" << import.file << "\"" << std::endl;
    }

    void operator()(ast::StandardImport& import) const {
        std::cout << indent() << "include <" << import.header << ">" << std::endl;
    }

    void operator()(ast::FunctionDeclaration& declaration) const {
        std::cout << indent() << "Function " << declaration.Content->functionName << std::endl;
        std::cout << indent() << "Parameters:" << std::endl;
        level++;
        for(auto param : declaration.Content->parameters){
            std::cout << indent() << param.parameterName << std::endl;
        }
        level--;
        std::cout << indent() << "Instructions:" << std::endl;
        print_each_sub(declaration.Content->instructions);
    }

    void operator()(ast::Struct& struct_) const {
        std::cout << indent() << "Structure declaration: " << struct_.Content->name << std::endl;
        level++;
        std::cout << indent() << "Members:" << std::endl;
        level++;
        visit_each_non_variant(*this, struct_.Content->members);
        level--;
        std::cout << indent() << "Functions:" << std::endl;
        level++;
        visit_each_non_variant(*this, struct_.Content->functions);
        level--;
        level--;
    }

    void operator()(ast::MemberDeclaration& declaration) const {
        std::cout << indent() << toStringType(declaration.Content->type)  << " " << declaration.Content->name << std::endl;
    }

    void operator()(ast::GlobalVariableDeclaration&) const {
        std::cout << indent() << "Global Variable" << std::endl;
    }

    void operator()(ast::GlobalArrayDeclaration&) const {
        std::cout << indent() << "Global Array" << std::endl;
    }

    void operator()(ast::For& for_) const {
        std::cout << indent() << "For" << std::endl;
        print_each_sub(for_.Content->instructions);
    }

    void operator()(ast::Foreach& for_) const {
        std::cout << indent() << "Foreach" << std::endl;
        print_each_sub(for_.Content->instructions);
    }

    void operator()(ast::ForeachIn& for_) const {
        std::cout << indent() << "Foreach in " << std::endl;
        print_each_sub(for_.Content->instructions);
    }

    void operator()(ast::Switch& switch_) const {
        std::cout << indent() << "Switch " << std::endl;

        ++level;

        std::cout << indent() << "Value" << std::endl;
        print_sub(switch_.Content->value);

        for(auto& case_ : switch_.Content->cases){
            visit_non_variant(*this, case_);
        }

        if(switch_.Content->default_case){
            visit_non_variant(*this, *switch_.Content->default_case);
        }

        --level;
    }

    void operator()(ast::SwitchCase& switch_case) const {
        std::cout << indent() << "Case" << std::endl;

        ++level;

        std::cout << indent() << "Value" << std::endl;
        print_sub(switch_case.value);

        std::cout << indent() << "Instructions" << std::endl;
        print_each_sub(switch_case.instructions);

        --level;
    }

    void operator()(ast::DefaultCase& default_case) const {
        std::cout << indent() << "Default Case" << std::endl;

        print_each_sub(default_case.instructions);
    }

    void operator()(ast::While& while_) const {
        std::cout << indent() << "While" << std::endl;
        std::cout << indent() << "Condition:" << std::endl;
        print_sub(while_.Content->condition);
        print_each_sub(while_.Content->instructions);
    }

    void operator()(ast::DoWhile& while_) const {
        std::cout << indent() << "Do while" << std::endl;
        std::cout << indent() << "Condition:" << std::endl;
        print_sub(while_.Content->condition);
        std::cout << indent() << "Body:" << std::endl;
        print_each_sub(while_.Content->instructions);
    }

    void operator()(ast::Swap&) const {
        std::cout << indent() << "Swap" << std::endl;
    }

    void operator()(ast::If& if_) const {
        std::cout << indent() << "If" << std::endl;

        std::cout << indent() << "Condition:" << std::endl;
        print_sub(if_.Content->condition);

        std::cout << indent() << "Instructions" << std::endl;
        print_each_sub(if_.Content->instructions);

        for(auto& else_if : if_.Content->elseIfs){
            std::cout << indent() << "ElseIf" << std::endl;

            std::cout << indent() << "Condition:" << std::endl;
            print_sub(else_if.condition);

            std::cout << indent() << "Instructions" << std::endl;
            print_each_sub(else_if.instructions);
        }

        if(if_.Content->else_){
            std::cout << indent() << "Else" << std::endl;

            std::cout << indent() << "Instructions" << std::endl;
            print_each_sub((*if_.Content->else_).instructions);
        }
    }

    void operator()(ast::FunctionCall& call) const {
        std::cout << indent() << "FunctionCall " << call.Content->functionName << std::endl;
        print_each_sub(call.Content->values);
    }

    void operator()(ast::MemberFunctionCall& call) const {
        std::cout << indent() << "Member FunctionCall " << call.Content->object_name << "." << call.Content->function_name << std::endl;
        print_each_sub(call.Content->values);
    }

    void operator()(ast::BuiltinOperator& builtin) const {
        std::cout << indent() << "Builtin Operator " << (int) builtin.Content->type << std::endl;
        print_each_sub(builtin.Content->values);
    }

    void operator()(ast::VariableDeclaration& declaration) const {
        std::cout << indent() << "Variable declaration [" << declaration.Content->variableName << "]" << std::endl;

        if(declaration.Content->value){
            print_sub(*declaration.Content->value);
        }
    }

    void operator()(ast::ArrayDeclaration&) const {
        std::cout << indent() << "Array declaration" << std::endl;
    }

    void operator()(ast::SuffixOperation& op) const {
        std::cout << indent() << op.Content->variableName << "(suffix)" << (int)op.Content->op << std::endl;
    }

    void operator()(ast::PrefixOperation& op) const {
        std::cout << indent() << (int)op.Content->op << "(prefix)" << op.Content->variableName << std::endl;
    }

    void operator()(ast::Assignment& assign) const {
        std::cout << indent() << "Assignment [operator = " << static_cast<int>(assign.Content->op) << " ] " << std::endl;

        std::cout << indent() << "Left Value:" << std::endl;
        print_sub(assign.Content->left_value);

        std::cout << indent() << "Right Value:" << std::endl;
        print_sub(assign.Content->value);
    }

    void operator()(ast::Ternary& ternary) const {
        std::cout << indent() << "Ternary" << std::endl;

        std::cout << indent() << "Condition Value:" << std::endl;
        print_sub(ternary.Content->condition);

        std::cout << indent() << "True Value:" << std::endl;
        print_sub(ternary.Content->true_value);

        std::cout << indent() << "False Value:" << std::endl;
        print_sub(ternary.Content->false_value);
    }

    void operator()(ast::Return& return_) const {
        std::cout << indent() << "Function return" << std::endl;
        print_sub(return_.Content->value);
    }

    void operator()(ast::Litteral& litteral) const {
        std::cout << indent() << "Litteral [" << litteral.value << "]" << std::endl;
    }

    void operator()(ast::Integer& integer) const {
        std::cout << indent() << "Integer [" << integer.value << "]" << std::endl;
    }

    void operator()(ast::IntegerSuffix& integer) const {
        std::cout << indent() << "Float (suffix) [" << integer.value << "f]" << std::endl;
    }

    void operator()(ast::Float& float_) const {
        std::cout << indent() << "Float [" << float_.value << "]" << std::endl;
    }

    void operator()(ast::True&) const {
        std::cout << indent() << "true" << std::endl;
    }

    void operator()(ast::Null&) const {
        std::cout << indent() << "null" << std::endl;
    }

    void operator()(ast::False&) const {
        std::cout << indent() << "false" << std::endl;
    }

    void operator()(ast::VariableValue& value) const {
        std::cout << indent() << "Variable " << value.Content->var->name();

        for(auto& member : value.Content->memberNames){
            std::cout << "." << member;
        }

        std::cout << std::endl;
    }

    void operator()(ast::DereferenceValue& value) const {
        std::cout << indent() << "Dereference Variable Value" << std::endl;;

        std::cout << indent() << "Left Value:" << std::endl;
        print_sub(value.Content->ref);
    }

    void operator()(ast::ArrayValue& value) const {
        std::cout << indent() << "Array value [" << value.Content->arrayName << "]" << std::endl;
        print_sub(value.Content->indexValue);
    }

    void operator()(ast::Expression& value) const {
        std::cout << indent() << "Expression [" << value.Content->operations.size() << "]" << std::endl;
        ++level;
        visit(*this, value.Content->first);
        for(auto& operation : value.Content->operations){
            std::cout << indent() << (int) operation.get<0>() << std::endl;
            visit(*this, operation.get<1>());
        }
        --level;
    }

    void operator()(ast::Unary& value) const {
        std::cout << indent() << "Unary " << static_cast<int>(value.Content->op) << std::endl;
        print_sub(value.Content->value);
    }

    void operator()(ast::Cast& cast) const {
        std::cout << indent() << "Cast " << std::endl;
        std::cout << indent() << "\tType: " << toStringType(cast.Content->type) << std::endl;
        print_sub(cast.Content->value);
    }
};

} //end of anonymous namespace

void ast::Printer::print(SourceFile& program){
    DebugVisitor visitor;
    visit_non_variant(visitor, program);
}
<|endoftext|>


<commit_before>//
//  settings_view.cc
//  AirHockey
//
//  Created by Jon Sharkey on 2013-05-08.
//  Copyright 2013 Sharkable. All rights reserved.
//

#include "airhockey/views/settings_view.h"

#include "gameengine/entities/multi_select.h"
#include "gameengine/entities/simple_item.h"
#include "gameengine/modules/persistence_module.h"
#include "gameengine/game_engine.h"

#include "airhockey/entities/paddle.h"

using std::string;

static const int kMaxNumPucks = 7;
static const int kAnimateTicks = 30;

// Local Store keys
const string kLocalStoreDifficulty = "ls_difficulty";
const string kLocalStoreNumPucks = "ls_num_pucks";
const string kLocalStorePaddleSize = "ls_paddle_size";

SettingsView::SettingsView(GameEngine &game_engine, SettingsViewDelegate &delegate)
    : game_engine_(game_engine),
      delegate_(delegate) {
  sp<PersistenceModule> persistence = game_engine.persistence_module();

  double width = game_engine.screen_size_to_game_size(game_engine.screen_size()).width;
  ending_position_ = GamePoint(-width, 0);

  x_position_animation_.Reset(width, 0, kAnimateTicks, kAnimationTypeCubicEaseOut);

  Sprite background_image(game_engine, "settings_bg");
  background_ = new SimpleItem(background_image, game_engine.position("settings_bg"));

  num_pucks_select_ = new MultiSelect(game_engine);
  for (int i = 1; i <= kMaxNumPucks; i++) {
    char pucks_str[15];
    sprintf(pucks_str, "%d", i);
    char pucks_selected_str[15];
    sprintf(pucks_selected_str, "%d_selected", i);

    Sprite num_pucks_image(game_engine, pucks_str);
    Sprite num_pucks_selected_image(game_engine, pucks_selected_str);
    GamePoint num_pucks_position = game_engine.position(pucks_str);
    num_pucks_select_->Add(num_pucks_image, num_pucks_selected_image, num_pucks_position);
  }
  num_pucks_select_->set_selected_value(persistence->IntegerForKey(kLocalStoreNumPucks));

  Sprite bad_image(game_engine, "bad");
  Sprite bad_image_selected(game_engine, "bad_selected");
  Sprite good_image(game_engine, "good");
  Sprite good_image_selected(game_engine, "good_selected");
  Sprite excellent_image(game_engine, "excellent");
  Sprite excellent_image_selected(game_engine, "excellent_selected");
  Sprite amazing_image(game_engine, "amazing");
  Sprite amazing_image_selected(game_engine, "amazing_selected");
  difficulty_select_ = new MultiSelect(game_engine);
  difficulty_select_->Add(bad_image, bad_image_selected, game_engine.position("bad"));
  difficulty_select_->Add(good_image, good_image_selected, game_engine.position("good"));
  difficulty_select_->Add(excellent_image, excellent_image_selected,
                          game_engine.position("excellent"));
  difficulty_select_->Add(amazing_image, amazing_image_selected, game_engine.position("amazing"));
  difficulty_select_->set_selected_value(persistence->IntegerForKey(kLocalStoreDifficulty));

  Sprite small_image(game_engine, "small");
  Sprite small_image_selected(game_engine, "small_selected");
  Sprite medium_image(game_engine, "medium");
  Sprite medium_image_selected(game_engine, "medium_selected");
  Sprite large_image(game_engine, "large");
  Sprite large_image_selected(game_engine, "large_selected");
  paddle_size_select_ = new MultiSelect(game_engine);
  paddle_size_select_->Add(small_image, small_image_selected, game_engine.position("small"));
  paddle_size_select_->Add(medium_image, medium_image_selected, game_engine.position("medium"));
  paddle_size_select_->Add(large_image, large_image_selected, game_engine.position("large"));
  paddle_size_select_->set_selected_value(persistence->IntegerForKey(kLocalStorePaddleSize));

  Sprite ok_button_image(game_engine, "ok_button");
  Sprite ok_button_pressed_image(game_engine, "ok_button_pressed");
  ok_button_ = new Button(game_engine);
  ok_button_->set_normal_sprite(ok_button_image);
  ok_button_->set_pressed_sprite(ok_button_pressed_image);
  ok_button_->set_position(game_engine.position("ok_button"));
  ok_button_->set_delegate(this);
}

// TOOD
//bool SettingsView::HandleBackButton() {
//  ButtonUp(NULL);
//  return true;
//}

#pragma mark - Simulator

void SettingsView::SimulateStep() {
  if (x_position_animation_.IsActive()) {
    x_position_ = x_position_animation_.Update();
  } else {
    if (x_position_ < 0) {
      delegate_.SettingsViewFinished();
    }
  }
}

#pragma mark - Renderer

void SettingsView::Render(CoordinateSystem const &coordinate_system) {
  GamePoint offset(x_position_, 0);
  CoordinateSystem local_system = coordinate_system.Subsystem(0.f, offset);
  background_->Render(local_system);
  num_pucks_select_->Render(offset);
  difficulty_select_->Render(offset);
  paddle_size_select_->Render(offset);
  ok_button_->Render(offset, 0.f);
}

#pragma mark - InputHandler

bool SettingsView::HandleEvent(InputEvent const &event) {
  // TODO NOW support event handling in MultiSelect.
  ok_button_->HandleEvent(event);
  return x_position_ >= 0;
}

#pragma mark - ButtonDelegate

void SettingsView::ButtonUp(Button *button) {
  sp<PersistenceModule> persistence = game_engine_.persistence_module();
  persistence->SetInteger(num_pucks_select_->selected_value(), kLocalStoreNumPucks);
  persistence->SetInteger(difficulty_select_->selected_value(), kLocalStoreDifficulty);
  persistence->SetInteger(paddle_size_select_->selected_value(), kLocalStorePaddleSize);
  x_position_animation_.Reset(x_position_, ending_position_.x, kAnimateTicks,
                              kAnimationTypeCubicEaseIn);
}
<commit_msg>Pass input to multi selects.<commit_after>//
//  settings_view.cc
//  AirHockey
//
//  Created by Jon Sharkey on 2013-05-08.
//  Copyright 2013 Sharkable. All rights reserved.
//

#include "airhockey/views/settings_view.h"

#include "gameengine/entities/multi_select.h"
#include "gameengine/entities/simple_item.h"
#include "gameengine/modules/persistence_module.h"
#include "gameengine/game_engine.h"

#include "airhockey/entities/paddle.h"

using std::string;

static const int kMaxNumPucks = 7;
static const int kAnimateTicks = 30;

// Local Store keys
const string kLocalStoreDifficulty = "ls_difficulty";
const string kLocalStoreNumPucks = "ls_num_pucks";
const string kLocalStorePaddleSize = "ls_paddle_size";

SettingsView::SettingsView(GameEngine &game_engine, SettingsViewDelegate &delegate)
    : game_engine_(game_engine),
      delegate_(delegate) {
  sp<PersistenceModule> persistence = game_engine.persistence_module();

  double width = game_engine.screen_size_to_game_size(game_engine.screen_size()).width;
  ending_position_ = GamePoint(-width, 0);

  x_position_animation_.Reset(width, 0, kAnimateTicks, kAnimationTypeCubicEaseOut);

  Sprite background_image(game_engine, "settings_bg");
  background_ = new SimpleItem(background_image, game_engine.position("settings_bg"));

  num_pucks_select_ = new MultiSelect(game_engine);
  for (int i = 1; i <= kMaxNumPucks; i++) {
    char pucks_str[15];
    sprintf(pucks_str, "%d", i);
    char pucks_selected_str[15];
    sprintf(pucks_selected_str, "%d_selected", i);

    Sprite num_pucks_image(game_engine, pucks_str);
    Sprite num_pucks_selected_image(game_engine, pucks_selected_str);
    GamePoint num_pucks_position = game_engine.position(pucks_str);
    num_pucks_select_->Add(num_pucks_image, num_pucks_selected_image, num_pucks_position);
  }
  num_pucks_select_->set_selected_value(persistence->IntegerForKey(kLocalStoreNumPucks));

  Sprite bad_image(game_engine, "bad");
  Sprite bad_image_selected(game_engine, "bad_selected");
  Sprite good_image(game_engine, "good");
  Sprite good_image_selected(game_engine, "good_selected");
  Sprite excellent_image(game_engine, "excellent");
  Sprite excellent_image_selected(game_engine, "excellent_selected");
  Sprite amazing_image(game_engine, "amazing");
  Sprite amazing_image_selected(game_engine, "amazing_selected");
  difficulty_select_ = new MultiSelect(game_engine);
  difficulty_select_->Add(bad_image, bad_image_selected, game_engine.position("bad"));
  difficulty_select_->Add(good_image, good_image_selected, game_engine.position("good"));
  difficulty_select_->Add(excellent_image, excellent_image_selected,
                          game_engine.position("excellent"));
  difficulty_select_->Add(amazing_image, amazing_image_selected, game_engine.position("amazing"));
  difficulty_select_->set_selected_value(persistence->IntegerForKey(kLocalStoreDifficulty));

  Sprite small_image(game_engine, "small");
  Sprite small_image_selected(game_engine, "small_selected");
  Sprite medium_image(game_engine, "medium");
  Sprite medium_image_selected(game_engine, "medium_selected");
  Sprite large_image(game_engine, "large");
  Sprite large_image_selected(game_engine, "large_selected");
  paddle_size_select_ = new MultiSelect(game_engine);
  paddle_size_select_->Add(small_image, small_image_selected, game_engine.position("small"));
  paddle_size_select_->Add(medium_image, medium_image_selected, game_engine.position("medium"));
  paddle_size_select_->Add(large_image, large_image_selected, game_engine.position("large"));
  paddle_size_select_->set_selected_value(persistence->IntegerForKey(kLocalStorePaddleSize));

  Sprite ok_button_image(game_engine, "ok_button");
  Sprite ok_button_pressed_image(game_engine, "ok_button_pressed");
  ok_button_ = new Button(game_engine);
  ok_button_->set_normal_sprite(ok_button_image);
  ok_button_->set_pressed_sprite(ok_button_pressed_image);
  ok_button_->set_position(game_engine.position("ok_button"));
  ok_button_->set_delegate(this);
}

// TOOD
//bool SettingsView::HandleBackButton() {
//  ButtonUp(NULL);
//  return true;
//}

#pragma mark - Simulator

void SettingsView::SimulateStep() {
  if (x_position_animation_.IsActive()) {
    x_position_ = x_position_animation_.Update();
  } else {
    if (x_position_ < 0) {
      delegate_.SettingsViewFinished();
    }
  }
}

#pragma mark - Renderer

void SettingsView::Render(CoordinateSystem const &coordinate_system) {
  GamePoint offset(x_position_, 0);
  CoordinateSystem local_system = coordinate_system.Subsystem(0.f, offset);
  background_->Render(local_system);
  num_pucks_select_->Render(offset);
  difficulty_select_->Render(offset);
  paddle_size_select_->Render(offset);
  ok_button_->Render(offset, 0.f);
}

#pragma mark - InputHandler

bool SettingsView::HandleEvent(InputEvent const &event) {
  InputEvent new_event(event.Action(), event.Id(), event.Location() + GamePoint(x_position_, 0));
  ok_button_->HandleEvent(new_event);
  num_pucks_select_->HandleEvent(new_event);
  difficulty_select_->HandleEvent(new_event);
  paddle_size_select_->HandleEvent(new_event);
  return x_position_ >= 0;
}

#pragma mark - ButtonDelegate

void SettingsView::ButtonUp(Button *button) {
  sp<PersistenceModule> persistence = game_engine_.persistence_module();
  persistence->SetInteger(num_pucks_select_->selected_value(), kLocalStoreNumPucks);
  persistence->SetInteger(difficulty_select_->selected_value(), kLocalStoreDifficulty);
  persistence->SetInteger(paddle_size_select_->selected_value(), kLocalStorePaddleSize);
  x_position_animation_.Reset(x_position_, ending_position_.x, kAnimateTicks,
                              kAnimationTypeCubicEaseIn);
}
<|endoftext|>


<commit_before>// MIT License
//
// Copyright (c) 2017 Artur Wyszyński, aljen at hitomi dot pl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "shared_library.h"

#include <dlfcn.h>
#include "spaghetti/logger.h"

namespace spaghetti {

SharedLibrary::SharedLibrary(fs::path a_file, std::error_code &a_errorCode)
  : m_filename{ a_file.string() }
{
  log::info("[shared_library]: Opening {}", m_filename);

  if (!fs::exists(a_file)) {
    log::error("{} don't exist!", m_filename);
    a_errorCode = std::error_code(ENOENT, std::system_category());
    return;
  }

  if (a_file.extension() != ".so") {
    log::error("{} is not shared library!", m_filename);
    a_errorCode = std::error_code(EINVAL, std::system_category());
    return;
  }

  m_handle = dlopen(a_file.c_str(), RTLD_NOW);
  if (m_handle == nullptr) {
    log::error("{}", dlerror());
    a_errorCode = std::error_code(EINVAL, std::system_category());
    return;
  }

  a_errorCode = std::error_code(0, std::system_category());
}

SharedLibrary::~SharedLibrary()
{
  log::info("[shared_library]: Closing {}", m_filename);
  if (m_handle) dlclose(m_handle);
}

bool SharedLibrary::has(std::string_view a_signature) const
{
  log::info("[shared_library]: Checking if symbol {} exists in {}", a_signature.data(), m_filename);

  if (m_handle == nullptr) return false;

  return dlsym(m_handle, a_signature.data()) != nullptr;
}

void *SharedLibrary::getSymbol(std::string_view a_signature)
{
  log::info("[shared_library]: Getting symbol {} from {}", a_signature.data(), m_filename);

  return dlsym(m_handle, a_signature.data());
}

} // namespace spaghetti
<commit_msg>Stub SharedLibrary on Windows for now<commit_after>// MIT License
//
// Copyright (c) 2017 Artur Wyszyński, aljen at hitomi dot pl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "shared_library.h"

#if defined(_WIN32)
#include <Windows.h>
#elif defined(__unix__)
#include <dlfcn.h>
#endif
#include "spaghetti/logger.h"

namespace spaghetti {

SharedLibrary::SharedLibrary(fs::path a_file, std::error_code &a_errorCode)
  : m_filename{ a_file.string() }
{
  log::info("[shared_library]: Opening {}", m_filename);

  if (!fs::exists(a_file)) {
    log::error("{} don't exist!", m_filename);
    a_errorCode = std::error_code(ENOENT, std::system_category());
    return;
  }

  if (a_file.extension() != ".so") {
    log::error("{} is not shared library!", m_filename);
    a_errorCode = std::error_code(EINVAL, std::system_category());
    return;
  }

#if defined(_WIN32)
  a_errorCode = std::error_code(EINVAL, std::system_category());
#elif defined(__unix__)
  m_handle = dlopen(a_file.c_str(), RTLD_NOW);
  if (m_handle == nullptr) {
    log::error("{}", dlerror());
    a_errorCode = std::error_code(EINVAL, std::system_category());
    return;
  }
#endif

  a_errorCode = std::error_code(0, std::system_category());
}

SharedLibrary::~SharedLibrary()
{
  log::info("[shared_library]: Closing {}", m_filename);
#if defined(_WIN32)
#elif defined(__unix__)
  if (m_handle) dlclose(m_handle);
#endif
}

bool SharedLibrary::has(std::string_view a_signature) const
{
  log::info("[shared_library]: Checking if symbol {} exists in {}", a_signature.data(), m_filename);

  if (m_handle == nullptr) return false;

#if defined(_WIN32)
  return false;
#elif defined(__unix__)
  return dlsym(m_handle, a_signature.data()) != nullptr;
#endif
}

void *SharedLibrary::getSymbol(std::string_view a_signature)
{
  log::info("[shared_library]: Getting symbol {} from {}", a_signature.data(), m_filename);

#if defined(_WIN32)
  return nullptr;
#elif defined(__unix__)
  return dlsym(m_handle, a_signature.data());
#endif
}

} // namespace spaghetti
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.txt
 */
#include <cassert>
#include <iostream>
#include "hdf5MetaData.h"
#include "halCommon.h"

using namespace hal;
using namespace H5;
using namespace std;

HDF5MetaData::HDF5MetaData() :
  _parent(NULL)
{
}

HDF5MetaData::HDF5MetaData(CommonFG* parent, const string& name)
{
  open(parent, name);
}

HDF5MetaData::~HDF5MetaData()
{
  write();
}

void HDF5MetaData::set(const string& key, const string& value)
{
  if (has(key) == true)
  {
    _map[key] = value;
  }
  else
  {
    _map.insert(pair<string, string>(key, value));
  }
  _dirty = true;
}

const string& HDF5MetaData::get(const string& key) const
{
  assert (has(key) == true);
  return _map.find(key)->second;
}

bool HDF5MetaData::has(const string& key) const
{
  return _map.find(key) != _map.end();
}

const map<string, string>& HDF5MetaData::getMap() const
{
  return _map;
}

static void attr_operator(H5Object& loc/*in*/,
                          const H5std_string attr_name/*in*/,
                          void *operator_data/*in,out*/)
{
  map<string, string>* attMap =
     static_cast<map<string, string>*>(operator_data);
  StrType vlsType(0, H5T_VARIABLE);
  Attribute attr = loc.openAttribute(attr_name);
  H5std_string strg;
  attr.read(vlsType, strg);
  attMap->insert(pair<string, string>(attr_name, strg));
}

void HDF5MetaData::open(CommonFG* parent, const string& name)
{
  assert(parent != NULL);
  _map.clear();
  _parent = parent;
  _name = name;
  _dirty = false;

  H5::Exception::dontPrint();
  try
  {
    _group = parent->openGroup(name);
  }
  catch (Exception& e)
  {
    _group = parent->createGroup(name);
  }

  if (_group.getNumAttrs() > 0)
  {
    _group.iterateAttrs(attr_operator, NULL, &_map);
  }
  assert(_map.size() == (size_t)_group.getNumAttrs());
}

void HDF5MetaData::write()
{
  if (!_dirty)
     return;

  for (map<string, string>::iterator i = _map.begin();
       i != _map.end();
       ++i)
  {
    StrType vlsType(0, H5T_VARIABLE);
    DataSpace attSpace(H5S_SCALAR);
    Attribute attr;
    // we delve into C api for this test
    if (H5Aexists(_group.getId(), i->first.c_str()) == true)
    {
      _group.removeAttr(i->first.c_str());
    }
    attr = _group.createAttribute(i->first, vlsType, attSpace);
    attr.write(vlsType, i->second);
  }
  _dirty = false;
}
<commit_msg>change attr_operator prototype to be compatible for newer hdf5 versions<commit_after>/*
 * Copyright (C) 2012 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.txt
 */
#include <cassert>
#include <iostream>
#include "hdf5MetaData.h"
#include "halCommon.h"

using namespace hal;
using namespace H5;
using namespace std;

HDF5MetaData::HDF5MetaData() :
  _parent(NULL)
{
}

HDF5MetaData::HDF5MetaData(CommonFG* parent, const string& name)
{
  open(parent, name);
}

HDF5MetaData::~HDF5MetaData()
{
  write();
}

void HDF5MetaData::set(const string& key, const string& value)
{
  if (has(key) == true)
  {
    _map[key] = value;
  }
  else
  {
    _map.insert(pair<string, string>(key, value));
  }
  _dirty = true;
}

const string& HDF5MetaData::get(const string& key) const
{
  assert (has(key) == true);
  return _map.find(key)->second;
}

bool HDF5MetaData::has(const string& key) const
{
  return _map.find(key) != _map.end();
}

const map<string, string>& HDF5MetaData::getMap() const
{
  return _map;
}

// hack this in for compatibility for newer hdf5 which seems to have changed
// interface from object to location here.
#if H5_VERSION_GE(1, 8, 12)
#define ATTR_OP_PARAM__ H5Location
#else
#define ATTR_OP_PARAM__ H5Object
#endif
static void attr_operator(ATTR_OP_PARAM__& loc/*in*/,
                          const H5std_string attr_name/*in*/,
                          void *operator_data/*in,out*/)
{
  map<string, string>* attMap =
     static_cast<map<string, string>*>(operator_data);
  StrType vlsType(0, H5T_VARIABLE);
  Attribute attr = loc.openAttribute(attr_name);
  H5std_string strg;
  attr.read(vlsType, strg);
  attMap->insert(pair<string, string>(attr_name, strg));
}

void HDF5MetaData::open(CommonFG* parent, const string& name)
{
  assert(parent != NULL);
  _map.clear();
  _parent = parent;
  _name = name;
  _dirty = false;

  H5::Exception::dontPrint();
  try
  {
    _group = parent->openGroup(name);
  }
  catch (Exception& e)
  {
    _group = parent->createGroup(name);
  }

  if (_group.getNumAttrs() > 0)
  {
    _group.iterateAttrs(attr_operator, NULL, (void*)&_map);
  }
  assert(_map.size() == (size_t)_group.getNumAttrs());
}

void HDF5MetaData::write()
{
  if (!_dirty)
     return;

  for (map<string, string>::iterator i = _map.begin();
       i != _map.end();
       ++i)
  {
    StrType vlsType(0, H5T_VARIABLE);
    DataSpace attSpace(H5S_SCALAR);
    Attribute attr;
    // we delve into C api for this test
    if (H5Aexists(_group.getId(), i->first.c_str()) == true)
    {
      _group.removeAttr(i->first.c_str());
    }
    attr = _group.createAttribute(i->first, vlsType, attSpace);
    attr.write(vlsType, i->second);
  }
  _dirty = false;
}
<|endoftext|>


<commit_before>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#ifndef NIX_DATA_ARRAY_H
#define NIX_DATA_ARRAY_H

#include <nix/DataSet.hpp>

#include <boost/multi_array.hpp>

#include <nix/base/EntityWithSources.hpp>
#include <nix/base/IDataArray.hpp>
#include <nix/Dimensions.hpp>
#include <nix/Hydra.hpp>

#include <nix/Platform.hpp>

namespace nix {

// TODO add documentation for undocumented methods.

/**
 * @brief A class that can store arbitrary n-dimensional data along with further
 * information.
 *
 * The {@link DataArray} is the core entity of the NIX data model, its purpose is to
 * store arbitrary n-dimensional data. In addition to the common fields id, name, type, and definition
 * the DataArray stores sufficient information to understand the physical nature of the stored data.
 *
 * A guiding principle of the data model is provides enough information to create a
 * plot of the stored data. In order to do so, the DataArray defines a property
 * {@link dataType} which provides the physical type of the stored data (for example
 * 16 bit integer or double precision IEEE floatingpoint number).
 * The property {@link unit} specifies the SI unit of the values stored in the
 * DataArray{} whereas the {@link label} defines what is given in this units.
 * Together, both specify what corresponds to the the y-axis of a plot.
 *
 * In some cases it is much more efficient or convenient to store data not as
 * floating point numbers but rather as (16 bit) integer values as, for example
 * read from a data acquisition board.
 * In order to convert such data to the correct values, we follow the approach
 * taken by the comedi data-acquisition library (http://www.comedi.org)
 * and provide {@link polynomCoefficients} and an {@link expansionOrigin}.
 *
 * ### Create a new data array with a 10 x 10 float matrix as data
 *
 * A DataArray can only be created at an existing block. Do not use the
 * DataArrays constructors for this purpose.
 *
 * ~~~
 * Block b = ...;
 * DataArray da = b.crateDataArray("matrix_10_10", "data");
 * da.createData(DataType::Float, {10, 10});
 * ~~~
 *
 * ### Remove a data array from a file
 *
 * ~~~
 * Block b = ...;
 * bool deleted = da.deleteDataArray(some_id);
 * ~~~
 */
class NIXAPI DataArray : public base::EntityWithSources<base::IDataArray>, public DataSet {

public:

    /**
     * @brief Constructor that creates an uninitialized DataArray.
     *
     * Calling any method on an uninitialized data array will throw a {@link nix::UninitializedEntity}
     * exception. The following code illustrates how to check if a data array is initialized:
     *
     * ~~~
     * DataArray e = ...;
     * if (e) {
     *     // e is initialised
     * } else {
     *     // e is uninitialized
     * }
     * ~~~
     */
    DataArray()
        : EntityWithSources()
    {}

    /**
     * @brief Copy constructor.
     *
     * Copying of all NIX front facing objects like DataArray is a rather cheap operation.
     * Semantically this is equivalent to the creation of another reference to the original
     * object.
     *
     * @param other     The data array to copy.
     */
    DataArray(const DataArray &other)
        : EntityWithSources(other.impl())
    {
    }

    /**
     * @brief Constructor that creates a new data array from a shared pointer to
     * an implementation instance.
     *
     * This constructor should only be used in the back-end.
     */
    DataArray(const std::shared_ptr<base::IDataArray> &p_impl)
        : EntityWithSources(p_impl)
    {
    }

    /**
     * @brief Constructor with move semantics that creates a new data array from a shared pointer to
     * an implementation instance.
     *
     * This constructor should only be used in the back-end.
     */
    DataArray(std::shared_ptr<base::IDataArray> &&ptr)
        : EntityWithSources(std::move(ptr))
    {
    }

    //--------------------------------------------------
    // Element getters and setters
    //--------------------------------------------------

    /**
     * @brief Get the label for the values stored in the DataArray.
     *
     * @return The label of the data array.
     */
    boost::optional<std::string> label() const {
        return backend()->label();
    }

    /**
     * @brief Set the label for the data stored.
     *
     * @param label     The label of the data array.
     */
    void label(const std::string &label) {
        backend()->label(label);
    }

    /**
     * @brief Deleter for the label attribute.
     *
     * @param t         None
     */
    void label(const none_t t) {
        backend()->label(t);
    }

    /**
     * @brief Get the unit of the data stored in this data array.
     *
     * @return The unit of the data array.
     */
    boost::optional<std::string> unit() const {
        return backend()->unit();
    }

    /**
     * @brief Deleter for the unit attribute.
     *
     * @param t         None
     */
    void unit(const none_t t) {
        backend()->unit(t);
    }

    /**
     * @brief Set the unit for the values stored in this DataArray.
     *
     * @param unit      The unit of the data array.
     */
    void unit(const std::string &unit);

    /**
     * @brief Returns the expansion origin of the calibration polynom.
     *
     * The expansion origin is 0.0 by default.
     *
     * @return The expansion origin.
     */
    boost::optional<double> expansionOrigin() const {
        return backend()->expansionOrigin();
    }

    /**
     * @brief Set the expansion origin for the calibration.
     *
     * @param expansion_origin  The expansion origin for the calibration.
     */
    void expansionOrigin(double expansion_origin) {
        backend()->expansionOrigin(expansion_origin);
    }

    /**
     * @brief Deleter for the expansion origin.
     *
     * This will reset the expansion origin for the calibration to its
     * default value which is given with 0.0.
     *
     * @param t         None
     */
    void expansionOrigin(const none_t t) {
        backend()->expansionOrigin(t);
    }

    /**
     * @brief Set the polynom coefficients for the calibration.
     *
     * By default this is set to a two element vector of [0.0, 1.0] for a linear calibration
     * with zero offset.
     *
     * @param polynom_coefficients      The new polynom coefficients for the calibration.
     */
    void polynomCoefficients(const std::vector<double> &polynom_coefficients) {
        backend()->polynomCoefficients(polynom_coefficients);
    }

    /**
     * @brief Returns the polynom coefficients.
     *
     * @return The polynom coefficients for the calibration.
     */
    std::vector<double> polynomCoefficients() const {
        return backend()->polynomCoefficients();
    }

    /**
     * @brief Deleter for the `polynomCoefficients` attribute.
     *
     * @param t         None
     */
    void polynomCoefficients(const none_t t) {
        backend()->polynomCoefficients(t);
    }

    //--------------------------------------------------
    // Methods concerning dimensions
    //--------------------------------------------------

    /**
     * @brief Get all dimensions associated with this data array.
     *
     * The parameter filter can be used to filter sources by various
     * criteria.
     *
     * @param filter    A filter function ({@link nix::util::Filter::type})
     *
     * @return The filtered dimensions as a vector
     */
    std::vector<Dimension> dimensions(const util::Filter<Dimension>::type &filter) const;

    /**
     * @brief Get all dimensions associated with this data array.
     *
     * Always uses filter that accepts all sources.
     *
     * @return The filtered dimensions as a vector
     */
    std::vector<Dimension> dimensions() const {
        return dimensions(util::AcceptAll<Dimension>());
    }

    /**
     * @brief Returns the number of dimensions stored in the DataArray.
     *
     * This matches the dimensionality of the data stored in this property.
     *
     * @return The number of dimensions.
     */
    size_t dimensionCount() const {
        return backend()->dimensionCount();
    }

    /**
     * @brief Returns the Dimension object for the specified dimension of the data.
     *
     * @param id        The index of the respective dimension.
     *
     * @return The dimension object.
     */
    Dimension getDimension(size_t id) const {
        return backend()->getDimension(id);
    }

    /**
     * @brief Append a new SetDimension to the list of existing dimension descriptors.
     *
     * @return The newly created SetDimension.
     */
    SetDimension appendSetDimension() {
        return backend()->createSetDimension(backend()->dimensionCount() + 1);
    }

    /**
     * @brief Append a new RangeDimension to the list of existing dimension descriptors.
     *
     * @param ticks     The ticks of the RangeDimension to create.
     *
     * @return The newly created RangeDimension
     */
    RangeDimension appendRangeDimension(const std::vector<double> &ticks) {
        return backend()->createRangeDimension(backend()->dimensionCount() + 1, ticks);
    }

    /**
     * @brief Append a new SampledDimension to the list of existing dimension descriptors.
     *
     * @param sampling_interval         The sampling interval of the SetDimension to create.
     *
     * @return The newly created SampledDimension.
     */
    SampledDimension appendSampledDimension(double sampling_interval) {
        return backend()->createSampledDimension(backend()->dimensionCount() + 1, sampling_interval);
    }

    /**
     * @brief Create a new SetDimension at a specified dimension index.
     *
     * This adds a new dimension descriptor of the type {@link nix::SetDimension} that describes the dimension
     * of the data at the specified index.
     *
     * @param id        The index of the dimension. Must be a value > 0 and <= `dimensionCount + 1`.
     *
     * @return The created dimension descriptor.
     */
    SetDimension createSetDimension(size_t id) {
        return backend()->createSetDimension(id);
    }

    /**
     * @brief Create a new RangeDimension at a specified dimension index.
     *
     * This adds a new dimension descriptor of the type {@link nix::RangeDimension} that describes the dimension
     * of the data at the specified index.
     *
     * @param id        The index of the dimension. Must be a value > 0 and <= `dimensionCount + 1`.
     * @param ticks     Vector with {@link nix::RangeDimension::ticks}.
     *
     * @return The created dimension descriptor.
     */
    RangeDimension createRangeDimension(size_t id, const std::vector<double> &ticks) {
        return backend()->createRangeDimension(id, ticks);
    }

    /**
     * @brief Create a new SampledDimension at a specified dimension index.
     *
     * This adds a new dimension descriptor of the type {@link nix::SampledDimension} that describes the dimension
     * of the data at the specified index.
     *
     * @param id                The index of the dimension. Must be a value > 0 and <= `dimensionCount + 1`.
     * @param sampling_interval  The sampling interval of the dimension.
     *
     * @return The created dimension descriptor.
     */
    SampledDimension createSampledDimension(size_t id, double sampling_interval) {
        return backend()->createSampledDimension(id, sampling_interval);
    }

    /**
     * @brief Remove a dimension descriptor at a specified index.
     *
     * @param id        The index of the dimension. Must be a value > 0 and < `dimensionCount + 1`.
     */
    bool deleteDimension(size_t id) {
        return backend()->deleteDimension(id);
    }

    //--------------------------------------------------
    // Methods concerning data access.
    //--------------------------------------------------

    void getDataDirect(DataType dtype,
                       void *data,
                       const NDSize &count,
                       const NDSize &offset) const {
        backend()->read(dtype, data, count, offset);
    }

    void setDataDirect(DataType dtype,
                       const void *data,
                       const NDSize &count,
                       const NDSize &offset)
    {
        backend()->write(dtype, data, count, offset);
    }

    /**
     * @brief Get the extent of the data of the DataArray entity.
     *
     * @return The data extent.
     */
    NDSize dataExtent() const {
        return backend()->dataExtent();
    }

    /**
     * @brief Set the data extent of the DataArray entity.
     *
     * @param extent    The extent of the data.
     */
    void dataExtent(const NDSize &extent) {
        backend()->dataExtent(extent);
    }

    /**
     * @brief Get the data type of the data stored in the DataArray entity.
     *
     * @return The data type of the DataArray.
     */
    DataType dataType(void) const {
        return backend()->dataType();
    }

    void appendData(DataType dtype, const void *data, const NDSize &count, size_t axis);

    //--------------------------------------------------
    // Other methods and functions
    //--------------------------------------------------

    /**
     * @brief Assignment operator for none.
     */
    DataArray &operator=(const none_t &t) {
        ImplContainer::operator=(t);
        return *this;
    }

    /**
     * @brief Output operator
     */
    NIXAPI friend std::ostream& operator<<(std::ostream &out, const DataArray &ent);

    //
protected:
    //implementation of the DataIO interface
    void ioRead(DataType dtype,
                void *data,
                const NDSize &count,
                const NDSize &offset) const override;

    void ioWrite(DataType dtype,
                 const void *data,
                 const NDSize &count,
                 const NDSize &offset) override;
};

} // namespace nix

#endif // NIX_DATA_ARRAY_H
<commit_msg>[DataArray] Raise proper exception if ticks of range dimension are empty.<commit_after>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#ifndef NIX_DATA_ARRAY_H
#define NIX_DATA_ARRAY_H

#include <nix/DataSet.hpp>

#include <boost/multi_array.hpp>

#include <nix/base/EntityWithSources.hpp>
#include <nix/base/IDataArray.hpp>
#include <nix/Dimensions.hpp>
#include <nix/Hydra.hpp>

#include <nix/Platform.hpp>

namespace nix {

// TODO add documentation for undocumented methods.

/**
 * @brief A class that can store arbitrary n-dimensional data along with further
 * information.
 *
 * The {@link DataArray} is the core entity of the NIX data model, its purpose is to
 * store arbitrary n-dimensional data. In addition to the common fields id, name, type, and definition
 * the DataArray stores sufficient information to understand the physical nature of the stored data.
 *
 * A guiding principle of the data model is provides enough information to create a
 * plot of the stored data. In order to do so, the DataArray defines a property
 * {@link dataType} which provides the physical type of the stored data (for example
 * 16 bit integer or double precision IEEE floatingpoint number).
 * The property {@link unit} specifies the SI unit of the values stored in the
 * DataArray{} whereas the {@link label} defines what is given in this units.
 * Together, both specify what corresponds to the the y-axis of a plot.
 *
 * In some cases it is much more efficient or convenient to store data not as
 * floating point numbers but rather as (16 bit) integer values as, for example
 * read from a data acquisition board.
 * In order to convert such data to the correct values, we follow the approach
 * taken by the comedi data-acquisition library (http://www.comedi.org)
 * and provide {@link polynomCoefficients} and an {@link expansionOrigin}.
 *
 * ### Create a new data array with a 10 x 10 float matrix as data
 *
 * A DataArray can only be created at an existing block. Do not use the
 * DataArrays constructors for this purpose.
 *
 * ~~~
 * Block b = ...;
 * DataArray da = b.crateDataArray("matrix_10_10", "data");
 * da.createData(DataType::Float, {10, 10});
 * ~~~
 *
 * ### Remove a data array from a file
 *
 * ~~~
 * Block b = ...;
 * bool deleted = da.deleteDataArray(some_id);
 * ~~~
 */
class NIXAPI DataArray : public base::EntityWithSources<base::IDataArray>, public DataSet {

public:

    /**
     * @brief Constructor that creates an uninitialized DataArray.
     *
     * Calling any method on an uninitialized data array will throw a {@link nix::UninitializedEntity}
     * exception. The following code illustrates how to check if a data array is initialized:
     *
     * ~~~
     * DataArray e = ...;
     * if (e) {
     *     // e is initialised
     * } else {
     *     // e is uninitialized
     * }
     * ~~~
     */
    DataArray()
        : EntityWithSources()
    {}

    /**
     * @brief Copy constructor.
     *
     * Copying of all NIX front facing objects like DataArray is a rather cheap operation.
     * Semantically this is equivalent to the creation of another reference to the original
     * object.
     *
     * @param other     The data array to copy.
     */
    DataArray(const DataArray &other)
        : EntityWithSources(other.impl())
    {
    }

    /**
     * @brief Constructor that creates a new data array from a shared pointer to
     * an implementation instance.
     *
     * This constructor should only be used in the back-end.
     */
    DataArray(const std::shared_ptr<base::IDataArray> &p_impl)
        : EntityWithSources(p_impl)
    {
    }

    /**
     * @brief Constructor with move semantics that creates a new data array from a shared pointer to
     * an implementation instance.
     *
     * This constructor should only be used in the back-end.
     */
    DataArray(std::shared_ptr<base::IDataArray> &&ptr)
        : EntityWithSources(std::move(ptr))
    {
    }

    //--------------------------------------------------
    // Element getters and setters
    //--------------------------------------------------

    /**
     * @brief Get the label for the values stored in the DataArray.
     *
     * @return The label of the data array.
     */
    boost::optional<std::string> label() const {
        return backend()->label();
    }

    /**
     * @brief Set the label for the data stored.
     *
     * @param label     The label of the data array.
     */
    void label(const std::string &label) {
        backend()->label(label);
    }

    /**
     * @brief Deleter for the label attribute.
     *
     * @param t         None
     */
    void label(const none_t t) {
        backend()->label(t);
    }

    /**
     * @brief Get the unit of the data stored in this data array.
     *
     * @return The unit of the data array.
     */
    boost::optional<std::string> unit() const {
        return backend()->unit();
    }

    /**
     * @brief Deleter for the unit attribute.
     *
     * @param t         None
     */
    void unit(const none_t t) {
        backend()->unit(t);
    }

    /**
     * @brief Set the unit for the values stored in this DataArray.
     *
     * @param unit      The unit of the data array.
     */
    void unit(const std::string &unit);

    /**
     * @brief Returns the expansion origin of the calibration polynom.
     *
     * The expansion origin is 0.0 by default.
     *
     * @return The expansion origin.
     */
    boost::optional<double> expansionOrigin() const {
        return backend()->expansionOrigin();
    }

    /**
     * @brief Set the expansion origin for the calibration.
     *
     * @param expansion_origin  The expansion origin for the calibration.
     */
    void expansionOrigin(double expansion_origin) {
        backend()->expansionOrigin(expansion_origin);
    }

    /**
     * @brief Deleter for the expansion origin.
     *
     * This will reset the expansion origin for the calibration to its
     * default value which is given with 0.0.
     *
     * @param t         None
     */
    void expansionOrigin(const none_t t) {
        backend()->expansionOrigin(t);
    }

    /**
     * @brief Set the polynom coefficients for the calibration.
     *
     * By default this is set to a two element vector of [0.0, 1.0] for a linear calibration
     * with zero offset.
     *
     * @param polynom_coefficients      The new polynom coefficients for the calibration.
     */
    void polynomCoefficients(const std::vector<double> &polynom_coefficients) {
        backend()->polynomCoefficients(polynom_coefficients);
    }

    /**
     * @brief Returns the polynom coefficients.
     *
     * @return The polynom coefficients for the calibration.
     */
    std::vector<double> polynomCoefficients() const {
        return backend()->polynomCoefficients();
    }

    /**
     * @brief Deleter for the `polynomCoefficients` attribute.
     *
     * @param t         None
     */
    void polynomCoefficients(const none_t t) {
        backend()->polynomCoefficients(t);
    }

    //--------------------------------------------------
    // Methods concerning dimensions
    //--------------------------------------------------

    /**
     * @brief Get all dimensions associated with this data array.
     *
     * The parameter filter can be used to filter sources by various
     * criteria.
     *
     * @param filter    A filter function ({@link nix::util::Filter::type})
     *
     * @return The filtered dimensions as a vector
     */
    std::vector<Dimension> dimensions(const util::Filter<Dimension>::type &filter) const;

    /**
     * @brief Get all dimensions associated with this data array.
     *
     * Always uses filter that accepts all sources.
     *
     * @return The filtered dimensions as a vector
     */
    std::vector<Dimension> dimensions() const {
        return dimensions(util::AcceptAll<Dimension>());
    }

    /**
     * @brief Returns the number of dimensions stored in the DataArray.
     *
     * This matches the dimensionality of the data stored in this property.
     *
     * @return The number of dimensions.
     */
    size_t dimensionCount() const {
        return backend()->dimensionCount();
    }

    /**
     * @brief Returns the Dimension object for the specified dimension of the data.
     *
     * @param id        The index of the respective dimension.
     *
     * @return The dimension object.
     */
    Dimension getDimension(size_t id) const {
        return backend()->getDimension(id);
    }

    /**
     * @brief Append a new SetDimension to the list of existing dimension descriptors.
     *
     * @return The newly created SetDimension.
     */
    SetDimension appendSetDimension() {
        return backend()->createSetDimension(backend()->dimensionCount() + 1);
    }

    /**
     * @brief Append a new RangeDimension to the list of existing dimension descriptors.
     *
     * @param ticks     The ticks of the RangeDimension to create.
     *
     * @return The newly created RangeDimension
     */
    RangeDimension appendRangeDimension(const std::vector<double> &ticks) {
        if (ticks.size() == 0) {
            throw std::runtime_error("The ticks of a range dimension must not be empty!");
        }
        return backend()->createRangeDimension(backend()->dimensionCount() + 1, ticks);
    }

    /**
     * @brief Append a new SampledDimension to the list of existing dimension descriptors.
     *
     * @param sampling_interval         The sampling interval of the SetDimension to create.
     *
     * @return The newly created SampledDimension.
     */
    SampledDimension appendSampledDimension(double sampling_interval) {
        return backend()->createSampledDimension(backend()->dimensionCount() + 1, sampling_interval);
    }

    /**
     * @brief Create a new SetDimension at a specified dimension index.
     *
     * This adds a new dimension descriptor of the type {@link nix::SetDimension} that describes the dimension
     * of the data at the specified index.
     *
     * @param id        The index of the dimension. Must be a value > 0 and <= `dimensionCount + 1`.
     *
     * @return The created dimension descriptor.
     */
    SetDimension createSetDimension(size_t id) {
        return backend()->createSetDimension(id);
    }

    /**
     * @brief Create a new RangeDimension at a specified dimension index.
     *
     * This adds a new dimension descriptor of the type {@link nix::RangeDimension} that describes the dimension
     * of the data at the specified index.
     *
     * @param id        The index of the dimension. Must be a value > 0 and <= `dimensionCount + 1`.
     * @param ticks     Vector with {@link nix::RangeDimension::ticks}.
     *
     * @return The created dimension descriptor.
     */
    RangeDimension createRangeDimension(size_t id, const std::vector<double> &ticks) {
        if (ticks.size() == 0) {
            throw std::runtime_error("The ticks of a range dimension must not be empty!");
        }
        return backend()->createRangeDimension(id, ticks);
    }

    /**
     * @brief Create a new SampledDimension at a specified dimension index.
     *
     * This adds a new dimension descriptor of the type {@link nix::SampledDimension} that describes the dimension
     * of the data at the specified index.
     *
     * @param id                The index of the dimension. Must be a value > 0 and <= `dimensionCount + 1`.
     * @param sampling_interval  The sampling interval of the dimension.
     *
     * @return The created dimension descriptor.
     */
    SampledDimension createSampledDimension(size_t id, double sampling_interval) {
        return backend()->createSampledDimension(id, sampling_interval);
    }

    /**
     * @brief Remove a dimension descriptor at a specified index.
     *
     * @param id        The index of the dimension. Must be a value > 0 and < `dimensionCount + 1`.
     */
    bool deleteDimension(size_t id) {
        return backend()->deleteDimension(id);
    }

    //--------------------------------------------------
    // Methods concerning data access.
    //--------------------------------------------------

    void getDataDirect(DataType dtype,
                       void *data,
                       const NDSize &count,
                       const NDSize &offset) const {
        backend()->read(dtype, data, count, offset);
    }

    void setDataDirect(DataType dtype,
                       const void *data,
                       const NDSize &count,
                       const NDSize &offset)
    {
        backend()->write(dtype, data, count, offset);
    }

    /**
     * @brief Get the extent of the data of the DataArray entity.
     *
     * @return The data extent.
     */
    NDSize dataExtent() const {
        return backend()->dataExtent();
    }

    /**
     * @brief Set the data extent of the DataArray entity.
     *
     * @param extent    The extent of the data.
     */
    void dataExtent(const NDSize &extent) {
        backend()->dataExtent(extent);
    }

    /**
     * @brief Get the data type of the data stored in the DataArray entity.
     *
     * @return The data type of the DataArray.
     */
    DataType dataType(void) const {
        return backend()->dataType();
    }

    void appendData(DataType dtype, const void *data, const NDSize &count, size_t axis);

    //--------------------------------------------------
    // Other methods and functions
    //--------------------------------------------------

    /**
     * @brief Assignment operator for none.
     */
    DataArray &operator=(const none_t &t) {
        ImplContainer::operator=(t);
        return *this;
    }

    /**
     * @brief Output operator
     */
    NIXAPI friend std::ostream& operator<<(std::ostream &out, const DataArray &ent);

    //
protected:
    //implementation of the DataIO interface
    void ioRead(DataType dtype,
                void *data,
                const NDSize &count,
                const NDSize &offset) const override;

    void ioWrite(DataType dtype,
                 const void *data,
                 const NDSize &count,
                 const NDSize &offset) override;
};

} // namespace nix

#endif // NIX_DATA_ARRAY_H
<|endoftext|>


<commit_before>// See Fossen 2011, chapter 12.3.2
#include "lagrange_allocator.h"
#include <iostream>

template<typename Derived>
inline bool isFucked(const Eigen::MatrixBase<Derived>& x)
{
    return !((x.array() == x.array())).all() && !( (x - x).array() == (x - x).array()).all();
}

// Worlds worst print function :DDD
void printMatrix6(Eigen::MatrixXd m)
{
    ROS_INFO("----------------------------------");
    for(int col = 0; col < 6; col++){

        char buffer[512];

        for(int row = 0; row < 6; row++){
            snprintf( (buffer + (row*8) ), sizeof(buffer), "  %f  ", m(col, row));
        }
        ROS_INFO("%s", buffer);
    }
    ROS_INFO("----------------------------------\n");
}

LagrangeAllocator::LagrangeAllocator()
{
    // n = 4;
    // r = 6;

    tauSub = nh.subscribe("control_forces", 1, &LagrangeAllocator::tauCallback, this);
    uPub   = nh.advertise<uranus_dp::ThrusterForces>("control_inputs", 1);

    W.setIdentity(6,6); // Default to identity (i.e. equal weights)
    K.setIdentity(6,6); // Scaling is done on Arduino, so this can be identity

    // Our test ROV cannot control heave and roll, so they are removed from the control objective
    T <<  0.7071 ,  0.7071 ,  0.7071 ,  0.7071 ,  1    ,  1    , // Surge
         -0.7071 ,  0.7071 , -0.7071 ,  0.7071 ,  0    ,  0    , // Sway
          0.06718,  0.06718,  0.06718,  0.06718, -0.210, -0.210, // Pitch
          0.4172 ,  0.4172 , -0.4172 , -0.4172 , -0.165,  0.165; // Yaw

    K_inverse = K.inverse();
    computeGeneralizedInverse();
}

void LagrangeAllocator::tauCallback(const geometry_msgs::Wrench& tauMsg)
{
    tau << tauMsg.force.x,
           tauMsg.force.y,
           // tauMsg.force.z,  // Not part of control objective for test rov
           // tauMsg.torque.x, // Ditto
           tauMsg.torque.y,
           tauMsg.torque.z;

    u = K_inverse * T_geninverse * tau;

    if (isFucked(K_inverse))
    {
        ROS_WARN("K is not invertible");
    }

    uranus_dp::ThrusterForces uMsg;
    uMsg.F1 = u(0);
    uMsg.F2 = u(1);
    uMsg.F3 = u(2);
    uMsg.F4 = u(3);
    uMsg.F5 = u(4);
    uMsg.F6 = u(5);
    uPub.publish(uMsg);

    ROS_INFO_STREAM("Published: " << u(0) << ", " << u(1) << ", " << u(2) << ", " << u(3) << ", " << u(4) << ", " << u(5));
}

void LagrangeAllocator::setWeights(const Eigen::MatrixXd &W_new)
{
    bool correctDimensions = ( W_new.rows() == r && W_new.cols() == r );
    if (!correctDimensions)
    {
        ROS_WARN_STREAM("Attempt to set weight matrix in LagrangeAllocator with wrong dimensions " << W_new.rows() << "*" << W_new.cols() << ".");
        return;
    }

    W = W_new;

    // New weights require recomputing the generalized inverse of the thrust config matrix
    computeGeneralizedInverse();
}

void LagrangeAllocator::computeGeneralizedInverse()
{
    T_geninverse = W.inverse()*T.transpose() * (T*W.inverse()*T.transpose()).inverse();

    printMatrix6(T_geninverse);
    printMatrix6(W);
    printMatrix6(T);
    printMatrix6(K_inverse);

    if (isFucked(T_geninverse))
    {
        ROS_WARN("T_geninverse NAN");
    }

    if (isFucked( W.inverse() ))
    {
        ROS_WARN("W is not invertible");
    }

    if (isFucked( (T*W.inverse()*T.transpose()).inverse() ) )
    {
        ROS_WARN("T * W_inv * T transposed is not invertible");
    }
}
<commit_msg>Comment out troublesome printing<commit_after>// See Fossen 2011, chapter 12.3.2
#include "lagrange_allocator.h"
#include <iostream>

template<typename Derived>
inline bool isFucked(const Eigen::MatrixBase<Derived>& x)
{
    return !((x.array() == x.array())).all() && !( (x - x).array() == (x - x).array()).all();
}

// Worlds worst print function :DDD
void printMatrix6(Eigen::MatrixXd m)
{
    ROS_INFO("----------------------------------");
    for(int col = 0; col < 6; col++)
    {
        char buffer[512];

        for(int row = 0; row < 6; row++)
        {
            snprintf( (buffer + (row*8) ), sizeof(buffer), "  %f  ", m(col, row));
        }
        ROS_INFO("%s", buffer);
    }
    ROS_INFO("----------------------------------\n");
}

LagrangeAllocator::LagrangeAllocator()
{
    // n = 4;
    // r = 6;

    tauSub = nh.subscribe("control_forces", 1, &LagrangeAllocator::tauCallback, this);
    uPub   = nh.advertise<uranus_dp::ThrusterForces>("control_inputs", 1);

    W.setIdentity(6,6); // Default to identity (i.e. equal weights)
    K.setIdentity(6,6); // Scaling is done on Arduino, so this can be identity

    // Our test ROV cannot control heave and roll, so they are removed from the control objective
    T <<  0.7071 ,  0.7071 ,  0.7071 ,  0.7071 ,  1    ,  1    , // Surge
         -0.7071 ,  0.7071 , -0.7071 ,  0.7071 ,  0    ,  0    , // Sway
          0.06718,  0.06718,  0.06718,  0.06718, -0.210, -0.210, // Pitch
          0.4172 ,  0.4172 , -0.4172 , -0.4172 , -0.165,  0.165; // Yaw

    K_inverse = K.inverse();
    computeGeneralizedInverse();
}

void LagrangeAllocator::tauCallback(const geometry_msgs::Wrench& tauMsg)
{
    tau << tauMsg.force.x,
           tauMsg.force.y,
           // tauMsg.force.z,  // Not part of control objective for test rov
           // tauMsg.torque.x, // Ditto
           tauMsg.torque.y,
           tauMsg.torque.z;

    u = K_inverse * T_geninverse * tau;

    if (isFucked(K_inverse))
    {
        ROS_WARN("K is not invertible");
    }

    uranus_dp::ThrusterForces uMsg;
    uMsg.F1 = u(0);
    uMsg.F2 = u(1);
    uMsg.F3 = u(2);
    uMsg.F4 = u(3);
    uMsg.F5 = u(4);
    uMsg.F6 = u(5);
    uPub.publish(uMsg);

    ROS_INFO_STREAM("Published: " << u(0) << ", " << u(1) << ", " << u(2) << ", " << u(3) << ", " << u(4) << ", " << u(5));
}

void LagrangeAllocator::setWeights(const Eigen::MatrixXd &W_new)
{
    bool correctDimensions = ( W_new.rows() == r && W_new.cols() == r );
    if (!correctDimensions)
    {
        ROS_WARN_STREAM("Attempt to set weight matrix in LagrangeAllocator with wrong dimensions " << W_new.rows() << "*" << W_new.cols() << ".");
        return;
    }

    W = W_new;

    // New weights require recomputing the generalized inverse of the thrust config matrix
    computeGeneralizedInverse();
}

void LagrangeAllocator::computeGeneralizedInverse()
{
    T_geninverse = W.inverse()*T.transpose() * (T*W.inverse()*T.transpose()).inverse();

    // ROS_INFO("Printing in order: T_geninverse, W, T, K_inverse.");
    // printMatrix6(T_geninverse);
    // printMatrix6(W);
    // printMatrix6(T);
    // printMatrix6(K_inverse);

    if (isFucked(T_geninverse))
    {
        ROS_WARN("T_geninverse NAN");
    }

    if (isFucked( W.inverse() ))
    {
        ROS_WARN("W is not invertible");
    }

    if (isFucked( (T*W.inverse()*T.transpose()).inverse() ) )
    {
        ROS_WARN("T * W_inv * T transposed is not invertible");
    }
}
<|endoftext|>


<commit_before><commit_msg>use new scheme of LED_BUILTIN pins.h define<commit_after><|endoftext|>


<commit_before>#ifndef NN_RELU_HPP
#define NN_RELU_HPP

#include <math.h>
#include "map.hpp"

namespace nnlib
{

/// Rectified linear activation function.
template <typename T = double>
class ReLU : public Map<T>
{
public:
	ReLU(double leak = 0.1) :
		m_leak(leak)
	{}

	ReLU(const ReLU &module) :
		m_leak(module.m_leak)
	{}

	ReLU(const Serialized &node) :
		m_leak(node.get<T>("leak"))
	{}

	ReLU &operator=(const ReLU &module)
	{
		m_leak = module.m_leak;
		return *this;
	}

	/// Save to a serialized node.
	virtual void save(Serialized &node) const override
	{
		Map<T>::save(node);
		node.set("leak", m_leak);
	}

	/// Get the "leak" for this ReLU. 0 if non-leaky.
	T leak() const
	{
		return m_leak;
	}

	/// Set the "leak" for this ReLU. 0 <= leak < 1.
	ReLU &leak(T leak)
	{
		NNAssertGreaterThanOrEquals(leak, 0, "Expected positive leak!");
		NNAssertLessThan(leak, 1, "Expected leak to be a percentage!");
		m_leak = leak;
		return *this;
	}

	/// Single element forward.
	virtual T forwardOne(const T &x) override
	{
		return x > 0 ? x : m_leak * x;
	}

	/// Single element backward.
	virtual T backwardOne(const T &x, const T &y) override
	{
		return x > 0 ? 1 : m_leak;
	}

private:
	T m_leak;
};

}

NNRegisterType(ReLU, Module);

#endif
<commit_msg>Fixed a hard-coded type.<commit_after>#ifndef NN_RELU_HPP
#define NN_RELU_HPP

#include <math.h>
#include "map.hpp"

namespace nnlib
{

/// Rectified linear activation function.
template <typename T = double>
class ReLU : public Map<T>
{
public:
	ReLU(T leak = 0.1) :
		m_leak(leak)
	{}

	ReLU(const ReLU &module) :
		m_leak(module.m_leak)
	{}

	ReLU(const Serialized &node) :
		m_leak(node.get<T>("leak"))
	{}

	ReLU &operator=(const ReLU &module)
	{
		m_leak = module.m_leak;
		return *this;
	}

	/// Save to a serialized node.
	virtual void save(Serialized &node) const override
	{
		Map<T>::save(node);
		node.set("leak", m_leak);
	}

	/// Get the "leak" for this ReLU. 0 if non-leaky.
	T leak() const
	{
		return m_leak;
	}

	/// Set the "leak" for this ReLU. 0 <= leak < 1.
	ReLU &leak(T leak)
	{
		NNAssertGreaterThanOrEquals(leak, 0, "Expected positive leak!");
		NNAssertLessThan(leak, 1, "Expected leak to be a percentage!");
		m_leak = leak;
		return *this;
	}

	/// Single element forward.
	virtual T forwardOne(const T &x) override
	{
		return x > 0 ? x : m_leak * x;
	}

	/// Single element backward.
	virtual T backwardOne(const T &x, const T &y) override
	{
		return x > 0 ? 1 : m_leak;
	}

private:
	T m_leak;
};

}

NNRegisterType(ReLU, Module);

#endif
<|endoftext|>


<commit_before>/*
 * (cd ../lib && make all-c)
 * afl-g++ -std=gnu++11 -fPIC -O -I../lib fuzz.cc ../lib/graph.cc ../lib/murmur32s.pico ../lib/murmur32v.pico ../lib/xxh32s.pico ../lib/xxh64s.pico ../lib/fastdiv.pico ../lib/jenkins2v.pico
 *
 * ./a.out && mv fuzz.dat ${INPUTDIR:?}
 * afl-fuzz -i ${INPUTDIR:?} -o ${OUTPUTDIR:?} ./a.out @@
 */

#include <assert.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

#include <set>
#include <string>

#include "rgph_defs.h"
#include "rgph_graph.h"

static const char letters[] = "abcdefghijklmnopqrstuvwxyz";

struct fuzz_entry {
	uint64_t index;
	uint8_t has_index;
	uint8_t keylen;
	char key[54];
};

struct fuzz_header {
	size_t alloc_nkeys;
	size_t build_nkeys;
	unsigned long seed;
	int alloc_flags;
	int build_flags;
	int assign_flags;
	struct fuzz_entry entries[];
};

struct iterator_state {
	size_t pos;
	size_t alloc_nkeys;
	size_t build_nkeys;
	size_t nentries;
	struct fuzz_entry *entries;
	struct rgph_entry out;
};

static inline size_t
min(size_t a, size_t b)
{

	return a < b ? a : b;
}

static inline size_t
max(size_t a, size_t b)
{

	return a > b ? a : b;
}

static const struct rgph_entry *
iterator_func(void *state)
{
	struct iterator_state *s = (struct iterator_state *)state;
	struct fuzz_entry *in = &s->entries[s->pos % s->nentries];
	struct rgph_entry *out = &s->out;

	if (s->pos == s->build_nkeys)
		return NULL;

	out->key = out->data = in->key;
	out->keylen = out->datalen = min(sizeof(in->key), in->keylen);
	out->index = in->index;
	out->has_index = in->has_index;

	s->pos++;
	return out;
}

static bool
has_duplicates(const struct fuzz_entry *entries, size_t nentries)
{
	std::set<std::string> keys;

	for (size_t i = 0; i < nentries; i++) {
		size_t keylen = min(entries[i].keylen,
		    sizeof(entries[i].key));

		if (!keys.insert(std::string(entries[i].key, keylen)).second)
			return true;
	}

	return false;
}

int
write_sample_input(void)
{
	fuzz_header h;
	FILE *f;
	size_t i;

	memset(&h, 0, sizeof(h));

	f = fopen("fuzz.dat", "w");
	if (f == NULL)
		return EXIT_FAILURE;

	h.alloc_nkeys = h.build_nkeys = sizeof(letters) - 1;
	h.seed = 123456789;
	h.alloc_flags = 0;
	h.build_flags = 0;
	h.assign_flags = 0;

	if (fwrite(&h, 1, sizeof(h), f) != sizeof(h)) {
		fclose(f);
		return EXIT_FAILURE;
	}

	for (i = 0; i < sizeof(letters) - 1; i++) {
		struct fuzz_entry e;

		e.index = i;
		e.has_index = true;
		e.keylen = 2;
		memcpy(e.key, &letters[i], 2);

		if (fwrite(&e, 1, sizeof(e), f) != sizeof(e)) {
			fclose(f);
			return EXIT_FAILURE;
		}
	}

	fclose(f);
	return EXIT_SUCCESS;
}

int
main(int argc, char *argv[])
{
	iterator_state state;
	struct stat st;
	struct fuzz_header *h;
	struct rgph_graph *g;
	void *buf;
	size_t flen;
	unsigned long seed;
	int build_flags, fd, res;
	bool dup_checked = false;

	if (argc < 2)
		return write_sample_input();

	fd = open(argv[1], O_RDONLY);
	if (fd == -1)
		return EXIT_FAILURE;

	if (fstat(fd, &st) == -1) {
		close(fd);
		return EXIT_FAILURE;
	}

	flen = max(st.st_size, sizeof(*h) + sizeof(h->entries[0]));

	buf = mmap(NULL, flen, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
	h = (struct fuzz_header *)buf;
	close(fd);

	if (buf == MAP_FAILED)
		return EXIT_FAILURE;

	g = rgph_alloc_graph(h->alloc_nkeys, h->alloc_flags);
	if (g == NULL)
		return EXIT_FAILURE;

	seed = h->seed;
	build_flags = h->build_flags;
	state.entries = h->entries;
	state.alloc_nkeys = h->alloc_nkeys;
	state.build_nkeys = h->build_nkeys;
	state.nentries = (flen - sizeof(*h)) / sizeof(h->entries[0]);

	assert(state.nentries != 0);

	for (size_t i = 0; true; i++) {
		size_t dup[2];

		state.pos = 0;
		res = rgph_build_graph(g, build_flags, seed++,
		    &iterator_func, &state);
		if (res == RGPH_SUCCESS || res != RGPH_AGAIN)
			break;

		state.pos = 0;
		res = rgph_find_duplicates(g, &iterator_func, &state, dup);
		if (res == RGPH_SUCCESS)
			break;

		if (res == RGPH_AGAIN && !dup_checked) {
			if (state.build_nkeys > state.nentries)
				break;
			if (has_duplicates(state.entries, state.nentries))
				break;
			dup_checked = true;
		}

		/* Some hashes are weak. Rotate them periodically. */
		if ((i % 128) == 127) {
			int next_hash = (build_flags & RGPH_HASH_MASK) + 1;

			if (next_hash >= RGPH_HASH_LAST)
				next_hash = 0;

			build_flags &= ~RGPH_HASH_MASK;
			build_flags |= next_hash;
		}
	}

	res = rgph_assign(g, h->assign_flags);

	rgph_free_graph(g);

	return res == RGPH_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
}
<commit_msg>Check BDZ assignments.<commit_after>/*
 * (cd ../lib && make all-c)
 * afl-g++ -std=gnu++11 -fPIC -O -I../lib fuzz.cc ../lib/graph.cc ../lib/murmur32s.pico ../lib/murmur32v.pico ../lib/xxh32s.pico ../lib/xxh64s.pico ../lib/fastdiv.pico ../lib/jenkins2v.pico
 *
 * ./a.out && mv fuzz.dat ${INPUTDIR:?}
 * afl-fuzz -i ${INPUTDIR:?} -o ${OUTPUTDIR:?} ./a.out @@
 */

#include <assert.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

#include <set>
#include <string>

#include "rgph_defs.h"
#include "rgph_graph.h"

static const char letters[] = "abcdefghijklmnopqrstuvwxyz";

struct fuzz_entry {
	uint64_t index;
	uint8_t has_index;
	uint8_t keylen;
	char key[54];
};

struct fuzz_header {
	size_t alloc_nkeys;
	size_t build_nkeys;
	unsigned long seed;
	int alloc_flags;
	int build_flags;
	int assign_flags;
	struct fuzz_entry entries[];
};

struct iterator_state {
	size_t pos;
	size_t alloc_nkeys;
	size_t build_nkeys;
	size_t nentries;
	struct fuzz_entry *entries;
	struct rgph_entry out;
};

static inline size_t
min(size_t a, size_t b)
{

	return a < b ? a : b;
}

static inline size_t
max(size_t a, size_t b)
{

	return a > b ? a : b;
}

static const struct rgph_entry *
iterator_func(void *state)
{
	struct iterator_state *s = (struct iterator_state *)state;
	struct fuzz_entry *in = &s->entries[s->pos % s->nentries];
	struct rgph_entry *out = &s->out;

	if (s->pos == s->build_nkeys)
		return NULL;

	out->key = out->data = in->key;
	out->keylen = out->datalen = min(sizeof(in->key), in->keylen);
	out->index = in->index;
	out->has_index = in->has_index;

	s->pos++;
	return out;
}

static bool
has_duplicates(const struct fuzz_entry *entries, size_t nentries)
{
	std::set<std::string> keys;

	for (size_t i = 0; i < nentries; i++) {
		size_t keylen = min(entries[i].keylen,
		    sizeof(entries[i].key));

		if (!keys.insert(std::string(entries[i].key, keylen)).second)
			return true;
	}

	return false;
}

static void
check_bdz(struct rgph_graph *g)
{
	size_t const nkeys = rgph_entries(g);
	int const rank = (rgph_flags(g) & RGPH_RANK3) ? 3 : 2;
	std::set<uint32_t> hashes;
	size_t width = 0;
	int res;
	uint8_t const *assign;

	assign = (uint8_t const *)rgph_assignments(g, &width);
	assert(assign != nullptr && width == 1);

	for (size_t i = 0; i < nkeys; i++) {
		unsigned long edge[3];
		int h = 0;

		res = rgph_copy_edge(g, i, edge, nullptr);
		assert(res == RGPH_SUCCESS);

		for (int j = 0; j < rank; j++) {
			assert(edge[j] < nkeys && assign[edge[j]] < rank);
			h += assign[edge[j]];
			if (h >= rank)
				h -= rank;
		}

		bool inserted = hashes.insert(edge[h]).second;
		assert(inserted);
	}
}

int
write_sample_input(void)
{
	fuzz_header h;
	FILE *f;
	size_t i;

	memset(&h, 0, sizeof(h));

	f = fopen("fuzz.dat", "w");
	if (f == NULL)
		return EXIT_FAILURE;

	h.alloc_nkeys = h.build_nkeys = sizeof(letters) - 1;
	h.seed = 123456789;
	h.alloc_flags = 0;
	h.build_flags = 0;
	h.assign_flags = 0;

	if (fwrite(&h, 1, sizeof(h), f) != sizeof(h)) {
		fclose(f);
		return EXIT_FAILURE;
	}

	for (i = 0; i < sizeof(letters) - 1; i++) {
		struct fuzz_entry e;

		e.index = i;
		e.has_index = true;
		e.keylen = 2;
		memcpy(e.key, &letters[i], 2);

		if (fwrite(&e, 1, sizeof(e), f) != sizeof(e)) {
			fclose(f);
			return EXIT_FAILURE;
		}
	}

	fclose(f);
	return EXIT_SUCCESS;
}

int
main(int argc, char *argv[])
{
	iterator_state state;
	struct stat st;
	struct fuzz_header *h;
	struct rgph_graph *g;
	void *buf;
	size_t flen;
	unsigned long seed;
	int build_flags, fd, res;
	bool dup_checked = false;

	if (argc < 2)
		return write_sample_input();

	fd = open(argv[1], O_RDONLY);
	if (fd == -1)
		return EXIT_FAILURE;

	if (fstat(fd, &st) == -1) {
		close(fd);
		return EXIT_FAILURE;
	}

	flen = max(st.st_size, sizeof(*h) + sizeof(h->entries[0]));

	buf = mmap(NULL, flen, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
	h = (struct fuzz_header *)buf;
	close(fd);

	if (buf == MAP_FAILED)
		return EXIT_FAILURE;

	g = rgph_alloc_graph(h->alloc_nkeys, h->alloc_flags);
	if (g == NULL)
		return EXIT_FAILURE;

	seed = h->seed;
	build_flags = h->build_flags;
	state.entries = h->entries;
	state.alloc_nkeys = h->alloc_nkeys;
	state.build_nkeys = h->build_nkeys;
	state.nentries = (flen - sizeof(*h)) / sizeof(h->entries[0]);

	assert(state.nentries != 0);

	for (size_t i = 0; true; i++) {
		size_t dup[2];

		state.pos = 0;
		res = rgph_build_graph(g, build_flags, seed++,
		    &iterator_func, &state);
		if (res == RGPH_SUCCESS || res != RGPH_AGAIN)
			break;

		state.pos = 0;
		res = rgph_find_duplicates(g, &iterator_func, &state, dup);
		if (res == RGPH_SUCCESS)
			break;

		if (res == RGPH_AGAIN && !dup_checked) {
			if (state.build_nkeys > state.nentries)
				break;
			if (has_duplicates(state.entries, state.nentries))
				break;
			dup_checked = true;
		}

		/* Some hashes are weak. Rotate them periodically. */
		if ((i % 128) == 127) {
			int next_hash = (build_flags & RGPH_HASH_MASK) + 1;

			if (next_hash >= RGPH_HASH_LAST)
				next_hash = 0;

			build_flags &= ~RGPH_HASH_MASK;
			build_flags |= next_hash;
		}
	}

	res = rgph_assign(g, h->assign_flags);
	assert(res != RGPH_SUCCESS || rgph_core_size(g) == 0);

	if (res == RGPH_SUCCESS && (rgph_flags(g) & RGPH_ALGO_BDZ))
		check_bdz(g);

	rgph_free_graph(g);

	return res == RGPH_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
}
<|endoftext|>