Parcourir la source

Change observation system

Eric Ramat il y a 6 ans
Parent
commit
9affb0e1cc

+ 0 - 13
CMakeLists.txt

@@ -69,19 +69,6 @@ INCLUDE(CheckIncludeFile)
 INCLUDE(CheckLibraryExists)
 INCLUDE(CMakeDetermineCCompiler)
 
-#
- # Check libraries with pkgconfig
-#
-
-#FIND_PACKAGE(PkgConfig REQUIRED)
-
-# FIXME use old-style link directories for now
-IF (COMMAND CMAKE_POLICY)
-  CMAKE_POLICY(SET CMP0003 OLD)
-ENDIF (COMMAND CMAKE_POLICY)
-
-#PKG_CHECK_MODULES(GLIBMM REQUIRED glibmm-2.4)
-#PKG_CHECK_MODULES(LIBXML REQUIRED libxml-2.0)
 #
  # Test the libboost header and libboost-text library.
 #

+ 5 - 4
src/paradevs/common/CMakeLists.txt

@@ -9,12 +9,13 @@ LINK_DIRECTORIES(
   ${GLIBMM_LIBRARY_DIRS}
   ${LIBXML_LIBRARY_DIR})
 
-SET(COMMON_HPP Bag.hpp Coordinator.hpp ExternalEvent.hpp InternalEvent.hpp
-  Links.hpp Model.hpp Node.hpp Parameters.hpp RootCoordinator.hpp Scheduler.hpp
-  Simulator.hpp Value.hpp)
+SET(COMMON_HPP Bag.hpp Coordinator.hpp ExternalEvent.hpp
+  GraphManager.hpp InternalEvent.hpp Links.hpp Model.hpp Node.hpp Parameters.hpp
+  RootCoordinator.hpp Scheduler.hpp Simulator.hpp Value.hpp)
 
 INSTALL(FILES ${COMMON_HPP} DESTINATION ${PARADEVS_INCLUDE_DIRS}/common)
 
+ADD_SUBDIRECTORY(observer)
 ADD_SUBDIRECTORY(scheduler)
 ADD_SUBDIRECTORY(time)
-ADD_SUBDIRECTORY(utils)
+ADD_SUBDIRECTORY(utils)

+ 42 - 2
src/paradevs/common/Coordinator.hpp

@@ -25,7 +25,7 @@
  */
 
 #ifndef COMMON_COORDINATOR
-#define COMMON_COORDINATOR 1
+#define COMMON_COORDINATOR
 
 #include <paradevs/common/Bag.hpp>
 #include <paradevs/common/ExternalEvent.hpp>
