<commit_before>#include "interpreter.h"

#include <list>
#include <iostream>

#include "additionexpression.h"
#include "assignmentexpression.h"
#include "class.h"
#include "classfactory.h"
#include "expression.h"
#include "expressionsource.h"
#include "expressiontype.h"
#include "function.h"
#include "functions/print.h"
#include "interpreterexception.h"
#include "intliteralexpression.h"
#include "log.h"
#include "nativefunction.h"
#include "object.h"
#include "scope.h"
#include "stringliteralexpression.h"
#include "types/int.h"
#include "types/string.h"
#include "valueexpression.h"
#include "variableexpression.h"

namespace peachy {

  Interpreter::~Interpreter() {}

  void Interpreter::consume() {
    Scope * globalScope = new Scope(logger);
    Class * stringClass = classFactory->getClass(std::string("String"));
    globalScope->addClass(stringClass);
    Class * intClass = classFactory->getClass(std::string("Int"));
    globalScope->addClass(intClass);
    globalScope->addNativeFunction(std::string("print"), new Print());
    Expression * e;
    do {
      e = evaluate(expressionSource->nextExpression(), globalScope);
    } while(e != NULL);
  }

  Expression * Interpreter::evaluate(Expression * expression, Scope * scope) {
    Expression * lValue, * rValue;
    switch(expression->getExpressionType()) {
      case EXPRESSION_ADDITION:
        return evaluateAddition(expression, scope);
      case EXPRESSION_ASSIGNMENT:
        AssignmentExpression * ae =
          static_cast<AssignmentExpression*>(expression);
        lValue = ae->getLValue();
        rValue = ae->getRValue();
        switch(lValue->getExpressionType()) {
          case EXPRESSION_VALUE:
            throw InterpreterException("lvalue of assignment is a value");
          case EXPRESSION_VARIABLE:
            Expression * rVal = evaluate(rValue, scope);
            switch(rVal->getExpressionType()) {
              case EXPRESSION_VALUE:
                return assignValueToVariable(lValue, rVal, scope);
              case EXPRESSION_VARIABLE:
                return assignVariableToVariable(lValue, rVal, scope);
              default:
                throw InterpreterException("Unexpected rvalue");
            }
          case EXPRESSION_ASSIGNMENT:
            return assignAssignment(lValue, rValue, scope);
          default:
            throw InterpreterException("Invalid assignment");
        }
        break;
      case EXPRESSION_INT_LITERAL:
        return evaluateIntLiteral(expression);
      case EXPRESSION_QUIT:
        return NULL;
      case EXPRESSION_STRING_LITERAL:
        return evaluateStringLiteral(expression);
      case EXPRESSION_VARIABLE:
        return evaluateVariable(expression, scope);
      case EXPRESSION_VALUE:
        return expression;
      case EXPRESSION_UNKNOWN:
      default:
        throw InterpreterException("Unknown expression");
    }
  }

  Expression * Interpreter::evaluateIntLiteral(Expression * expression) {
    IntLiteralExpression * e =
      static_cast<IntLiteralExpression*>(expression);
    if(e == NULL) {
      throw InterpreterException("Invalid int literal expression");
    }
    return new ValueExpression(logger,
      new Int(logger, classFactory, e->getValue()));
  }

  Expression * Interpreter::evaluateStringLiteral(Expression * expression) {
    StringLiteralExpression * e =
      static_cast<StringLiteralExpression*>(expression);
    if(e == NULL) {
      throw InterpreterException("Invalid string literal expression");
    }
    return new ValueExpression(logger,
      new String(logger, classFactory, e->getStringValue()));
  }

  Expression * Interpreter::evaluateVariable(Expression * expression, Scope * scope) {
    VariableExpression * e =
      static_cast<VariableExpression*>(expression);
    if(!scope->hasVariable(e->getVariableName())) {
      scope->addVariable(e->getVariableName(), e->getValue());
    }
    Object * o = scope->getVariable(e->getVariableName());
    e->setValue(o);
    return e;
  }

  Expression * Interpreter::evaluateIntLiteralAddition(Expression * lValue,
    Expression * rValue, Scope * scope) {
    IntLiteralExpression * intEx =
      static_cast<IntLiteralExpression*>(lValue);
    switch(rValue->getExpressionType()) {
      case EXPRESSION_INT_LITERAL:
        IntLiteralExpression * rIntEx =
          static_cast<IntLiteralExpression*>(rValue);
        if(rIntEx == NULL) {
          throw InterpreterException("Invalid int literal expression");
        }
        intEx->setValue(intEx->getValue() + rIntEx->getValue());
        return evaluate(intEx, scope);
      case EXPRESSION_VARIABLE:
        VariableExpression * varEx =
          static_cast<VariableExpression*>(rValue);
        if(!scope->hasVariable(varEx->getVariableName())) {
          throw InterpreterException("Assigning a variable that isn't in scope");
        } else {
          if(scope->getVariable(varEx->getVariableName())->getClassName().compare(std::string("Int")) != 0) {
            throw InterpreterException("Adding a non-int variable to an int literal");
          } else {
            Int * i = static_cast<Int*>(varEx->getValue());
            intEx->setValue(intEx->getValue() + i->getValue());
            return evaluate(intEx, scope);
          }
        }
        default:
          throw InterpreterException("I don't know how to add one of those to an int literal");
    }
  }

  Expression * Interpreter::evaluateStringLiteralAddition(Expression * lValue,
    Expression * rValue, Scope * scope) {
      StringLiteralExpression * stringEx =
        static_cast<StringLiteralExpression*>(lValue);
      switch(rValue->getExpressionType()) {
        case EXPRESSION_STRING_LITERAL:
          StringLiteralExpression * rStringEx =
            static_cast<StringLiteralExpression*>(rValue);
          stringEx->setStringValue(stringEx->getStringValue().append(rStringEx->getStringValue()));
          return evaluate(stringEx, scope);
        case EXPRESSION_VARIABLE:
          VariableExpression * varEx =
            static_cast<VariableExpression*>(rValue);
          if(!scope->hasVariable(varEx->getVariableName())) {
            throw InterpreterException(varEx->getVariableName().append(" is not defined"));
          } else {
            if(scope->getVariable(varEx->getVariableName())->getClassName().compare(std::string("String")) != 0) {
              throw InterpreterException("Adding a non-string variable to a string literal");
            } else {
              String * s = static_cast<String*>(varEx->getValue());
              stringEx->setStringValue(stringEx->getStringValue().append(s->getValue()));
              return evaluate(stringEx, scope);
            }
          }
        default:
          throw InterpreterException("I don't know how to add one of those to a string literal");
      }
  }

  Expression * Interpreter::evaluateVariableAddition(Expression * lValue,
    Expression * rValue, Scope * scope) {
    VariableExpression * varEx =
      static_cast<VariableExpression*>(lValue);
    if(!scope->hasVariable(varEx->getVariableName())) {
      throw InterpreterException("variable is not in this scope");
    }
    Object * leftObj = scope->getVariable(varEx->getVariableName());
    Expression * rightEx = evaluate(rValue, scope);
    switch(rightEx->getExpressionType()) {
      case EXPRESSION_VALUE:
        ValueExpression * valEx =
          static_cast<ValueExpression*>(rightEx);
        if(valEx == NULL) {
          throw InterpreterException("Invalid expression");
        }
        Object * rightObj = valEx->getValue();
        Object * newValue;
        if(leftObj->getClassName().compare("Int") == 0) {
          Int * leftObjInt = static_cast<Int*>(leftObj);
          newValue = leftObjInt->add(rightObj);
        } else if(leftObj->getClassName().compare("String") == 0) {
          String * leftObjString = static_cast<String*>(leftObj);
          newValue = leftObjString->add(rightObj);
        } else {
          throw InterpreterException("Unsupported operation");
        }
        valEx->setValue(newValue);
        return valEx;
      default:
        throw InterpreterException("Invalid expression");
    }
  }

  Expression * Interpreter::evaluateAddition(Expression * expression,
    Scope * scope) {
    AdditionExpression * addEx =
      static_cast<AdditionExpression*>(expression);
    if(addEx == NULL) {
      throw InterpreterException("Invalid expression");
    }
    Expression * lValue = addEx->getLValue();
    Expression * rValue = addEx->getRValue();
    switch(lValue->getExpressionType()) {
      case EXPRESSION_VARIABLE:
        return evaluateVariableAddition(lValue, rValue, scope);
      case EXPRESSION_INT_LITERAL:
        return evaluateIntLiteralAddition(lValue, rValue, scope);
      case EXPRESSION_STRING_LITERAL:
        return evaluateStringLiteralAddition(lValue, rValue, scope);
      default:
        throw InterpreterException("Invalid addition");
    }
  }

  Expression * Interpreter::assignValueToVariable(Expression * lValue,
    Expression * rValue, Scope * scope) {
    VariableExpression * var =
      static_cast<VariableExpression*>(lValue);
    if(var == NULL) {
      throw InterpreterException("Invalid lValue");
    }
    ValueExpression * rVal =
      static_cast<ValueExpression*>(rValue);
    Object * rObj = rVal->getValue();
    if(scope->hasNativeFunction(var->getVariableName())) {
      NativeFunction * f =
        scope->getNativeFunction(var->getVariableName());
      std::list<Object*> params;
      params.push_front(rObj);
      Object * result = f->call(params);
      return new ValueExpression(logger, result);
    } else {
      var->setValue(rObj);
    }
    return var;
  }

