31 #ifndef __adevs_simulator_h_
32 #define __adevs_simulator_h_
33 #include "adevs_abstract_simulator.h"
34 #include "adevs_models.h"
35 #include "adevs_event_listener.h"
36 #include "adevs_sched.h"
37 #include "adevs_bag.h"
38 #include "adevs_set.h"
39 #include "object_pool.h"
55 template <
class X,
class T =
double>
class Simulator:
56 public AbstractSimulator<X,T>,
57 private Schedule<X,T>::ImminentVisitor
71 schedule(model,adevs_zero<T>());
79 return sched.minPriority();
122 schedule(model,adevs_zero<T>());
154 typedef enum { OUTPUT_OK, OUTPUT_NOT_OK, RESTORING_OUTPUT } OutputStatus;
159 LogicalProcess<X,T>* lp;
160 bool look_ahead, stop_forced;
161 OutputStatus out_flag;
162 Bag<Atomic<X,T>*> to_restore;
167 Bag<Event<X,T> > bogus_input;
171 Bag<Atomic<X,T>*> activated;
173 object_pool<Bag<X> > io_pool;
174 object_pool<Bag<Event<X,T> > > recv_pool;
176 Bag<Devs<X,T>*> added;
177 Bag<Devs<X,T>*> removed;
178 Set<Devs<X,T>*> next;
179 Set<Devs<X,T>*> prev;
181 struct bottom_to_top_depth_compare
183 bool operator()(
const Network<X,T>* m1,
const Network<X,T>* m2)
const
185 unsigned long int d1 = 0, d2 = 0;
187 const Network<X,T>* m = m1->getParent();
201 if (d1 == d2)
return m1 < m2;
206 struct top_to_bottom_depth_compare
208 bool operator()(
const Devs<X,T>* m1,
const Devs<X,T>* m2)
const
210 unsigned long int d1 = 0, d2 = 0;
212 const Network<X,T>* m = m1->getParent();
226 if (d1 == d2)
return m1 < m2;
231 std::set<Network<X,T>*,bottom_to_top_depth_compare> model_func_eval_set;
232 std::set<Devs<X,T>*,top_to_bottom_depth_compare> sorted_removed;
237 void schedule(Devs<X,T>* model, T t);
239 void route(Network<X,T>* parent, Devs<X,T>* src, X& x);
245 void inject_event(Atomic<X,T>* model, X& value);
250 void unschedule_model(Devs<X,T>* model);
256 void clean_up(Devs<X,T>* model);
263 void exec_event(Atomic<X,T>* model, T t);
267 void getAllChildren(Network<X,T>* model, Set<Devs<X,T>*>& s);
273 bool manage_lookahead_data(Atomic<X,T>* model);
277 void visit(Atomic<X,T>* model);
280 template <
class X,
class T>
281 void Simulator<X,T>::visit(Atomic<X,T>* model)
283 assert(model->y == NULL);
284 model->y = io_pool.make_obj();
286 if (model->x == NULL)
287 activated.insert(model);
290 model->output_func(*(model->y));
292 for (
typename Bag<X>::iterator y_iter = model->y->begin();
293 y_iter != model->y->end(); y_iter++)
295 route(model->getParent(),model,*y_iter);
299 template <
class X,
class T>
303 if (activated.empty() ==
false)
return;
305 sched.visitImminent(
this);
308 template <
class X,
class T>
312 if (t < sched.minPriority())
315 for (iter = activated.
begin(); iter != activated.
end(); iter++)
322 else if (t == sched.minPriority())
327 for (
typename Bag<
Event<X,T> >::iterator iter = input.begin();
328 iter != input.end(); iter++)
333 inject_event(amodel,(*iter).value);
337 route((*iter).model->typeIsNetwork(),(*iter).model,(*iter).value);
346 for (
typename Bag<
Atomic<X,T>*>::iterator iter = activated.begin();
347 iter != activated.end(); iter++)
357 if (model_func_eval_set.empty() ==
false)
359 while (!model_func_eval_set.empty())
361 Network<X,T>* network_model = *(model_func_eval_set.begin());
362 model_func_eval_set.erase(model_func_eval_set.begin());
363 getAllChildren(network_model,prev);
367 model_func_eval_set.insert(network_model->
getParent());
369 getAllChildren(network_model,next);
385 for (
typename Bag<
Devs<X,T>*>::iterator iter = added.begin();
386 iter != added.end(); iter++)
393 for (
typename Bag<
Devs<X,T>*>::iterator iter = removed.begin();
394 iter != removed.end(); iter++)
397 unschedule_model(*iter);
399 sorted_removed.insert(*iter);
404 while (!sorted_removed.empty())
407 Devs<X,T>* model_to_remove = *(sorted_removed.begin());
409 sorted_removed.erase(sorted_removed.begin());
418 for (; iter != prev.end(); iter++)
419 sorted_removed.erase(*iter);
423 delete model_to_remove;
426 assert(prev.empty());
427 assert(sorted_removed.empty());
431 for (
typename Bag<
Atomic<X,T>*>::iterator iter = activated.begin();
432 iter != activated.end(); iter++)
440 if (lps != NULL && lps->stop_forced)
447 template <
class X,
class T>
453 if (amodel->x != NULL)
456 io_pool.destroy_obj(amodel->x);
459 if (amodel->y != NULL)
463 io_pool.destroy_obj(amodel->y);
469 Set<Devs<X,T>*> components;
471 for (
typename Set<Devs<X,T>*>::iterator iter = components.begin();
472 iter != components.end(); iter++)
479 template <
class X,
class T>
480 void Simulator<X,T>::unschedule_model(Devs<X,T>* model)
482 if (model->typeIsAtomic() != NULL)
484 sched.schedule(model->typeIsAtomic(),adevs_inf<T>());
485 activated.erase(model->typeIsAtomic());
489 Set<Devs<X,T>*> components;
490 model->typeIsNetwork()->getComponents(components);
491 for (
typename Set<Devs<X,T>*>::iterator iter = components.begin();
492 iter != components.end(); iter++)
494 unschedule_model(*iter);
499 template <
class X,
class T>
500 void Simulator<X,T>::schedule(Devs<X,T>* model, T t)
502 Atomic<X,T>* a = model->typeIsAtomic();
507 if (dt < adevs_zero<T>())
509 exception err(
"Negative time advance",a);
512 if (dt == adevs_inf<T>())
513 sched.schedule(a,adevs_inf<T>());
515 sched.schedule(a,t+dt);
519 Set<Devs<X,T>*> components;
520 model->typeIsNetwork()->getComponents(components);
521 typename Set<Devs<X,T>*>::iterator iter = components.begin();
522 for (; iter != components.end(); iter++)
529 template <
class X,
class T>
530 void Simulator<X,T>::inject_event(Atomic<X,T>* model, X& value)
532 if (model->x == NULL)
534 if (model->y == NULL)
535 activated.insert(model);
536 model->x = io_pool.make_obj();
538 model->x->insert(value);
541 template <
class X,
class T>
542 void Simulator<X,T>::route(Network<X,T>* parent, Devs<X,T>* src, X& x)
545 if (parent != src && (lps == NULL || lps->out_flag != RESTORING_OUTPUT))
546 this->notify_output_listeners(src,x,sched.minPriority());
548 if (parent == NULL)
return;
550 Bag<Event<X,T> >* recvs = recv_pool.make_obj();
551 parent->route(x,src,*recvs);
553 Atomic<X,T>* amodel = NULL;
554 typename Bag<Event<X,T> >::iterator recv_iter = recvs->begin();
555 for (; recv_iter != recvs->end(); recv_iter++)
558 if (src == (*recv_iter).model)
560 exception err(
"Model tried to influence self",src);
567 amodel = (*recv_iter).model->typeIsAtomic();
571 if (lps == NULL || amodel->getProc() == lps->lp->getID())
572 inject_event(amodel,(*recv_iter).value);
574 else if (lps->out_flag != RESTORING_OUTPUT)
575 lps->lp->notifyInput(amodel,(*recv_iter).value);
578 else if ((*recv_iter).model == parent)
580 route(parent->getParent(),parent,(*recv_iter).value);
585 route((*recv_iter).model->typeIsNetwork(),
586 (*recv_iter).model,(*recv_iter).value);
590 recv_pool.destroy_obj(recvs);
593 template <
class X,
class T>
594 void Simulator<X,T>::exec_event(Atomic<X,T>* model, T t)
596 if (!manage_lookahead_data(model))
return;
598 if (model->x == NULL)
601 else if (model->y != NULL)
602 model->delta_conf(*(model->x));
605 model->delta_ext(t-model->tL,*(model->x));
607 this->notify_state_listeners(model,t);
609 if (model->model_transition() && model->getParent() != NULL)
611 model_func_eval_set.insert(model->getParent());
615 template <
class X,
class T>
616 void Simulator<X,T>::getAllChildren(Network<X,T>* model, Set<Devs<X,T>*>& s)
620 model->getComponents(tmp);
622 s.insert(tmp.begin(),tmp.end());
624 typename Set<Devs<X,T>*>::iterator iter;
625 for (iter = tmp.begin(); iter != tmp.end(); iter++)
627 if ((*iter)->typeIsNetwork() != NULL)
629 getAllChildren((*iter)->typeIsNetwork(),s);
634 template <
class X,
class T>
639 for (iter = activated.
begin(); iter != activated.
end(); iter++)
645 template <
class X,
class T>
649 lps =
new lp_support;
651 lps->look_ahead =
false;
652 lps->stop_forced =
false;
653 lps->out_flag = OUTPUT_OK;
656 template <
class X,
class T>
664 lps->look_ahead =
true;
665 if (!activated.empty())
666 lps->out_flag = OUTPUT_NOT_OK;
669 template <
class X,
class T>
675 template <
class X,
class T>
678 if (lps == NULL)
return;
680 for (; iter != lps->to_restore.
end(); iter++)
682 (*iter)->endLookahead();
683 schedule(*iter,(*iter)->tL_cp);
684 (*iter)->tL_cp = adevs_sentinel<T>();
685 assert((*iter)->x == NULL);
686 assert((*iter)->y == NULL);
688 lps->to_restore.clear();
689 assert(activated.empty());
690 if (lps->out_flag == OUTPUT_NOT_OK)
692 lps->out_flag = RESTORING_OUTPUT;
694 lps->out_flag = OUTPUT_OK;
696 lps->look_ahead =
false;
697 lps->stop_forced =
false;
700 template <
class X,
class T>
703 if (lps == NULL)
return true;
704 if (lps->look_ahead && model->tL_cp < adevs_zero<T>())
706 lps->to_restore.insert(model);
707 model->tL_cp = model->tL;
712 catch(method_not_supported_exception err)
714 lps->stop_forced =
true;
717 return !(lps->stop_forced);
Atomic< X, T > * typeIsAtomic()
Returns a pointer to this model.
Definition: adevs_models.h:255
Definition: adevs_models.h:49
Definition: adevs_abstract_simulator.h:45
Definition: adevs_set.h:42
void execNextEvent()
Execute the simulation cycle at time nextEventTime()
Definition: adevs_simulator.h:82
void beginLookahead()
Definition: adevs_simulator.h:657
void lookNextEvent()
Definition: adevs_simulator.h:670
void computeNextOutput()
Definition: adevs_simulator.h:300
Definition: adevs_models.h:46
void computeNextState(Bag< Event< X, T > > &input, T t)
Definition: adevs_simulator.h:309
void clear()
Remove all of the elements from the bag.
Definition: adevs_bag.h:144
virtual void gc_output(Bag< X > &g)=0
void addModel(Atomic< X, T > *model)
Definition: adevs_simulator.h:120
iterator begin() const
Get an iterator pointing to the first element in the bag.
Definition: adevs_bag.h:128
Definition: adevs_exception.h:43
Definition: adevs_models.h:48
iterator end() const
Get an iterator to the end of the bag (i.e., just after the last element)
Definition: adevs_bag.h:130
virtual Network< X, T > * typeIsNetwork()
Definition: adevs_models.h:81
virtual bool model_transition()
Definition: adevs_models.h:110
void set_assign_diff(Bag< T > &result, const Set< T > &A, const Set< T > &B)
Set difference operator. Returns the set A-B.
Definition: adevs_set.h:48
virtual void beginLookahead()
Definition: adevs_models.h:240
T nextEventTime()
Definition: adevs_simulator.h:77
void execUntil(T tend)
Execute until nextEventTime() > tend.
Definition: adevs_simulator.h:88
virtual Atomic< X, T > * typeIsAtomic()
Returns NULL if this is not an atomic model; returns itself otherwise.
Definition: adevs_models.h:83
~Simulator()
Definition: adevs_simulator.h:635
Definition: adevs_models.h:63
Definition: adevs_models.h:142
void endLookahead()
Definition: adevs_simulator.h:676
Definition: adevs_models.h:47
Simulator(Devs< X, T > *model)
Definition: adevs_simulator.h:66
Definition: adevs_exception.h:99
const Network< X, T > * getParent() const
Definition: adevs_models.h:88
Definition: adevs_bag.h:45