Browse Source

Simplify and add template for Dynamics

Eric Ramat 11 years ago
parent
commit
4e098ff687

+ 2 - 2
src/common/Coordinator.hpp

@@ -48,8 +48,8 @@ public :
 
 // DEVS methods
     virtual void output(common::Time t) =0;
-    virtual void post_message(common::Time t,
-                              const common::ExternalEvent& event) =0;
+    virtual void post_event(common::Time t,
+                            const common::ExternalEvent& event) =0;
     virtual common::Time dispatch_events(common::Bag bag,
                                          common::Time t) =0;
     virtual common::Time start(common::Time t) =0;

+ 3 - 4
src/common/ExternalEvent.cpp

@@ -25,7 +25,6 @@
  */
 
 #include <common/ExternalEvent.hpp>
-#include <common/Node.hpp>
 
 #include <sstream>
 
@@ -35,9 +34,9 @@ ExternalEvent::ExternalEvent(const std::string& port_name, double content) :
     _port_name(port_name), _model(0), _content(content)
 { }
 
-ExternalEvent::ExternalEvent(const std::string& port_name, Model* model,
-                             double content) :
-    _port_name(port_name), _model(model), _content(content)
+ExternalEvent::ExternalEvent(const Node& node, double content) :
+    _port_name(node.get_port_name()), _model(node.get_model()),
+    _content(content)
 { }
 
 ExternalEvent::ExternalEvent()

+ 3 - 1
src/common/ExternalEvent.hpp

@@ -28,6 +28,7 @@
 #define COMMON_EXTERNAL_EVENT 1
 
 #include <common/Model.hpp>
+#include <common/Node.hpp>
 
 #include <string>
 #include <vector>