  Expression * Interpreter::assignVariableToVariable(Expression * lValue,
    Expression * rValue, Scope * scope) {
    VariableExpression * var =
      static_cast<VariableExpression*>(lValue);
    if(var == NULL) {
      throw InterpreterException("Invalid lValue");
    }
    VariableExpression * rVar =
      static_cast<VariableExpression*>(rValue);
    if(rVar == NULL) {
      throw InterpreterException("Invalid variable");
    }
    if(scope->hasNativeFunction(rVar->getVariableName())) {
      NativeFunction * f =
        scope->getNativeFunction(var->getVariableName());
      std::list<Object*> params;
      params.push_front(rVar->getValue());
      Object * result = f->call(params);
      return new ValueExpression(logger, result);
    } else {
      if(scope->hasNativeFunction(var->getVariableName())) {
        NativeFunction * f =
          scope->getNativeFunction(var->getVariableName());
        std::list<Object*> params;
        params.push_front(rVar->getValue());
        Object * result = f->call(params);
        return new ValueExpression(logger, result);
      } else {
        Object * rObj = rVar->getValue();
        var->setValue(rObj);
        return var;
      }
    }
  }

  Expression * Interpreter::assignAssignment(Expression * lValue,
    Expression * rValue, Scope * scope) {
    ValueExpression * lVal =
      static_cast<ValueExpression*>(evaluate(lValue, scope));
    if(lVal == NULL) {
      throw InterpreterException("Invalid expression");
    }
    ValueExpression * rValue =
      static_cast<ValueExpression*>(evaluate(rValue, scope));
    if(rVal == NULL) {
      throw InterpreterException("Invalid expression");
    }
    lVal->setValue(rValue->getValue());
    return lVal;
  }

  void Interpreter::dumpVar(VariableExpression * v) {
    if(v->hasValue()) {
      std::string className = v->getValue()->getClassName();
      std::cout << v->getVariableName();
      dumpObj(v->getValue());
    } else {
      std::cout << " (no value)" << std::endl;
    }
  }

  void Interpreter::dumpObj(Object * o) {
    std::string className = o->getClassName();
    if(className.compare("Int") == 0 ) {
      Int * i = static_cast<Int*>(o);
      std::cout << " [Int] " << i->getValue() << std::endl;
    } else if(className.compare("String") == 0) {
      String * s = static_cast<String*>(o);
      std::cout << " [String] " << s->getValue() << std::endl;
    } else if(className.compare("Object") == 0) {
      std::cout << " [Object]" << std::endl;
    } else {
      std::cout << "[Unknown type]" << std::endl;
    }
  }
}
<commit_msg>Refactoring interpreter<commit_after>#include "interpreter.h"

#include <list>
#include <iostream>

#include "additionexpression.h"
#include "assignmentexpression.h"
#include "class.h"
#include "classfactory.h"
#include "expression.h"
#include "expressionsource.h"
#include "expressiontype.h"
#include "function.h"
#include "functions/print.h"
#include "interpreterexception.h"
#include "intliteralexpression.h"
#include "log.h"
#include "nativefunction.h"
#include "object.h"
#include "scope.h"
#include "stringliteralexpression.h"
#include "types/int.h"
#include "types/string.h"
#include "valueexpression.h"
#include "variableexpression.h"

namespace peachy {

  Interpreter::~Interpreter() {}

  void Interpreter::consume() {
    Scope * globalScope = new Scope(logger);
    Class * stringClass = classFactory->getClass(std::string("String"));
    globalScope->addClass(stringClass);
    Class * intClass = classFactory->getClass(std::string("Int"));
    globalScope->addClass(intClass);
    globalScope->addNativeFunction(std::string("print"), new Print());
    Expression * e;
    do {
      e = evaluate(expressionSource->nextExpression(), globalScope);
    } while(e != NULL);
  }

  Expression * Interpreter::evaluate(Expression * expression, Scope * scope) {
    Expression * lValue, * rValue;
    switch(expression->getExpressionType()) {
      case EXPRESSION_ADDITION:
        return evaluateAddition(expression, scope);
      case EXPRESSION_ASSIGNMENT:
        AssignmentExpression * ae =
          static_cast<AssignmentExpression*>(expression);
        lValue = ae->getLValue();
        rValue = ae->getRValue();
        switch(lValue->getExpressionType()) {
          case EXPRESSION_VALUE:
            throw InterpreterException("lvalue of assignment is a value");
          case EXPRESSION_VARIABLE:
            Expression * rVal = evaluate(rValue, scope);
            switch(rVal->getExpressionType()) {
              case EXPRESSION_VALUE:
                return assignValueToVariable(lValue, rVal, scope);
              case EXPRESSION_VARIABLE:
                return assignVariableToVariable(lValue, rVal, scope);
              default:
                throw InterpreterException("Unexpected rvalue");
            }
          case EXPRESSION_ASSIGNMENT:
            return assignAssignment(lValue, rValue, scope);
          default:
            throw InterpreterException("Invalid assignment");
        }
        break;
      case EXPRESSION_INT_LITERAL:
        return evaluateIntLiteral(expression);
      case EXPRESSION_QUIT:
        return NULL;
      case EXPRESSION_STRING_LITERAL:
        return evaluateStringLiteral(expression);
      case EXPRESSION_VARIABLE:
        return evaluateVariable(expression, scope);
      case EXPRESSION_VALUE:
        return expression;
      case EXPRESSION_UNKNOWN:
      default:
        throw InterpreterException("Unknown expression");
    }
  }

  Expression * Interpreter::evaluateIntLiteral(Expression * expression) {
    IntLiteralExpression * e =
      static_cast<IntLiteralExpression*>(expression);
    if(e == NULL) {
      throw InterpreterException("Invalid int literal expression");
    }
    return new ValueExpression(logger,
      new Int(logger, classFactory, e->getValue()));
  }

  Expression * Interpreter::evaluateStringLiteral(Expression * expression) {
    StringLiteralExpression * e =
      static_cast<StringLiteralExpression*>(expression);
    if(e == NULL) {
      throw InterpreterException("Invalid string literal expression");
    }
    return new ValueExpression(logger,
      new String(logger, classFactory, e->getStringValue()));
  }

  Expression * Interpreter::evaluateVariable(Expression * expression, Scope * scope) {
    VariableExpression * e =
      static_cast<VariableExpression*>(expression);
    if(!scope->hasVariable(e->getVariableName())) {
      scope->addVariable(e->getVariableName(), e->getValue());
    }
    Object * o = scope->getVariable(e->getVariableName());
    e->setValue(o);
    return e;
  }

  Expression * Interpreter::evaluateIntLiteralAddition(Expression * lValue,
    Expression * rValue, Scope * scope) {
    IntLiteralExpression * intEx =
      static_cast<IntLiteralExpression*>(lValue);
    switch(rValue->getExpressionType()) {
      case EXPRESSION_INT_LITERAL:
        IntLiteralExpression * rIntEx =
          static_cast<IntLiteralExpression*>(rValue);
        if(rIntEx == NULL) {
          throw InterpreterException("Invalid int literal expression");
        }
        intEx->setValue(intEx->getValue() + rIntEx->getValue());
        return evaluate(intEx, scope);
      case EXPRESSION_VARIABLE:
        VariableExpression * varEx =
          static_cast<VariableExpression*>(rValue);
        if(!scope->hasVariable(varEx->getVariableName())) {
          throw InterpreterException("Assigning a variable that isn't in scope");
        } else {
          if(scope->getVariable(varEx->getVariableName())->getClassName().compare(std::string("Int")) != 0) {
            throw InterpreterException("Adding a non-int variable to an int literal");
          } else {
            Int * i = static_cast<Int*>(varEx->getValue());
            intEx->setValue(intEx->getValue() + i->getValue());
            return evaluate(intEx, scope);
          }
        }
        default:
          throw InterpreterException("I don't know how to add one of those to an int literal");
    }
  }

  Expression * Interpreter::evaluateStringLiteralAddition(Expression * lValue,
    Expression * rValue, Scope * scope) {
      StringLiteralExpression * stringEx =
        static_cast<StringLiteralExpression*>(lValue);
      switch(rValue->getExpressionType()) {
        case EXPRESSION_STRING_LITERAL:
          StringLiteralExpression * rStringEx =
            static_cast<StringLiteralExpression*>(rValue);
          stringEx->setStringValue(stringEx->getStringValue().append(rStringEx->getStringValue()));
          return evaluate(stringEx, scope);
        case EXPRESSION_VARIABLE:
          VariableExpression * varEx =
            static_cast<VariableExpression*>(rValue);
          if(!scope->hasVariable(varEx->getVariableName())) {
            throw InterpreterException(varEx->getVariableName().append(" is not defined"));
          } else {
            if(scope->getVariable(varEx->getVariableName())->getClassName().compare(std::string("String")) != 0) {
              throw InterpreterException("Adding a non-string variable to a string literal");
            } else {
              String * s = static_cast<String*>(varEx->getValue());
              stringEx->setStringValue(stringEx->getStringValue().append(s->getValue()));
              return evaluate(stringEx, scope);
            }
          }
        default:
          throw InterpreterException("I don't know how to add one of those to a string literal");
      }
  }

