1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/**
* @file ModuleCreator.h
* @author <a href="mailto:mellmann@informatik.hu-berlin.de">Heinrich Mellmann</a>
*/

#ifndef _ModuleCreator_h_
#define _ModuleCreator_h_

#include "Module.h"

#include <Tools/DataStructures/Printable.h>
#include <Representations/Debug/Stopwatch.h>

#include <Eigen/Eigen>

/**
 * AbstractModuleCreator is an interface.
 * It is used to create lists of modules.
 * Additionally it provides functionality to enable/disable the module
 */
class AbstractModuleCreator: public Printable
{
public:
  virtual std::string moduleClassName() const = 0;
  virtual std::string modulePath() const = 0;
  virtual void setEnabled(bool value) = 0;
  virtual bool isEnabled() const = 0;
  virtual void execute() = 0;
  virtual Module* getModule() const = 0;
  virtual const Stopwatch& getStopwatch() const = 0;
  virtual ~AbstractModuleCreator() {}

  virtual const RegistrationInterfaceMap& staticProvided() const = 0;
  virtual const RegistrationInterfaceMap& staticRequired() const = 0;
};

/**
 * ModuleInstance is needed to instantiate the 
 * BlackBoardInterface of the class V (if it has one)
 * with a blackboard.
 * We assume, that the class V already inherites from BlackBoardInterface.
 * Thereby 'virtual' inheritence is esential (!).
 * 
 * (in fact, what we are doing is to extend the default constructor of the class V
 *  by providing a pointer to a blackboard instance, i.e., we call another 
 *  constructor of the BlackBoardInterface)
 */
template<class V>
class ModuleInstance: virtual public BlackBoardInterface, virtual public V
{
public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  ModuleInstance(BlackBoard& theBlackBoard)
    : BlackBoardInterface(&theBlackBoard)
  {}
};

/**
 * ModuleCreator implements the AbstractModuleCreator.
 * A module is deleted if it is disabled and created new if it is enabled.
 */
template<class M>
class ModuleCreator : public AbstractModuleCreator
{
private:
  BlackBoard& theBlackBoard;
  M* theInstance;

  // cannot be copied
  //ModuleCreator& operator=( const ModuleCreator& ) {}

  //
  Stopwatch& stopwatch;

public:

  ModuleCreator(BlackBoard& theBlackBoard, bool enabled = false)
    : theBlackBoard(theBlackBoard),
      theInstance(NULL),
      //stopwatch(StopwatchManager::getInstance().getStopwatch(IF<M>::getName()))
      stopwatch((*(theBlackBoard.template getRepresentation<DataHolder<StopwatchManager> >("StopwatchManager"))).getStopwatch(IF<M>::getName()))
  {
    setEnabled(enabled);
  }

  virtual ~ModuleCreator() {
    delete theInstance;
  }


  bool isEnabled() const {
    return theInstance != NULL;
  }


  void setEnabled(bool value)
  {
    if(value) {
      if( theInstance == NULL ) {
        theInstance = new ModuleInstance<M>(theBlackBoard);
      }
    } else {
      delete theInstance;
      theInstance = NULL;
    }
  }


  void execute()
  {
    if( theInstance != NULL ) {
      stopwatch.start();
      theInstance->execute();
      stopwatch.stop();
    }
  }


  Module* getModule() const
  {
    ASSERT(isEnabled());
    // ACHTUNG:
    // we have to use the unsafe C-cast because some modules may be privatly 
    // derive from Module and make a type cast inaccesible
    return (Module*)(theInstance);
  }


  M* getModuleT() const {
    ASSERT(isEnabled());
    return theInstance;
  }


  std::string moduleClassName() const {
    return typeid(M).name();
  }

  virtual std::string modulePath() const {
    return IF<M>::getModulePath();
  }

  const RegistrationInterfaceMap& staticProvided() const {
    return IF<M>::getProvide();
  }

  const RegistrationInterfaceMap& staticRequired() const {
    return IF<M>::getRequire();
  }

  void print(std::ostream& stream) const
  {
    if(isEnabled()) {
      stream << *getModule();
      return;
    }

    stream << "[ " << moduleClassName() << " ]" << std::endl;
    RegistrationInterfaceMap::const_iterator i = staticRequired().begin();
    for(;i != staticRequired().end(); ++i) {
      stream << " > " << i->first << std::endl;
    }

    i = staticProvided().begin();
    for(;i != staticProvided().end(); ++i) {
      stream << " < " << i->first << std::endl;
    }
  }//end print

  virtual const Stopwatch& getStopwatch() const
  {
    return stopwatch;
  }
};

#endif //_ModuleCreator_h_