ConditionRoot.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 2012
21* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22* GNU General Public License
23*/
24
25#include <cstdarg>
26#include <list>
27
31
32#include "LiteralImpl.h"
33
34namespace armarx
35{
36 void
37 ConditionRoot::update(const Ice::Current& c)
38 {
39 std::unique_lock lock(updateMutex);
40
41 if (childs.size() != 1)
42 {
43 return;
44 }
45
46 // empty terms is always evaluated to true
47 if ((!fired || !onlyFireOnce) && (!childs.at(0) || childs.at(0)->getValue()))
48 {
49 value = true;
50 ARMARX_DEBUG_S << "Condition fulfilled, sending event " << event->eventName
51 << std::endl;
52 try
53 {
54 event->properties.clear();
55 for (const DatafieldRefBasePtr& ref : refs)
56 {
57 DatafieldRefPtr r = DatafieldRefPtr::dynamicCast(ref);
58 const Variant& data = *r->getDataField();
59 event->properties[r->getDataFieldIdentifier()->getIdentifierStr()] =
61 }
62 //needs to be async otherwise it can lead to deadlock if the listener uses a datafield of an observer
63 listener->begin_reportEvent(event);
64 }
65 catch (std::exception& e)
66 {
67 ARMARX_ERROR_S << "Could not report event: " << e.what();
68 }
69
70 fired = true;
71 }
72 }
73
74 void
75 ConditionRoot::updateWithData(const Ice::Current& c)
76 {
77 std::unique_lock lock(updateMutex);
78
79 if (childs.size() != 1)
80 {
81 return;
82 }
83
84 // empty terms is always evaluated to true
85 if ((!fired || !onlyFireOnce) && (!childs.at(0) || childs.at(0)->getValue()))
86 {
87 value = true;
88 ARMARX_VERBOSE_S << "Condition fulfilled, sending event with data " << event->eventName
89 << std::endl;
90 try
91 {
92 StringVariantBaseMap values = childs.at(0)->getDatafields();
93 event->properties.clear();
94 ARMARX_INFO_S << VAROUT(event->eventName);
95 for (auto& v : values)
96 {
97 const Variant& data = *VariantPtr::dynamicCast(v.second);
98 event->properties[v.first] = new SingleVariant(data);
99 ARMARX_INFO_S << v.first << " cond val: "
100 << VariantPtr::dynamicCast(v.second)->getOutputValueOnly();
101 }
102 for (const DatafieldRefBasePtr& ref : refs)
103 {
104 DatafieldRefPtr r = DatafieldRefPtr::dynamicCast(ref);
105 auto id = r->getDataFieldIdentifier()->getIdentifierStr();
106 if (event->properties.count(id) > 0)
107 {
108 continue;
109 }
110 const Variant& data = *r->getDataField();
111 event->properties[id] = new SingleVariant(data);
112 ARMARX_INFO_S << r->getDataFieldIdentifier()->getIdentifierStr()
113 << " val: " << r->getDataField()->getOutputValueOnly();
114 }
115
116 //needs to be async otherwise it can lead to deadlock if the listener uses a datafield of an observer
117 listener->begin_reportEvent(event);
118 }
119 catch (std::exception& e)
120 {
121 ARMARX_ERROR_S << "Could not report event: " << e.what();
122 }
123
124 fired = true;
125 }
126 }
127
128 void
129 ConditionRoot::output(std::ostream& out) const
130 {
131 out << "Event: " << event->eventName << " - ";
132
133 if (childs.size() > 0)
134 {
135 out << "Expression: " << TermImplPtr::dynamicCast(childs.at(0));
136 }
137 }
138
140 {
141 type = eConditionRoot;
142 }
143
144 ConditionRoot::ConditionRoot(const EventListenerInterfacePrx& listener,
145 const EventBasePtr& event,
146 const std::string& description,
147 bool onlyFireOnce,
148 const DatafieldRefList& refs)
149 {
150 type = eConditionRoot;
151 this->listener = listener->ice_collocationOptimized(
152 false); // events are reported with begin_reportEvent -> this does not work if the event receiver is in the same process and collocation is used
153 this->event = event;
154 this->description = description;
155 this->onlyFireOnce = onlyFireOnce;
156 this->refs = refs;
157 }
158
159 std::vector<LiteralImplPtr>
160 ConditionRoot::ExtractLiterals(const TermImplBasePtr& expression)
161 {
162 std::list<TermImplPtr> terms;
163 std::vector<LiteralImplPtr> literals;
164
165 terms.push_back(TermImplPtr::dynamicCast(expression));
166
167 while (terms.size() != 0)
168 {
169 // retrieve front of list
170 TermImplPtr term = terms.front();
171 terms.pop_front();
172
173 // test type
174 if (term->getType() == eLiteral)
175 {
176 literals.push_back(LiteralImplPtr::dynamicCast(term));
177 }
178 else
179 {
180 // add childs to list
181 TermImplSequence childs = term->getChilds();
182 TermImplSequence::iterator iterChilds = childs.begin();
183
184 while (iterChilds != childs.end())
185 {
186 terms.push_back(TermImplPtr::dynamicCast(*iterChilds));
187 iterChilds++;
188 }
189 }
190 }
191
192
193 return literals;
194 }
195} // namespace armarx
#define VAROUT(x)
constexpr T c
void update(const Ice::Current &c=Ice::emptyCurrent) override
Update state f the ConditionRoot object based on the child.
void updateWithData(const Ice::Current &c=Ice::emptyCurrent) override
void output(std::ostream &out) const override
output to stream.
static std::vector< LiteralImplPtr > ExtractLiterals(const TermImplBasePtr &expression)
ConditionRoot()
Creates an empty ConditionRoot.
The SingleVariant class is required to store single Variant instances in VariantContainer subclasses.
The Variant class is described here: Variants.
Definition Variant.h:224
#define ARMARX_DEBUG_S
The logging level for output that is only interesting while debugging.
Definition Logging.h:205
#define ARMARX_ERROR_S
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:216
#define ARMARX_INFO_S
Definition Logging.h:202
#define ARMARX_VERBOSE_S
Definition Logging.h:207
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::map< std::string, VariantBasePtr > StringVariantBaseMap
IceInternal::Handle< DatafieldRef > DatafieldRefPtr
Definition Observer.h:43
IceInternal::Handle< TermImpl > TermImplPtr
Typedef of TermImplPtr as IceInternal::Handle<TermImpl> for convenience.
Definition TermImpl.h:41