  Expression * Interpreter::evaluateVariableAddition(Expression * lValue,
    Expression * rValue, Scope * scope) {
    VariableExpression * varEx =
      static_cast<VariableExpression*>(lValue);
    if(!scope->hasVariable(varEx->getVariableName())) {
      throw InterpreterException("variable is not in this scope");
    }
    Object * leftObj = scope->getVariable(varEx->getVariableName());
    Expression * rightEx = evaluate(rValue, scope);
    switch(rightEx->getExpressionType()) {
      case EXPRESSION_VALUE:
        ValueExpression * valEx =
          static_cast<ValueExpression*>(rightEx);
        if(valEx == NULL) {
          throw InterpreterException("Invalid expression");
        }
        Object * rightObj = valEx->getValue();
        Object * newValue;
        if(leftObj->getClassName().compare("Int") == 0) {
          Int * leftObjInt = static_cast<Int*>(leftObj);
          newValue = leftObjInt->add(rightObj);
        } else if(leftObj->getClassName().compare("String") == 0) {
          String * leftObjString = static_cast<String*>(leftObj);
          newValue = leftObjString->add(rightObj);
        } else {
          throw InterpreterException("Unsupported operation");
        }
        valEx->setValue(newValue);
        return valEx;
      default:
        throw InterpreterException("Invalid expression");
    }
  }

  Expression * Interpreter::evaluateAddition(Expression * expression,
    Scope * scope) {
    AdditionExpression * addEx =
      static_cast<AdditionExpression*>(expression);
    if(addEx == NULL) {
      throw InterpreterException("Invalid expression");
    }
    Expression * lValue = addEx->getLValue();
    Expression * rValue = addEx->getRValue();
    switch(lValue->getExpressionType()) {
      case EXPRESSION_VARIABLE:
        return evaluateVariableAddition(lValue, rValue, scope);
      case EXPRESSION_INT_LITERAL:
        return evaluateIntLiteralAddition(lValue, rValue, scope);
      case EXPRESSION_STRING_LITERAL:
        return evaluateStringLiteralAddition(lValue, rValue, scope);
      default:
        throw InterpreterException("Invalid addition");
    }
  }

  Expression * Interpreter::assignValueToVariable(Expression * lValue,
    Expression * rValue, Scope * scope) {
    VariableExpression * var =
      static_cast<VariableExpression*>(lValue);
    if(var == NULL) {
      throw InterpreterException("Invalid lValue");
    }
    ValueExpression * rVal =
      static_cast<ValueExpression*>(rValue);
    Object * rObj = rVal->getValue();
    if(scope->hasNativeFunction(var->getVariableName())) {
      NativeFunction * f =
        scope->getNativeFunction(var->getVariableName());
      std::list<Object*> params;
      params.push_front(rObj);
      Object * result = f->call(params);
      return new ValueExpression(logger, result);
    } else {
      var->setValue(rObj);
    }
    return var;
  }

  Expression * Interpreter::assignVariableToVariable(Expression * lValue,
    Expression * rValue, Scope * scope) {
    VariableExpression * var =
      static_cast<VariableExpression*>(lValue);
    if(var == NULL) {
      throw InterpreterException("Invalid lValue");
    }
    VariableExpression * rVar =
      static_cast<VariableExpression*>(rValue);
    if(rVar == NULL) {
      throw InterpreterException("Invalid variable");
    }
    if(scope->hasNativeFunction(rVar->getVariableName())) {
      NativeFunction * f =
        scope->getNativeFunction(var->getVariableName());
      std::list<Object*> params;
      params.push_front(rVar->getValue());
      Object * result = f->call(params);
      return new ValueExpression(logger, result);
    } else {
      if(scope->hasNativeFunction(var->getVariableName())) {
        NativeFunction * f =
          scope->getNativeFunction(var->getVariableName());
        std::list<Object*> params;
        params.push_front(rVar->getValue());
        Object * result = f->call(params);
        return new ValueExpression(logger, result);
      } else {
        Object * rObj = rVar->getValue();
        var->setValue(rObj);
        return var;
      }
    }
  }

  Expression * Interpreter::assignAssignment(Expression * lValue,
    Expression * rValue, Scope * scope) {
    ValueExpression * lVal =
      static_cast<ValueExpression*>(evaluate(lValue, scope));
    if(lVal == NULL) {
      throw InterpreterException("Invalid expression");
    }
    ValueExpression * rVal =
      static_cast<ValueExpression*>(evaluate(rValue, scope));
    if(rVal == NULL) {
      throw InterpreterException("Invalid expression");
    }
    lVal->setValue(rVal->getValue());
    return lVal;
  }

  void Interpreter::dumpVar(VariableExpression * v) {
    if(v->hasValue()) {
      std::string className = v->getValue()->getClassName();
      std::cout << v->getVariableName();
      dumpObj(v->getValue());
    } else {
      std::cout << " (no value)" << std::endl;
    }
  }

  void Interpreter::dumpObj(Object * o) {
    std::string className = o->getClassName();
    if(className.compare("Int") == 0 ) {
      Int * i = static_cast<Int*>(o);
      std::cout << " [Int] " << i->getValue() << std::endl;
    } else if(className.compare("String") == 0) {
      String * s = static_cast<String*>(o);
      std::cout << " [String] " << s->getValue() << std::endl;
    } else if(className.compare("Object") == 0) {
      std::cout << " [Object]" << std::endl;
    } else {
      std::cout << "[Unknown type]" << std::endl;
    }
  }
}
<|endoftext|>


<commit_before>#include "GUISystemPort.h"
#include "GUISystem.h"
#include "GUIPort.h"
#include "loadObjects.h"

GUISystemPort::GUISystemPort(AppearanceData* pAppearanceData, QPoint position, qreal rotation, GUISystem *system, selectionStatus startSelected, graphicsType gfxType, QGraphicsItem *parent)
        : GUIModelObject(position, rotation, pAppearanceData, startSelected, gfxType, system, parent)
{
    this->mHmfTagName = HMF_SYSTEMPORTTAG;
    //Sets the ports
    createPorts();
    refreshDisplayName();
}

GUISystemPort::~GUISystemPort()
{
    //! @todo delete systemport in core
}

//! @brief Help function to create ports in the component when it is created
void GUISystemPort::createPorts()
{
    //! @todo Only one port in system ports could simplify this
    PortAppearanceMapT::iterator i;
    for (i = mAppearanceData.getPortAppearanceMap().begin(); i != mAppearanceData.getPortAppearanceMap().end(); ++i)
    {
        qreal x = i.value().x;
        qreal y = i.value().y;

        i.value().selectPortIcon("", "", "Undefined"); //Dont realy need to write undefined here, could be empty, (just to make it clear)

        mAppearanceData.setName(mpParentSystem->mpCoreSystemAccess->addSystemPort(i.key()));

        //We supply ptr to rootsystem to indicate that this is a systemport
        //! @todo this is a very bad way of doing this (ptr to rootsystem for systemport), really need to figure out some better way
        mpGuiPort = new GUIPort(mAppearanceData.getName(), x*mpIcon->sceneBoundingRect().width(), y*mpIcon->sceneBoundingRect().height(), &(i.value()), this, mpParentSystem->mpCoreSystemAccess);
        mPortListPtrs.append(mpGuiPort);
    }
}

//! Returns a string with the GUIObject type.
QString GUISystemPort::getTypeName()
{
    return "SystemPort";
}

//! Set the name of a system port
void GUISystemPort::setName(QString newName, renameRestrictions renameSettings)
{
    QString oldName = getName();
    //If name same as before do nothing
    if (newName != oldName)
    {
        //Check if we want to avoid trying to rename in the graphics view map
        if (renameSettings == CORERENAMEONLY)
        {
            //Set name in core component, Also set the current name to the resulting one (might have been changed)
            mAppearanceData.setName(mpParentSystem->mpCoreSystemAccess->renameSystemPort(oldName, newName));
            refreshDisplayName();
            mpGuiPort->setDisplayName(mAppearanceData.getName()); //change the actual gui port name
        }
        else
        {
            //Rename
            mpParentSystem->renameGUIObject(oldName, newName);
        }
    }
}

int GUISystemPort::type() const
{
    return Type;
}
<commit_msg>fixed a systemport naming bug that could prevent the systemports from getting the saved name on load<commit_after>#include "GUISystemPort.h"
#include "GUISystem.h"
#include "GUIPort.h"
#include "loadObjects.h"

GUISystemPort::GUISystemPort(AppearanceData* pAppearanceData, QPoint position, qreal rotation, GUISystem *system, selectionStatus startSelected, graphicsType gfxType, QGraphicsItem *parent)
        : GUIModelObject(position, rotation, pAppearanceData, startSelected, gfxType, system, parent)
{
    this->mHmfTagName = HMF_SYSTEMPORTTAG;
    //Sets the ports
    createPorts();
    refreshDisplayName();
}

GUISystemPort::~GUISystemPort()
{
    //! @todo delete systemport in core
}

//! @brief Help function to create ports in the component when it is created
void GUISystemPort::createPorts()
{
    //A system port only contains one port, which should be first in the map, ignore any others (should not be any more)
    PortAppearanceMapT::iterator i = mAppearanceData.getPortAppearanceMap().begin();

    //Check if a systemport name is given in appearance data (for example if the systemport is loaded from file)
    //In that case override the default port name with this name
    QString desiredportname;
    if (mAppearanceData.getName().isEmpty())
    {
        desiredportname = i.key();
    }
    else
    {
        desiredportname = mAppearanceData.getName();
    }

    qreal x = i.value().x;
    qreal y = i.value().y;

    //! @todo should make this function select a systemport icon not undefined
    i.value().selectPortIcon("", "", "Undefined"); //Dont realy need to write undefined here, could be empty, (just to make it clear)

    //qDebug() << ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,Adding systemport with name: " << desiredportname;
    mAppearanceData.setName(mpParentSystem->mpCoreSystemAccess->addSystemPort(desiredportname));
    //qDebug() << ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,resulting in name from core: " << mAppearanceData.getName();

    //We supply ptr to rootsystem to indicate that this is a systemport
    //! @todo this is a very bad way of doing this (ptr to rootsystem for systemport), really need to figure out some better way
    mpGuiPort = new GUIPort(mAppearanceData.getName(), x*mpIcon->sceneBoundingRect().width(), y*mpIcon->sceneBoundingRect().height(), &(i.value()), this, mpParentSystem->mpCoreSystemAccess);
    mPortListPtrs.append(mpGuiPort);

}

