Parcourir la source

Add context and save/restore

Eric Ramat il y a 4 ans
Parent
commit
c95f7f6c20

+ 240 - 0
src/artis-star/common/Any.hpp

@@ -0,0 +1,240 @@
+/**
+ * @file Any.hpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 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_ANY_HPP
+#define COMMON_ANY_HPP
+
+#include <artis-star/common/Value.hpp>
+
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+namespace artis {
+    namespace common {
+
+        class Any {
+        private:
+            struct base {
+                virtual ~base() { }
+
+                virtual base* clone() const = 0;
+            };
+
+            template<typename T, typename V>
+            struct data : base {
+                data(V T::* const& value)
+                        :value_(value) { }
+
+                base* clone() const { return new data<T, V>(*this); }
+
+                V T::* value_;
+            };
+
+            base* ptr_;
+
+        public:
+            Any()
+                    :ptr_(nullptr) { }
+
+            template<typename T, typename V>
+            Any(V T::* const& value)
+                    : ptr_(new data<T, V>(value)) { }
+
+            Any(Any const& other)
+                    :ptr_(other.ptr_ ? other.ptr_->clone() : nullptr) { }
+
+            virtual ~Any() { if (ptr_) delete ptr_; }
+
+            void operator=(Any const& other) { Any(other).swap(*this); }
+
+            void swap(Any& other) { std::swap(ptr_, other.ptr_); }
+
+            template<typename T, typename V>
+            V T::* get() const { return dynamic_cast < data<T, V>* >(ptr_)->value_; }
+
+            bool is_null() const { return ptr_ == nullptr; }
+
+            template<typename T, typename V>
+            void put(T* o, const V& value)
+            {
+                V T::* p = dynamic_cast <data<T, V>* >(ptr_)->value_;
+                o->*(p) = value;
+            }
+
+            template<typename T>
+            void restore(T* o, const common::Value& value)
+            {
+                if (value.is_type<double>()) {
+                    double v;
+
+                    value(v);
+                    put(o, v);
+                } else if (value.is_type<int>()) {
+                    int v;
+
+                    value(v);
+                    put(o, v);
+                } else if (value.is_type<bool>()) {
+                    bool v;
+
+                    value(v);
+                    put(o, v);
+                } else if (value.is_type<std::vector<double> >()) {
+                    std::vector<double> v;
+
+                    value(v);
+                    put(o, v);
+                } else if (value.is_type<std::vector<int> >()) {
+                    std::vector<int> v;
+
+                    value(v);
+                    put(o, v);
+                } else if (value.is_type<std::vector<bool> >()) {
+                    std::vector<bool> v;
+
+                    value(v);
+                    put(o, v);
+                } else {
+                    assert(false);
+                }
+            }
+
+            template<typename T>
+            common::Value save(const T* o) const
+            {
+                if (ptr_) {
+                    data<T, double>* q_double =
+                            dynamic_cast < data<T, double>* >(ptr_);
+
+                    if (q_double) {
+                        return common::Value(o->*(q_double->value_));
+                    } else {
+                        data<T, int>* q_int =
+                                dynamic_cast < data<T, int>* >(ptr_);
+
+                        if (q_int) {
+                            return common::Value(o->*(q_int->value_));
+                        } else {
+                            data<T, bool>* q_bool =
+                                    dynamic_cast < data<T, bool>* >(ptr_);
+
+                            if (q_bool) {
+                                return common::Value(o->*(q_bool->value_));
+                            } else {
+                                data<T, std::vector<double> >* q_double_v =
+                                        dynamic_cast < data<T, std::vector<
+                                                double> >* >(ptr_);
+
+                                if (q_double_v) {
+                                    return common::Value(o->*(q_double_v->value_));
+                                } else {
+                                    data<T, std::vector<int> >* q_int_v =
+                                            dynamic_cast < data<T, std::vector<
+                                                    int> >* >(ptr_);
+
+                                    if (q_int_v) {
+                                        return common::Value(o->*(q_int_v->value_));
+                                    } else {
+                                        data<T, std::vector<bool> >* q_bool_v =
+                                                dynamic_cast < data<T, std::vector<
+                                                        bool> >* >(ptr_);
+
+                                        if (q_bool_v) {
+                                            return common::Value(
+                                                    o->*(q_bool_v->value_));
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                assert(false);
+                return common::Value();
+            }
+
+            template<typename T>
+            std::string to_string(const T* o) const
+            {
+                if (ptr_) {
+                    data<T, double>* q_double =
+                            dynamic_cast < data<T, double>* >(ptr_);
+
+                    if (q_double) {
+                        return std::to_string(o->*(q_double->value_));
+                    } else {
+                        data<T, int>* q_int =
+                                dynamic_cast < data<T, int>* >(ptr_);
+
+                        if (q_int) {
+                            return std::to_string(o->*(q_int->value_));
+                        } else {
+                            data<T, bool>* q_bool =
+                                    dynamic_cast < data<T, bool>* >(ptr_);
+
+                            if (q_bool) {
+                                return o->*(q_bool->value_) ? "true" : "false";
+                            } else {
+                                data<T, std::vector<double> >* q_double_v =
+                                        dynamic_cast < data<T, std::vector<
+                                                double> >* >(ptr_);
+
+                                if (q_double_v) {
+                                    return "";
+                                } else {
+                                    data<T, std::vector<int> >* q_int_v =
+                                            dynamic_cast < data<T, std::vector<
+                                                    int> >* >(ptr_);
+
+                                    if (q_int_v) {
+                                        return "";
+                                    } else {
+                                        data<T, std::vector<bool> >* q_bool_v =
+                                                dynamic_cast < data<T, std::vector<
+                                                        bool> >* >(ptr_);
+
+                                        if (q_bool_v) {
+                                            return "";
+                                        } else {
+                                            return "NA";
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    return "NA";
+                }
+            }
+        };
+
+    }
+}
+
+#endif

+ 5 - 3
src/artis-star/common/CMakeLists.txt

@@ -6,12 +6,14 @@ INCLUDE_DIRECTORIES(
 LINK_DIRECTORIES(
         ${Boost_LIBRARY_DIRS})
 
-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)
+SET(COMMON_HPP Any.hpp Bag.hpp Coordinator.hpp ExternalEvent.hpp
+        GraphManager.hpp InternalEvent.hpp Links.hpp Macro.hpp Model.hpp
+        Node.hpp Parameters.hpp RootCoordinator.hpp Scheduler.hpp Simulator.hpp States.hpp
+        Value.hpp)
 
 INSTALL(FILES ${COMMON_HPP} DESTINATION ${ARTIS_INCLUDE_DIRS}/common)
 
+ADD_SUBDIRECTORY(context)
 ADD_SUBDIRECTORY(observer)
 ADD_SUBDIRECTORY(scheduler)
 ADD_SUBDIRECTORY(time)

+ 10 - 0
src/artis-star/common/Coordinator.hpp

@@ -52,6 +52,8 @@ namespace artis {
 
             virtual ~Coordinator() { }
 
+            virtual GraphManager<Time>& get_graph_manager() = 0;
+
             virtual const GraphManager<Time>& get_graph_manager() const = 0;
 
             virtual const Model<Time>* get_submodel(unsigned int index) const
@@ -116,6 +118,14 @@ namespace artis {
                 }
             }
 
+            void restore(const common::context::State<Time>& state) {
+                get_graph_manager().restore(state);
+            }
+
+            void save(common::context::State<Time>& state) const {
+                get_graph_manager().save(state);
+            }
+
             virtual std::string to_string(int /* level */) const
             {
                 std::ostringstream ss;

+ 14 - 0
src/artis-star/common/GraphManager.hpp

@@ -72,6 +72,20 @@ namespace artis {
 
             common::Coordinator<Time>* get_coordinator() const { return _coordinator; }
 
+            void restore(const common::context::State<Time>& state)
+            {
+                for(auto& child: _children) {
+                    child->restore(state);
+                }
+            }
+
+            void save(common::context::State<Time>& state) const
+            {
+                for(const auto& child: _children) {
+                    child->save(state);
+                }
+            }
+
         protected:
             common::Models<Time> _children;
             common::ModelMap<Time> _child_map;

+ 63 - 0
src/artis-star/common/Macro.hpp

@@ -0,0 +1,63 @@
+/**
+ * @file Macro.hpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 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_MACRO_HPP
+#define COMMON_MACRO_HPP
+
+#define DOUBLEESCAPE(a) #a
+#define ESCAPEQUOTE(a) DOUBLEESCAPE(a)
+
+#define ITEM(index, var) { index,                                       \
+                std::string(ESCAPEQUOTE(index)),                        \
+                var }
+#define UNWRAP_ITEM(...) ITEM __VA_ARGS__
+#define LIST_16(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15, L16) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10), UNWRAP_ITEM(L11), UNWRAP_ITEM(L12), UNWRAP_ITEM(L13), UNWRAP_ITEM(L14), UNWRAP_ITEM(L15), UNWRAP_ITEM(L16) }
+#define LIST_15(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10), UNWRAP_ITEM(L11), UNWRAP_ITEM(L12), UNWRAP_ITEM(L13), UNWRAP_ITEM(L14), UNWRAP_ITEM(L15) }
+#define LIST_14(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10), UNWRAP_ITEM(L11), UNWRAP_ITEM(L12), UNWRAP_ITEM(L13), UNWRAP_ITEM(L14) }
+#define LIST_13(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10), UNWRAP_ITEM(L11), UNWRAP_ITEM(L12), UNWRAP_ITEM(L13) }
+#define LIST_12(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10), UNWRAP_ITEM(L11), UNWRAP_ITEM(L12) }
+#define LIST_11(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10), UNWRAP_ITEM(L11) }
+#define LIST_10(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10) }
+#define LIST_9(L1, L2, L3, L4, L5, L6, L7, L8, L9) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9) }
+#define LIST_8(L1, L2, L3, L4, L5, L6, L7, L8) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8) }
+#define LIST_7(L1, L2, L3, L4, L5, L6, L7) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7) }
+#define LIST_6(L1, L2, L3, L4, L5, L6) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6) }
+#define LIST_5(L1, L2, L3, L4, L5) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5) }
+#define LIST_4(L1, L2, L3, L4) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4) }
+#define LIST_3(L1, L2, L3) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3) }
+#define LIST_2(L1, L2) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2) }
+#define LIST_1(L1) { UNWRAP_ITEM(L1) }
+
+#define EXPAND(X) X
+#define PP_NARG(...) EXPAND( PP_NARG_(__VA_ARGS__, PP_RSEQ_N()) )
+#define PP_NARG_(...) EXPAND( PP_ARG_N(__VA_ARGS__) )
+#define PP_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10_, _11, _12, _13, _14, _15, _16, N, ...) N
+#define PP_RSEQ_N() 16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+#define LIST_(N) LIST_##N
+#define LIST_EVAL(N) LIST_(N)
+#define UNWRAP2(...) EXPAND( LIST_EVAL(EXPAND( PP_NARG(__VA_ARGS__) ))(__VA_ARGS__) )
+
+#endif

+ 9 - 0
src/artis-star/common/Model.hpp

@@ -32,6 +32,7 @@
 #include <artis-star/common/InternalEvent.hpp>
 #include <artis-star/common/Scheduler.hpp>
 #include <artis-star/common/Value.hpp>
+#include <artis-star/common/context/State.hpp>
 
 #include <algorithm>
 #include <cassert>
@@ -194,6 +195,10 @@ namespace artis {
                 return (_parent != nullptr ? _parent->path() : "") + ":" + get_name();
             }
 
+            virtual void restore(const common::context::State<Time>& state) = 0;
+
+            virtual void save(common::context::State<Time>& state) const = 0;
+
             void set_parent(Model<Time>* parent) { _parent = parent; }
 
             virtual std::string to_string(int /* level */) const = 0;
@@ -233,6 +238,10 @@ namespace artis {
 
             typename Time::type get_tn() const { return _tn; }
 
+            void set_tl(const typename Time::type& time) { _tl = time; }
+
+            void set_tn(const typename Time::type& time) { _tn = time; }
+
             // devs methods
             virtual common::Value observe(const typename Time::type& t,
                     unsigned int index) const = 0;

+ 19 - 11
src/artis-star/common/RootCoordinator.hpp

@@ -27,6 +27,7 @@
 #ifndef COMMON_ROOT_COORDINATOR
 #define COMMON_ROOT_COORDINATOR
 
+#include <artis-star/common/context/Context.hpp>
 #include <artis-star/common/observer/Observer.hpp>
 #include <artis-star/common/observer/View.hpp>
 #include <artis-star/common/Parameters.hpp>
@@ -40,30 +41,26 @@ namespace artis {
         template<class Time, class Coordinator>
         class RootCoordinator {
         public :
-            RootCoordinator(
-                    const typename Time::type& t_start,
-                    const typename Time::type& t_max,
+            RootCoordinator(const common::context::Context<Time>& context,
                     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), _observer(&_root),
-                    _t_max(t_max), _tn(t_start) { }
+                    _t_max(context.end()), _tn(context.begin()) { }
 
-            RootCoordinator(const typename Time::type& t_start,
-                    const typename Time::type& t_max,
+            RootCoordinator(const common::context::Context<Time>& context,
                     const std::string& root_name,
                     const typename Coordinator::parameters_type& parameters)
                     :
                     _root(root_name, parameters, NoParameters()), _observer(&_root),
-                    _t_max(t_max), _tn(t_start) { }
+                    _t_max(context.end()), _tn(context.begin()) { }
 
-            RootCoordinator(const typename Time::type& t_start,
-                    const typename Time::type& t_max,
+            RootCoordinator(const common::context::Context<Time>& context,
                     const std::string& root_name)
                     :
                     _root(root_name, NoParameters(), NoParameters()), _observer(&_root),
-                    _t_max(t_max), _tn(t_start) { }
+                    _t_max(context.end()), _tn(context.begin()) { }
 
             virtual ~RootCoordinator() { }
 
@@ -71,10 +68,14 @@ namespace artis {
 
             const observer::Observer<Time>& observer() const { return _observer; }
 
-            void run()
+            void run(const common::context::Context<Time>& context)
             {
                 _observer.init();
                 _tn = _root.start(_tn);
+                if (context.valid()) {
+// TODO
+//                    _root->restore(context.state());
+                }
                 while (_tn <= _t_max) {
                     _root.output(_tn);
                     _tn = _root.transition(_tn);
@@ -82,6 +83,13 @@ namespace artis {
                 }
             }
 
+            void save(common::context::Context<Time>& context) const
+            {
+// TODO
+//                _root->save(context.state());
+                context.saved();
+            }
+
             std::string to_string() const
             {
                 std::ostringstream ss;

+ 127 - 0
src/artis-star/common/States.hpp

@@ -0,0 +1,127 @@
+/**
+ * @file States.hpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 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_STATES_HPP
+#define COMMON_STATES_HPP
+
+#include <artis-star/common/context/State.hpp>
+#include <artis-star/common/Any.hpp>
+#include <artis-star/common/Macro.hpp>
+
+#include <vector>
+
+namespace artis {
+    namespace common {
+
+        template<typename Time, typename Dyn>
+        class States {
+            template<typename W>
+            struct element {
+                unsigned int index;
+                const std::string name;
+                W Dyn::* var;
+
+                element(unsigned int index, const std::string& name, W Dyn::* var)
+                        :
+                        index(index), name(name), var(var) { }
+            };
+
+        public:
+            States() { }
+
+            virtual ~States() { }
+
+            common::Any& get(unsigned int index) { return states.at(index); }
+
+            const common::Any& get(unsigned int index) const { return states.at(index); }
+
+            unsigned int state_number() const { return states.size(); }
+
+            template<typename W>
+            void S_(std::initializer_list<element<W> > list)
+            {
+                for (typename std::initializer_list<element<W> >::iterator it =
+                        list.begin(); it != list.end(); ++it) {
+                    if (states.size() <= it->index) {
+                        states.resize(it->index + 1, common::Any());
+                        state_names.resize(it->index + 1, std::string());
+                    }
+                    states[it->index] = it->var;
+                    state_names[it->index] = it->name;
+                }
+            }
+
+            virtual void restore(Dyn* model, const common::context::State<Time>& state)
+            {
+                unsigned int index = 0;
+
+                for (typename std::vector<common::Any>::iterator it = states.begin();
+                     it != states.end(); ++it) {
+                    if (not it->is_null()) {
+                        it->restore<Dyn>(model, state.get_state(index));
+                    }
+                    ++index;
+                }
+            }
+
+            virtual void save(const Dyn* model, common::context::State<Time>& state) const
+            {
+                unsigned int index = 0;
+
+                for (typename std::vector<common::Any>::const_iterator it =
+                        states.begin(); it != states.end(); ++it) {
+                    if (not it->is_null()) {
+                        state.add_state(index, it->save<Dyn>(model));
+                    }
+                    ++index;
+                }
+            }
+
+            template<typename W>
+            void state_(unsigned int index, const std::string& name, W Dyn::* var)
+            {
+                if (states.size() <= index) {
+                    states.resize(index + 1, common::Any());
+                    state_names.resize(index + 1, std::string());
+                }
+                states[index] = common::Any(var);
+                state_names[index] = name;
+            }
+
+        private:
+            std::vector<common::Any> states;
+            std::vector<std::string> state_names;
+        };
+
+#define State(index, var)                                    \
+        state_(index, std::string(ESCAPEQUOTE(index)), var)
+
+#define States(W, L) S_< W >(UNWRAP2 L)
+
+    }
+}
+
+#endif

+ 12 - 0
src/artis-star/common/context/CMakeLists.txt

@@ -0,0 +1,12 @@
+INCLUDE_DIRECTORIES(
+        ${ARTIS_BINARY_DIR}/src
+        ${ARTIS_SOURCE_DIR}/src
+        ${Boost_INCLUDE_DIRS})
+
+LINK_DIRECTORIES(
+        ${Boost_LIBRARY_DIRS})
+
+SET(COMMON_CONTEXT_HPP Context.hpp State.hpp StateValues.hpp)
+
+INSTALL(FILES ${COMMON_CONTEXT_HPP} DESTINATION
+        ${ARTIS_INCLUDE_DIRS}/common/context)

+ 106 - 0
src/artis-star/common/context/Context.hpp

@@ -0,0 +1,106 @@
+/**
+ * @file artis-star/common/context/Context.hpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 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_CONTEXT_CONTEXT_HPP
+#define COMMON_CONTEXT_CONTEXT_HPP
+
+#include <artis-star/common/context/State.hpp>
+
+#include <boost/serialization/serialization.hpp>
+
+namespace artis {
+    namespace common {
+        namespace context {
+
+            template<class Time>
+            class Context {
+            public:
+                Context()
+                        :_begin(-1), _end(-1), _valid(false) { }
+
+                Context(const typename Time::type& begin, const typename Time::type& end)
+                        :_begin(begin), _end(end), _valid(false) { }
+
+                virtual ~Context() { }
+
+                const typename Time::type& begin() const { return _begin; }
+
+                void begin(const typename Time::type& begin) { _begin = begin; }
+
+                const typename Time::type& end() const { return _end; }
+
+                void end(const typename Time::type& end) { _end = end; }
+
+                const Context& operator=(const Context& context)
+                {
+                    _begin = context._begin;
+                    _end = context._end;
+                    _valid = context._valid;
+                    _state = context._state;
+                    return *this;
+                }
+
+                void saved() { _valid = true; }
+
+                const State<Time>& state() const { return _state; }
+
+                State<Time>& state() { return _state; }
+
+                std::string to_string() const
+                {
+                    return "begin: " + std::to_string(_begin) +
+                            "; end: " + std::to_string(_end) +
+                            "; valid: " + (_valid ? "true" : "false") +
+                            "; state: " + _state.to_string();
+                }
+
+                bool valid() const { return _valid; }
+
+            private:
+                friend class boost::serialization::access;
+
+                template<class Archive>
+                void serialize(Archive& ar, const unsigned int version)
+                {
+                    (void) version;
+
+                    ar & _begin;
+                    ar & _end;
+                    ar & _state;
+                    ar & _valid;
+                }
+
+                typename Time::type _begin;
+                typename Time::type  _end;
+                State<Time> _state;
+                bool _valid;
+            };
+
+        }
+    }
+}
+
+#endif

+ 138 - 0
src/artis-star/common/context/State.hpp

@@ -0,0 +1,138 @@
+/**
+ * @file artis-star/common/context/State.hpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 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_CONTEXT_STATE_HPP
+#define COMMON_CONTEXT_STATE_HPP
+
+#include <artis-star/common/context/StateValues.hpp>
+
+#include <map>
+
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/map.hpp>
+#include <boost/serialization/vector.hpp>
+
+namespace artis {
+    namespace common {
+        namespace context {
+
+            template<class Time>
+            class State {
+                typedef std::map<unsigned int, State<Time> > Substates;
+
+            public:
+                State()
+                        :_last_time(-1), _next_time(-1) { }
+
+                virtual ~State() { }
+
+                void add_external(unsigned int variable_key, const Value& value)
+                {
+                    _values.add_external(variable_key, value);
+                }
+
+                void add_internal(unsigned int variable_key, const Value& value)
+                {
+                    _values.add_internal(variable_key, value);
+                }
+
+                void add_state(unsigned int variable_key, const Value& value)
+                {
+                    _values.add_state(variable_key, value);
+                }
+
+                void add_substate(unsigned int model_key, State& state)
+                {
+                    _substates.insert(std::make_pair(model_key, state));
+                }
+
+                const Value& get_external(unsigned int variable_key) const
+                {
+                    return _values.get_external(variable_key);
+                }
+
+                const Value& get_internal(unsigned int variable_key) const
+                {
+                    return _values.get_internal(variable_key);
+                }
+
+                const Value& get_state(unsigned int variable_key) const
+                {
+                    return _values.get_state(variable_key);
+                }
+
+                const State<Time>& get_substate(unsigned int model_key) const
+                {
+                    return _substates.find(model_key)->second;
+                }
+
+                typename Time::type last_time() const { return _last_time; }
+
+                void last_time(typename Time::type t) { _last_time = t; }
+
+                typename Time::type next_time() const { return _next_time; }
+
+                void next_time(typename Time::type t) { _next_time = t; }
+
+                std::string to_string() const
+                {
+                    std::string str = "last_time: " + std::to_string(_last_time) +
+                            "; next_time: " + std::to_string(_next_time) +
+                            "; values: " + _values.to_string() + "; sub_states: [ ";
+
+                    for (typename Substates::const_iterator it = _substates.begin();
+                         it != _substates.end(); ++it) {
+                        str += it->second.to_string() + " ";
+                    }
+                    str += "]";
+                    return str;
+                }
+
+            private:
+                friend class boost::serialization::access;
+
+                template<class Archive>
+                void serialize(Archive& ar, const unsigned int version)
+                {
+                    (void) version;
+
+                    ar & _values;
+                    ar & _substates;
+                    ar & _last_time;
+                    ar & _next_time;
+                }
+
+                StateValues _values;
+                Substates _substates;
+                typename Time::type _last_time;
+                typename Time::type _next_time;
+            };
+
+        }
+    }
+}
+
+#endif

+ 136 - 0
src/artis-star/common/context/StateValues.hpp

@@ -0,0 +1,136 @@
+/**
+ * @file artis-star/common/context/StateValues.hpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 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_CONTEXT_STATE_VALUES_HPP
+#define COMMON_CONTEXT_STATE_VALUES_HPP
+
+#include <artis-star/common/Value.hpp>
+
+#include <map>
+
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/map.hpp>
+
+namespace artis {
+    namespace common {
+        namespace context {
+
+            class StateValues {
+            public:
+                StateValues() { }
+
+                virtual ~StateValues() { }
+
+                void add_external(unsigned int key, const Value& value) { _externals[key] = value; }
+
+                void add_internal(unsigned int key, const Value& value) { _internals[key] = value; }
+
+                void add_state(unsigned int key, const Value& value) { _states[key] = value; }
+
+                const Value& get_external(unsigned int key) const
+                {
+                    std::map<unsigned int, Value>::const_iterator it =
+                            _externals.find(key);
+
+                    if (it != _externals.end()) {
+                        return it->second;
+                    } else {
+                        assert(false);
+                        return it->second;
+                    }
+                }
+
+                const Value& get_internal(unsigned int key) const
+                {
+                    std::map<unsigned int, Value>::const_iterator it =
+                            _internals.find(key);
+
+                    if (it != _internals.end()) {
+                        return it->second;
+                    } else {
+                        assert(false);
+                        return it->second;
+                    }
+                }
+
+                const Value& get_state(unsigned int key) const
+                {
+                    std::map<unsigned int, Value>::const_iterator it =
+                            _states.find(key);
+
+                    if (it != _states.end()) {
+                        return it->second;
+                    } else {
+                        assert(false);
+                        return it->second;
+                    }
+                }
+
+                std::string to_string() const
+                {
+                    std::string str = "externals: [ ";
+
+                    for (std::map<unsigned int, Value>::const_iterator it =
+                            _externals.begin(); it != _externals.end(); ++it) {
+                        str += it->second.to_string() + " ";
+                    }
+                    str += "]; internals: [ ";
+                    for (std::map<unsigned int, Value>::const_iterator it =
+                            _internals.begin(); it != _internals.end(); ++it) {
+                        str += it->second.to_string() + " ";
+                    }
+                    str += "]; states: [ ";
+                    for (std::map<unsigned int, Value>::const_iterator it =
+                            _states.begin(); it != _states.end(); ++it) {
+                        str += it->second.to_string() + " ";
+                    }
+                    str += "]";
+                    return str;
+                }
+
+            private:
+                friend class boost::serialization::access;
+
+                template<class Archive>
+                void serialize(Archive& ar, const unsigned int version)
+                {
+                    (void) version;
+
+                    ar & _externals;
+                    ar & _internals;
+                    ar & _states;
+                }
+
+                std::map<unsigned int, Value> _externals;
+                std::map<unsigned int, Value> _internals;
+                std::map<unsigned int, Value> _states;
+            };
+
+        }
+    }
+}
+
+#endif

+ 26 - 52
src/artis-star/common/observer/View.hpp

@@ -57,19 +57,6 @@ namespace artis {
 
             void attachModel(const artis::common::Model<Time>* m) { _model = m; }
 
-            double begin() const
-            {
-                double t = common::DoubleTime::infinity;
-
-                // for (SelectorValues::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();
@@ -90,45 +77,32 @@ namespace artis {
                 return v;
             }
 
-            double end() const
-            {
-                double t = 0;
-
-                // for (SelectorValues::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& selector_name, const std::string& variable_name) const
-            {
-                SelectorValues::const_iterator it = _values.find(selector_name);
-
-                if (it != _values.end()) {
-                    VariableValues::const_iterator itp = it->second.find(variable_name);
-
-                    if (itp != it->second.end()) {
-                        Values::const_iterator itv = itp->second.begin();
-
-                        while (itv != itp->second.end() and itv->first < t) {
-                            ++itv;
-                        }
-                        if (itv != itp->second.end()) {
-                            // TODO: to improve
-                            return boost::lexical_cast<double>(itv->second);
-                        } else {
-                            return 0;
-                        }
-                    } else {
-                        return 0;
-                    }
-                }
-                return 0;
-            }
+//            double
+//            get(double t, const std::string& selector_name, const std::string& variable_name) const
+//            {
+//                SelectorValues::const_iterator it = _values.find(selector_name);
+//
+//                if (it != _values.end()) {
+//                    VariableValues::const_iterator itp = it->second.find(variable_name);
+//
+//                    if (itp != it->second.end()) {
+//                        Values::const_iterator itv = itp->second.begin();
+//
+//                        while (itv != itp->second.end() and itv->first < t) {
+//                            ++itv;
+//                        }
+//                        if (itv != itp->second.end()) {
+//                            // TODO: to improve
+//                            return boost::lexical_cast<double>(itv->second);
+//                        } else {
+//                            return 0;
+//                        }
+//                    } else {
+//                        return 0;
+//                    }
+//                }
+//                return 0;
+//            }
 
             const Values&
             get(const std::string& selector_name, const std::string& variable_name) const

+ 2 - 0
src/artis-star/kernel/dtss/Coordinator.hpp

@@ -64,6 +64,8 @@ namespace artis {
 
             virtual ~Coordinator() { }
 
+            common::GraphManager<Time>& get_graph_manager() { return _graph_manager; }
+
             const common::GraphManager<Time>& get_graph_manager() const { return _graph_manager; }
 
             typename Time::type start(const typename Time::type& t)

+ 18 - 2
src/artis-star/kernel/dtss/Dynamics.hpp

@@ -30,6 +30,7 @@
 #include <artis-star/common/Bag.hpp>
 #include <artis-star/common/ExternalEvent.hpp>
 #include <artis-star/common/Parameters.hpp>
+#include <artis-star/common/States.hpp>
 #include <artis-star/kernel/dtss/Simulator.hpp>
 
 namespace artis {
@@ -37,7 +38,7 @@ namespace artis {
 
         template<class Time, class Dyn,
                 class Parameters = common::NoParameters>
-        class Dynamics {
+        class Dynamics : public common::States<Time, Dyn> {
             typedef dtss::Simulator<Time, Dyn, Parameters> Simulator;
 
         public:
@@ -50,7 +51,8 @@ namespace artis {
             virtual void transition(const common::Bag<Time>& /* x */,
                     typename Time::type /* t */) { }
 
-            virtual typename Time::type start(typename Time::type/* time */) { return Time::infinity; }
+            virtual typename Time::type
+            start(typename Time::type/* time */) { return Time::infinity; }
 
             virtual common::Bag<Time> lambda(
                     typename Time::type /* time */) const { return common::Bag<Time>(); }
@@ -86,6 +88,20 @@ namespace artis {
                 }
             }
 
+            void restore(const common::context::State<Time>& state)
+            {
+                common::States<Time, Dyn>::restore(static_cast<Dyn*>(this), state);
+                _simulator->set_tn(state.last_time());
+                _simulator->set_tl(state.next_time());
+            }
+
+            void save(common::context::State<Time>& state) const
+            {
+                common::States<Time, Dyn>::save(static_cast<const Dyn*>(this), state);
+                state.last_time(_simulator->get_tn());
+                state.next_time(_simulator->get_tl());
+            }
+
         private:
             std::string _name;
             Simulator* _simulator;

+ 10 - 0
src/artis-star/kernel/dtss/Simulator.hpp

@@ -76,6 +76,16 @@ namespace artis {
 
             ~Simulator() { }
 
+            virtual void restore(const common::context::State<Time>& state)
+            {
+                _dynamics.restore(state);
+            }
+
+            virtual void save(common::context::State<Time>& state) const
+            {
+                _dynamics.save(state);
+            }
+
             typename Time::type start(const typename Time::type& t)
             {
 

+ 2 - 0
src/artis-star/kernel/pdevs/Coordinator.hpp

@@ -57,6 +57,8 @@ namespace artis {
 
             virtual ~Coordinator() { }
 
+            common::GraphManager<Time>& get_graph_manager() { return _graph_manager; }
+
             const common::GraphManager<Time>& get_graph_manager() const { return _graph_manager; }
 
             virtual std::string to_string(int level) const

+ 28 - 6
src/artis-star/kernel/pdevs/Dynamics.hpp

@@ -30,6 +30,7 @@
 #include <artis-star/common/Bag.hpp>
 #include <artis-star/common/ExternalEvent.hpp>
 #include <artis-star/common/Parameters.hpp>
+#include <artis-star/common/States.hpp>
 #include <artis-star/kernel/pdevs/Simulator.hpp>
 
 #include <string>
@@ -39,7 +40,7 @@ namespace artis {
     namespace pdevs {
 
         template<class Time, class Dyn, class Parameters = common::NoParameters>
-        class Dynamics {
+        class Dynamics : public common::States<Time, Dyn> {
             typedef pdevs::Simulator<Time, Dyn, Parameters> Simulator;
 
         public:
@@ -64,11 +65,14 @@ namespace artis {
             virtual void dext(typename Time::type /* t */, typename Time::type /* e */,
                     const common::Bag<Time>& /* bag */) { }
 
-            virtual typename Time::type start(typename Time::type /* time */) { return Time::infinity; }
+            virtual typename Time::type
+            start(typename Time::type /* time */) { return Time::infinity; }
 
-            virtual typename Time::type ta(typename Time::type /* time */) const { return Time::infinity; }
+            virtual typename Time::type
+            ta(typename Time::type /* time */) const { return Time::infinity; }
 
-            virtual common::Bag<Time> lambda(typename Time::type /* time */) const { return common::Bag<Time>(); }
+            virtual common::Bag<Time>
+            lambda(typename Time::type /* time */) const { return common::Bag<Time>(); }
 
             virtual common::Value observe(const typename Time::type& /* t */,
                     unsigned int /* index */) const { return common::Value(); }
@@ -84,7 +88,9 @@ namespace artis {
 
             void input_ports(std::initializer_list<common::Port> list)
             {
-                for (typename std::initializer_list<common::Port>::iterator it = list.begin(); it != list.end(); ++it) {
+                for (typename std::initializer_list<common::Port>::iterator it = list.begin();
+                     it != list.end();
+                     ++it) {
                     _simulator->add_in_port(*it);
                 }
             }
@@ -96,7 +102,9 @@ namespace artis {
 
             void observables(std::initializer_list<Observable> list)
             {
-                for (typename std::initializer_list<Observable>::iterator it = list.begin(); it != list.end(); ++it) {
+                for (typename std::initializer_list<Observable>::iterator it = list.begin();
+                     it != list.end();
+                     ++it) {
                     _observables[it->index] = it->name;
                 }
             }
@@ -123,6 +131,20 @@ namespace artis {
                 }
             }
 
+            void restore(const common::context::State<Time>& state)
+            {
+                common::States<Time, Dyn>::restore(static_cast<Dyn*>(this), state);
+                _simulator->set_tn(state.last_time());
+                _simulator->set_tl(state.next_time());
+            }
+
+            void save(common::context::State<Time>& state) const
+            {
+                common::States<Time, Dyn>::save(static_cast<const Dyn*>(this), state);
+                state.last_time(_simulator->get_tn());
+                state.next_time(_simulator->get_tl());
+            }
+
         private:
             std::string _name;
             Simulator* _simulator;

+ 10 - 0
src/artis-star/kernel/pdevs/Simulator.hpp

@@ -76,6 +76,16 @@ namespace artis {
 
             ~Simulator() { }
 
+            virtual void restore(const common::context::State<Time>& state)
+            {
+                _dynamics.restore(state);
+            }
+
+            virtual void save(common::context::State<Time>& state) const
+            {
+                _dynamics.save(state);
+            }
+
             virtual std::string to_string(int level) const
             {
                 std::ostringstream ss;

+ 10 - 0
src/artis-star/kernel/pdevs/mpi/ModelProxy.hpp

@@ -60,6 +60,16 @@ namespace artis {
 
                 virtual bool is_atomic() const { return _atomic; }
 
+                virtual void restore(const common::context::State<Time>& state)
+                {
+// TODO
+                }
+
+                virtual void save(common::context::State<Time>& state) const
+                {
+// TODO
+                }
+
                 virtual std::string to_string(int level) const
                 {
                     (void) level;

+ 4 - 9
src/artis-star/kernel/pdevs/qss/Derivative.hpp

@@ -38,11 +38,11 @@ namespace artis {
             class Derivative : public artis::pdevs::Dynamics<Time, Dyn, Parameters> {
             public:
                 enum inputs {
-                    IN = 1
+                    IN
                 };
 
                 enum outputs {
-                    OUT = 1
+                    OUT
                 };
 
                 Derivative(const std::string& name, const Context<Time, Dyn, Parameters>& context)
@@ -80,10 +80,10 @@ namespace artis {
                                 IntegratorData data;
 
                                 event.data()(data);
-                                _inputs[event.port_index()] = data.value;
+                                this->get(event.port_index()).put(dynamic_cast<Dyn*>(this), data.value);
                                 switch (_state) {
                                 case INIT:
-                                    if (_inputs.size() == _input_number) {
+                                    if (_input_number == this->state_number()) {
                                         _output_value = compute();
                                         _state = RESPONSE;
                                     }
@@ -153,10 +153,6 @@ namespace artis {
                     return common::Value();
                 }
 
-                double input(unsigned int index) const {
-                    return _inputs.at(index);
-                }
-
             private:
                 typedef enum {
                     INIT, WAIT, RESPONSE
@@ -164,7 +160,6 @@ namespace artis {
 
                 State _state;
                 unsigned int _input_number;
-                std::map<unsigned int, double> _inputs;
                 double _output_value;
                 double _last_output;
             };

+ 4 - 0
src/artis-star/kernel/sss/Coordinator.hpp

@@ -71,6 +71,10 @@ namespace artis {
 
             virtual ~Coordinator() { }
 
+            common::GraphManager<Time>& get_graph_manager() { return _graph_manager; }
+
+            const common::GraphManager<Time>& get_graph_manager() const { return _graph_manager; }
+
             virtual bool is_atomic() const { return common::Coordinator<Time>::is_atomic(); }
 
             virtual std::string to_string(int level) const { return common::Coordinator<Time>::to_string(level); }

+ 20 - 4
src/artis-star/kernel/sss/Dynamics.hpp

@@ -30,13 +30,14 @@
 #include <artis-star/common/Bag.hpp>
 #include <artis-star/common/ExternalEvent.hpp>
 #include <artis-star/common/Parameters.hpp>
+#include <artis-star/common/States.hpp>
 
 namespace artis {
     namespace sss {
 
         template<class Time,
                 class Parameters = common::NoParameters>
-        class Dynamics {
+        class Dynamics : public common::States<Time, Dyn> {
         public:
             Dynamics(const std::string& name, const Parameters& /* parameters */)
                     :
@@ -47,17 +48,32 @@ namespace artis {
             virtual void transition(const common::Bag<Time>& /* x */,
                     typename Time::type /* t */) { }
 
-            virtual typename Time::type start(typename Time::type/* time */) { return Time::infinity; }
+            virtual typename Time::type
+            start(typename Time::type/* time */) { return Time::infinity; }
 
             common::Bag<Time> lambda(
                     typename Time::type /* time */) const { return common::Bag<Time>(); }
 
             virtual void observation(std::ostream& /* file */) const { }
 
-            virtual void update_buffer(typename Time::type /* time */) { }
-
             const std::string& get_name() const { return _name; }
 
+            void restore(const common::context::State<Time>& state)
+            {
+                common::States<Time, Dyn>::restore(static_cast<Dyn*>(this), state);
+                _simulator->set_tn(state.last_time());
+                _simulator->set_tl(state.next_time());
+            }
+
+            void save(common::context::State<Time>& state) const
+            {
+                common::States<Time, Dyn>::save(static_cast<const Dyn*>(this), state);
+                state.last_time(_simulator->get_tn());
+                state.next_time(_simulator->get_tl());
+            }
+
+            virtual void update_buffer(typename Time::type /* time */) { }
+
         private:
             std::string _name;
         };

+ 10 - 0
src/artis-star/kernel/sss/Simulator.hpp

@@ -59,6 +59,16 @@ namespace artis {
 
             virtual bool is_atomic() const { return common::Simulator<Time>::is_atomic(); }
 
+            virtual void restore(const common::context::State<Time>& state)
+            {
+                _dynamics.restore(state);
+            }
+
+            virtual void save(context::State<Time>& state) const
+            {
+                _dynamics.save(state);
+            }
+
             virtual std::string to_string(int level) const { return common::Simulator<Time>::to_string(level); }
 
             typename Time::type start(const typename Time::type& t)