@@ -40,6 +40,9 @@ namespace paradevs { namespace common {
 template < class Time >
 class Model;
 
+template < class Time >
+class GraphManager;
+
 template < class Time >
 class Coordinator : public virtual Model < Time >
 {
@@ -50,6 +53,42 @@ public :
     virtual ~Coordinator()
     { }
 
+    virtual const GraphManager < Time >& get_graph_manager() const = 0;
+
+    virtual const Model < Time >* get_submodel(unsigned int index) const
+    {
+        const GraphManager < Time >& graph_manager =
+            get_graph_manager();
+        typename common::ModelMap < Time >::const_iterator it =
+            graph_manager.children().find(index);
+
+        if (it != graph_manager.children().end()) {
+            return it->second;
+        } else {
+            return nullptr;
+        }
+    }
+
+    virtual const Model < Time >* get_submodel(unsigned int /* index */,
+                                               unsigned int /* rank */) const
+    {
+/*        const GraphManager < Time >& graph_manager =
+            get_graph_manager();
+        typename common::Models < Time >::const_iterator it =
+            graph_manager.children().find(index);
+
+
+        typename AbstractCoupledModel::Setsubmodels::const_iterator it =
+            setsubmodels.find(index);
+
+        if (it != setsubmodels.end() and it->second.size() > rank) {
+            return it->second.at(rank);
+        } else {
+            return nullptr;
+            } */
+        return nullptr;
+    }
+
     virtual bool is_atomic() const
     { return false; }
 
@@ -63,7 +102,8 @@ public :
     }
 
 // DEVS methods
-    virtual void observation(std::ostream& file) const =0;
+    virtual common::Value observe(const typename Time::type& t,
+                                  unsigned int index) const =0;
     virtual void output(const typename Time::type& t) =0;
     virtual void post_event(const typename Time::type& t,
                             const common::ExternalEvent < Time >& event) =0;

+ 70 - 0
src/paradevs/common/GraphManager.hpp

@@ -0,0 +1,70 @@
+/**
+ * @file common/GraphManager.hpp
+ * @author The PARADEVS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * PARADEVS - the multimodeling and simulation environment
+ * This file is a part of the PARADEVS environment
+ *
+ * Copyright (C) 2013-2016 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef COMMON_GRAPH_MANANGER
+#define COMMON_GRAPH_MANANGER
+
+#include <paradevs/common/Coordinator.hpp>
+#include <paradevs/common/Links.hpp>
+#include <paradevs/common/Model.hpp>
+#include <paradevs/common/Parameters.hpp>
+#include <paradevs/common/utils/String.hpp>
+
+#include <sstream>
+
+namespace paradevs { namespace common {
+
+template < class Time >
+class GraphManager
+{
+public:
+    GraphManager(common::Coordinator < Time >* coordinator) :
+        _coordinator(coordinator)
+    { }
+
+    virtual ~GraphManager()
+    { }
+
+    void add_child(unsigned int index, common::Model < Time >* child)
+    {
+        _child_list[index] = child;
+        child->set_parent(_coordinator);
+    }
+
+    const common::ModelMap < Time >& children() const
+    { return _child_list; }
+
+    common::Coordinator < Time >* get_coordinator() const
+    { return _coordinator; }
+
+protected:
+    common::ModelMap < Time >     _child_list;
+    common::Coordinator < Time >* _coordinator;
+};
+
+} } // namespace paradevs common
+
+#endif

+ 37 - 4
src/paradevs/common/Model.hpp

@@ -25,18 +25,19 @@
  */
 
 #ifndef COMMON_MODEL
-#define COMMON_MODEL 1
+#define COMMON_MODEL
 
 #include <paradevs/common/Bag.hpp>
 #include <paradevs/common/ExternalEvent.hpp>
 #include <paradevs/common/InternalEvent.hpp>
 #include <paradevs/common/Scheduler.hpp>
+#include <paradevs/common/Value.hpp>
 
 #include <algorithm>
 #include <cassert>
+#include <map>
 #include <iostream>
 #include <sstream>
-#include <vector>
 
 namespace paradevs { namespace common {
 
@@ -120,6 +121,13 @@ public:
     virtual int get_receiver_number(typename Time::type t)
     { (void)t; return 0; }
 
+    virtual const Model < Time >* get_submodel(unsigned int index) const
+    { (void)index; assert(false); }
+
+    virtual const Model < Time >* get_submodel(unsigned int index,
+                                               unsigned int rank) const
+    { (void)index; (void)rank; assert(false); }
+
     virtual bool is_atomic() const = 0;
 
     virtual bool is_remote() const
@@ -172,10 +180,11 @@ public:
     { return _tn; }
 
     // devs methods
-    virtual void observation(std::ostream& file) const =0;
+    virtual common::Value observe(const typename Time::type& t,
+                                  unsigned int index) const =0;
     virtual void output(const typename Time::type& t) =0;
     virtual void post_event(const typename Time::type& t,
-                            const common::ExternalEvent < Time >& event) = 0;
+                            const common::ExternalEvent < Time >& event) =0;
     virtual typename Time::type start(const typename Time::type& t) =0;
     virtual typename Time::type transition(const typename Time::type& t) =0;
 
@@ -200,6 +209,30 @@ private :
     SchedulerHandle _handle;
 };
 
+template < class Time >
+class ModelMap : public std::map < unsigned int, Model < Time >* >
+{
+public:
+    ModelMap()
+    { }
+    virtual ~ModelMap()
+    { }
+
+    std::string to_string() const
+    {
+        std::ostringstream ss;
+
+        ss << "{ ";
+        for (typename ModelMap < Time >::const_iterator it =
+                 ModelMap < Time >::begin();
+             it != ModelMap < Time >::end(); ++it) {
+            ss << it->second->get_name() << " ";
+        }
+        ss << "}";
+        return ss.str();
+    }
+};
+
 template < class Time >
 class Models : public std::vector < Model < Time >* >
 {

+ 18 - 8
src/paradevs/common/RootCoordinator.hpp

@@ -25,8 +25,10 @@
  */
 
 #ifndef COMMON_ROOT_COORDINATOR
-#define COMMON_ROOT_COORDINATOR 1
+#define COMMON_ROOT_COORDINATOR
 
+#include <paradevs/common/observer/Observer.hpp>
+#include <paradevs/common/observer/View.hpp>
 #include <paradevs/common/Parameters.hpp>
 
 #include <sstream>
@@ -44,7 +46,7 @@ public :
         const std::string& root_name,
         const typename Coordinator::parameters_type& parameters,
         const typename Coordinator::graph_parameters_type& graph_parameters) :
-        _root(root_name, parameters, graph_parameters),
+        _root(root_name, parameters, graph_parameters), _observer(&_root),
         _t_max(t_max), _tn(t_start)
     { }
 
@@ -52,26 +54,34 @@ public :
                     const typename Time::type& t_max,
                     const std::string& root_name,
                     const typename Coordinator::parameters_type& parameters) :
-        _root(root_name, parameters, NoParameters()),
+        _root(root_name, parameters, NoParameters()), _observer(&_root),
         _t_max(t_max), _tn(t_start)
     { }
 
     RootCoordinator(const typename Time::type& t_start,
                     const typename Time::type& t_max,
                     const std::string& root_name) :
-        _root(root_name, NoParameters(), NoParameters()),
+        _root(root_name, NoParameters(), NoParameters()), _observer(&_root),
         _t_max(t_max), _tn(t_start)
     { }
 
     virtual ~RootCoordinator()
     { }
 
+    void attachView(const std::string& name, observer::View < Time >* view)
+    { _observer.attachView(name, view); }
+
+    const observer::Observer < Time >& observer() const
+    { return _observer; }
+
     void run()
     {
+        _observer.init();
         _tn = _root.start(_tn);
         while (_tn <= _t_max) {
             _root.output(_tn);
             _tn = _root.transition(_tn);
+            _observer.observe(_tn);
         }
     }
 
@@ -84,10 +94,10 @@ public :
     }
 
 private :