//! Returns a string with the GUIObject type.
QString GUISystemPort::getTypeName()
{
    return "SystemPort";
}

//! Set the name of a system port
void GUISystemPort::setName(QString newName, renameRestrictions renameSettings)
{
    QString oldName = getName();
    //If name same as before do nothing
    if (newName != oldName)
    {
        //Check if we want to avoid trying to rename in the graphics view map
        if (renameSettings == CORERENAMEONLY)
        {
            //Set name in core component, Also set the current name to the resulting one (might have been changed)
            mAppearanceData.setName(mpParentSystem->mpCoreSystemAccess->renameSystemPort(oldName, newName));
            refreshDisplayName();
            mpGuiPort->setDisplayName(mAppearanceData.getName()); //change the actual gui port name
        }
        else
        {
            //Rename
            mpParentSystem->renameGUIObject(oldName, newName);
        }
    }
}

int GUISystemPort::type() const
{
    return Type;
}
<|endoftext|>


<commit_before>#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/Module.h"
#include "llvm/Constants.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Instructions.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/PassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/DebugInfo.h"
#include "llvm/DataLayout.h"

#include <set>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <string>

#include "accept.h"

using namespace llvm;

// Command-line flags.
cl::opt<bool> optRelax ("accept-relax",
    cl::desc("ACCEPT: enable relaxations"));

ACCEPTPass::ACCEPTPass() : FunctionPass(ID) {
  module = 0;
  opportunityId = 0;
  log = 0;
}

void ACCEPTPass::getAnalysisUsage(AnalysisUsage &Info) const {
  Info.addRequired<LoopInfo>();
  Info.addRequired<ApproxInfo>();
  if (acceptUseProfile)
    Info.addRequired<ProfileInfo>();
}

bool ACCEPTPass::shouldSkipFunc(Function &F) {
  if (F.getName().startswith("accept_")) {
    return true;
  }

  // If we're missing debug info for the function, give up.
  if (!funcDebugInfo.count(&F)) {
    return false;
  }

  DISubprogram funcInfo = funcDebugInfo[&F];
  StringRef filename = funcInfo.getFilename();
  if (filename.startswith("/usr/include/") ||
      filename.startswith("/usr/lib/"))
    return false; // true;
  if (AI->markerAtLine(filename, funcInfo.getLineNumber()) == markerForbid) {
    return true;
  }
  return false;
}

bool ACCEPTPass::runOnFunction(Function &F) {
  AI = &getAnalysis<ApproxInfo>();
  log = AI->log;

  // Skip optimizing functions that seem to be in standard libraries.
  if (shouldSkipFunc(F))
    return false;

  return optimizeLoops(F) || optimizeSync(F);
}

// Find the debug info for every "subprogram" (i.e., function).
// Inspired by DebugInfoFinder::procuessModule, but actually examines
// multiple compilation units.
void ACCEPTPass::collectFuncDebug(Module &M) {
  NamedMDNode *cuNodes = module->getNamedMetadata("llvm.dbg.cu");
  if (!cuNodes) {
    errs() << "ACCEPT: debug information not available\n";
    return;
  }

  for (unsigned i = 0; i != cuNodes->getNumOperands(); ++i) {
    DICompileUnit cu(cuNodes->getOperand(i));

    DIArray spa = cu.getSubprograms();
    for (unsigned j = 0; j != spa.getNumElements(); ++j) {
      collectSubprogram(DISubprogram(spa.getElement(j)));
    }

    DIArray tya = cu.getRetainedTypes();
    for (unsigned j = 0; j != tya.getNumElements(); ++j) {
      collectType(DIType(spa.getElement(i)));
    }
  }
}
void ACCEPTPass::collectSubprogram(DISubprogram sp) {
  if (Function *func = sp.getFunction()) {
    funcDebugInfo[func] = sp;
  }
}
void ACCEPTPass::collectType(DIType ty) {
  if (ty.isCompositeType()) {
    DICompositeType cty(ty);
    collectType(cty.getTypeDerivedFrom());
    DIArray da = cty.getTypeArray();
    for (unsigned i = 0; i != da.getNumElements(); ++i) {
      DIDescriptor d = da.getElement(i);
      if (d.isType())
        collectType(DIType(d));
      else if (d.isSubprogram())
        collectSubprogram(DISubprogram(d));
    }
  }
}

bool ACCEPTPass::doInitialization(Module &M) {
  module = &M;
  relax = optRelax;

  if (relax)
    loadRelaxConfig();

  collectFuncDebug(M);

  return false;
}

bool ACCEPTPass::doFinalization(Module &M) {
  if (!relax)
    dumpRelaxConfig();
  return false;
}

IntegerType *ACCEPTPass::getNativeIntegerType() {
  DataLayout layout(module->getDataLayout());
  return Type::getIntNTy(module->getContext(),
                          layout.getPointerSizeInBits());
}

const char *ACCEPTPass::getPassName() const {
  return "ACCEPT relaxation";
}

/**** RELAXATION CONFIGURATION ***/

void ACCEPTPass::dumpRelaxConfig() {
  std::ofstream configFile("accept_config.txt", std::ios_base::out);
  for (std::map<int, int>::iterator i = relaxConfig.begin();
        i != relaxConfig.end(); ++i) {
    configFile << i->first << " "
                << i->second << "\n";
  }
  configFile.close();

  std::ofstream descFile("accept_config_desc.txt", std::ios_base::out);
  for (std::map<int, std::string>::iterator i = configDesc.begin();
        i != configDesc.end(); ++i) {
    descFile << i->first << " "
              << i->second << "\n";
  }
  descFile.close();
}

void ACCEPTPass::loadRelaxConfig() {
  std::ifstream configFile("accept_config.txt");;
  if (!configFile.good()) {
    errs() << "no config file; no optimizations will occur\n";
    return;
  }

  while (configFile.good()) {
    int ident;
    int param;
    configFile >> ident >> param;
    relaxConfig[ident] = param;
  }

  configFile.close();
}

char ACCEPTPass::ID = 0;

FunctionPass *llvm::createAcceptTransformPass() {
  return new ACCEPTPass();
}
<commit_msg>skip analyzing intrinsics<commit_after>#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/Module.h"
#include "llvm/Constants.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Instructions.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/PassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/DebugInfo.h"
#include "llvm/DataLayout.h"

#include <set>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <string>

#include "accept.h"

using namespace llvm;

// Command-line flags.
cl::opt<bool> optRelax ("accept-relax",
    cl::desc("ACCEPT: enable relaxations"));

ACCEPTPass::ACCEPTPass() : FunctionPass(ID) {
  module = 0;
  opportunityId = 0;
  log = 0;
}

void ACCEPTPass::getAnalysisUsage(AnalysisUsage &Info) const {
  Info.addRequired<LoopInfo>();
  Info.addRequired<ApproxInfo>();
  if (acceptUseProfile)
    Info.addRequired<ProfileInfo>();
}

bool ACCEPTPass::shouldSkipFunc(Function &F) {
  // ACCEPT internal functions.
  if (F.getName().startswith("accept_")) {
    return true;
  }

  // LLVM intrinsics.
  if (F.isIntrinsic()) {
    return true;
  }

  // If we're missing debug info for the function, give up.
  if (!funcDebugInfo.count(&F)) {
    return false;
  }

  DISubprogram funcInfo = funcDebugInfo[&F];
  StringRef filename = funcInfo.getFilename();
  if (filename.startswith("/usr/include/") ||
      filename.startswith("/usr/lib/"))
    return false; // true;
  if (AI->markerAtLine(filename, funcInfo.getLineNumber()) == markerForbid) {
    return true;
  }
  return false;
}

bool ACCEPTPass::runOnFunction(Function &F) {
  AI = &getAnalysis<ApproxInfo>();
  log = AI->log;

  // Skip optimizing functions that seem to be in standard libraries.
  if (shouldSkipFunc(F))
    return false;

  return optimizeLoops(F) || optimizeSync(F);
}

// Find the debug info for every "subprogram" (i.e., function).
// Inspired by DebugInfoFinder::procuessModule, but actually examines
// multiple compilation units.
void ACCEPTPass::collectFuncDebug(Module &M) {
  NamedMDNode *cuNodes = module->getNamedMetadata("llvm.dbg.cu");
  if (!cuNodes) {
    errs() << "ACCEPT: debug information not available\n";
    return;
  }

  for (unsigned i = 0; i != cuNodes->getNumOperands(); ++i) {
    DICompileUnit cu(cuNodes->getOperand(i));

    DIArray spa = cu.getSubprograms();
    for (unsigned j = 0; j != spa.getNumElements(); ++j) {
      collectSubprogram(DISubprogram(spa.getElement(j)));
    }

    DIArray tya = cu.getRetainedTypes();
    for (unsigned j = 0; j != tya.getNumElements(); ++j) {
      collectType(DIType(spa.getElement(i)));
    }
  }
}
void ACCEPTPass::collectSubprogram(DISubprogram sp) {
  if (Function *func = sp.getFunction()) {
    funcDebugInfo[func] = sp;
  }
}
void ACCEPTPass::collectType(DIType ty) {
  if (ty.isCompositeType()) {
    DICompositeType cty(ty);
    collectType(cty.getTypeDerivedFrom());
    DIArray da = cty.getTypeArray();
    for (unsigned i = 0; i != da.getNumElements(); ++i) {
      DIDescriptor d = da.getElement(i);
      if (d.isType())
        collectType(DIType(d));
      else if (d.isSubprogram())
        collectSubprogram(DISubprogram(d));
    }
  }
}

