DiaDes  0.1
DIAgnosis of Discrete-Event System
SynchronisationEvent.hh
Go to the documentation of this file.
1 
8 #ifndef __DIADES__AUTOMATA__EXPERIMENTAL__SYNCHRONISATIONEVENT__HH__
9 #define __DIADES__AUTOMATA__EXPERIMENTAL__SYNCHRONISATIONEVENT__HH__
10 
11 #include<string>
12 #include<vector>
13 #include<set>
17 
18 namespace Diades
19 {
20  namespace Automata
21  {
22  namespace Experimental
23  {
24  using namespace Diades::Utils;
25 
45  template<typename StateMachine>
47  {
48  public:
49 
50  static std::string
52  {
53  return "Automata::Experimental::SynchronisationEvent";
54  }
56 
62 
63 
67  using ComponentVector = std::vector<const Component *>;
68 
72  using Size = typename ComponentVector::size_type;
73 
78 
82  using EventVector = std::vector<Event>;
83 
84  private:
86 
87  public:
88 
96  {
97  public:
98  using iterator_category = std::input_iterator_tag;
101  using pointer = typename Ptr<Component>::P;
103 
104  private:
108 
109  public:
110 
117  ComponentIterator(const ComponentVector * pVect, const EventVector * pEvent,
118  Size index) : _pVect(pVect), _pEvent(pEvent), _index(index)
119  {
120  }
121 
125  ComponentIterator(const ComponentIterator & it) : _pVect(it._pVect), _pEvent(it._pEvent), _index(it._index)
126  {
127  }
128 
132  const Component & operator*() const
133  {
134  return *(_pVect->operator[](_index));
135  }
136 
140  const Component * operator->() const
141  {
142  return(_pVect->operator[](_index));
143  }
144 
149  {
150  ++_index;
151  return(*this);
152  }
153 
158  {
159  ComponentIterator res(_pVect, _pEvent, _index + 1);
160  ++_index;
161  return res;
162  }
163 
167  bool operator==(const ComponentIterator & compIt) const
168  {
169  return(_pVect == compIt._pVect) && (_pEvent == compIt._pEvent)
170  && (_index == compIt._index);
171  }
172 
176  bool operator!=(const ComponentIterator & compIt) const
177  {
178  return !(*this == compIt);
179  }
180 
184  Event
186  {
187  return(*_pEvent)[_index];
188  }
189 
193  Size
194  index() const
195  {
196  return _index;
197  }
198  };
199 
200 
201  private:
211 
212 
219 
220 
227 
228 
234 
235  public:
236 
240  SynchronisationEvent() = default;
241 
242 
247  SynchronisationEvent(SynchronisationEvent const& other) = default;
253  SynchronisationEvent& operator=(SynchronisationEvent const& other) = default;
258  SynchronisationEvent(SynchronisationEvent&& other) = default;
264  SynchronisationEvent& operator=(SynchronisationEvent&& other) = default;
268  ~SynchronisationEvent() = default;
269 
275  SynchronisationEvent(const ComponentVector & components) :
276  _components(),
277  _support(),
278  _events(),
279  _supportEvents()
280  {
281  require(Exception, !components.empty(), "constructor: empty set of components");
282  std::set<const Component *> sortedComponents;
283  bool null = components.empty();
284  Size index = 0;
285  while((!null) && (index != components.size()))
286  {
287  null = (components[index] == nullptr);
288  require(Exception, !null, "constructor: one pointer in the set of components is null");
289  if(!null)
290  {
291  null = sortedComponents.find(components[index]) != sortedComponents.end();
292  if(!null)
293  {
294  require(Exception, !null, "constructor: the set of components contains twice the same component");
295  sortedComponents.insert(components[index]);
296  }
297  }
298  ++index;
299  }
300  if(!null)
301  {
302  std::for_each(components.begin(), components.end(),
303  [&](const Component * comp)
304  {
305  _components.push_back(comp);
306  _events.push_back(comp->nullEvent());
307  });
308  }
309  ensure(Exception, isValid(), "constructor: it should be valid");
310  }
311 
322  :
323  _components(),
324  _support(),
325  _events(),
326  _supportEvents()
327  {
328  require(Exception, sync1.isValid(), "merging constructor: the first synchronisation event is not valid");
329  require(Exception, sync2.isValid(), "merging constructor: the second synchronisation event is not valid");
330  bool null = !(sync1.isValid() && sync2.isValid());
331  ComponentIterator it1 = sync1.beginOfComponents();
332  ComponentIterator it2 = sync2.beginOfComponents();
333  while((!null) && (it1 != sync1.endOfComponents())
334  &&
335  (it2 != sync2.endOfComponents()))
336  {
337  null = &(*it1) == &(*it2);
338  require(Exception, !null, "merging constructor: sync1 and sync2 contains the same component");
339  if(!null)
340  {
341  if(&(*it1) < &(*it2))
342  {
343  _components.push_back(&(*it1));
344  _events.push_back(sync1.getAssociatedEvent(it1));
345  if(_events.back().isValid())
346  {
347  _support.push_back(_components.back());
348  _supportEvents.push_back(_events.back());
349  }
350  ++it1;
351  }
352  else
353  {
354  _components.push_back(&(*it2));
355  _events.push_back(sync2.getAssociatedEvent(it2));
356  if(_events.back().isValid())
357  {
358  _support.push_back(_components.back());
359  _supportEvents.push_back(_events.back());
360  }
361  ++it2;
362  }
363  }
364  }
365  if(!null)
366  {
367  if(it1 == sync1.endOfComponents())
368  {
369  while(it2 != sync2.endOfComponents())
370  {
371  _components.push_back(&(*it2));
372  _events.push_back(sync2.getAssociatedEvent(it2));
373  if(_events.back().isValid())
374  {
375  _support.push_back(_components.back());
376  _supportEvents.push_back(_events.back());
377  }
378  ++it2;
379  }
380  }
381  else
382  {
383  if(it2 == sync2.endOfComponents())
384  {
385  while(it1 != sync1.endOfComponents())
386  {
387  _components.push_back(&(*it1));
388  _events.push_back(sync1.getAssociatedEvent(it1));
389  if(_events.back().isValid())
390  {
391  _support.push_back(_components.back());
392  _supportEvents.push_back(_events.back());
393  }
394  ++it1;
395  }
396  }
397  }
398  }
399  else
400  {
401  _components.clear();
402  _events.clear();
403  _supportEvents.clear();
404  _support.clear();
405  }
406  ensure(Exception, isValid(), "merging constructor: it should be valid but it is not.");
407  }
408 
419  :
420  _components(),
421  _support(),
422  _events(),
423  _supportEvents()
424  {
425  require(Exception, !components.empty(), "constructor: empty set of components");
426  std::set<const Component *> sortedComponents;
427  bool null = components.empty();
428  Size index = 0;
429  while((!null) && (index != components.size()))
430  {
431  null = (components[index] == 0);
432  require(Exception, !null, "constructor: one pointer in the set of components is null");
433  if(!null)
434  {
435  null = sortedComponents.find(components[index]) != sortedComponents.end();
436  if(!null)
437  {
438  require(Exception, !null, "constructor: the set of components contains twice the same component");
439  sortedComponents.insert(components[index]);
440  }
441  }
442  ++index;
443  }
444  if(!null)
445  {
446  std::for_each(components.begin(), components.end(),
447  [&](const Component * comp)
448  {
449  _components.push_back(comp);
450  _events.push_back(comp->nullEvent());
451  });
452  }
453  ensure(Exception, isValid(), "constructor: it should be invalid");
454  }
455 
461  bool operator==(const SynchronisationEvent & evt) const
462  {
463  return _components == evt._components
464  &&
465  _support == evt._support
466  &&
467  _events == evt._events
468  &&
469  _supportEvents == evt._supportEvents;
470  }
471 
477  bool operator!=(const SynchronisationEvent & evt) const
478  {
479  return !(*this == evt);
480  }
481 
485  Size
486  size() const
487  {
488  return _components.size();
489  }
490 
494  Size
495  supportSize() const
496  {
497  return _support.size();
498  }
499 
504  bool
505  isValid() const
506  {
507  bool result = (_components.size() == _events.size())
508  && (_support.size() == _supportEvents.size())
509  && (_support.size() <= _components.size());
510 #ifdef __DEBUG
511  if(result)
512  {
513  map<const Component *, Size> theSupport;
514  Size index = 0;
515  while(result && index < _components.size())
516  {
517  result = _components[index] != 0
518  && _components[index]->isValid();
519  if(result)
520  {
521  if(_events[index].isValid())
522  {
523  result = _components[index]->containsEvent(_events[index]);
524  theSupport[_components[index]] = index;
525  }
526  }
527  ++index;
528  }
529  index = 0;
530  result = _support.size() == theSupport.size();
531  while(result && index < _support.size())
532  {
533 
534  result = _support[index] != 0
535  && _support[index]->isValid();
536  if(result)
537  {
538  map<const Component *, Size>::const_iterator it = theSupport.find(_support[index]);
539  result = (it != theSupport.end())
540  && _supportEvents[index].isValid()
541  && _support[index]->containsEvent(_supportEvents[index])
542  && (_support[index] == _components[it->second])
543  && (_events[it->second] == _supportEvents[index]);
544  }
545  ++index;
546  }
547  }
548 #endif
549  return result;
550 
551  }
552 
562  addEvent(const Component & component, Event e)
563  {
564  require(Exception, e != NullEvent().nullValue(), "addEvent: invalid event");
565  require(Exception, component.containsEvent(e), "addEvent: the event does not belong to the component");
566  ComponentIterator it = findComponent(component);
567  require(Exception, it != endOfComponents(), "addEvent: the component does not belong to the SynchronisationEvent");
568  if(it != endOfComponents())
569  {
570  if(e != getAssociatedEvent(it))
571  {
572  if(getAssociatedEvent(it) == NullEvent().nullValue())
573  {
574  _support.push_back(&component);
575  _supportEvents.push_back(e);
576  }
577  else
578  {
579  ComponentIterator itSupp = findSupportComponent(component);
580  if(e != NullEvent().nullValue())
581  {
582 
583  _supportEvents[itSupp.index()] = e;
584  }
585  else
586  {
587  Size index = itSupp.index();
588  while(index < (_support.size() - 1))
589  {
590  _support[index] = _support[index + 1];
591  _supportEvents[index] = _supportEvents[index + 1];
592  ++index;
593  }
594  _supportEvents.resize(_supportEvents.size() - 1);
595  _support.resize(_support.size() - 1);
596  }
597  }
598  _events[it.index()] = e;
599  }
600  }
601  ensure(Exception, isValid(), "addEvent: the result should be valid but it is not.");
602  return it;
603  }
604 
610  {
611  return ComponentIterator(&_components, &_events, 0);
612  }
613 
619  {
620  return ComponentIterator(&_components, &_events, _components.size());
621  }
622 
628  {
629  return ComponentIterator(&_support, &_supportEvents, 0);
630  }
631 
636  endOfSupport() const
637  {
638  return ComponentIterator(&_support, &_supportEvents, _support.size());
639  }
640 
644  Event
646  {
647  return it.getAssociatedEvent();
648  }
649 
654  Event
655  getAssociatedEvent(const Component & comp) const
656  {
657  require(Exception, findComponent(comp) != endOfComponents(), "getAssociatedEvent: the component does not exist in the synchronisation event");
658  ComponentIterator it = findComponent(comp);
659  if(it == endOfComponents())
660  {
661  return Event();
662  }
663  return getAssociatedEvent(it);
664  }
665 
672  findComponent(const Component & component) const
673  {
674  bool found = false;
675  ComponentIterator it = beginOfComponents();
676  while((!found) && (it != endOfComponents()))
677  {
678  found = (Ptr<Component>::get(component) == Ptr<Component>::get(*it));
679  if(!found)
680  {
681  ++it;
682  }
683  }
684  return it;
685  }
686 
693  findSupportComponent(const Component & component) const
694  {
695  bool found = false;
696  ComponentIterator it = beginOfSupport();
697  while((!found) && (it != endOfSupport()))
698  {
699  found = (Ptr<Component>::get(component) == Ptr<Component>::get(*it));
700  if(!found)
701  {
702  ++it;
703  }
704  }
705  return it;
706  }
707 
714  Event
716  {
717  return _synchronisedEvent;
718  }
719 
724  void
726  {
727  _synchronisedEvent = evt;
728  }
729 
730 
731 
732  };
733 
734  template<typename _SyncEvent>
736  {
737  private:
739 
740  public:
741  using SyncEvent = _SyncEvent;
742  using Event = typename SyncEvent::Event;
743 
744  SynchronisationEventEncoder(size_t numberOfSynchronisationEventsToEncode) :
745  _numberOfSynchronisationEventsToEncode(numberOfSynchronisationEventsToEncode)
746  {
747  }
748 
749  virtual Event newEvent(const SyncEvent & synchronisedEvent) = 0;
750 
751  };
752  }
753  }
754 }
755 
756 #endif /* __DIADES__AUTOMATA__EXPERIMENTAL__SYNCHRONISATIONEVENT__HH__ */
757 
static ConstP get(const T &obj)
Definition: Pointer.hh:37
SynchronisationEvent(const SynchronisationEvent &sync1, const SynchronisationEvent &sync2)
ComponentIterator findSupportComponent(const Component &component) const
ComponentIterator(const ComponentVector *pVect, const EventVector *pEvent, Size index)
typename StateMachine::NullEventPropertyId NullEvent
#define ensure(Exception, expr, message)
Definition: Assertion.hh:98
bool containsEvent(const EventPropertyId &e) const
bool operator!=(const SynchronisationEvent &evt) const
Event getAssociatedEvent(const ComponentIterator &it) const
SynchronisationEventEncoder(size_t numberOfSynchronisationEventsToEncode)
SynchronisationEvent(const SynchronisationEvent &sync, const ComponentVector &components)
DdAutFsm::EventPropertyId Event
Definition: TrimState.cc:139
ComponentIterator findComponent(const Component &component) const
ComponentIterator addEvent(const Component &component, Event e)
#define require(Exception, expr, message)
Definition: Assertion.hh:90
Namespace of the Diades project.
bool operator==(const SynchronisationEvent &evt) const