-    Coordinator         _root;
-    typename Time::type _t_max;
-
-    typename Time::type _tn;
+    Coordinator                 _root;
+    observer::Observer < Time > _observer;
+    typename Time::type         _t_max;
+    typename Time::type         _tn;
 };
 
 } } // namespace paradevs common

+ 3 - 2
src/paradevs/common/Simulator.hpp

@@ -25,7 +25,7 @@
  */
 
 #ifndef COMMON_SIMULATOR
-#define COMMON_SIMULATOR 1
+#define COMMON_SIMULATOR
 
 #include <paradevs/common/Model.hpp>
 
@@ -54,7 +54,8 @@ public :
     }
 
 // DEVS methods
-    virtual void observation(std::ostream& file) const =0;
+    virtual common::Value observe(const typename Time::type& t,
+                                  unsigned int index) const =0;
     virtual void output(const typename Time::type& t) =0;
     virtual void post_event(const typename Time::type& t,
                             const common::ExternalEvent < Time >& event) = 0;

+ 1 - 1
src/paradevs/common/Value.hpp

@@ -131,7 +131,7 @@ public:
             get_content(v);
             return "";
         } else {
-            assert(false);
+            return "<unstringify>";
         }
     }
 

+ 9 - 0
src/paradevs/common/observer/CMakeLists.txt

@@ -0,0 +1,9 @@
+INCLUDE_DIRECTORIES(
+  ${CMAKE_SOURCE_DIR}/src)
+
+LINK_DIRECTORIES()
+
+SET(COMMON_OBSERVER_HPP Observer.hpp Output.hpp View.hpp)
+
+INSTALL(FILES ${COMMON_OBSERVER_HPP} DESTINATION
+  ${PARADEVS_INCLUDE_DIRS}/common/observer)

+ 96 - 0
src/paradevs/common/observer/Observer.hpp