bool ACCEPTPass::doInitialization(Module &M) {
  module = &M;
  relax = optRelax;

  if (relax)
    loadRelaxConfig();

  collectFuncDebug(M);

  return false;
}

bool ACCEPTPass::doFinalization(Module &M) {
  if (!relax)
    dumpRelaxConfig();
  return false;
}

IntegerType *ACCEPTPass::getNativeIntegerType() {
  DataLayout layout(module->getDataLayout());
  return Type::getIntNTy(module->getContext(),
                          layout.getPointerSizeInBits());
}

const char *ACCEPTPass::getPassName() const {
  return "ACCEPT relaxation";
}

/**** RELAXATION CONFIGURATION ***/

void ACCEPTPass::dumpRelaxConfig() {
  std::ofstream configFile("accept_config.txt", std::ios_base::out);
  for (std::map<int, int>::iterator i = relaxConfig.begin();
        i != relaxConfig.end(); ++i) {
    configFile << i->first << " "
                << i->second << "\n";
  }
  configFile.close();

  std::ofstream descFile("accept_config_desc.txt", std::ios_base::out);
  for (std::map<int, std::string>::iterator i = configDesc.begin();
        i != configDesc.end(); ++i) {
    descFile << i->first << " "
              << i->second << "\n";
  }
  descFile.close();
}

void ACCEPTPass::loadRelaxConfig() {
  std::ifstream configFile("accept_config.txt");;
  if (!configFile.good()) {
    errs() << "no config file; no optimizations will occur\n";
    return;
  }

  while (configFile.good()) {
    int ident;
    int param;
    configFile >> ident >> param;
    relaxConfig[ident] = param;
  }

  configFile.close();
}

char ACCEPTPass::ID = 0;

FunctionPass *llvm::createAcceptTransformPass() {
  return new ACCEPTPass();
}
<|endoftext|>


<commit_before>#ifndef DISABLE_VISP
//! needed to avoid a weird bug in ViSP
#define PNG_SKIP_SETJMP_CHECK
#endif
#ifdef _WIN32
#define hypot _hypot
#endif

#include "mtf/TrackerStrct_mt.h"

#include <Python.h>
#include <numpy/arrayobject.h>

using namespace std;
using namespace mtf::params;

static PyObject* initInput(PyObject* self, PyObject* args);
static PyObject* create(PyObject* self, PyObject* args);
static PyObject* getRegion(PyObject* self, PyObject* args);
static PyObject* setRegion(PyObject* self, PyObject* args);
static PyObject* remove(PyObject* self, PyObject* args);

static PyMethodDef pyMTF2Methods[] = {
	{ "init", init, METH_VARARGS },
	{ "is_initialized", is_initialized, METH_VARARGS },
	{ "quit", quit, METH_VARARGS },
	{ "get_frame", get_frame, METH_VARARGS },
	{ "create_tracker", create_tracker, METH_VARARGS | METH_KEYWORDS },
	{ "get_region", get_region, METH_VARARGS },
	{ "set_region", set_region, METH_VARARGS },
	{ "remove_tracker", remove_tracker, METH_VARARGS },
	{ "remove_trackers", remove_trackers, METH_VARARGS },
	{ NULL, NULL, 0, NULL }     /* Sentinel - marks the end of this structure */
};

#if PY_MAJOR_VERSION < 3
PyMODINIT_FUNC initpyMTF2()  {
	(void)Py_InitModule("pyMTF2", pyMTF2Methods);
	import_array();  // Must be present for NumPy.  Called first after above line.
}
#else
static struct PyModuleDef pyMTF2Module = {
	PyModuleDef_HEAD_INIT,
	"pyMTF2",   /* name of module */
	NULL, /* module documentation, may be NULL */
	-1,       /* size of per-interpreter state of the module,
			  or -1 if the module keeps state in global variables. */
			  pyMTF2Methods
};
PyMODINIT_FUNC PyInit_pyMTF2(void) {
	import_array();
	return PyModule_Create(&pyMTF2Module);
}
#endif

static InputStructPtr input;
static std::map<int, TrackerStruct> trackers;

static unsigned int _tracker_id = 0;

bool createInput() {
	if(input_buffer_size <= 1){
		input_buffer_size = 100;
	}
	Input _input;
	try{
		_input.reset(mtf::getInput(pipeline));
		if(!_input->initialize()){
			PySys_WriteStdout("Pipeline could not be initialized successfully\n");
			return false;
		}
	} catch(const mtf::utils::Exception &err){
		PySys_WriteStdout("Exception of type %s encountered while initializing the input pipeline: %s\n",
			err.type(), err.what());
		return false;
	}
	if(input) {
		input->reset(_input);
	} else {
		input.reset(new InputStruct(_input));
	}

	return true;
}
bool checkInput(bool verbose=true) {
	if(!input){
		if(verbose){
			PySys_WriteStdout("Input pipeline has not been initialized\n");
		}
		return false;
	}
	if(!input->isValid()) {
		if(verbose){
			PySys_WriteStdout("Input pipeline is not active\n");
		}
		return false;
	}
	return true;
}
bool getFrame(){

	return true;
}

bool initializeTracker(Tracker &tracker, PreProc &pre_proc,
	const cv::Mat &init_img, const cv::Mat &init_corners) {
	try{
		pre_proc->initialize(init_img);
	} catch(const mtf::utils::Exception &err){
		PySys_WriteStdout("Exception of type %s encountered while initializing the pre processor: %s\n",
			err.type(), err.what());
		return false;
	}
	try{
		for(PreProc curr_obj = pre_proc; curr_obj; curr_obj = curr_obj->next){
			tracker->setImage(curr_obj->getFrame());
		}
		double min_x = init_corners.at<double>(0, 0);
		double min_y = init_corners.at<double>(1, 0);
		double max_x = init_corners.at<double>(0, 2);
		double max_y = init_corners.at<double>(1, 2);
		double size_x = max_x - min_x;
		double size_y = max_y - min_y;
		PySys_WriteStdout("Initializing tracker with object of size %f x %f...\n", size_x, size_y);

		tracker->initialize(init_corners);
	} catch(const mtf::utils::Exception &err){
		PySys_WriteStdout("Exception of type %s encountered while initializing the tracker: %s\n",
			err.type(), err.what());
		return false;
	}
	PySys_WriteStdout("Initialization successful.\n");
	return true;
}
bool createTracker(const cv::Mat &init_corners) {
	if(!input->isValid()){
		PySys_WriteStdout("Input has not been initialized\n");
		return false;
	}
	Tracker tracker;
	try{
		tracker.reset(mtf::getTracker(mtf_sm, mtf_am, mtf_ssm, mtf_ilm));
		if(!tracker){
			PySys_WriteStdout("Tracker could not be created successfully\n");
			return false;
		}
	} catch(const mtf::utils::Exception &err){
		PySys_WriteStdout("Exception of type %s encountered while creating the tracker: %s\n",
			err.type(), err.what());
		return false;
	}
	PreProc pre_proc;
	try{
		pre_proc = mtf::getPreProc(tracker->inputType(), pre_proc_type);
	} catch(const mtf::utils::Exception &err){
		PySys_WriteStdout("Exception of type %s encountered while creating the pre processor: %s\n",
			err.type(), err.what());
		return false;
	}
	if(!initializeTracker(tracker, pre_proc, input->getFrame(), init_corners)){
		PySys_WriteStdout("Tracker initialization failed");
		return false;
	}
	++_tracker_id;
	trackers.insert(std::pair<int, TrackerStruct>(_tracker_id,
		TrackerStruct(tracker, pre_proc, input, _tracker_id)));
	return true;
}

bool setRegion(unsigned int tracker_id, const cv::Mat &corners) {
	std::map<int, TrackerStruct>::iterator it = trackers.find(tracker_id);
	if(it == trackers.end()){
		PySys_WriteStdout("Invalid tracker ID: %d\n", tracker_id);
		return false;
	}
	try{
		it->second.setRegion(corners);
	} catch(const mtf::utils::Exception &err){
		PySys_WriteStdout("Exception of type %s encountered while resetting the tracker: %s\n",
			err.type(), err.what());
		return false;
	}
	return true;
}
static PyMethodDef pyMTF2Methods[] = {
	{ "set_region", set_region, METH_VARARGS },
	{ "remove_tracker", remove_tracker, METH_VARARGS },
	{ "remove_trackers", remove_trackers, METH_VARARGS },
	{ NULL, NULL, 0, NULL }     /* Sentinel - marks the end of this structure */
};

