ARGoS  3
A parallel, multi-engine simulator for swarm robotics
core/simulator/entity/entity.h
Go to the documentation of this file.
00001 
00013 #ifndef ENTITY_H
00014 #define ENTITY_H
00015 
00016 namespace argos {
00017    class CEntity;
00018    class CComposableEntity;
00019    class CSpace;
00020 }
00021 
00022 #include <argos3/core/utility/datatypes/datatypes.h>
00023 #include <argos3/core/utility/configuration/argos_configuration.h>
00024 #include <argos3/core/utility/configuration/base_configurable_resource.h>
00025 #include <argos3/core/utility/plugins/factory.h>
00026 #include <argos3/core/utility/plugins/vtable.h>
00027 
00028 #include <vector>
00029 #include <map>
00030 #include <string>
00031 
00032 #if defined(__apple_build_version__ )
00033 // We are on Apple, check compiler version
00034 # if __clang_major__ >= 5
00035   // XCode 5.0.0 or later
00036 #  include <unordered_map>
00037 using std::unordered_map;
00038 # else
00039   // XCode 4.6.3 or earlier
00040 #  include <tr1/unordered_map>
00041 using std::tr1::unordered_map;
00042 # endif
00043 #else
00044 // We are on Linux, use c++03 standard
00045 # include <tr1/unordered_map>
00046 using std::tr1::unordered_map;
00047 #endif
00048 
00049 namespace argos {
00050 
00089    class CEntity : public CBaseConfigurableResource,
00090                    public EnableVTableFor<CEntity> {
00091 
00092    public:
00093 
00094       ENABLE_VTABLE();
00095 
00097       typedef std::vector<CEntity*> TVector;
00098 
00100       typedef unordered_map<std::string, CEntity*> TMap;
00101 
00103       typedef std::multimap<std::string, CEntity*> TMultiMap;
00104 
00105    public:
00106 
00112       CEntity(CComposableEntity* pc_parent);
00113 
00122       CEntity(CComposableEntity* pc_parent,
00123               const std::string& str_id);
00124 
00128       virtual ~CEntity() {}
00129 
00139       virtual void Init(TConfigurationNode& t_tree);
00140 
00145       virtual void Reset() {}
00146 
00151       virtual void Destroy() {}
00152 
00157       inline const std::string& GetId() const {
00158          return m_strId;
00159       }
00160 
00165       std::string GetContext() const;
00166 
00171       inline bool HasParent() const {
00172          return (m_pcParent != NULL);
00173       }
00174 
00179       CEntity& GetRootEntity();
00180 
00185       const CEntity& GetRootEntity() const;
00186 
00192       CComposableEntity& GetParent();
00193 
00199       const CComposableEntity& GetParent() const;
00200 
00205       inline void SetParent(CComposableEntity& c_parent) {
00206          m_pcParent = &c_parent;
00207       }
00208 
00213       virtual std::string GetTypeDescription() const {
00214          return "entity";
00215       }
00216 
00221       virtual void Update() {}
00222 
00229       bool IsEnabled() const {
00230          return m_bEnabled;
00231       }
00232 
00239       inline void Enable() {
00240          SetEnabled(true);
00241       }
00242 
00249       inline void Disable() {
00250          SetEnabled(false);
00251       }
00252 
00259       virtual void SetEnabled(bool b_enabled);
00260 
00267       bool CanBeEnabledIfDisabled() const {
00268          return m_bCanBeEnabledIfDisabled;
00269       }
00270 
00277       void SetCanBeEnabledIfDisabled(bool b_can_it) {
00278          m_bCanBeEnabledIfDisabled = b_can_it;
00279       }
00280 
00281    private:
00282 
00284       CComposableEntity* m_pcParent;
00285 
00287       std::string m_strId;
00288 
00290       bool m_bEnabled;
00291 
00298       bool m_bCanBeEnabledIfDisabled;
00299 
00300    };
00301 
00305    template <typename LABEL, typename PLUGIN, typename RETURN_TYPE>
00306    class CEntityOperation {
00307    public:
00308       template <typename DERIVED, typename OPERATION_IMPL>
00309       RETURN_TYPE Hook(PLUGIN& t_plugin, CEntity& c_entity) {
00310          return Dispatch<DERIVED, OPERATION_IMPL>(t_plugin, c_entity);
00311       }
00312    protected:
00313       template <typename DERIVED, typename OPERATION_IMPL>
00314       RETURN_TYPE Dispatch(PLUGIN& t_plugin, CEntity& c_entity) {
00315          /* First dispatch: cast this operation into the specific operation */
00316          OPERATION_IMPL& tOperation = static_cast<OPERATION_IMPL&>(*this);
00317          /* Second dispatch: cast t_base to DERIVED */
00318          DERIVED& tDerived = static_cast<DERIVED&>(c_entity);
00319          /* Perform visit */
00320          return tOperation.ApplyTo(t_plugin, tDerived);
00321       }
00322    };
00323 
00327    template <typename LABEL, typename PLUGIN, typename RETURN_TYPE>
00328    class CEntityOperationInstanceHolder {
00329    public:
00330       ~CEntityOperationInstanceHolder() {
00331          while(!m_vecOperationInstances.empty()) {
00332             if(m_vecOperationInstances.back() != NULL) {
00333                delete m_vecOperationInstances.back();
00334             }
00335             m_vecOperationInstances.pop_back();
00336          }
00337       }
00338       template <typename DERIVED>
00339       void Add(CEntityOperation<LABEL, PLUGIN, RETURN_TYPE>* pc_operation) {
00340          /* Find the slot */
00341          size_t unIndex = GetTag<DERIVED, CEntity>();
00342          /* Does the holder have a slot for this index? */
00343          if(unIndex >= m_vecOperationInstances.size()) {
00344             /* No, new slots must be created
00345              * Fill the slots with NULL
00346              */
00347             /* Create new slots up to index+1 and fill them with tDefaultFunction */
00348             m_vecOperationInstances.resize(unIndex+1, NULL);
00349          }
00350          m_vecOperationInstances[unIndex] = pc_operation;
00351       }
00352       CEntityOperation<LABEL, PLUGIN, RETURN_TYPE>* operator[](size_t un_index) const {
00353          if(un_index >= m_vecOperationInstances.size()) {
00354             return NULL;
00355          }
00356          return m_vecOperationInstances[un_index];
00357       }
00358    private:
00359       std::vector<CEntityOperation<LABEL, PLUGIN, RETURN_TYPE>*> m_vecOperationInstances;
00360    };
00369    template <typename LABEL, typename PLUGIN, typename RETURN_VALUE>
00370    CEntityOperationInstanceHolder<LABEL, PLUGIN, RETURN_VALUE>& GetEntityOperationInstanceHolder() {
00371       static CEntityOperationInstanceHolder<LABEL, PLUGIN, RETURN_VALUE> cHolder;
00372       return cHolder;
00373    }
00382    template<typename LABEL, typename PLUGIN, typename RETURN_VALUE>
00383    RETURN_VALUE CallEntityOperation(PLUGIN& t_plugin, CEntity& c_entity) {
00384       typedef RETURN_VALUE (CEntityOperation<LABEL, PLUGIN, RETURN_VALUE>::*TFunction)(PLUGIN& t_plugin, CEntity&);
00385       TFunction tFunction = GetVTable<LABEL, CEntity, TFunction>()[c_entity.GetTag()];
00386       if(tFunction != NULL) {
00387          CEntityOperation<LABEL, PLUGIN, RETURN_VALUE>* pcOperation = GetEntityOperationInstanceHolder<LABEL, PLUGIN, RETURN_VALUE>()[c_entity.GetTag()];
00388          if(pcOperation != NULL) {
00389             return (pcOperation->*tFunction)(t_plugin, c_entity);
00390          }
00391       }
00392       return RETURN_VALUE();
00393    }
00394 
00395 }
00396 
00397 #define REGISTER_ENTITY(CLASSNAME,                  \
00398                         LABEL,                      \
00399                         AUTHOR,                     \
00400                         VERSION,                    \
00401                         BRIEF_DESCRIPTION,          \
00402                         LONG_DESCRIPTION,           \
00403                         STATUS)                     \
00404    REGISTER_SYMBOL(CEntity,                         \
00405                    CLASSNAME,                       \
00406                    LABEL,                           \
00407                    AUTHOR,                          \
00408                    VERSION,                         \
00409                    BRIEF_DESCRIPTION,               \
00410                    LONG_DESCRIPTION,                \
00411                    STATUS)
00412 
00416 #define REGISTER_ENTITY_OPERATION(LABEL, PLUGIN, OPERATION, RETURN_VALUE, DERIVED)                         \
00417    class C ## LABEL ## PLUGIN ## OPERATION ## RETURN_VALUE ## DERIVED {                                    \
00418       typedef RETURN_VALUE (CEntityOperation<LABEL, PLUGIN, RETURN_VALUE>::*TFunction)(PLUGIN&, CEntity&); \
00419    public:                                                                                                 \
00420       C ## LABEL ## PLUGIN ## OPERATION ## RETURN_VALUE ## DERIVED() {                                     \
00421          GetVTable<LABEL, CEntity, TFunction>().Add<DERIVED>(&OPERATION::Hook<DERIVED, OPERATION>);        \
00422          GetEntityOperationInstanceHolder<LABEL, PLUGIN, RETURN_VALUE>().Add<DERIVED>(new OPERATION());    \
00423       }                                                                                                    \
00424    } c ## LABEL ## PLUGIN ## OPERATION ## RETURN_VALUE ## DERIVED;
00425 
00426 #endif