@@ -0,0 +1,96 @@
+/**
+ * @file paradevs/common/observer/Observer.hpp
+ * @author The PARADEVS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * PARADEVS - the multimodeling and simulation environment
+ * This file is a part of the PARADEVS environment
+ *
+ * Copyright (C) 2013-2016 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PARADEVS_OBSERVER_OBSERVER_HPP
+#define PARADEVS_OBSERVER_OBSERVER_HPP
+
+#include <paradevs/common/Model.hpp>
+#include <paradevs/common/observer/View.hpp>
+
+#include <vector>
+
+namespace paradevs { namespace observer {
+
+template < typename Time >
+class Observer
+{
+public:
+    typedef std::map < std::string, View < Time >* > Views;
+
+    Observer(const common::Model < Time >* model) :
+        _model(model)
+    { }
+
+    virtual ~Observer()
+    {
+        for (typename Views::iterator it = _views.begin(); it != _views.end();
+             ++it) {
+            delete it->second;
+        }
+    }
+
+    void attachView(const std::string& name, View < Time >* view)
+    {
+        _views[name] = view;
+        view->attachModel(_model);
+    }
+
+    Views* cloneViews() const
+    {
+        Views* v = new Views();
+
+        for (typename Views::const_iterator it = _views.begin();
+             it != _views.end(); ++it) {
+            (*v)[it->first] = it->second->clone();
+        }
+        return v;
+    }
+
+    const View < Time >& view(const std::string& name) const
+    { return *_views.find(name)->second; }
+
+    const Views& views() const
+    { return _views; }
+
+    void init()
+    { }
+
+    void observe(double t)
+    {
+        for (typename Views::iterator it = _views.begin(); it != _views.end();
+             ++it) {
+            it->second->observe(t);
+        }
+    }
+
+private:
+    const common::Model < Time >* _model;
+    Views                         _views;
+};
+
+} }
+
+#endif

+ 94 - 0
src/paradevs/common/observer/Output.hpp

@@ -0,0 +1,94 @@
+/**
+ * @file paradevs/observer/Output.hpp
+ * @author See the AUTHORS file
+ */
+
+/*
+ * Copyright (C) 2012-2017 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PARADEVS_COMMON_OBSERVER_OUTPUT_HPP
+#define PARADEVS_COMMON_OBSERVER_OUTPUT_HPP
+
+#include <paradevs/common/observer/Observer.hpp>
+#include <paradevs/common/observer/View.hpp>
+#include <paradevs/utils/DateTime.hpp>
+
+#include <boost/format.hpp>
+
+namespace paradevs { namespace observer {
+
+template < typename Time >
+class Output
+{
+public:
+    Output(const Observer < Time >& observer) : _observer(observer)
+    { }
+
+    virtual ~Output()
+    { }
+
+    void operator()() const
+    {
+        const typename Observer < Time >::Views& views = _observer.views();
+
+        for (typename Observer < Time >::Views::const_iterator it =
+                 views.begin(); it != views.end(); ++it) {
+            std::ofstream o((boost::format("%1%.csv") % it->first).str());
+            typename View < Time >::Values values = it->second->values();
+            double begin = it->second->begin();
+            double end = it->second->end();
+
+            o.precision(10);
+            // write header
+            o << "time";
+            for (typename View < Time >::Values::const_iterator
+                     itv = values.begin(); itv != values.end(); ++itv) {
+                o << ";" << itv->first;
+            }
+            o << std::endl;
+
+            // write values
+            for (double t = begin; t <= end; ++t) {
+                o << utils::DateTime::toJulianDay(t);
+                // o << t;
+                for (typename View < Time >::Values::const_iterator itv =
+                         values.begin(); itv != values.end(); ++itv) {
+                    typename View < Time >::Value::const_iterator itp =
+                        itv->second.begin();
+
+                    while (itp != itv->second.end() and itp->first < t) {
+                        ++itp;
+                    }
+                    o << ";";
+                    if (itp != itv->second.end()) {
+                        o << itp->second;
+                    } else {
+                        o << "NA";
+                    }
+                }
+                o << std::endl;
+            }
+        }
+    }
+
+private:
+    const Observer < Time >& _observer;
+};
+
+} }
+
+#endif

+ 175 - 0
src/paradevs/common/observer/View.hpp

@@ -0,0 +1,175 @@
+/**
+ * @file paradevs/common/observer/View.hpp
+ * @author The PARADEVS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * PARADEVS - the multimodeling and simulation environment
+ * This file is a part of the PARADEVS environment
+ *
+ * Copyright (C) 2013-2016 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PARADEVS_COMMON_OBSERVER_VIEW_HPP
+#define PARADEVS_COMMON_OBSERVER_VIEW_HPP
+
+#include <paradevs/common/Model.hpp>
+#include <paradevs/common/time/DoubleTime.hpp>
+#include <paradevs/common/Value.hpp>
+
+#include <boost/lexical_cast.hpp>
+
+namespace paradevs { namespace observer {
+
+template < typename Time >
+class View
+{
+    typedef std::vector < unsigned int > Selector;
+
+public:
+    typedef std::vector < std::pair < double, common::Value > > Value;
+    typedef std::map < std::string, Value > Values;
+
+    View() : _model(0)
+    { }
+
+    virtual ~View()
+    { }
+
+    void attachModel(const paradevs::common::Model < Time >* m)
+    { _model = m; }
+
+    double begin() const
+    {
+        double t = common::DoubleTime::infinity;
+
+        for (Values::const_iterator it = _values.begin(); it!= _values.end();
+             ++it) {
+            if (t > it->second.begin()->first) {
+                t = it->second.begin()->first;
+            }
+        }
+        return t;
+    }
+
+    View* clone() const
+    {
+        View* v = new View();
+
+        v->_selectors = _selectors;
+        for (Values::const_iterator it = _values.begin(); it!= _values.end();
+             ++it) {
+
+            v->_values[it->first] = Value();
+            Value::const_iterator itp = it->second.begin();
+
+            while (itp != it->second.end()) {
+                v->_values[it->first].push_back(*itp);
+                ++itp;
+            }
+        }
+        v->_model = 0;
+        return v;
+    }
+
+    double end() const
+    {
+        double t = 0;
+
+        for (Values::const_iterator it = _values.begin(); it!= _values.end();
+             ++it) {
+            if (t < it->second.back().first) {
+                t = it->second.back().first;
+            }
+        }
+        return t;
+    }
+
+    double get(double t, const std::string& name) const
+    {
+        Values::const_iterator it = _values.find(name);
+
+        if (it != _values.end()) {
+            Value::const_iterator itp = it->second.begin();
+
+            while (itp != it->second.end() and itp->first < t) {
+                ++itp;
+            }
+            if (itp != it->second.end()) {
+                // TODO: to improve
+                return boost::lexical_cast < double >(itp->second);
+            } else {
+                return 0;
+            }
+        }
+        return 0;
+    }
+
+    const Value& get(const std::string& name) const
+    {
+        Values::const_iterator it = _values.find(name);
+
+        if (it != _values.end()) {
+            return it->second;
+        } else {
+            assert(false);
+        }
+    }
+
+    virtual void observe(double time)
+    {
+        for (typename Selectors::const_iterator it = _selectors.begin();
+             it != _selectors.end(); ++it) {
+            const common::Model < common::DoubleTime >* model = _model;
+
+            if (it->second.size() > 1) {
+                size_t i = 0;
+
+                while (i < it->second.size() - 1 and model) {
+                    model = model->get_submodel(it->second[i]);
+                    ++i;
+                }
+            }
+            if (model) {
+                _values[it->first].push_back(
+                    std::make_pair(time,
+                                   model->observe(time,
+                                                  it->second.back())));
+            }
+        }
+    }
+
+    void selector(const std::string& name, const Selector& chain)
+    {
+        _selectors[name] = chain;
+        _values[name] = Value();
+    }
+
+    const Values& values() const
+    { return _values;}
+
+private:
+    typedef std::map < std::string, Selector > Selectors;
+
+    Selectors                               _selectors;
+    Values                                  _values;
+    const paradevs::common::Model < Time >* _model;
+};
+
+} }
+
+#endif

+ 2 - 6
src/paradevs/common/time/CMakeLists.txt

@@ -1,16 +1,12 @@
 INCLUDE_DIRECTORIES(
   ${PARADEVS_BINARY_DIR}/src
   ${PARADEVS_SOURCE_DIR}/src
-  ${Boost_INCLUDE_DIRS}
-  ${GLIBMM_INCLUDE_DIRS}
-  ${LIBXML_INCLUDE_DIRS})
+  ${Boost_INCLUDE_DIRS})
 
 LINK_DIRECTORIES(
-  ${GLIBMM_LIBRARY_DIRS}
-  ${LIBXML_LIBRARY_DIR}
   ${Boost_LIBRARY_DIRS})
 
 SET(COMMON_TIME_HPP DoubleTime.hpp Time.hpp)
 
 INSTALL(FILES ${COMMON_TIME_HPP} DESTINATION
-  ${PARADEVS_INCLUDE_DIRS}/common/time)
+  ${PARADEVS_INCLUDE_DIRS}/common/time)

+ 5 - 15
src/paradevs/kernel/dtss/GraphManager.hpp

@@ -25,9 +25,10 @@
  */
 
 #ifndef DTSS_GRAPH_MANAGER