static PyObject* get_region(PyObject* self, PyObject* args) {
	unsigned int tracker_id;
	if(!PyArg_ParseTuple(args, "I", &tracker_id)) {
		PySys_WriteStdout("\n----pyMTF2::get_region: Input argument could not be parsed----\n\n");
		return Py_BuildValue("");
	}

	std::map<int, TrackerStruct>::iterator it = trackers.find(tracker_id);
	if(it == trackers.end()){
		PySys_WriteStdout("Invalid tracker ID: %d\n", tracker_id);
		return Py_BuildValue("");
	}
	cv::Mat corners = it->second.getRegion();
	int dims[] = { 2, 4 };
	PyArrayObject *corners_py = (PyArrayObject *)PyArray_FromDims(2, dims, NPY_DOUBLE);
	double* corners_py_data = (double*)corners_py->data;
	for(unsigned int corner_id = 0; corner_id < 4; ++corner_id) {
		corners_py_data[corner_id] = corners.at<double>(0, corner_id);
		corners_py_data[corner_id + 4] = corners.at<double>(1, corner_id);
	}
	return Py_BuildValue("O", corners_py);
}

static PyObject* init(PyObject* self, PyObject* args) {
	if(checkInput(false)) {
		PySys_WriteStdout("Input pipeline has already been initialized\n");
		return Py_BuildValue("i", 1);
	}
	char* _params = nullptr;
	if(!PyArg_ParseTuple(args, "|z", &_params)) {
		PySys_WriteStdout("\n----pyMTF::init: Input arguments could not be parsed----\n\n");
		return Py_BuildValue("i", 0);
	}
	if(_params == NULL) {
		PySys_WriteStdout("\n----pyMTF::init::_params is NULL----\n\n");
		return Py_BuildValue("i", 0);
	}
	if(!readParams(_params)) {
		PySys_WriteStdout("Parameters could not be parsed");
		return Py_BuildValue("i", 0);
	}
	if(!createInput()){
		return Py_BuildValue("i", 0);
	}
	return Py_BuildValue("i", 1);
}

static PyObject* is_initialized(PyObject* self, PyObject* args) {
	if(checkInput(false)) {
		return Py_BuildValue("i", 1);
	}
	return Py_BuildValue("i", 0);
}

static PyObject* quit(PyObject* self, PyObject* args) {
	PySys_WriteStdout("Clearing up...");
	input->reset();
	for(auto it = trackers.begin(); it != trackers.end(); ++it){
		it->second.reset();
	}
	trackers.clear();
	PySys_WriteStdout("Done\n");
	return Py_BuildValue("i", 1);
}

static PyObject* get_frame(PyObject* self, PyObject* args) {
	if(!checkInput()) {
		return Py_BuildValue("");
	}

	const cv::Mat frame = input->getFrame();
	int n_rows = frame.rows, n_cols = frame.cols;

	int dims[] = { n_rows, n_cols, 3 };
	PyArrayObject *frame_py = (PyArrayObject *)PyArray_FromDims(3, dims, NPY_UBYTE);
	unsigned char *result = (unsigned char*)frame_py->data;

	for(int row = 0; row < n_rows; ++row) {
		for(int col = 0; col < n_cols; ++col) {
			int np_location = col*frame_py->strides[1] + row*frame_py->strides[0];
			cv::Vec3b pix_vals = frame.at<cv::Vec3b>(row, col);
			for(int ch = 0; ch < 3; ++ch) {
				*(result + np_location + ch*frame_py->strides[2]) = pix_vals[ch];
			}
		}
	}
	return Py_BuildValue("O", frame_py);
}

static PyObject* create_tracker(PyObject* self, PyObject* args, PyObject *keywds) {
	PyArrayObject *in_corners_py = nullptr;
	char* _params = nullptr;
	static char *kwlist[] = { "params", "corners", NULL };
	if(!PyArg_ParseTupleAndKeywords(args, keywds, "|zO!", &_params, &PyArray_Type, &in_corners_py)) {
		PySys_WriteStdout("\n----pyMTF::init: Input arguments could not be parsed----\n\n");
		return Py_BuildValue("i", 0);
	}
	if(!readParams(_params)) {
		PySys_WriteStdout("Parameters could not be parsed");
		return Py_BuildValue("i", 0);
	}

	cv::Mat init_corners_cv(2, 4, CV_64FC1);
	if(in_corners_py) {
		cv::Mat temp(2, 4, CV_64FC1, in_corners_py->data);
		init_corners_cv.at<double>(0, 0) = temp.at<double>(0, 0);
		init_corners_cv.at<double>(1, 0) = temp.at<double>(0, 1);
		init_corners_cv.at<double>(0, 1) = temp.at<double>(0, 2);
		init_corners_cv.at<double>(1, 1) = temp.at<double>(0, 3);
		init_corners_cv.at<double>(0, 2) = temp.at<double>(1, 0);
		init_corners_cv.at<double>(1, 2) = temp.at<double>(1, 1);
		init_corners_cv.at<double>(0, 3) = temp.at<double>(1, 2);
		init_corners_cv.at<double>(1, 3) = temp.at<double>(1, 3);
	} else {
		ObjectSelectorThread obj_sel_thread(input, init_corners_cv);
		boost::thread t = boost::thread{ boost::ref(obj_sel_thread) };
		try{
			t.join();
		} catch(boost::thread_interrupted) {
			printf("Caught exception from object selector thread\n");
		}
		if(!obj_sel_thread.success) {
			PySys_WriteStdout("Initial corners could not be obtained\n");
			return Py_BuildValue("i", 0);
		}
	}
	if(!createTracker(init_corners_cv)) {
		PySys_WriteStdout("Tracker creation was unsuccessful corners\n");
		return Py_BuildValue("i", 0);
	}
	return Py_BuildValue("I", _tracker_id);
}<commit_msg>Completed set_region;<commit_after>#ifndef DISABLE_VISP
//! needed to avoid a weird bug in ViSP
#define PNG_SKIP_SETJMP_CHECK
#endif
#ifdef _WIN32
#define hypot _hypot
#endif

#include "mtf/TrackerStrct_mt.h"

#include <Python.h>
#include <numpy/arrayobject.h>

using namespace std;
using namespace mtf::params;

static PyObject* initInput(PyObject* self, PyObject* args);
static PyObject* create(PyObject* self, PyObject* args);
static PyObject* getRegion(PyObject* self, PyObject* args);
static PyObject* setRegion(PyObject* self, PyObject* args);
static PyObject* remove(PyObject* self, PyObject* args);

static PyMethodDef pyMTF2Methods[] = {
	{ "init", init, METH_VARARGS },
	{ "is_initialized", is_initialized, METH_VARARGS },
	{ "quit", quit, METH_VARARGS },
	{ "get_frame", get_frame, METH_VARARGS },
	{ "create_tracker", create_tracker, METH_VARARGS | METH_KEYWORDS },
	{ "get_region", get_region, METH_VARARGS },
	{ "set_region", set_region, METH_VARARGS },
	{ "remove_tracker", remove_tracker, METH_VARARGS },
	{ "remove_trackers", remove_trackers, METH_VARARGS },
	{ NULL, NULL, 0, NULL }     /* Sentinel - marks the end of this structure */
};

#if PY_MAJOR_VERSION < 3
PyMODINIT_FUNC initpyMTF2()  {
	(void)Py_InitModule("pyMTF2", pyMTF2Methods);
	import_array();  // Must be present for NumPy.  Called first after above line.
}
#else
static struct PyModuleDef pyMTF2Module = {
	PyModuleDef_HEAD_INIT,
	"pyMTF2",   /* name of module */
	NULL, /* module documentation, may be NULL */
	-1,       /* size of per-interpreter state of the module,
			  or -1 if the module keeps state in global variables. */
			  pyMTF2Methods
};
PyMODINIT_FUNC PyInit_pyMTF2(void) {
	import_array();
	return PyModule_Create(&pyMTF2Module);
}
#endif

static InputStructPtr input;
static std::map<int, TrackerStruct> trackers;

static unsigned int _tracker_id = 0;

bool createInput() {
	if(input_buffer_size <= 1){
		input_buffer_size = 100;
	}
	Input _input;
	try{
		_input.reset(mtf::getInput(pipeline));
		if(!_input->initialize()){
			PySys_WriteStdout("Pipeline could not be initialized successfully\n");
			return false;
		}
	} catch(const mtf::utils::Exception &err){
		PySys_WriteStdout("Exception of type %s encountered while initializing the input pipeline: %s\n",
			err.type(), err.what());
		return false;
	}
	if(input) {
		input->reset(_input);
	} else {
		input.reset(new InputStruct(_input));
	}

	return true;
}
bool checkInput(bool verbose=true) {
	if(!input){
		if(verbose){
			PySys_WriteStdout("Input pipeline has not been initialized\n");
		}
		return false;
	}
	if(!input->isValid()) {
		if(verbose){
			PySys_WriteStdout("Input pipeline is not active\n");
		}
		return false;
	}
	return true;
}
bool getFrame(){

	return true;
}

