charon-core  0.3.1
Slots.hxx
Go to the documentation of this file.
1 /* This file is part of Charon.
2 
3  Charon is free software: you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as published by
5  the Free Software Foundation, either version 3 of the License, or
6  (at your option) any later version.
7 
8  Charon is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU Lesser General Public License for more details.
12 
13  You should have received a copy of the GNU Lesser General Public License
14  along with Charon. If not, see <http://www.gnu.org/licenses/>.
15  */
32 #ifndef _SLOTS_HXX_
33 #define _SLOTS_HXX_
34 
35 #include "ParameteredObject.h"
36 #include "PluginManagerInterface.h"
37 #include <sstream>
38 #include <stdexcept>
39 
40 // ======================== class AbstractSlot ==========================
41 
42 template<class T>
44 }
45 
46 template<class T>
48  if (connected())
49  disconnect();
50 }
51 
52 template<class T>
54  if(!target) {
55  Slot::raise("AbstractSlot::_addTarget: null pointer given");
56  }
57 
58  // Check slot types by comparing their _type strings.
59  if ((target->getType() != this->getType())&&!((target->getType()=="virtual")||(this->getType()=="virtual"))) {
60  this->printError("Source slot of failed connection");
61  target->printError("Target slot of failed connection");
62  Slot::raise("Cannot connect slots of different types.");
63  }
64 // AbstractSlot<T>* abstarget=dynamic_cast<AbstractSlot<T>*>(target);
65 // // Check slot types by comparing their _type strings.
66 // if ((!abstarget)&&!((target->getType()=="Virtual")||(this->getType()=="Virtual"))) {
67 // this->printError("Source slot of failed connection");
68 // target->printError("Target slot of failed connection");
69 // Slot::raise("Cannot connect slots of different types.");
70 // }
71 
72  _targets.insert((AbstractSlot<T>*)target);
73  if (!_multiSlot && _targets.size() > 1) {
74  this->printError("Source slot of failed connection");
75  target->printError("Target slot of failed connection");
76  Slot::raise("Tried to add multiple targets to non-multi slot.");
77  }
78  return true;
79 }
80 
81 template<class T>
83  if(!target) {
84  Slot::raise("AbstractSlot::_removeTarget: null pointer given");
85  }
86  // dynamic_cast isn't possible on dynamically loaded plugins.
87  // AbstractSlot<T>* t = dynamic_cast<AbstractSlot<T>*>(target);
88  AbstractSlot<T>* abstarget=(AbstractSlot<T>*)target;
89  return (_targets.erase( abstarget) > 0);
90 }
91 
92 template<class T>
93 std::string AbstractSlot<T>::guessType() const {
94  return TypeDetector::type(typeid(T).name());
95 }
96 
97 template<class T>
98 std::set<Slot*> AbstractSlot<T>::getTargets() const {
99  std::set<Slot*> res;
100  res.insert(_targets.begin(), _targets.end());
101  return res;
102 }
103 
104 template<class T>
106  Slot::save(pf);
107  std::vector<std::string> targetList;
108  typename std::set<AbstractSlot<T>*>::const_iterator slot;
109  for (slot = _targets.begin(); slot != _targets.end(); slot++)
110  targetList.push_back((*slot)->getParent().getName() + "."
111  + (*slot)->getName());
112  if (targetList.size())
113  pf.set<std::string> (_parent->getName() + "." + _name, targetList);
114  else if (pf.isSet(_parent->getName() + "." + _name))
115  pf.erase(_parent->getName() + "." + _name);
116 }
117 
118 template<typename T>
119 inline std::string AbstractSlot<T>::getType() const {
120  std::string::size_type pos = _type.find("<t>");
121  if (pos != std::string::npos) {
122  std::string temp(this->_type);
123  temp.replace(pos + 1, 1, getParent().getTemplateType());
124  return temp;
125  } else if (_type == "t") {
126  return (getParent().getTemplateType());
127  }
128  return _type;
129 }
130 
131 template<class T>
132 typename std::set<AbstractSlot<T>*>::const_iterator AbstractSlot<T>::begin() const {
133  return _targets.begin();
134 }
135 
136 template<class T>
137 typename std::set<AbstractSlot<T>*>::const_iterator AbstractSlot<T>::end() const {
138  return _targets.end();
139 }
140 
141 // ========================= class InputSlot ============================
142 
143 template<class T>
144 InputSlot<T>::InputSlot(bool optional, bool multi) {
145  AbstractSlot<T>::_optional = optional;
147 }
148 
149 template<class T>
151 }
152 
153 template<class T>
155  const PluginManagerInterface * man) {
156  // disconnect from other slots
158 
159  if (!pf.isSet(Slot::_parent->getName() + "." + Slot::_name))
160  // nothing to do
161  return;
162 
163  // get all targets from parameter file
164  std::vector<std::string> targetList = pf.getList<std::string> (
165  Slot::_parent->getName() + "." + Slot::_name);
166 
167  // only multislots can be connected to more than one source!
168  if (!(Slot::_multiSlot || (targetList.size() < 2))) {
169  Slot::raise("multiple targets but not a multi-slot");
170  }
171 
172  if (!targetList.size())
173  // nothing to do
174  return;
175 
176  typename std::vector<std::string>::const_iterator tStrIter;
177 
178  // and add corresponding slots to _targets
179  for (tStrIter = targetList.begin(); tStrIter != targetList.end(); tStrIter++) {
180  ParameteredObject* targObj = man->getInstance(tStrIter->substr(0,
181  tStrIter->find(".")));
182 
183  Slot * targetSlot = targObj->getSlot(
184  tStrIter->substr(tStrIter->find(".") + 1));
185 
186  // typecheck is performed in _addTarget that is called in connect
187  //AbstractSlot<T>* tmp = (AbstractSlot<T>*) (targetSlot);
188  AbstractSlot<T>* tmp=dynamic_cast<AbstractSlot<T>* >(targetSlot);
189  if(tmp)
190  Slot::connect(*tmp);
191  else
192  {
193  VirtualSlot* vtmp=dynamic_cast<VirtualSlot*>(targetSlot);
194  Slot ::connect(*vtmp);
195  }
196  }
197 }
198 
199 template<class T>
201  if (!AbstractSlot<T>::_targets.size()) {
202  Slot::raise("access to unconnected input slot (cast operator)");
203  }
204  return getDataFromOutputSlot(*(AbstractSlot<T>::_targets.begin()));
205 }
206 
207 template<class T>
208 const T& InputSlot<T>::operator()() const {
209  if (!AbstractSlot<T>::_targets.size()) {
210  Slot::raise("access to unconnected input slot (operator())");
211  }
212  return getDataFromOutputSlot(*(AbstractSlot<T>::_targets.begin()));
213 }
214 
215 template<class T>
216 const T& InputSlot<T>::operator[](std::size_t pos) const {
217  if (pos >= AbstractSlot<T>::_targets.size()) {
218  std::ostringstream err;
219  err << "pos out of range: pos = " << pos;
220  err << "; size = " << AbstractSlot<T>::_targets.size();
221  throw std::out_of_range(err.str());
222  }
223 
224  typename std::set<AbstractSlot<T>*>::const_iterator item;
226  for (unsigned int i = 0; i < pos; i++)
227  item++;
228  return getDataFromOutputSlot(*item);
229 }
230 
231 template<typename T>
232 std::size_t InputSlot<T>::size() const {
233  return AbstractSlot<T>::_targets.size();
234 }
235 
236 template <typename T>
237 const T& InputSlot<T>::getDataFromOutputSlot(const Slot* slot) const {
238  const OutputSlotIntf* outsl=dynamic_cast<const OutputSlotIntf*>(slot);
239  if(!outsl) {
240  Slot::raise("Invalid slot for data retrieval!!");
241  }
242  return getDataFromOutputSlot(outsl);
243 }
244 
245 template <typename T>
247  const OutputSlotIntf* slot) const {
248 
249  // c-style cast can produce weird errors, so use dynamic cast to make sure
250  // const OutputSlot<T>* source = (const OutputSlot<T>*) slot;
251  const OutputSlotIntf* source = slot->getDataSlot();
252 
253  if (source->getType() != this->getType()) {
254  Slot::raise("input connection type mismatch");
255  }
256 
257  const Slot::CacheType& scType = source->getCacheType();
258  switch (scType) {
259  case Slot::CACHE_MEM:
260  {
261  const OutputSlot<T>* outsl=dynamic_cast<const OutputSlot<T>*>(source);
262  if (!outsl) {
263  Slot::raise("input connection data type mismatch (dynamic cast)");
264  }
265  return outsl->operator()();
266  }
267  case Slot::CACHE_MANAGED: {
268  const std::string& config = source->getConfig();
269  typename std::map<std::string,T>::const_iterator found;
270  found = _dataCache.find(config);
271  if (found == _dataCache.end()) {
272  Slot::raise("data could not be retrieved (not cached)");
273  }
274  return found->second;
275  }
276  case Slot::CACHE_INVALID:
277  Slot::raise("cannot read from output with cache type \"invalid\"");
278  default:
279  Slot::raise("no implementation for given output slot cache type");
280  }
281  // this should never be reached
282  throw std::runtime_error(
283  "unexpected error in InputSlot::_getDataFromOutputSlot");
284 }
285 
286 template<typename T>
288  typename std::set<AbstractSlot<T>*>::const_iterator item;
290  for (;item != AbstractSlot<T>::_targets.end(); item++) {
291  const Slot* slot = *item;
292  if (slot->getType() != this->getType()) {
293  Slot::raise("input connection type mismatch");
294  }
295  //const OutputSlot<T>* source = dynamic_cast<const OutputSlot<T>*>(slot);
296  const OutputSlotIntf* source = dynamic_cast<const OutputSlotIntf*>(slot);
297  if (!source) {
298  Slot::raise("input connection data type mismatch (dynamic cast)");
299  }
300 
301  const Slot::CacheType scType = source->getCacheType();
302  if (scType == Slot::CACHE_MANAGED) {
303  const Slot* sl=dynamic_cast<const Slot*>(slot);
304  const std::string& config = source->getConfig();
305  Slot::DataManager<T>* manager =
307  if (!manager) {
308  Slot::raise("no data manager for this slot type available");
309  }
310  _dataCache.insert(std::pair<std::string,T>(
311  config,manager->getData()));
312  delete manager;
313  }
314  }
315 }
316 
317 template<typename T>
319  _dataCache.clear();
320 }
321 
322 // ============================ class OutputSlot ========================
323 
324 template<typename T>
325 OutputSlot<T>::OutputSlot(const T& initval) :
326  _initVal(initval), data(0), _cacheType(Slot::CACHE_MEM) {
329 }
330 
331 template<typename T>
333  if (!data) {
334  data = new T(_initVal);
335  }
336 }
337 
338 template<typename T>
340  if (data) {
341  delete data;
342  }
343 }
344 
345 template<class T>
347  const ParameterFile& pf, const PluginManagerInterface*) {
348  const std::string parName =
349  Slot::_parent->getName()+"."+Slot::_name+".caching";
350  if (pf.isSet(parName)) {
351  const std::string cType = pf.get<std::string>(parName);
352  if (cType == "managed") {
354  }
355  else if (cType == "memory") {
357  }
358  else if (cType == "invalid") {
360  }
361  else {
362  Slot::raise("Invalid cache type specified in parameter file.");
363  }
364  }
365 }
366 
367 template<typename T>
369  const std::string prefix = "selected cache type: ";
370  switch (type) {
371  case Slot::CACHE_MEM:
372  Slot::printInfo(prefix + "memory");
373  break;
374  case Slot::CACHE_MANAGED: {
375  Slot::printInfo(prefix + "managed");
376  Slot::DataManager<T>* manager =
378  if (!manager) {
379  Slot::raise("no data manager for this slot type available");
380  }
381  delete manager;
382  }
383  break;
384  case Slot::CACHE_INVALID:
385  Slot::printWarning(prefix + "invalid");
386  break;
387  default:
388  Slot::raise("setCacheType: invalid cache type given");
389  break;
390  }
391  _cacheType = type;
392 }
393 
394 template<typename T>
395 void OutputSlot<T>::_check() const {
396  if (!data) {
397  Slot::raise("reading from uninitialized output slot");
398  }
399 }
400 
401 template<typename T>
403  if (!data) {
405  "accessing uninitialized output slot, "
406  "creating default data element");
407  prepare();
408  }
409 }
410 
411 template<class T>
413  _check();
414  return *data;
415 }
416 
417 template<class T>
418 const T& OutputSlot<T>::operator()() const {
419  _check();
420  return *data;
421 }
422 
423 template<class T>
425  _prepare();
426  return *data;
427 }
428 
429 template<class T>
430 T& OutputSlot<T>::operator=(const T& B) {
431  _prepare();
432  *data = B;
433  return *data;
434 }
435 
436 template<typename T>
438  switch (_cacheType) {
439  case Slot::CACHE_MEM:
440  // do not delete data after execution if memory caching is selected
441  break;
442  case Slot::CACHE_MANAGED: {
443  // write data to manager
444 
445  Slot::DataManager<T>* manager =
446  Slot::DataManagerFactory<T>::getManager(*this,_managerConfig);
447  if (!manager) {
448  Slot::raise("no data manager for this slot type available");
449  }
450  manager->setData(*data);
451  _managerConfig = manager->getConfig();
452  delete manager;
453  }
454  // now data can be deleted
455  // so continue as invalid
456  case Slot::CACHE_INVALID:
457  delete data;
458  data = 0;
459  break;
460  default:
461  break;
462  }
463 }
464 
465 // ============================== data managers ==========================
466 template <typename T>
468  const Slot&, const std::string&) {
469  return 0;
470 }
471 
472 #endif /* _SLOTS_HXX_ */
Encapsulation of slot connection handling (type specific) and common code for input and output slots...
Definition: Slots.h:253
virtual const std::string & getConfig() const =0
get manager configuration string
std::set< AbstractSlot< T > * >::const_iterator begin() const
iterator to the beginning of the source list
Definition: Slots.hxx:132
stay in memory after execution
Definition: Slots.h:206
static DataManager< T > * getManager(const Slot &slot, const std::string &config="")
get data manager from configuration string
Definition: Slots.hxx:467
virtual const OutputSlotIntf * getDataSlot() const =0
Return a pointer to a real slot.
virtual std::string getType() const =0
Get slot type.
Interface for a plugin manager.
virtual Slot::CacheType getCacheType() const =0
query data cache type
Provides an interface for a plugin manager.
This class serves to store parameters used within the Charon Project.
Definition: ParameterFile.h:68
virtual std::string getType() const
Get slot type.
Definition: Slots.hxx:119
Output slot.
Definition: Slots.h:402
virtual std::size_t size() const
Access to number of members.
Definition: Slots.hxx:232
interface of data management classes
Definition: Slots.h:216
void erase(std::string parameter)
Delete a parameter from the parameter list.
bool disconnect()
Remove all slot targets.
Definition: Slots.cpp:104
Base class for serializable objects.
void printInfo(const std::string &msg) const
print info message with slot name to sout
Definition: Slots.cpp:129
virtual std::set< Slot * > getTargets() const
Get pointers to the connected targets.
Definition: Slots.hxx:98
virtual const T & operator()() const
Call operator.
Definition: Slots.hxx:418
bool connected() const
Check if slot is connected.
Definition: Slots.cpp:85
dumped after execution, not recommended
Definition: Slots.h:205
std::vector< T > getList(std::string parameter) const
If multiple values are set, return a list containing these values.
virtual ParameteredObject * getInstance(const std::string &instanceName) const =0
Get an existing instance of a loaded plugin.
void _check() const
check for valid data pointer
Definition: Slots.hxx:395
virtual void finalize()
finalize slot
Definition: Slots.hxx:437
VirtualOutputSlot This class holds a pointer to an output if the output is CACHE_MEM, otherwise it loads a config string from a given parameterfile.
Definition: Slots.h:478
ParameteredObject & getParent()
get parent object
Definition: Slots.cpp:65
Declaration of the base class ParameteredObject.
virtual void finalize()
finalize slot
Definition: Slots.hxx:318
void setCacheType(Slot::CacheType type)
change data cache type
Definition: Slots.hxx:368
virtual std::string guessType() const
Try to guess slot type.
Definition: Slots.hxx:93
virtual T getData()=0
read data
virtual ~OutputSlot()
initialize data element
Definition: Slots.hxx:339
std::string getType() const
overloaded getType
Definition: Slots.cpp:421
void setCacheType(Slot::CacheType type)
set the cache type of _slot
Definition: Slots.cpp:290
virtual std::string getConfig() const =0
get configuration string
virtual bool _addTarget(Slot *target)
Add slot target.
Definition: Slots.hxx:53
void set(std::string parameter, const T &value=T())
Set a parameter to the given single value.
abstract interface class for output slots
Definition: Slots.h:373
InputSlot(bool optional=false, bool multi=false)
Create new input slot.
Definition: Slots.hxx:144
virtual void load(const ParameterFile &pf, const PluginManagerInterface *man)
Load slot connections.
Definition: Slots.hxx:346
virtual const T & operator[](std::size_t pos) const
Access to specific member (read-only).
Definition: Slots.hxx:216
virtual void load(const ParameterFile &pf, const PluginManagerInterface *man)
Load slot connections.
Definition: Slots.hxx:154
bool _multiSlot
flag to mark this slot as a multislot, that can have multiple sources/targets.
Definition: Slots.h:84
T get(std::string parameter) const
Get the value of a specified parameter.
bool isSet(std::string parameter) const
Check if a givem parameter has already been set.
virtual void prepare()
prepare slot
Definition: Slots.hxx:332
virtual bool _removeTarget(Slot *target)
Remove slot target.
Definition: Slots.hxx:82
CacheType
slot data cache type
Definition: Slots.h:204
OutputSlot(const T &initval=T())
Create new output slot.
Definition: Slots.hxx:325
Slot * getSlot(const std::string &slotName) const
Get pointer to some slot (by name)
virtual T & operator=(const T &B)
data assignment operator
Definition: Slots.hxx:430
virtual void setData(const T &data)=0
write data
std::string _type
Slot type.
Definition: Slots.h:77
charon_core_DLL_PUBLIC std::string type(const std::string &typeInfo)
Get type representation.
Commom properties of slot objects.
Definition: Slots.h:47
Input slot.
Definition: Slots.h:312
std::set< AbstractSlot< T > * >::const_iterator end() const
iterator to the end of the source list
Definition: Slots.hxx:137
void printWarning(const std::string &msg) const
print warning message with slot name to sout
Definition: Slots.cpp:134
const T & getDataFromOutputSlot(const OutputSlotIntf *slot) const
handle data extraction from output slot
Definition: Slots.hxx:246
void raise(const std::string &msg) const
throw runtime error with slot name and type info
Definition: Slots.cpp:144
std::string _name
Slot name.
Definition: Slots.h:71
virtual void prepare()
prepare slot
Definition: Slots.hxx:287
const std::string & getName() const
instance name
virtual void save(ParameterFile &pf) const
Save slot connections This function disconnects already established connections in the parameterFile ...
Definition: Slots.cpp:125
virtual void save(ParameterFile &pf) const
Save slot connections This function disconnects already established connections in the parameterFile ...
Definition: Slots.hxx:105
void printError(const std::string &msg) const
print error with slot name and type info to sout
Definition: Slots.cpp:139
void _prepare()
create data element, if needed
Definition: Slots.hxx:402
virtual void prepare()
prepare slot
Definition: Slots.cpp:298
virtual const T & operator()() const
Call operator.
Definition: Slots.hxx:208
cached on disk after execution, save memory
Definition: Slots.h:207
ParameteredObject * _parent
Pointer to parent object.
Definition: Slots.h:68
bool connect(Slot &target)
Connect with given slot.
Definition: Slots.cpp:94
virtual std::string getType() const =0
get the type