-#define DTSS_GRAPH_MANAGER 1
+#define DTSS_GRAPH_MANAGER
 
 #include <paradevs/common/Coordinator.hpp>
+#include <paradevs/common/GraphManager.hpp>
 #include <paradevs/common/Links.hpp>
 #include <paradevs/common/Model.hpp>
 #include <paradevs/common/Parameters.hpp>
@@ -36,23 +37,17 @@ namespace paradevs { namespace dtss {
 
 template < class Time,
            class GraphParameters = common::NoParameters >
-class GraphManager
+class GraphManager : public common::GraphManager < Time >
 {
 public:
     GraphManager(common::Coordinator < Time >* coordinator,
                  const GraphParameters& /* parameters */) :
-        _coordinator(coordinator)
+        common::GraphParameters < Time >(coordinator)
     { }
 
     virtual ~GraphManager()
     { }
 
-    void add_child(common::Model < Time >* child)
-    {
-        _child_list.push_back(child);
-        child->set_parent(_coordinator);
-    }
-
     void add_link(common::Model < Time >* src_model,
                   const std::string& src_port_name,
                   common::Model < Time >* dst_model,
@@ -74,9 +69,6 @@ public:
         _link_list.add(src_model, src_port_name, dst_model, dst_port_name);
     }
 
-    const common::Models < Time >& children() const
-    { return _child_list; }
-
     void dispatch_events(common::Bag < Time > bag,
                          typename Time::type t)
     {
@@ -121,9 +113,7 @@ public:
     }
 
 private:
-    common::Links < Time >        _link_list;
-    common::Models < Time >       _child_list;
-    common::Coordinator < Time >* _coordinator;
+    common::Links < Time > _link_list;
 };
 
 } } // namespace paradevs dtss