bool initializeTracker(Tracker &tracker, PreProc &pre_proc,
	const cv::Mat &init_img, const cv::Mat &init_corners) {
	try{
		pre_proc->initialize(init_img);
	} catch(const mtf::utils::Exception &err){
		PySys_WriteStdout("Exception of type %s encountered while initializing the pre processor: %s\n",
			err.type(), err.what());
		return false;
	}
	try{
		for(PreProc curr_obj = pre_proc; curr_obj; curr_obj = curr_obj->next){
			tracker->setImage(curr_obj->getFrame());
		}
		double min_x = init_corners.at<double>(0, 0);
		double min_y = init_corners.at<double>(1, 0);
		double max_x = init_corners.at<double>(0, 2);
		double max_y = init_corners.at<double>(1, 2);
		double size_x = max_x - min_x;
		double size_y = max_y - min_y;
		PySys_WriteStdout("Initializing tracker with object of size %f x %f...\n", size_x, size_y);

		tracker->initialize(init_corners);
	} catch(const mtf::utils::Exception &err){
		PySys_WriteStdout("Exception of type %s encountered while initializing the tracker: %s\n",
			err.type(), err.what());
		return false;
	}
	PySys_WriteStdout("Initialization successful.\n");
	return true;
}
bool createTracker(const cv::Mat &init_corners) {
	if(!input->isValid()){
		PySys_WriteStdout("Input has not been initialized\n");
		return false;
	}
	Tracker tracker;
	try{
		tracker.reset(mtf::getTracker(mtf_sm, mtf_am, mtf_ssm, mtf_ilm));
		if(!tracker){
			PySys_WriteStdout("Tracker could not be created successfully\n");
			return false;
		}
	} catch(const mtf::utils::Exception &err){
		PySys_WriteStdout("Exception of type %s encountered while creating the tracker: %s\n",
			err.type(), err.what());
		return false;
	}
	PreProc pre_proc;
	try{
		pre_proc = mtf::getPreProc(tracker->inputType(), pre_proc_type);
	} catch(const mtf::utils::Exception &err){
		PySys_WriteStdout("Exception of type %s encountered while creating the pre processor: %s\n",
			err.type(), err.what());
		return false;
	}
	if(!initializeTracker(tracker, pre_proc, input->getFrame(), init_corners)){
		PySys_WriteStdout("Tracker initialization failed");
		return false;
	}
	++_tracker_id;
	trackers.insert(std::pair<int, TrackerStruct>(_tracker_id,
		TrackerStruct(tracker, pre_proc, input, _tracker_id)));
	return true;
}

bool setRegion(unsigned int tracker_id, const cv::Mat &corners) {
	std::map<int, TrackerStruct>::iterator it = trackers.find(tracker_id);
	if(it == trackers.end()){
		PySys_WriteStdout("Invalid tracker ID: %d\n", tracker_id);
		return false;
	}
	try{
		it->second.setRegion(corners);
	} catch(const mtf::utils::Exception &err){
		PySys_WriteStdout("Exception of type %s encountered while resetting the tracker: %s\n",
			err.type(), err.what());
		return false;
	}
	return true;
}
static PyMethodDef pyMTF2Methods[] = {
	{ "remove_tracker", remove_tracker, METH_VARARGS },
	{ "remove_trackers", remove_trackers, METH_VARARGS },
};

static PyObject* set_region(PyObject* self, PyObject* args) {
	unsigned int tracker_id;
	PyArrayObject *corners_py;
	if(!PyArg_ParseTuple(args, "O!I", &PyArray_Type, &corners_py, &tracker_id)) {
		PySys_WriteStdout("\n----pyMTF2::set_region: Input arguments could not be parsed----\n\n");
		return Py_BuildValue("i", 0);
	}

	std::map<int, TrackerStruct>::iterator it = trackers.find(tracker_id);
	if(it == trackers.end()){
		PySys_WriteStdout("Invalid tracker ID: %d\n", tracker_id);
		return Py_BuildValue("i", 0);
	}
	if(corners_py == NULL) {
		PySys_WriteStdout("\n----pyMTF2::set_region::init_corners is NULL----\n\n");
		return Py_BuildValue("i", 0);
	}
	if(corners_py->dimensions[0] != 2 || corners_py->dimensions[1] != 4){
		PySys_WriteStdout("pyMTF2::set_region::Corners matrix has incorrect dimensions: %ld, %ld\n",
			corners_py->dimensions[0], corners_py->dimensions[1]);
		return Py_BuildValue("i", 0);
	}
	cv::Mat corners(2, 4, CV_64FC1);
	double* corners_py_data = (double*)corners_py->data;
	for(unsigned int corner_id = 0; corner_id < 4; ++corner_id) {
		corners.at<double>(0, corner_id) = corners_py_data[corner_id];
		corners.at<double>(1, corner_id) = corners_py_data[corner_id + 4];
	}
	try{
		it->second.setRegion(corners);
	} catch(const mtf::utils::Exception &err){
		printf("Exception of type %s encountered while resetting the tracker: %s\n",
			err.type(), err.what());
		return Py_BuildValue("i", 0);
	}
	return Py_BuildValue("i", 1);

}

static PyObject* init(PyObject* self, PyObject* args) {
	if(checkInput(false)) {
		PySys_WriteStdout("Input pipeline has already been initialized\n");
		return Py_BuildValue("i", 1);
	}
	char* _params = nullptr;
	if(!PyArg_ParseTuple(args, "|z", &_params)) {
		PySys_WriteStdout("\n----pyMTF::init: Input arguments could not be parsed----\n\n");
		return Py_BuildValue("i", 0);
	}
	if(_params == NULL) {
		PySys_WriteStdout("\n----pyMTF::init::_params is NULL----\n\n");
		return Py_BuildValue("i", 0);
	}
	if(!readParams(_params)) {
		PySys_WriteStdout("Parameters could not be parsed");
		return Py_BuildValue("i", 0);
	}
	if(!createInput()){
		return Py_BuildValue("i", 0);
	}
	return Py_BuildValue("i", 1);
}

static PyObject* is_initialized(PyObject* self, PyObject* args) {
	if(checkInput(false)) {
		return Py_BuildValue("i", 1);
	}
	return Py_BuildValue("i", 0);
}

static PyObject* quit(PyObject* self, PyObject* args) {
	PySys_WriteStdout("Clearing up...");
	input->reset();
	for(auto it = trackers.begin(); it != trackers.end(); ++it){
		it->second.reset();
	}
	trackers.clear();
	PySys_WriteStdout("Done\n");
	return Py_BuildValue("i", 1);
}

static PyObject* get_frame(PyObject* self, PyObject* args) {
	if(!checkInput()) {
		return Py_BuildValue("");
	}

	const cv::Mat frame = input->getFrame();
	int n_rows = frame.rows, n_cols = frame.cols;

	int dims[] = { n_rows, n_cols, 3 };
	PyArrayObject *frame_py = (PyArrayObject *)PyArray_FromDims(3, dims, NPY_UBYTE);
	unsigned char *result = (unsigned char*)frame_py->data;

	for(int row = 0; row < n_rows; ++row) {
		for(int col = 0; col < n_cols; ++col) {
			int np_location = col*frame_py->strides[1] + row*frame_py->strides[0];
			cv::Vec3b pix_vals = frame.at<cv::Vec3b>(row, col);
			for(int ch = 0; ch < 3; ++ch) {
				*(result + np_location + ch*frame_py->strides[2]) = pix_vals[ch];
			}
		}
	}
	return Py_BuildValue("O", frame_py);
}

static PyObject* create_tracker(PyObject* self, PyObject* args, PyObject *keywds) {
	PyArrayObject *in_corners_py = nullptr;
	char* _params = nullptr;
	static char *kwlist[] = { "params", "corners", NULL };
	if(!PyArg_ParseTupleAndKeywords(args, keywds, "|zO!", &_params, &PyArray_Type, &in_corners_py)) {
		PySys_WriteStdout("\n----pyMTF::init: Input arguments could not be parsed----\n\n");
		return Py_BuildValue("i", 0);
	}
	if(!readParams(_params)) {
		PySys_WriteStdout("Parameters could not be parsed");
		return Py_BuildValue("i", 0);
	}

	cv::Mat init_corners_cv(2, 4, CV_64FC1);
	if(in_corners_py) {
		cv::Mat temp(2, 4, CV_64FC1, in_corners_py->data);
		init_corners_cv.at<double>(0, 0) = temp.at<double>(0, 0);
		init_corners_cv.at<double>(1, 0) = temp.at<double>(0, 1);
		init_corners_cv.at<double>(0, 1) = temp.at<double>(0, 2);
		init_corners_cv.at<double>(1, 1) = temp.at<double>(0, 3);
		init_corners_cv.at<double>(0, 2) = temp.at<double>(1, 0);
		init_corners_cv.at<double>(1, 2) = temp.at<double>(1, 1);
		init_corners_cv.at<double>(0, 3) = temp.at<double>(1, 2);
		init_corners_cv.at<double>(1, 3) = temp.at<double>(1, 3);
	} else {
		ObjectSelectorThread obj_sel_thread(input, init_corners_cv);
		boost::thread t = boost::thread{ boost::ref(obj_sel_thread) };
		try{
			t.join();
		} catch(boost::thread_interrupted) {
			printf("Caught exception from object selector thread\n");
		}
		if(!obj_sel_thread.success) {
			PySys_WriteStdout("Initial corners could not be obtained\n");
			return Py_BuildValue("i", 0);
		}
	}
	if(!createTracker(init_corners_cv)) {
		PySys_WriteStdout("Tracker creation was unsuccessful corners\n");
		return Py_BuildValue("i", 0);
	}
	return Py_BuildValue("I", _tracker_id);
}

static PyObject* get_region(PyObject* self, PyObject* args) {
	unsigned int tracker_id;
	if(!PyArg_ParseTuple(args, "I", &tracker_id)) {
		PySys_WriteStdout("\n----pyMTF2::get_region: Input argument could not be parsed----\n\n");
		return Py_BuildValue("");
	}

	std::map<int, TrackerStruct>::iterator it = trackers.find(tracker_id);
	if(it == trackers.end()){
		PySys_WriteStdout("Invalid tracker ID: %d\n", tracker_id);
		return Py_BuildValue("");
	}
	cv::Mat corners = it->second.getRegion();
	int dims[] = { 2, 4 };
	PyArrayObject *corners_py = (PyArrayObject *)PyArray_FromDims(2, dims, NPY_DOUBLE);
	double* corners_py_data = (double*)corners_py->data;
	for(unsigned int corner_id = 0; corner_id < 4; ++corner_id) {
		corners_py_data[corner_id] = corners.at<double>(0, corner_id);
		corners_py_data[corner_id + 4] = corners.at<double>(1, corner_id);
	}
	return Py_BuildValue("O", corners_py);
}<|endoftext|>