@@ -35,12 +36,13 @@
 namespace paradevs { namespace common {
 
 class Model;
+class Node;
 
 class ExternalEvent
 {
 public:
     ExternalEvent(const std::string& port_name, double content);
-    ExternalEvent(const std::string& port_name, Model* model, double content);
+    ExternalEvent(const Node& node, double content);
     ExternalEvent();
     virtual ~ExternalEvent();
 

+ 12 - 0
src/common/Links.cpp

@@ -30,6 +30,18 @@
 
 namespace paradevs { namespace common {
 
+void Links::add(Model* out_model, const std::string& out_port_name,
+                Model* in_model, const std::string& in_port_name)
+{
+    insert(std::pair < Node, Node >(Node(out_model, out_port_name),
+                                    Node(in_model, in_port_name)));
+}
+
+Links::Result Links::find(Model* out_model, const std::string& out_port_name)
+{
+    return equal_range(common::Node(out_model, out_port_name));
+}
+
 std::string Links::to_string() const
 {
     std::stringstream ss;

+ 9 - 0
src/common/Links.hpp

@@ -38,11 +38,20 @@ class Node;
 class Links : public std::multimap < Node, Node >
 {
 public:
+
+    typedef std::pair < common::Links::iterator,
+                        common::Links::iterator > Result;
+
     Links()
     { }
     virtual ~Links()
     { }
 
+    void add(Model* out_model, const std::string& out_port_name,
+             Model* in_model, const std::string& in_port_name);
+
+    Result find(Model* out_model, const std::string& out_port_name);
+
     std::string to_string() const;
 };
 

+ 2 - 2
src/common/Model.hpp

@@ -47,8 +47,8 @@ public:
 
     virtual void observation(std::ostream& file) const =0;
     virtual void output(common::Time t) =0;
-    virtual void post_message(common::Time t,
-                              const common::ExternalEvent& event) = 0;
+    virtual void post_event(common::Time t,
+                            const common::ExternalEvent& event) = 0;
     virtual common::Time start(common::Time t) =0;
     virtual common::Time transition(common::Time t) =0;
 

+ 3 - 3
src/common/Node.cpp

@@ -28,12 +28,12 @@
 
 namespace paradevs { namespace common {
 
-Node::Node(const std::string& port_name, Model* model)
-    : _port_name(port_name), _model(model)
+Node::Node(Model* model, const std::string& port_name)
+    : _model(model), _port_name(port_name)
 { }
 
 Node::Node(const Node& other)
-    : _port_name(other._port_name), _model(other._model)
+    : _model(other._model), _port_name(other._port_name)
 { }
 
 Node::~Node()

+ 3 - 3
src/common/Node.hpp

@@ -38,8 +38,8 @@ class Model;
 class Node
 {
 public :
-    Node(const std::string& port_name, Model* model);
-    Node(const Node & other);
+    Node(Model* model, const std::string& port_name);
+    Node(const Node& other);
     virtual ~Node();
 
     Model* get_model() const;
@@ -49,8 +49,8 @@ public :
     virtual bool operator==(const Node& other) const;
 
 private :
-    std::string _port_name;
     Model*      _model;
+    std::string _port_name;
 };
 
 } } // namespace paradevs common

+ 2 - 2
src/common/Simulator.hpp

@@ -42,8 +42,8 @@ public :
 
     virtual void observation(std::ostream& file) const =0;
     virtual void output(common::Time t) =0;
-    virtual void post_message(common::Time t,
-                              const common::ExternalEvent& event) = 0;
+    virtual void post_event(common::Time t,
+                            const common::ExternalEvent& event) = 0;
     virtual common::Time start(common::Time t) =0;
     virtual common::Time transition(common::Time t) =0;
 };

+ 1 - 1
src/common/Trace.cpp

@@ -41,7 +41,7 @@ std::string TraceElements::to_string() const
         {
         case NONE: ss << "none"; break;
         case I_MESSAGE: ss << "i_message"; break;
-        case POST_MESSAGE:  ss << "post_message"; break;
+        case POST_EVENT:  ss << "post_event"; break;
         case S_MESSAGE: ss << "s_message"; break;
         case Y_MESSAGE: ss << "y_message"; break;
         case DELTA_INT: ss << "delta_int"; break;

+ 1 - 1
src/common/Trace.hpp

@@ -37,7 +37,7 @@
 
 namespace paradevs { namespace common {
 
-enum TraceType { NONE = 0, I_MESSAGE, POST_MESSAGE, S_MESSAGE, Y_MESSAGE,
+enum TraceType { NONE = 0, I_MESSAGE, POST_EVENT, S_MESSAGE, Y_MESSAGE,
                  DELTA_INT, DELTA_EXT, DELTA_CONF, TA, LAMBDA, START, OUTPUT };
 
 class TraceElement

+ 26 - 37
src/dtss/Coordinator.hpp

@@ -49,10 +49,12 @@ public:
     Coordinator(const std::string& name, common::Time time_step) :
         common::Coordinator(name), _time_step(time_step)
     { }
+
     virtual ~Coordinator()
     {
-        for (unsigned int i = 0; i < _child_list.size(); i++)
-        { delete _child_list[i]; }
+        for (auto & child : _child_list) {
+            delete child;
+        }
     }
 
 // DEVS methods
@@ -71,10 +73,8 @@ public:
     common::Time dispatch_events(common::Bag bag, common::Time t)
     {
         for (auto & ymsg : bag) {
-            std::pair < common::Links::iterator ,
-                        common::Links::iterator > result_model =
-                _link_list.equal_range(common::Node(ymsg.get_port_name(),
-                                                    ymsg.get_model()));
+            common::Links::Result result_model =
+                _link_list.find(ymsg.get_model(), ymsg.get_port_name());
 
             for (common::Links::iterator it = result_model.first;
                  it != result_model.second; ++it) {
@@ -83,18 +83,13 @@ public:
                     common::Bag ymessages;
 
                     ymessages.push_back(
-                        common::ExternalEvent(it->second.get_port_name(),
-                                              it->second.get_model(),
-                                              ymsg.get_content()));
-                    dynamic_cast < Coordinator* >(get_parent())->dispatch_events(
-                        ymessages, t);
+                        common::ExternalEvent(it->second, ymsg.get_content()));
+                    dynamic_cast < common::Coordinator* >(get_parent())
+                        ->dispatch_events(ymessages, t);
                 } else { // event on input port of internal model
-                    Model* model = dynamic_cast < Model* >(
-                        it->second.get_model());
-                    common::ExternalEvent message(it->second.get_port_name(),
-                                                  model, ymsg.get_content());
-
-                    model->post_message(t, message);
+                    it->second.get_model()->post_event(
+                        t, common::ExternalEvent(it->second,
+                                                 ymsg.get_content()));
                 }
             }
         }
@@ -103,8 +98,8 @@ public:
 
     void observation(std::ostream& file) const
     {
-        for (unsigned i = 0; i < _child_list.size(); i++) {
-            _child_list[i]->observation(file);
+        for (auto & child : _child_list) {
+            child->observation(file);
         }
     }
 
@@ -117,20 +112,18 @@ public:
         }
     }
 
-    void post_message(common::Time t,
-                      const common::ExternalEvent& event)
+    void post_event(common::Time t,
+                    const common::ExternalEvent& event)
     {
         if (t == _tn) {
-            std::pair < common::Links::iterator, common::Links::iterator > result =
-                _link_list.equal_range(common::Node(event.get_port_name(), this));
+            common::Links::Result result =
+                _link_list.find(this, event.get_port_name());
 
             for (common::Links::iterator it_r = result.first;
                  it_r != result.second; ++it_r) {
-                Model* model = dynamic_cast < Model* >((*it_r).second.get_model());
-
-                model->post_message(t,
-                                    common::ExternalEvent(it_r->second.get_port_name(),
-                                                          model, event.get_content()));
+                it_r->second.get_model()->post_event(
+                    t, common::ExternalEvent(it_r->second,
+                                             event.get_content()));
             }
         } else {
             _policy(t, event, _tl, _tn);
@@ -140,11 +133,8 @@ public:
     common::Time transition(common::Time t)
     {
         if (t == _tn) {
-            if (not _policy.bag().empty()) {
-                for (common::Bag::const_iterator it = _policy.bag().begin();
-                     it != _policy.bag().end(); ++it) {
-                    post_message(t, *it);
-                }
+            for (auto & event : _policy.bag()) {
+                post_event(t, event);
             }
             for (auto & model : _child_list) {
                 model->transition(t);
@@ -163,11 +153,10 @@ public:
         child->set_parent(this);
     }
 
-    void add_link(const common::Node& source,
-                  const common::Node& destination)
+    void add_link(Model* out_model, const std::string& out_port_name,
+                  Model* in_model, const std::string& in_port_name)
     {
-        _link_list.insert(std::pair < common::Node, common::Node >(source,
-                                                                   destination));
+        _link_list.add(out_model, out_port_name, in_model, in_port_name);
     }
 
 private:

+ 0 - 57
src/dtss/Simulator.cpp

@@ -24,65 +24,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <common/Trace.hpp>
-
-#include <dtss/Coordinator.hpp>
 #include <dtss/Simulator.hpp>
 
-#include <cassert>
-#include <stdexcept>
-
 namespace paradevs { namespace dtss {
 
-Simulator::Simulator(Dynamics* dynamics, common::Time time_step) :
-    common::Simulator(dynamics->get_name()), _dynamics(dynamics),
-    _time_step(time_step)
-{ }
-
-Simulator::~Simulator()
-{ delete _dynamics; }
-
-common::Time Simulator::start(common::Time t)
-{
-    _dynamics->start(t);
-    _tl = t;
-    _tn = t;
-    return _tn;
-}
-
-void Simulator::observation(std::ostream &file) const
-{ _dynamics->observation(file); }
-
-void Simulator::output(common::Time t)
-{
-    if(t == _tn) {
-        common::Bag bag = _dynamics->lambda(t);
-
-        if (not bag.empty()) {
-            for (common::Bag::iterator it = bag.begin(); it != bag.end();
-                 ++it) {
-                it->set_model(this);
-            }
-            dynamic_cast < common::Coordinator* >(get_parent())->dispatch_events(bag,
-                                                                                 t);
-        }
-    }
-}
-
-void Simulator::post_message(common::Time /* t */,
-                             const common::ExternalEvent& event)
-{ add_event(event); }
-
-common::Time Simulator::transition(common::Time t)
-{
-
-    assert(t == _tn);
-
-    _dynamics->transition(get_bag(), t);
-    _tl = t;
-    _tn = t + _time_step;
-    clear_bag();
-    return _tn;
-}
-
 } } // namespace paradevs dtss

+ 54 - 14
src/dtss/Simulator.hpp

@@ -27,32 +27,72 @@
 #ifndef DTSS_SIMULATOR
 #define DTSS_SIMULATOR 1
 
-#include <common/Links.hpp>
-#include <common/Node.hpp>
+#include <common/Coordinator.hpp>
 #include <common/Simulator.hpp>
 
-#include <dtss/Dynamics.hpp>
+#include <cassert>
 
 namespace paradevs { namespace dtss {
 
+template < class Dynamics >
 class Simulator : public common::Simulator
 {
 public :
-    Simulator(Dynamics* dynamics, common::Time time_step);
-    virtual ~Simulator();
+    Simulator(const std::string& name, common::Time time_step) :
+        common::Simulator(name), _dynamics(name), _time_step(time_step)
+    { }
 
-    virtual void observation(std::ostream& file) const;
-    virtual void output(common::Time /* t */);
-    virtual void post_message(common::Time /* t */,
-                              const common::ExternalEvent& /* message */);
-    virtual common::Time start(common::Time /* t */);
-    virtual common::Time transition(common::Time /* t */);
+    ~Simulator()
+    {  }
 
-    virtual Dynamics* get_dynamics() const
-    { return _dynamics; }
+    common::Time start(common::Time t)
+    {
+        _dynamics.start(t);
+        _tl = t;
+        _tn = t;
+        return _tn;
+    }
+
+    void observation(std::ostream &file) const
+    {
+        _dynamics.observation(file);
+    }
+
+    void output(common::Time t)
+    {
+        if(t == _tn) {
+            common::Bag bag = _dynamics.lambda(t);
+
+            if (not bag.empty()) {
+                for (auto & event : bag) {
+                    event.set_model(this);
+                }
+                dynamic_cast < common::Coordinator* >(get_parent())
+                    ->dispatch_events(bag, t);
+            }
+        }
+    }
+
+    void post_event(common::Time /* t */,
+                    const common::ExternalEvent& event)
+    {
+        add_event(event);
+    }
+
+    common::Time transition(common::Time t)
+    {
+
+        assert(t == _tn);
+
+        _dynamics.transition(get_bag(), t);
+        _tl = t;
+        _tn = t + _time_step;
+        clear_bag();
+        return _tn;
+    }
 
 private :
-    Dynamics*    _dynamics;
+    Dynamics     _dynamics;
     common::Time _time_step;
 };
 

+ 53 - 72
src/pdevs/Coordinator.cpp

@@ -39,8 +39,9 @@ Coordinator::Coordinator(const std::string& name) : common::Coordinator(name)
 
 Coordinator::~Coordinator()
 {
-    for (unsigned int i = 0; i < _child_list.size(); i++)
-    { delete _child_list[i]; }
+    for (auto & child : _child_list) {
+        delete child;
+    }
 }
 
 common::Time Coordinator::start(common::Time t)
@@ -135,41 +136,17 @@ common::Time Coordinator::transition(common::Time t)
 
     common::Models receivers = _event_table.get_current_models(t);
 
-    for (common::Models::const_iterator it = _child_list.begin();
-         it != _child_list.end(); ++it) {
-        Model* model = dynamic_cast < Model* >(*it);
-
-        if (model->event_number() > 0) {
-            common::Models::const_iterator itm = std::find(receivers.begin(),
-                                                           receivers.end(),
-                                                           model);
-            if (itm == receivers.end()) {
-                receivers.push_back(model);
-            }
-        }
-    }
+    add_models_with_inputs(receivers);
 
     common::Trace::trace() << common::TraceElement(get_name(), t,
                                                    common::S_MESSAGE)
                            << ": receivers = " << receivers.to_string();
     common::Trace::trace().flush();
 
-    for (common::Models::const_iterator it = receivers.begin();
-         it != receivers.end(); ++it) {
-        common::Time tn = (*it)->transition(t);
-
-        _event_table.put(tn, *it);
+    for (auto & model : receivers) {
+        _event_table.put(model->transition(t), model);
     }
-
-    for (common::Models::const_iterator it = _child_list.begin();
-         it != _child_list.end(); ++it) {
-        Model* model = dynamic_cast < Model* >(*it);
-
-        if (model->event_number() > 0) {
-            _event_table.put(t, model);
-        }
-    }
-
+    update_event_table(t);
     _tl = t;
     _tn = _event_table.get_current_time();
     clear_bag();
@@ -184,42 +161,31 @@ common::Time Coordinator::transition(common::Time t)
     return _tn;
 }
 
-void Coordinator::post_message(common::Time t,
-                               const common::ExternalEvent& message)
+void Coordinator::post_event(common::Time t,
+                             const common::ExternalEvent& event)
 {
 
     common::Trace::trace() << common::TraceElement(get_name(), t,
-                                                   common::POST_MESSAGE)
-                           << ": BEFORE => " << message.to_string();
+                                                   common::POST_EVENT)
+                           << ": BEFORE => " << event.to_string();
     common::Trace::trace().flush();
 
-    add_event(message);
+    add_event(event);
 
-    std::pair < common::Links::iterator, common::Links::iterator > result =
-        _link_list.equal_range(common::Node(message.get_port_name(), this));
+    common::Links::Result result =
+        _link_list.find(this, event.get_port_name());
 
     for (common::Links::iterator it_r = result.first;
          it_r != result.second; ++it_r) {
-        Model* model = dynamic_cast < Model* >((*it_r).second.get_model());
-
-        model->post_message(t,
-                            common::ExternalEvent(it_r->second.get_port_name(),
-                                                  model,
-                                                  message.get_content()));
-    }
-    for (common::Models::const_iterator it = _child_list.begin();
-         it != _child_list.end(); ++it) {
-        Model* model = dynamic_cast < Model* >(*it);
-
-        if (model->event_number() > 0) {
-            _event_table.put(t, model);
-        }
+        it_r->second.get_model()->post_event(
+            t, common::ExternalEvent(it_r->second, event.get_content()));
     }
+    update_event_table(t);
     _tn = _event_table.get_current_time();
 
     common::Trace::trace() << common::TraceElement(get_name(), t,
-                                                   common::POST_MESSAGE)
-                           << ": AFTER => " << message.to_string();
+                                                   common::POST_EVENT)
+                           << ": AFTER => " << event.to_string();
     common::Trace::trace().flush();
 
 }
@@ -238,10 +204,8 @@ common::Time Coordinator::dispatch_events(common::Bag bag, common::Time t)
     common::Trace::trace().flush();
 
     for (auto & ymsg : bag) {
-        std::pair < common::Links::iterator ,
-                    common::Links::iterator > result_model =
-            _link_list.equal_range(common::Node(ymsg.get_port_name(),
-                                                ymsg.get_model()));
+            common::Links::Result result_model =
+                _link_list.find(ymsg.get_model(), ymsg.get_port_name());
 
         for (common::Links::iterator it = result_model.first;
              it != result_model.second; ++it) {
@@ -250,18 +214,13 @@ common::Time Coordinator::dispatch_events(common::Bag bag, common::Time t)
                 common::Bag ymessages;
 
                 ymessages.push_back(
-                    common::ExternalEvent(it->second.get_port_name(),
-                                          it->second.get_model(),
-                                          ymsg.get_content()));
+                    common::ExternalEvent(it->second, ymsg.get_content()));
                 dynamic_cast < Coordinator* >(get_parent())->dispatch_events(
                     ymessages, t);
             } else { // event on input port of internal model
-                Model* model = dynamic_cast < Model* >(
-                    it->second.get_model());
-                common::ExternalEvent message(it->second.get_port_name(),
-                                              model, ymsg.get_content());
-
-                model->post_message(t, message);
+                    it->second.get_model()->post_event(
+                        t, common::ExternalEvent(it->second,
+                                                 ymsg.get_content()));
             }
         }
     }
@@ -277,8 +236,8 @@ common::Time Coordinator::dispatch_events(common::Bag bag, common::Time t)
 
 void Coordinator::observation(std::ostream& file) const
 {
-    for (unsigned i = 0; i < _child_list.size(); i++) {
-        _child_list[i]->observation(file);
+    for (auto & child : _child_list) {
+        child->observation(file);
     }
 }
 
@@ -288,9 +247,31 @@ void Coordinator::add_child(Model* child)
     child->set_parent(this);
 }
 
-void Coordinator::add_link(const common::Node& source,
-                           const common::Node& destination)
-{ _link_list.insert(std::pair < common::Node, common::Node >(source,
-                                                             destination)); }
+void Coordinator::add_link(Model* out_model, const std::string& out_port_name,
+                           Model* in_model, const std::string& in_port_name)
+{
+    _link_list.add(out_model, out_port_name, in_model, in_port_name);
+}
+
+void Coordinator::add_models_with_inputs(common::Models& receivers)
+{
+    for (auto & model : _child_list) {
+        if (model->event_number() > 0) {
+            if (std::find(receivers.begin(), receivers.end(), model) ==
+                receivers.end()) {
+                receivers.push_back(model);
+            }
+        }
+    }
+}
+
+void Coordinator::update_event_table(common::Time t)
+{
+    for (auto & model : _child_list) {
+        if (model->event_number() > 0) {
+            _event_table.put(t, model);
+        }
+    }
+}
 
 } } // namespace paradevs pdevs

+ 7 - 4
src/pdevs/Coordinator.hpp

@@ -46,8 +46,8 @@ public:
 
 // DEVS methods
     virtual void output(common::Time /* t */);
-    virtual void post_message(common::Time /* t */,
-                              const common::ExternalEvent& /* message */);
+    virtual void post_event(common::Time /* t */,
+                            const common::ExternalEvent& /* event */);
     virtual common::Time dispatch_events(common::Bag /* bag */,
                                          common::Time /* t */);
     virtual common::Time start(common::Time /* t */);
@@ -56,10 +56,13 @@ public:
 
 // graph methods
     virtual void add_child(Model* child);
-    virtual void add_link(const common::Node& source,
-                          const common::Node& destination);
+    virtual void add_link(Model* out_model, const std::string& out_port_name,
+                          Model* in_model, const std::string& in_port_name);
 
 private:
+    void add_models_with_inputs(common::Models& receivers);
+    void update_event_table(common::Time t);
+
     common::Links      _link_list;
     common::Models     _child_list;
     common::EventTable _event_table;

+ 0 - 141
src/pdevs/Simulator.cpp

@@ -24,149 +24,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <common/Trace.hpp>
-
-#include <pdevs/Coordinator.hpp>
 #include <pdevs/Simulator.hpp>
 
-#include <cassert>
-#include <stdexcept>
-
 namespace paradevs { namespace pdevs {
 
-Simulator::Simulator(Dynamics* dynamics) :
-    common::Simulator(dynamics->get_name()), _dynamics(dynamics)
-{ }
-
-Simulator::~Simulator()
-{ delete _dynamics; }
-
-/*************************************************
- * when i-message(t)
- *   tl = t - e
- *   tn = tl + ta(s)
- *************************************************/
-common::Time Simulator::start(common::Time t)
-{
-
-    common::Trace::trace() << common::TraceElement(get_name(), t,
-                                                   common::I_MESSAGE)
-                           << ": BEFORE => "
-                           << "tl = " << _tl << " ; tn = " << _tn;
-    common::Trace::trace().flush();
-
-    _tl = t;
-    _tn = _tl + _dynamics->start(t);
-
-    common::Trace::trace() << common::TraceElement(get_name(), t,
-                                                   common::I_MESSAGE)
-                           << ": AFTER => "
-                           << "tl = " << _tl << " ; tn = " << _tn;
-    common::Trace::trace().flush();
-
-    return _tn;
-}
-
-void Simulator::observation(std::ostream &file) const
-{
-    _dynamics->observation(file);
-}
-
-/*************************************************
- * when *-message(t)
- *   if (t = tn) then
- *     y = lambda(s)
- *     send y-message(y,t) to parent
- *************************************************/
-void Simulator::output(common::Time t)
-{
-
-    common::Trace::trace() << common::TraceElement(get_name(), t,
-                                                   common::OUTPUT)
-                           << ": BEFORE";
-    common::Trace::trace().flush();
-
-    if(t == _tn) {
-        common::Bag bag = _dynamics->lambda(t);
-
-        if (not bag.empty()) {
-            for (common::Bag::iterator it = bag.begin(); it != bag.end();
-                 ++it) {
-                it->set_model(this);
-            }
-            dynamic_cast < Coordinator* >(get_parent())->dispatch_events(bag,
-                                                                         t);
-        }
-    }
-
-    common::Trace::trace() << common::TraceElement(get_name(), t,
-                                                   common::OUTPUT)
-                           << ": AFTER";
-    common::Trace::trace().flush();
-
-}
-
-void Simulator::post_message(common::Time t,
-                             const common::ExternalEvent& message)
-{
-
-    common::Trace::trace() << common::TraceElement(get_name(), t,
-                                                   common::POST_MESSAGE)
-                           << ": BEFORE => " << message.to_string();
-    common::Trace::trace().flush();
-
-    add_event(message);
-
-    common::Trace::trace() << common::TraceElement(get_name(), t,
-                                                   common::POST_MESSAGE)
-                           << ": AFTER => " << message.to_string();
-    common::Trace::trace().flush();
-
-}
-
-/*************************************************
- * when x-message(t)
- *   if (x is empty and t = tn) then
- *       s = delta_int(s)
- *  else if (x isn't empty and t = tn)
- *       s = delta_conf(s,x)
- *  else if (x isn't empty and t < tn)
- *    e = t - tl
- *    s = delta_ext(s,e,x)
- *  tn = t + ta(s)
- *  tl = t
- *************************************************/
-common::Time Simulator::transition(common::Time t)
-{
-
-    common::Trace::trace() << common::TraceElement(get_name(), t,
-                                                   common::S_MESSAGE)
-                           << ": BEFORE => "
-                           << "tl = " << _tl << " ; tn = " << _tn;
-    common::Trace::trace().flush();
-
-    assert(_tl <= t and t <= _tn);
-
-    if(t == _tn) {
-        if (event_number() == 0) {
-            _dynamics->dint(t);
-        } else {
-            _dynamics->dconf(t, t - _tl, get_bag());
-        }
-    } else {
-        _dynamics->dext(t, t - _tl, get_bag());
-    }
-    _tn = t + _dynamics->ta(t);
-    _tl = t;
-    clear_bag();
-
-    common::Trace::trace() << common::TraceElement(get_name(), t,
-                                                   common::S_MESSAGE)
-                           << ": AFTER => "
-                           << "tl = " << _tl << " ; tn = " << _tn;
-    common::Trace::trace().flush();
-
-    return _tn;
-}
-
 } } // namespace paradevs pdevs

+ 149 - 14
src/pdevs/Simulator.hpp

@@ -27,32 +27,167 @@
 #ifndef PDEVS_SIMULATOR
 #define PDEVS_SIMULATOR 1
 
-#include <common/Links.hpp>
-#include <common/Node.hpp>
+#include <common/Coordinator.hpp>
 #include <common/Simulator.hpp>
+#include <common/Trace.hpp>
 
-#include <pdevs/Dynamics.hpp>
+#include <cassert>
 
 namespace paradevs { namespace pdevs {
 
+template < class Dynamics >
 class Simulator : public common::Simulator
 {
 public :
-    Simulator(Dynamics* dynamics);
-    virtual ~Simulator();
+    Simulator(const std::string& name) :
+        common::Simulator(name), _dynamics(name)
+    { }
 
-    virtual void observation(std::ostream& file) const;
-    virtual void output(common::Time /* t */);
-    virtual void post_message(common::Time /* t */,
-                              const common::ExternalEvent& /* message */);
-    virtual common::Time start(common::Time /* t */);
-    virtual common::Time transition(common::Time /* t */);
+    ~Simulator()
+    { }
 
-    virtual Dynamics* get_dynamics() const
-    { return _dynamics; }
+/*************************************************
+ * when i-message(t)
+ *   tl = t - e
+ *   tn = tl + ta(s)
+ *************************************************/
+    common::Time start(common::Time t)
+    {
+
+        common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                       common::I_MESSAGE)
+                               << ": BEFORE => "
+                               << "tl = " << _tl << " ; tn = " << _tn;
+        common::Trace::trace().flush();
+
+        _tl = t;
+        _tn = _tl + _dynamics.start(t);
+
+        common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                       common::I_MESSAGE)
+                               << ": AFTER => "
+                               << "tl = " << _tl << " ; tn = " << _tn;
+        common::Trace::trace().flush();
+
+        return _tn;
+    }
+
+    void observation(std::ostream &file) const
+    {
+        _dynamics.observation(file);
+    }
+
+/*************************************************
+ * when *-message(t)
+ *   if (t = tn) then
+ *     y = lambda(s)
+ *     send y-message(y,t) to parent
+ *************************************************/
+    void output(common::Time t)
+    {
+
+        common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                       common::OUTPUT)
+                               << ": BEFORE";
+        common::Trace::trace().flush();
+
+        if(t == _tn) {
+            common::Bag bag = _dynamics.lambda(t);
+
+            if (not bag.empty()) {
+                for (auto & event : bag) {
+                    event.set_model(this);
+                }
+                dynamic_cast < common::Coordinator* >(get_parent())
+                    ->dispatch_events(bag, t);
+            }
+        }
+
+        common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                       common::OUTPUT)
+                               << ": AFTER";
+        common::Trace::trace().flush();
+
+    }
+
+    void post_event(common::Time t,
+                    const common::ExternalEvent& event)
+    {
+
+        common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                       common::POST_EVENT)
+                               << ": BEFORE => " << event.to_string();
+        common::Trace::trace().flush();
+
+        add_event(event);
+
+        common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                       common::POST_EVENT)
+                               << ": AFTER => " << event.to_string();
+        common::Trace::trace().flush();
+
+    }
+
+/*************************************************
+ * when x-message(t)
+ *   if (x is empty and t = tn) then
+ *       s = delta_int(s)
+ *  else if (x isn't empty and t = tn)
+ *       s = delta_conf(s,x)
+ *  else if (x isn't empty and t < tn)
+ *    e = t - tl
+ *    s = delta_ext(s,e,x)
+ *  tn = t + ta(s)
+ *  tl = t
+ *************************************************/
+    common::Time transition(common::Time t)
+    {
+
+        common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                       common::S_MESSAGE)
+                               << ": BEFORE => "
+                               << "tl = " << _tl << " ; tn = " << _tn;
+        common::Trace::trace().flush();
+
+        assert(_tl <= t and t <= _tn);
+
+        if(t == _tn) {
+            if (event_number() == 0) {
+                _dynamics.dint(t);
+            } else {
+                _dynamics.dconf(t, t - _tl, get_bag());
+            }
+        } else {
+            _dynamics.dext(t, t - _tl, get_bag());
+        }
+        _tn = t + _dynamics.ta(t);
+        _tl = t;
+        clear_bag();
+
+        common::Trace::trace() << common::TraceElement(get_name(), t,
+                                                       common::S_MESSAGE)
+                               << ": AFTER => "
+                               << "tl = " << _tl << " ; tn = " << _tn;
+        common::Trace::trace().flush();
+
+        return _tn;
+    }
+
+    // Simulator(Dynamics* dynamics);
+    // virtual ~Simulator();
+
+    // virtual void observation(std::ostream& file) const;
+    // virtual void output(common::Time /* t */);
+    // virtual void post_event(common::Time /* t */,
+    //                         const common::ExternalEvent& /* event */);
+    // virtual common::Time start(common::Time /* t */);
+    // virtual common::Time transition(common::Time /* t */);
+
+    // virtual Dynamics* get_dynamics() const
+    // { return _dynamics; }
 
 private :
-    Dynamics* _dynamics;
+    Dynamics _dynamics;
 };
 
 } } // namespace paradevs pdevs

+ 12 - 8
src/tests/dtss_tests.cpp

@@ -103,8 +103,10 @@ struct Policy
     const common::Bag& bag() const
     { return _bag; }
 
-    virtual void operator()(common::Time /* t */, const common::ExternalEvent& event,
-                            common::Time /* tl */, common::Time /* tn */)
+    virtual void operator()(common::Time /* t */,
+                            const common::ExternalEvent& event,
+                            common::Time /* tl */,
+                            common::Time /* tn */)
     {
         _bag.clear();
         _bag.push_back(event);
@@ -116,8 +118,9 @@ private:
 
 common::Model* OnlyOneBuilder::build() const
 {
-    dtss::Coordinator < Policy >* root = new dtss::Coordinator < Policy >("root", 1);
-    dtss::Simulator* a = new dtss::Simulator(new A("a"), 1);
+    dtss::Coordinator < Policy >* root =
+        new dtss::Coordinator < Policy >("root", 1);
+    dtss::Simulator < A >* a = new dtss::Simulator < A >("a", 1);
 
     root->add_child(a);
     return root;
@@ -125,13 +128,14 @@ common::Model* OnlyOneBuilder::build() const
 
 common::Model* TwoBuilder::build() const
 {
-    dtss::Coordinator < Policy >* root = new dtss::Coordinator < Policy >("root", 1);
-    dtss::Simulator* a = new dtss::Simulator(new A("a"), 1);
-    dtss::Simulator* b = new dtss::Simulator(new B("b"), 1);
+    dtss::Coordinator < Policy >* root =
+        new dtss::Coordinator < Policy >("root", 1);
+    dtss::Simulator < A >* a = new dtss::Simulator < A >("a", 1);
+    dtss::Simulator < B >* b = new dtss::Simulator < B >("b", 1);
 
     root->add_child(a);
     root->add_child(b);
-    root->add_link(common::Node("out", a), common::Node("in", b));
+    root->add_link(a, "out", b, "in");
     return root;
 }
 

+ 13 - 12
src/tests/mixed_tests.cpp

@@ -201,7 +201,7 @@ common::Bag A2::lambda(common::Time t) const
 {
     common::Bag msgs;
 
-    msgs.push_back(common::ExternalEvent("out", 0, true));
+    msgs.push_back(common::ExternalEvent("out", 0.));
 
     common::Trace::trace() << common::TraceElement(get_name(), t,
                                                    common::LAMBDA)
@@ -233,7 +233,7 @@ common::Bag B2::lambda(common::Time t) const
 {
     common::Bag msgs;
 
-    msgs.push_back(common::ExternalEvent("out", 0, true));
+    msgs.push_back(common::ExternalEvent("out", 0.));
 
     common::Trace::trace() << common::TraceElement(get_name(), t,
                                                    common::LAMBDA)
@@ -248,7 +248,8 @@ struct LastBagPolicy
     const common::Bag& bag() const
     { return _bag; }
 
-    virtual void operator()(common::Time /* t */, const common::ExternalEvent& event,
+    virtual void operator()(common::Time /* t */,
+                            const common::ExternalEvent& event,
                             common::Time /* tl */, common::Time /* tn */)
     {
         _bag.clear();
@@ -279,29 +280,29 @@ common::Model* HierachicalBuilder::build() const
 
     pdevs::Coordinator* S1 = new pdevs::Coordinator("S1");
     {
-        pdevs::Simulator* a = new pdevs::Simulator(new A1("a1"));
-        pdevs::Simulator* b = new pdevs::Simulator(new B1("b1"));
+        pdevs::Simulator < A1 >* a = new pdevs::Simulator < A1 >("a1");
+        pdevs::Simulator < B1 >* b = new pdevs::Simulator < B1 >("b1");
 
         S1->add_child(a);
         S1->add_child(b);
-        S1->add_link(common::Node("out", a), common::Node("in", b));
-        S1->add_link(common::Node("out", b), common::Node("out", S1));
+        S1->add_link(a, "out", b, "in");
+        S1->add_link(b, "out", S1, "out");
     }
 
     dtss::Coordinator < LastBagPolicy >* S2 =
         new dtss::Coordinator < LastBagPolicy >("S2", 20);
     {
-        dtss::Simulator* a = new dtss::Simulator(new A2("a2"), 20);
-        dtss::Simulator* b = new dtss::Simulator(new B2("b2"), 20);
+        dtss::Simulator < A2 >* a = new dtss::Simulator < A2 >("a2", 20);
+        dtss::Simulator < B2 >* b = new dtss::Simulator < B2 >("b2", 20);
 
         S2->add_child(a);
         S2->add_child(b);
-        S2->add_link(common::Node("out", a), common::Node("in", b));
-        S2->add_link(common::Node("in", S2), common::Node("in", a));
+        S2->add_link(a, "out", b, "in");
+        S2->add_link(S2, "in", a, "in");
     }
     root->add_child(S1);
     root->add_child(S2);
-    root->add_link(common::Node("out", S1), common::Node("in", S2));
+    root->add_link(S1, "out", S2, "in");
     return root;
 }
 

+ 19 - 19
src/tests/pdevs_tests.cpp

@@ -97,7 +97,7 @@ common::Bag A::lambda(common::Time t) const
 {
     common::Bag msgs;
 
-    msgs.push_back(common::ExternalEvent("out", 0, true));
+    msgs.push_back(common::ExternalEvent("out", 0.));
 
     common::Trace::trace() << common::TraceElement(get_name(), t,
                                                    common::LAMBDA)
@@ -172,7 +172,7 @@ common::Bag B::lambda(common::Time t) const
 {
     common::Bag msgs;
 
-    msgs.push_back(common::ExternalEvent("out", 0, true));
+    msgs.push_back(common::ExternalEvent("out", 0.));
 
     common::Trace::trace() << common::TraceElement(get_name(), t,
                                                    common::LAMBDA)
@@ -191,35 +191,35 @@ common::Model* HierachicalBuilder::build() const
 
     pdevs::Coordinator* S1 = new pdevs::Coordinator("S1");
     {
-        pdevs::Simulator* a = new pdevs::Simulator(new A("a1"));
-        pdevs::Simulator* b = new pdevs::Simulator(new B("b1"));
+        pdevs::Simulator < A >* a = new pdevs::Simulator < A >("a1");
+        pdevs::Simulator < B >* b = new pdevs::Simulator < B >("b1");
 
         S1->add_child(a);
         S1->add_child(b);
-        S1->add_link(common::Node("out", a), common::Node("in", b));
-        S1->add_link(common::Node("out", b), common::Node("out", S1));
+        S1->add_link(a, "out", b, "in");
+        S1->add_link(b, "out", S1, "out");
     }
 
     pdevs::Coordinator* S2 = new pdevs::Coordinator("S2");
     {
-        pdevs::Simulator* a = new pdevs::Simulator(new A("a2"));
-        pdevs::Simulator* b = new pdevs::Simulator(new B("b2"));
+        pdevs::Simulator < A >* a = new pdevs::Simulator < A >("a2");
+        pdevs::Simulator < B >* b = new pdevs::Simulator < B >("b2");
 
         S2->add_child(a);
         S2->add_child(b);
-        S2->add_link(common::Node("out", a), common::Node("in", b));
-        S2->add_link(common::Node("in", S2), common::Node("in", a));
+        S2->add_link(a, "out", b, "in");
+        S2->add_link(S2, "in", a, "in");
     }
     root->add_child(S1);
     root->add_child(S2);
-    root->add_link(common::Node("out", S1), common::Node("in", S2));
+    root->add_link(S1, "out", S2, "in");
     return root;
 }
 
 common::Model* OnlyOneBuilder::build() const
 {
     pdevs::Coordinator* root = new pdevs::Coordinator("root");
-    pdevs::Simulator* a = new pdevs::Simulator(new A("a"));
+    pdevs::Simulator < A >* a = new pdevs::Simulator < A >("a");
 
     root->add_child(a);
     return root;
@@ -228,18 +228,18 @@ common::Model* OnlyOneBuilder::build() const
 common::Model* FlatBuilder::build() const
 {
     pdevs::Coordinator* root = new pdevs::Coordinator("root");
-    pdevs::Simulator* a1 = new pdevs::Simulator(new A("a1"));
-    pdevs::Simulator* b1 = new pdevs::Simulator(new B("b1"));
-    pdevs::Simulator* a2 = new pdevs::Simulator(new A("a2"));
-    pdevs::Simulator* b2 = new pdevs::Simulator(new B("b2"));
+    pdevs::Simulator < A >* a1 = new pdevs::Simulator < A >("a1");
+    pdevs::Simulator < B >* b1 = new pdevs::Simulator < B >("b1");
+    pdevs::Simulator < A >* a2 = new pdevs::Simulator < A >("a2");
+    pdevs::Simulator < B >* b2 = new pdevs::Simulator < B >("b2");
 
     root->add_child(a1);
     root->add_child(b1);
     root->add_child(a2);
     root->add_child(b2);
-    root->add_link(common::Node("out", a1), common::Node("in", b1));
-    root->add_link(common::Node("out", b1), common::Node("in", a2));
-    root->add_link(common::Node("out", a2), common::Node("in", b2));
+    root->add_link(a1, "out", b1, "in");
+    root->add_link(b1, "out", a2, "in");
+    root->add_link(a2, "out", b2, "in");
     return root;
 }