ConditionHandler.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5*
6* ArmarX is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License version 2 as
8* published by the Free Software Foundation.
9*
10* ArmarX is distributed in the hope that it will be useful, but
11* WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this program. If not, see <http://www.gnu.org/licenses/>.
17*
18* @package ArmarX::Core
19* @author Kai Welke (welke _at_ kit _dot_ edu)
20* @date 2011
21* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22* GNU General Public License
23*/
24
25#include "ConditionHandler.h"
26
27#include <sstream>
28
29#include <SimoxUtility/algorithm/string/string_tools.h>
30
34
35namespace armarx
36{
39 {
40 defineOptionalProperty<std::string>("Observers", "", "Comma seperated observer list");
42 "HistoryLength", 1000, "Length of condition history kept by the conditionhandler");
43 }
44
45 // *******************************************************
46 // implementation of ObserverInterface
47 // *******************************************************
48 ConditionIdentifier
49 ConditionHandler::installCondition(const EventListenerInterfacePrx& listener,
50 const TermImplBasePtr& expression,
51 const EventBasePtr& e,
52 bool onlyFireOnce,
53 bool reportDatafields,
54 const DatafieldRefList& refs,
55 const Ice::Current& c)
56 {
58 listener, expression, e, "", onlyFireOnce, reportDatafields, refs, c);
59 }
60
61 ConditionIdentifier
62 ConditionHandler::installConditionWithDescription(const EventListenerInterfacePrx& listener,
63 const TermImplBasePtr& expression,
64 const EventBasePtr& e,
65 const std::string& desc,
66 bool onlyFireOnce,
67 bool reportDatafields,
68 const DatafieldRefList& refs,
69 const Ice::Current& c)
70 {
71 // generate root expression
72 ConditionRootPtr root = new ConditionRoot(listener, e, desc, onlyFireOnce, refs);
73 ARMARX_DEBUG << "Installing condition: " << root << std::endl;
74 root->addChild(expression);
75
76 // extract checks
77 std::vector<LiteralImplPtr> literals = ConditionRoot::ExtractLiterals(root);
78
79 // forward the onlyfireonce flag to all literals
80 for (LiteralImplPtr& literal : literals)
81 {
82 literal->checkConfig.reportAlways = !onlyFireOnce;
83 literal->checkConfig.reportDatafieldValues = reportDatafields;
84 }
85
86 std::unique_lock lock(conditionRegistryMutex);
87
88 // go through literals and install checks
89 installChecks(literals, c);
90
91 // store in registry
92 std::pair<int, ConditionRootBasePtr> entry;
93 entry.first = generateId();
94 entry.second = root;
95
96 conditionRegistry.insert(entry);
97
98 ConditionIdentifier id;
99 id.uniqueId = entry.first;
100
101 ARMARX_DEBUG << "Installed condition: " << root << std::endl;
102 setMetaInfo("conditionCount", new Variant((int)conditionRegistry.size()));
103 return id;
104 }
105
106 void
107 ConditionHandler::removeCondition(const ConditionIdentifier& id, const Ice::Current& c)
108 {
109 ARMARX_DEBUG << "Removing condition " << id.uniqueId << std::endl;
110
111 std::unique_lock lock(conditionRegistryMutex);
112 ConditionRegistry::iterator iter = conditionRegistry.find(id.uniqueId);
113
114 if (iter == conditionRegistry.end())
115 {
116 return;
117 }
118
119 ConditionRootPtr root = ConditionRootPtr::dynamicCast(iter->second);
120
121 // extract checks
122 std::vector<LiteralImplPtr> literals = ConditionRoot::ExtractLiterals(root);
123
124 // go through literals and remove checks
125 removeChecks(literals, c);
126
127 // remove from registry
128 std::pair<int, ConditionRootBasePtr> tmp = *iter;
129 conditionRegistry.erase(iter);
130
131 // insert into history
132 std::unique_lock lockHistory(conditionHistoryMutex);
133 conditionHistory.insert(tmp);
134
135 if (int(conditionHistory.size()) > historyLength)
136 {
137 conditionHistory.erase(conditionHistory.begin());
138 }
139 setMetaInfo("conditionHistory", new Variant((int)conditionHistory.size()));
140 setMetaInfo("conditionCount", new Variant((int)conditionRegistry.size()));
141 }
142
143 void
145 {
146 ConditionRegistry::iterator iter;
147 std::vector<int> conditionIds;
148
149 {
150 std::unique_lock lock(conditionRegistryMutex);
151
152 if (!conditionRegistry.empty())
153 {
154 for (iter = conditionRegistry.begin(); iter != conditionRegistry.end(); iter++)
155 {
156 conditionIds.push_back(iter->first);
157 }
158 }
159 }
160
161 if (!conditionIds.empty())
162 {
163 for (int id : conditionIds)
164 {
165 removeCondition(ConditionIdentifier{id}, c);
166 }
167 }
168
169 std::unique_lock lockHistory(conditionHistoryMutex);
170 conditionHistory.clear();
171 setMetaInfo("conditionHistory", new Variant((int)conditionHistory.size()));
172 setMetaInfo("conditionCount", new Variant((int)conditionRegistry.size()));
173 }
174
175 ConditionRegistry
177 {
178 std::unique_lock lock(conditionRegistryMutex);
179
180 return conditionRegistry;
181 }
182
183 ConditionRegistry
185 {
186 std::unique_lock lock(conditionHistoryMutex);
187
188 return conditionHistory;
189 }
190
191 ConditionRootBasePtr
192 ConditionHandler::getCondition(Ice::Int id, const Ice::Current& c)
193 {
194 {
195 std::unique_lock lock(conditionRegistryMutex);
196 auto it = conditionRegistry.find(id);
197
198 if (it != conditionRegistry.end())
199 {
200 return it->second;
201 }
202 }
203 {
204 std::unique_lock lock(conditionHistoryMutex);
205 auto it = conditionHistory.find(id);
206
207 if (it != conditionHistory.end())
208 {
209 return it->second;
210 }
211 }
212 return nullptr;
213 }
214
215 std::string
217 {
218 return "ConditionHandler";
219 }
220
221 Ice::StringSeq
223 {
224 return observerNames;
225 }
226
227 // *******************************************************
228 // Component hooks
229 // *******************************************************
230 void
232 {
233 currentId = 0;
234
235 // read observer dependencies. These observers will be precaches
236 std::string observers = getProperty<std::string>("Observers");
237 simox::alg::trim(observers);
238
239 if (!observers.empty())
240 {
241 observerNames = simox::alg::split(observers, ",");
242 }
243
244 useObservers(observerNames);
245
246 // read max length of history
247 historyLength = getProperty<int>("HistoryLength").getValue();
248
250 }
251
252 void
254 {
255
256 // precach
257 preCacheObservers(observerNames);
258
259 // subclass init
261 }
262
263 // *******************************************************
264 // private methods
265 // *******************************************************
266 int
267 ConditionHandler::generateId()
268 {
269 std::unique_lock lock(idMutex);
270 return currentId++;
271 }
272
273 void
274 ConditionHandler::useObservers(std::vector<std::string>& names)
275 {
276 std::unique_lock lock(iceManagerMutex);
277
278 std::vector<std::string>::iterator iter = names.begin();
279
280 while (iter != names.end())
281 {
282 usingProxy(*iter);
283 iter++;
284 }
285 }
286
287 void
288 ConditionHandler::preCacheObservers(std::vector<std::string>& names)
289 {
290 std::unique_lock lock(iceManagerMutex);
291
292 std::vector<std::string>::iterator iter = names.begin();
293
294 while (iter != names.end())
295 {
297 iter++;
298 }
299 }
300
301 ObserverInterfacePrx
302 ConditionHandler::getObserver(std::string observerName)
303 {
304 std::unique_lock lock(iceManagerMutex);
305 ObserverInterfacePrx proxy;
306
307 try
308 {
309 proxy = getProxy<ObserverInterfacePrx>(observerName);
310 ObserverInterfacePrx::checkedCast(proxy);
311 }
312 catch (...)
313 {
314 throw InvalidConditionException("Observer \"" + observerName + "\" does not exist.");
315 }
316
317 return proxy;
318 }
319
320 void
321 ConditionHandler::installChecks(std::vector<LiteralImplPtr>& literals, const Ice::Current& c)
322 {
323 std::vector<LiteralImplPtr>::iterator iter = literals.begin();
324
325 while (iter != literals.end())
326 {
327 ObserverInterfacePrx proxy =
328 getObserver((*iter)->checkConfig.dataFieldIdentifier->observerName);
329 (*iter)->installCheck(c.adapter, proxy);
330
331 iter++;
332 }
333 }
334
335 void
336 ConditionHandler::removeChecks(std::vector<LiteralImplPtr>& literals, const Ice::Current& c)
337 {
338 std::vector<LiteralImplPtr>::iterator iter = literals.begin();
339
340 while (iter != literals.end())
341 {
342 ObserverInterfacePrx proxy =
343 getObserver((*iter)->checkConfig.dataFieldIdentifier->observerName);
344 (*iter)->removeCheck(c.adapter, proxy);
345
346 iter++;
347 }
348 }
349
356} // namespace armarx
constexpr T c
ComponentPropertyDefinitions(std::string prefix, bool hasObjectNameParameter=true)
Definition Component.cpp:46
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
Property< PropertyType > getProperty(const std::string &name)
void onInitComponent() override
Pure virtual hook for the subclass.
ConditionIdentifier installConditionWithDescription(const EventListenerInterfacePrx &listener, const TermImplBasePtr &expression, const EventBasePtr &e, const std::string &desc, bool onlyFireOnce, bool reportDatafields, const DatafieldRefList &refs, const Ice::Current &c=Ice::emptyCurrent) override
Installs a condition.
virtual void onInitConditionHandler()
Framework hook.
ConditionRegistry getActiveConditions(const Ice::Current &c=Ice::emptyCurrent) override
Retrieve the list of active conditions.
void removeCondition(const ConditionIdentifier &id, const Ice::Current &c=Ice::emptyCurrent) override
Removes a condition.
ConditionIdentifier installCondition(const EventListenerInterfacePrx &listener, const TermImplBasePtr &expression, const EventBasePtr &e, bool onlyFireOnce, bool reportDatafields, const DatafieldRefList &refs, const Ice::Current &c=Ice::emptyCurrent) override
Installs a condition.
ConditionRegistry getPastConditions(const Ice::Current &c=Ice::emptyCurrent) override
Retrieve the list of conditions that have been registered in the past.
Ice::StringSeq getObserverNames(const Ice::Current &c=Ice::emptyCurrent) override
Retrieve the list of known observers as provided in the config file.
void onConnectComponent() override
Pure virtual hook for the subclass.
PropertyDefinitionsPtr createPropertyDefinitions() override
virtual void onStartConditionHandler()
Framework hook.
ConditionRootBasePtr getCondition(Ice::Int id, const Ice::Current &c=Ice::emptyCurrent) override
void removeAllConditions(const Ice::Current &c=Ice::emptyCurrent) override
Removes all conditions.
std::string getDefaultName() const override
Retrieve default name of component.
ConditionRoot Condition roots are top-level nodes of the expression tree.
static std::vector< LiteralImplPtr > ExtractLiterals(const TermImplBasePtr &expression)
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
void setMetaInfo(const std::string &id, const VariantBasePtr &value)
Allows to set meta information that can be queried live via Ice interface on the ArmarXManager.
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
PropertyDefinition< PropertyType > & defineOptionalProperty(const std::string &name, PropertyType defaultValue, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
The Variant class is described here: Variants.
Definition Variant.h:224
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
const simox::meta::IntEnumNames names
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
IceInternal::Handle< ConditionRoot > ConditionRootPtr
Typedef of ConditionRootPtr as IceInternal::Handle<ConditionRoot> for convenience.
IceInternal::Handle< LiteralImpl > LiteralImplPtr
Typedef of LiteralImplPtr as IceInternal::Handle<LiteralImpl> for convenience.