<commit_before>// Copyright (c) 2016 Mirants Lu. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "paxos/node_impl.h"

#include <utility>

#include "paxos/schedule.h"
#include "proto/paxos.pb.h"
#include "skywalker/logging.h"

namespace skywalker {

NodeImpl::NodeImpl(const Options& options)
    : stop_(false), options_(options), network_(options.my) {}

NodeImpl::~NodeImpl() { stop_ = true; }

bool NodeImpl::StartWorking() {
  bool res = true;
  bool use_master = false;
  for (auto& g : options_.groups) {
    if (g.use_master) {
      use_master = true;
    }
    std::unique_ptr<Group> group(new Group(options_.my.id, g, &network_));
    res = group->Recover();
    if (res) {
      LOG_DEBUG("Group %u recover successful!", g.group_id);
      groups_.insert(std::make_pair(g.group_id, std::move(group)));
    } else {
      LOG_DEBUG("Group %u recover failed!", g.group_id);
      return res;
    }
  }

  Schedule::Instance()->Start(use_master);
  for (auto& g : groups_) {
    g.second->Start();
  }

  network_.StartServer(
      std::bind(&NodeImpl::OnReceiveMessage, this, std::placeholders::_1));
  LOG_DEBUG("Skywalker server start successful!");

  for (auto& g : groups_) {
    g.second->SyncMembership();
    g.second->SyncMaster();
  }

  return res;
}

size_t NodeImpl::group_size() const { return groups_.size(); }

bool NodeImpl::Propose(uint32_t group_id, uint32_t machine_id,
                       const std::string& value, void* context,
                       const ProposeCompleteCallback& cb) {
  if (!Valid(group_id)) {
    return false;
  }
  return groups_.at(group_id)->OnPropose(machine_id, value, context, cb);
}

bool NodeImpl::Propose(uint32_t group_id, uint32_t machine_id,
                       const std::string& value, void* context,
                       ProposeCompleteCallback&& cb) {
  if (!Valid(group_id)) {
    return false;
  }
  return groups_.at(group_id)->OnPropose(machine_id, value, context,
                                         std::move(cb));
}

void NodeImpl::OnReceiveMessage(const Slice& s) {
  // FIXME
  // Maybe use a mutex?
  if (!stop_) {
    std::shared_ptr<Content> c(new Content());
    c->ParseFromArray(s.data(), static_cast<int>(s.size()));
    if (Valid(c->group_id())) {
      groups_.at(c->group_id())->OnReceiveContent(c);
    }
  }
}

bool NodeImpl::ChangeMember(uint32_t group_id,
                            const std::vector<std::pair<Member, bool>>& value,
                            void* context, const ProposeCompleteCallback& cb) {
  if (!Valid(group_id)) {
    return false;
  }
  return groups_.at(group_id)->ChangeMember(value, context, cb);
}

void NodeImpl::GetMembership(uint32_t group_id, std::vector<Member>* result,
                             uint64_t* version) const {
  if (Valid(group_id)) {
    groups_.at(group_id)->GetMembership(result, version);
  }
}

bool NodeImpl::GetMaster(uint32_t group_id, Member* i,
                         uint64_t* version) const {
  if (!Valid(group_id)) {
    return false;
  }
  return groups_.at(group_id)->GetMaster(i, version);
}

bool NodeImpl::IsMaster(uint32_t group_id) const {
  if (!Valid(group_id)) {
    return false;
  }
  return groups_.at(group_id)->IsMaster();
}

void NodeImpl::RetireMaster(uint32_t group_id) {
  if (Valid(group_id)) {
    groups_.at(group_id)->RetireMaster();
  }
}

void NodeImpl::StartGC(uint32_t group_id) {
  if (Valid(group_id)) {
    groups_.at(group_id)->StartGC();
  }
}

void NodeImpl::StopGC(uint32_t group_id) {
  if (Valid(group_id)) {
    groups_.at(group_id)->StopGC();
  }
}

bool NodeImpl::Valid(uint32_t group_id) const {
  assert(groups_.find(group_id) != groups_.end());
  if (groups_.find(group_id) == groups_.end()) {
    LOG_WARN("Invalid groud id(%u)", group_id);
    return false;
  }
  return true;
}

bool Node::Start(const Options& options, Node** nodeptr) {
  *nodeptr = nullptr;
  NodeImpl* impl = new NodeImpl(options);
  bool res = impl->StartWorking();
  if (res) {
    *nodeptr = impl;
  } else {
    delete impl;
  }
  return res;
}

}  // namespace skywalker
<commit_msg>update node implement<commit_after>// Copyright (c) 2016 Mirants Lu. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "paxos/node_impl.h"

#include <algorithm>
#include <random>
#include <utility>

#include "paxos/schedule.h"
#include "proto/paxos.pb.h"
#include "skywalker/logging.h"

namespace skywalker {

NodeImpl::NodeImpl(const Options& options)
    : stop_(false), options_(options), network_(options.my) {}

NodeImpl::~NodeImpl() { stop_ = true; }

bool NodeImpl::StartWorking() {
  bool use_master = false;
  std::vector<Group*> groups;
  for (auto& g : options_.groups) {
    if (g.use_master) {
      use_master = true;
    }
    std::unique_ptr<Group> group(new Group(options_.my.id, g, &network_));
    if (group->Recover()) {
      LOG_DEBUG("Group %u recover successful!", g.group_id);
      groups.push_back(group.get());
      groups_.insert(std::make_pair(g.group_id, std::move(group)));
    } else {
      LOG_DEBUG("Group %u recover failed!", g.group_id);
      return false;
    }
  }

  Schedule::Instance()->Start(use_master);
  for (auto& g : groups) {
    g->Start();
  }

  network_.StartServer(
      std::bind(&NodeImpl::OnReceiveMessage, this, std::placeholders::_1));
  LOG_DEBUG("Skywalker server start successful!");

  // 防止所有的Master都是同一个节点。
  std::shuffle(groups.begin(), groups.end(),
               std::default_random_engine((unsigned)options_.my.id));
  for (auto& g : groups) {
    g->SyncMembership();
    g->SyncMaster();
  }

  return true;
}

size_t NodeImpl::group_size() const { return groups_.size(); }

bool NodeImpl::Propose(uint32_t group_id, uint32_t machine_id,
                       const std::string& value, void* context,
                       const ProposeCompleteCallback& cb) {
  if (!Valid(group_id)) {
    return false;
  }
  return groups_.at(group_id)->OnPropose(machine_id, value, context, cb);
}

bool NodeImpl::Propose(uint32_t group_id, uint32_t machine_id,
                       const std::string& value, void* context,
                       ProposeCompleteCallback&& cb) {
  if (!Valid(group_id)) {
    return false;
  }
  return groups_.at(group_id)->OnPropose(machine_id, value, context,
                                         std::move(cb));
}

void NodeImpl::OnReceiveMessage(const Slice& s) {
  // FIXME
  // Maybe use a mutex?
  if (!stop_) {
    std::shared_ptr<Content> c(new Content());
    c->ParseFromArray(s.data(), static_cast<int>(s.size()));
    if (Valid(c->group_id())) {
      groups_.at(c->group_id())->OnReceiveContent(c);
    }
  }
}

bool NodeImpl::ChangeMember(uint32_t group_id,
                            const std::vector<std::pair<Member, bool>>& value,
                            void* context, const ProposeCompleteCallback& cb) {
  if (!Valid(group_id)) {
    return false;
  }
  return groups_.at(group_id)->ChangeMember(value, context, cb);
}

void NodeImpl::GetMembership(uint32_t group_id, std::vector<Member>* result,
                             uint64_t* version) const {
  if (Valid(group_id)) {
    groups_.at(group_id)->GetMembership(result, version);
  }
}

bool NodeImpl::GetMaster(uint32_t group_id, Member* i,
                         uint64_t* version) const {
  if (!Valid(group_id)) {
    return false;
  }
  return groups_.at(group_id)->GetMaster(i, version);
}

bool NodeImpl::IsMaster(uint32_t group_id) const {
  if (!Valid(group_id)) {
    return false;
  }
  return groups_.at(group_id)->IsMaster();
}

void NodeImpl::RetireMaster(uint32_t group_id) {
  if (Valid(group_id)) {
    groups_.at(group_id)->RetireMaster();
  }
}

void NodeImpl::StartGC(uint32_t group_id) {
  if (Valid(group_id)) {
    groups_.at(group_id)->StartGC();
  }
}

void NodeImpl::StopGC(uint32_t group_id) {
  if (Valid(group_id)) {
    groups_.at(group_id)->StopGC();
  }
}

bool NodeImpl::Valid(uint32_t group_id) const {
  assert(groups_.find(group_id) != groups_.end());
  if (groups_.find(group_id) == groups_.end()) {
    LOG_WARN("Invalid groud id(%u)", group_id);
    return false;
  }
  return true;
}

bool Node::Start(const Options& options, Node** nodeptr) {
  *nodeptr = nullptr;
  NodeImpl* impl = new NodeImpl(options);
  bool res = impl->StartWorking();
  if (res) {
    *nodeptr = impl;
  } else {
    delete impl;
  }
  return res;
}

}  // namespace skywalker
<|endoftext|>