+ 14 - 11
src/paradevs/kernel/pdevs/Coordinator.hpp

@@ -62,6 +62,9 @@ public:
     virtual ~Coordinator()
     { }
 
+    const common::GraphManager < Time >& get_graph_manager() const
+    { return _graph_manager; }
+
     virtual std::string to_string(int level) const
     {
         std::ostringstream ss;
@@ -87,7 +90,7 @@ public:
         assert(_graph_manager.children().size() > 0);
 
         for (auto & child : _graph_manager.children()) {
-            _event_table.init(child->start(t), child);
+            _event_table.init(child.second->start(t), child.second);
         }
         type::_tl = t;
         type::_tn = _event_table.get_current_time();
@@ -273,21 +276,21 @@ public:
         return type::_tn;
     }
 
-    void observation(std::ostream& file) const
+    common::Value observe(const typename Time::type& /* t */,
+                          unsigned int /* index */) const
     {
-        for (auto & child : _graph_manager.children()) {
-            child->observation(file);
-        }
+        assert(false);
+        return common::Value();
     }
 
     void add_models_with_inputs(
         common::Models < Time >& receivers)
     {
         for (auto & model : _graph_manager.children()) {
-            if (model->event_number() > 0) {
-                if (std::find(receivers.begin(), receivers.end(), model) ==
-                    receivers.end()) {
-                    receivers.push_back(model);
+            if (model.second->event_number() > 0) {
+                if (std::find(receivers.begin(), receivers.end(),
+                              model.second) == receivers.end()) {
+                    receivers.push_back(model.second);
                 }
             }
         }
@@ -296,8 +299,8 @@ public:
     void update_event_table(typename Time::type t)
     {
         for (auto & model : _graph_manager.children()) {
-            if (model->event_number() > 0) {
-                _event_table.put(t, model);
+            if (model.second->event_number() > 0) {
+                _event_table.put(t, model.second);
             }
         }
     }

+ 4 - 3
src/paradevs/kernel/pdevs/Dynamics.hpp

@@ -25,7 +25,7 @@
  */
 
 #ifndef PDEVS_DYNAMICS
-#define PDEVS_DYNAMICS 1
+#define PDEVS_DYNAMICS
 
 #include <paradevs/common/Bag.hpp>
 #include <paradevs/common/ExternalEvent.hpp>
@@ -71,8 +71,9 @@ public:
         typename Time::type /* time */) const
     { return common::Bag < Time >(); }
 
-    virtual void observation(std::ostream& /* file */) const
-    { }
+    virtual common::Value observe(const typename Time::type& /* t */,
+                                  unsigned int /* index */) const
+    { return common::Value(); }
 
     const std::string& get_name() const
     { return _name; }

+ 19 - 30
src/paradevs/kernel/pdevs/GraphManager.hpp

@@ -25,9 +25,10 @@
  */
 
 #ifndef PDEVS_GRAPH_MANANGER
-#define PDEVS_GRAPH_MANANGER 1
+#define PDEVS_GRAPH_MANANGER
 
 #include <paradevs/common/Coordinator.hpp>
+#include <paradevs/common/GraphManager.hpp>
 #include <paradevs/common/Links.hpp>
 #include <paradevs/common/Model.hpp>
 #include <paradevs/common/Parameters.hpp>
@@ -39,47 +40,38 @@ namespace paradevs { namespace pdevs {
 
 template < class Time,
            class GraphParameters = common::NoParameters >
-class GraphManager
+class GraphManager : public common::GraphManager < Time >
 {
 public:
     GraphManager(common::Coordinator < Time >* coordinator,
                  const GraphParameters& /* parameters */) :
-        _coordinator(coordinator)
+        common::GraphManager < Time >(coordinator)
     { }
 
     virtual ~GraphManager()
     { }
 
-    void add_child(common::Model < Time >* child)
-    {
-        _child_list.push_back(child);
-        child->set_parent(_coordinator);
-    }
-
     void add_link(common::Model < Time >* src_model,
                   const std::string& src_port_name,
                   common::Model < Time >* dst_model,
                   const std::string& dst_port_name)
     {
-        assert((src_model != _coordinator and
-                dst_model != _coordinator and
+        assert((src_model != common::GraphManager < Time >::_coordinator and
+                dst_model != common::GraphManager < Time >::_coordinator and
                 src_model->exist_out_port(src_port_name) and
                 dst_model->exist_in_port(dst_port_name)) or
-               (src_model == _coordinator and
-                dst_model != _coordinator and
+               (src_model == common::GraphManager < Time >::_coordinator and
+                dst_model != common::GraphManager < Time >::_coordinator and
                 src_model->exist_in_port(src_port_name) and
                 dst_model->exist_in_port(dst_port_name)) or
-               (src_model != _coordinator and
-                dst_model == _coordinator and
+               (src_model != common::GraphManager < Time >::_coordinator and
+                dst_model == common::GraphManager < Time >::_coordinator and
                 src_model->exist_out_port(src_port_name) and
                 dst_model->exist_out_port(dst_port_name)));
 
         _link_list.add(src_model, src_port_name, dst_model, dst_port_name);
     }
 
-    const common::Models < Time >& children() const
-    { return _child_list; }
-
     void dispatch_events(common::Bag < Time > bag,
                          typename Time::type t)
     {
@@ -92,7 +84,8 @@ public:
                      const_iterator it = result_model.first;
                      it != result_model.second; ++it) {
                 // event on output port of coupled Model
-                if (it->second.get_model() == _coordinator) {
+                if (it->second.get_model() ==
+                    common::GraphManager < Time >::_coordinator) {
                     dispatch_events_to_parent(it->second, ymsg.get_content(),
                                               t);
                 } else { // event on input port of internal model
@@ -114,8 +107,8 @@ public:
             common::ExternalEvent <Time >(node, content));
 
         dynamic_cast < common::Coordinator < Time >* >(
-            _coordinator->get_parent())->dispatch_events(
-                ymessages, t);
+            common::GraphManager < Time >::_coordinator->get_parent())
+            ->dispatch_events(ymessages, t);
     }
 
     bool exist_link(common::Model < Time >* src_model,
@@ -127,14 +120,12 @@ public:
                                 dst_port_name);
     }
 
-    common::Coordinator < Time >* get_coordinator() const
-    { return _coordinator; }
-
     void post_event(typename Time::type t,
                     const common::ExternalEvent < Time >& event)
     {
         typename common::Links < Time >::Result result =
-            _link_list.find(_coordinator, event.get_port_name());
+            _link_list.find(common::GraphManager < Time >::_coordinator,
+                            event.get_port_name());
 
         for (typename common::Links < Time >::const_iterator it_r =
                  result.first; it_r != result.second; ++it_r) {
@@ -149,17 +140,15 @@ public:
     	std::ostringstream ss;
 
     	ss << common::spaces(level * 2) << "Childs :" << std::endl;
-        for (auto & child : _child_list) {
-            ss << child->to_string(level + 1);
+        for (auto & child : common::GraphManager < Time >::_child_list) {
+            ss << child.second->to_string(level + 1);
         }
         ss << _link_list.to_string(level);
         return ss.str();
     }
 
 private:
-    common::Links < Time >        _link_list;
-    common::Models < Time >       _child_list;
-    common::Coordinator < Time >* _coordinator;
+    common::Links < Time > _link_list;
 };
 
 } } // namespace paradevs pdevs

+ 3 - 4
src/paradevs/kernel/pdevs/Simulator.hpp

@@ -95,10 +95,9 @@ public :
         return type::_tn;
     }
 
-    void observation(std::ostream &file) const
-    {
-        _dynamics.observation(file);
-    }
+    common::Value observe(const typename Time::type& t,
+                          unsigned int index) const
+    { return _dynamics.observe(t, index); }
 
 /*************************************************
  * when *-message(t)

+ 5 - 15
src/paradevs/kernel/sss/GraphManager.hpp

@@ -25,9 +25,10 @@
  */
 
 #ifndef SSS_GRAPH_MANANGER
-#define SSS_GRAPH_MANANGER 1
+#define SSS_GRAPH_MANANGER
 
 #include <paradevs/common/Coordinator.hpp>
+#include <paradevs/common/GraphManager.hpp>
 #include <paradevs/common/Links.hpp>
 #include <paradevs/common/Parameters.hpp>
 
@@ -37,23 +38,17 @@ namespace paradevs { namespace sss {
 
 template < class Time,
            class GraphParameters = common::NoParameters >
-class GraphManager
+class GraphManager : public common::GraphManager < Time >
 {
 public:
     GraphManager(common::Coordinator < Time >* coordinator,
                  const GraphParameters& /* parameters */) :
-        _coordinator(coordinator)
+        common::GraphManager < Time >(coordinator)
     { }
 
     virtual ~GraphManager()
     { }
 
-    void add_child(sss::Model < Time >* child)
-    {
-        _child_list.push_back(child);
-        child->set_parent(_coordinator);
-    }
-
     void add_link(common::Model < Time >* src_model,
                   const std::string& src_port_name,
                   common::Model < Time >* dst_model,
@@ -75,9 +70,6 @@ public:
         _link_list.add(src_model, src_port_name, dst_model, dst_port_name);
     }
 
-    const sss::Models < Time >& children() const
-    { return _child_list; }
-
     void dispatch_events(common::Bag < Time > bag,
                          typename Time::type t)
     {
@@ -124,9 +116,7 @@ public:
     }
 
 private:
-    common::Links < Time >        _link_list;
-    sss::Models < Time >          _child_list;
-    common::Coordinator < Time >* _coordinator;
+    common::Links < Time > _link_list;
 };
 
 } } // namespace paradevs sss