ARGoS 3
A parallel, multi-engine simulator for swarm robotics
composable_entity.cpp
Go to the documentation of this file.
1
7#include "composable_entity.h"
8
9#include <argos3/core/utility/string_utilities.h>
10
11namespace argos {
12
13 /****************************************/
14 /****************************************/
15
18
19 /****************************************/
20 /****************************************/
21
23 const std::string& str_id) :
24 CEntity(pc_parent, str_id) {}
25
26 /****************************************/
27 /****************************************/
28
30 for(auto it = m_mapComponents.begin();
31 it != m_mapComponents.end();
32 ++it) {
33 it->second->Reset();
34 }
35 }
36
37 /****************************************/
38 /****************************************/
39
43
44 /****************************************/
45 /****************************************/
46
47 void CComposableEntity::SetEnabled(bool b_enabled) {
48 CEntity::SetEnabled(b_enabled);
49 for(auto it = m_mapComponents.begin();
50 it != m_mapComponents.end();
51 ++it) {
52 it->second->SetEnabled(b_enabled);
53 }
54 }
55
56 /****************************************/
57 /****************************************/
58
60 for(auto it = m_mapComponents.begin();
61 it != m_mapComponents.end();
62 ++it) {
63 if(it->second->IsEnabled()) {
64 it->second->Update();
65 }
66 }
67 }
68
69 /****************************************/
70 /****************************************/
71
73 m_mapComponents.insert(
74 std::pair<std::string, CEntity*>(
75 c_component.GetTypeDescription(),
76 &c_component));
77 m_vecComponents.push_back(&c_component);
78 }
79
80 /****************************************/
81 /****************************************/
82
83 CEntity& CComposableEntity::RemoveComponent(const std::string& str_component) {
84 try {
85 auto it = FindComponent(str_component);
86 if(it == m_mapComponents.end()) {
87 THROW_ARGOSEXCEPTION("Element \"" << str_component << "\" not found in the component map.");
88 }
89 CEntity& cRetVal = *(it->second);
90 m_mapComponents.erase(it);
91 size_t i;
92 for(i = 0; i < m_vecComponents.size() && m_vecComponents[i] != &cRetVal; ++i);
93 if(i < m_vecComponents.size()) {
94 m_vecComponents.erase(m_vecComponents.begin() + i);
95 }
96 else {
97 THROW_ARGOSEXCEPTION("Element \"" << str_component << "\" not found in the component vector, but present in the map. BUG!");
98 }
99 return cRetVal;
100 }
101 catch(CARGoSException& ex) {
102 THROW_ARGOSEXCEPTION_NESTED("While removing component \"" << str_component << "\" from the composable entity \"" << GetContext() << GetId() << "\"", ex);
103 }
104 }
105
106 /****************************************/
107 /****************************************/
108
109 CEntity& CComposableEntity::GetComponent(const std::string& str_path) {
110 try {
111 /* Search for the path separator character and take the first path segment */
112 size_t unFirstSeparatorIdx = str_path.find(".");
113 std::string strFrontIdentifier;
114 if(unFirstSeparatorIdx == std::string::npos) strFrontIdentifier = str_path;
115 else strFrontIdentifier = str_path.substr(0, unFirstSeparatorIdx);
116 /* Try to find the relevant component in this context */
117 auto itComponent = FindComponent(strFrontIdentifier);
118 if(itComponent != m_mapComponents.end()) {
119 if(unFirstSeparatorIdx == std::string::npos) {
120 /* Path separator not found, found component in the current context is the one we want */
121 return *(itComponent->second);
122 }
123 /* Path separator found, try to cast the found component to a composable entity */
124 else {
125 auto* pcComposableEntity = dynamic_cast<CComposableEntity*>(itComponent->second);
126 if(pcComposableEntity != nullptr) {
127 /* Dynamic cast of component to composable entity was successful, re-execute this function in the new context */
128 return pcComposableEntity->GetComponent(str_path.substr(unFirstSeparatorIdx + 1, std::string::npos));
129 }
130 else {
131 /* Dynamic cast failed, user is requesting an entity from an entity which is not composable -> error */
132 THROW_ARGOSEXCEPTION("Component \"" << strFrontIdentifier << "\" of \"" << GetContext() + GetId()
133 << "\" is not a composable entity");
134 }
135 }
136 }
137 else {
138 THROW_ARGOSEXCEPTION("Component \"" << strFrontIdentifier << "\" does not exist in \""
139 << GetContext() + GetId() << "\"");
140 }
141 }
142 catch(CARGoSException& ex) {
143 THROW_ARGOSEXCEPTION_NESTED("While getting a component from a composable entity", ex);
144 }
145 }
146
147 /****************************************/
148 /****************************************/
149
150 bool CComposableEntity::HasComponent(const std::string& str_path) {
151 /* Search for the path separator character and take the first path segement */
152 size_t unFirstSeparatorIdx = str_path.find(".");
153 std::string strFrontIdentifier;
154 if(unFirstSeparatorIdx == std::string::npos) strFrontIdentifier = str_path;
155 else strFrontIdentifier = str_path.substr(0, unFirstSeparatorIdx);
156 /* Try to find the relevant component in this context */
157 auto itComponent = FindComponent(strFrontIdentifier);
158 if(itComponent != m_mapComponents.end()) {
159 if(unFirstSeparatorIdx == std::string::npos) {
160 /* Path separator not found, found component in the current context is the one we want */
161 return true;
162 }
163 else {
164 /* Path separator found, try to cast the found component to a composable entity */
165 auto* pcComposableEntity = dynamic_cast<CComposableEntity*>(itComponent->second);
166 if(pcComposableEntity != nullptr) {
167 /* Dynamic cast of component to composable entity was sucessful, re-execute this function in the new context */
168 return pcComposableEntity->HasComponent(str_path.substr(unFirstSeparatorIdx + 1, std::string::npos));
169 }
170 else {
171 /* Could not cast to a composable entity, the queried component cannot exist in the specified context */
172 return false;
173 }
174 }
175 }
176 else {
177 /* Could not find the queried component in this context */
178 return false;
179 }
180 }
181
182 /****************************************/
183 /****************************************/
184
185 CEntity::TMultiMap::iterator CComposableEntity::FindComponent(const std::string& str_component) {
186 /* Check for the presence of [ */
187 std::string::size_type unIdentifierStart = str_component.find('[');
188 if(unIdentifierStart != std::string::npos) {
189 /* Found, now check for the presence of ] after [ */
190 std::string::size_type unIdentifierEnd = str_component.rfind(']');
191 if(unIdentifierEnd != std::string::npos &&
192 unIdentifierEnd > unIdentifierStart) {
193 /* Use the string between [ and ] as an index and whatever comes before as base id */
194 /* Count how many components there are for the base type */
195 std::string strBaseType = str_component.substr(0, unIdentifierStart);
196 if(m_mapComponents.count(strBaseType) == 0) {
197 /* No components of this base type, return an iterator to the end of the collection */
198 return m_mapComponents.end();
199 }
200 else {
201 /* Components of base type found - extract the uid and search for it */
202 std::string strComponentId = str_component.substr(unIdentifierStart + 1, unIdentifierEnd - unIdentifierStart - 1);
203 /* Create a pair of iterators which mark the beginning and the end of the components that match the base type */
204 std::pair<CEntity::TMultiMap::iterator,
205 CEntity::TMultiMap::iterator> cRange = m_mapComponents.equal_range(strBaseType);
206 /* Create an iterator to hold the component we are trying to locate */
207 CEntity::TMultiMap::iterator itComponent;
208 /* Search through components of base type and try find a match for the specified Id */
209 for(itComponent = cRange.first;
210 (itComponent != cRange.second) && (itComponent->second->GetId() != strComponentId);
211 ++itComponent);
212 /* If the iterator itComponent is not equal to cRange.second, then we have found our component */
213 if(itComponent != cRange.second) {
214 return itComponent;
215 }
216 else {
217 /* Identifer not found in the collection of components with the specified base type,
218 * return an iterator to the end of the collect to show this */
219 return m_mapComponents.end();
220 }
221 }
222 }
223 else {
224 THROW_ARGOSEXCEPTION("Syntax error in entity id \"" << str_component << "\"");
225 }
226 }
227 else {
228 /* Identifier syntax not used, return an iterator to the first element or the end of collection if
229 * no elements are found */
230 return m_mapComponents.find(str_component);
231 }
232 }
233
234 /****************************************/
235 /****************************************/
236
238
239 /****************************************/
240 /****************************************/
241
242}
#define THROW_ARGOSEXCEPTION_NESTED(message, nested)
This macro throws an ARGoS exception with the passed message and nesting the passed exception.
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
The namespace containing all the ARGoS related code.
Definition ci_actuator.h:12
REGISTER_STANDARD_SPACE_OPERATIONS_ON_COMPOSABLE(CComposableEntity)
Basic class for an entity that contains other entities.
CEntity & RemoveComponent(const std::string &str_component)
Removes a component from this composable entity.
virtual void Reset()
Resets the state of the entity to whatever it was after Init() or the standalone constructor was call...
virtual void SetEnabled(bool b_enabled)
Enables or disables an entity.
CComposableEntity(CComposableEntity *pc_parent)
Class constructor.
virtual void UpdateComponents()
Calls the Update() method on all the components.
CEntity & GetComponent(const std::string &str_component)
Returns the component with the passed string label.
virtual void Update()
Updates the status of this entity.
void AddComponent(CEntity &c_component)
Adds a component to this composable entity.
bool HasComponent(const std::string &str_component)
Returns true if this composable entity has a component with the given string label.
CEntity::TMultiMap::iterator FindComponent(const std::string &str_component)
Searches for a component with the given string label.
The basic entity type.
Definition entity.h:90
const std::string & GetId() const
Returns the id of this entity.
Definition entity.h:157
std::string GetContext() const
Returns the context of this entity.
Definition entity.cpp:79
virtual void SetEnabled(bool b_enabled)
Enables or disables an entity.
Definition entity.cpp:139
virtual std::string GetTypeDescription() const
Returns a string label for this class.
Definition entity.h:213
The exception that wraps all errors in ARGoS.