Преглед на файлове

Add context concept and serialization of simulation

Eric Ramat преди 7 години
родител
ревизия
0808e60f24

+ 1 - 1
src/artis/context/CMakeLists.txt

@@ -3,7 +3,7 @@ INCLUDE_DIRECTORIES(
 
 LINK_DIRECTORIES()
 
-SET(ARTIS_CONTEXT_HPP Context.hpp State.hpp Values.hpp)
+SET(ARTIS_CONTEXT_HPP Context.hpp State.hpp StateValues.hpp Value.hpp)
 
 SET(ARTIS_CONTEXT_CPP)
 

+ 27 - 2
src/artis/context/Context.hpp

@@ -33,10 +33,10 @@ template < typename U >
 class Context
 {
 public:
-    Context()
+    Context() : _begin(-1), _end(-1), _valid(false)
     { }
 
-    Context(double begin, double end) : _begin(begin), _end(end)
+    Context(double begin, double end) : _begin(begin), _end(end), _valid(false)
     { }
 
     virtual ~Context()
@@ -45,15 +45,38 @@ public:
     double begin() const
     { return _begin; }
 
+    void begin(double begin)
+    { _begin = begin; }
+
     double end() const
     { return _end; }
 
+    void end(double end)
+    { _end = end; }
+
+    const Context& operator=(const Context& /* context */)
+    { assert(false); }
+
+    void saved()
+    { _valid = true; }
+
     const State < U >& state() const
     { return _state; }
 
     State < U >& 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;
 
@@ -65,11 +88,13 @@ private:
         ar & _begin;
         ar & _end;
         ar & _state;
+        ar & _valid;
     }
 
     double      _begin;
     double      _end;
     State < U > _state;
+    bool        _valid;
 };
 
 } }

+ 29 - 13
src/artis/context/State.hpp

@@ -23,7 +23,7 @@
 #ifndef __ARTIS_KERNEL_STATE_HPP
 #define __ARTIS_KERNEL_STATE_HPP
 
-#include <artis/context/Values.hpp>
+#include <artis/context/StateValues.hpp>
 
 #include <map>
 
@@ -39,30 +39,32 @@ class State
     typedef std::map < unsigned int, State < U > > Substates;
 
 public:
-    State()
+    State() : _last_time(-1)
     { }
 
     virtual ~State()
     { }
 
-    template < typename T >
-    void add_internal(unsigned int variable_key, T value)
+    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); }
 
-    template < typename T >
-    void add_state(unsigned int variable_key, T 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)); }
 
-    template < typename T >
-    void get_internal(unsigned int variable_key, T& value) const
-    { return _values.get_internal(variable_key, value); }
+    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); }
 
-    template < typename T >
-    void get_state(unsigned int variable_key, T& value) const
-    { return _values.get_state(variable_key, value); }
+    const Value& get_state(unsigned int variable_key) const
+    { return _values.get_state(variable_key); }
 
     const State < U >& get_substate(unsigned int model_key) const
     { return _substates.find(model_key)->second; }
@@ -73,6 +75,19 @@ public:
     void last_time(typename U::type t)
     { _last_time = t; }
 
+    std::string to_string() const
+    {
+        std::string str = "last_time: " + std::to_string(_last_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;
 
@@ -83,9 +98,10 @@ private:
 
         ar & _values;
         ar & _substates;
+        ar & _last_time;
     }
 
-    Values           _values;
+    StateValues      _values;
     Substates        _substates;
     typename U::type _last_time;
 };

+ 131 - 0
src/artis/context/StateValues.hpp

@@ -0,0 +1,131 @@
+/**
+ * @file artis/context/StateValues.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 __ARTIS_KERNEL_STATE_VALUES_HPP
+#define __ARTIS_KERNEL_STATE_VALUES_HPP
+
+#include <artis/context/Value.hpp>
+
+#include <map>
+
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/map.hpp>
+
+namespace artis { 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);
+        }
+    }
+
+    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);
+        }
+    }
+
+    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);
+        }
+    }
+
+    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

+ 147 - 0
src/artis/context/Value.hpp

@@ -0,0 +1,147 @@
+/**
+ * @file artis/context/Value.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 __ARTIS_CONTEXT_VALUE_HPP
+#define __ARTIS_CONTEXT_VALUE_HPP
+
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/array.hpp>
+
+#include <algorithm>
+#include <cstring>
+#include <typeinfo>
+
+namespace artis { namespace context {
+
+class Value
+{
+public:
+    Value() : _content(nullptr), _size(0)
+    { }
+
+    template < typename T >
+    Value(T value) : _content(nullptr), _size(0)
+    { assign(&value, sizeof(T), typeid(T).hash_code()); }
+
+    Value(void* content, size_t size) : _content(nullptr), _size(0)
+    { assign(content, size, typeid(void*).hash_code()); }
+
+    Value(const char* value, unsigned int size) : _content(nullptr), _size(0)
+    { assign(value, size * sizeof(char), typeid(char*).hash_code()); }
+
+    Value(const Value& value) : _content(nullptr), _size(0)
+    {
+        if (value._content) {
+            assign(value._content, value._size, value._type_id);
+        }
+    }
+
+    virtual ~Value()
+    { if (_content) delete[] _content; }
+
+    bool empty() const
+    { return _content == nullptr; }
+
+    template < typename T >
+    void get_content(T& value) const
+    {
+        assert(_type_id == typeid(T).hash_code());
+
+        value = *(T*)(_content);
+    }
+
+    const Value& operator=(const Value& value)
+    {
+        if (_content) delete[] _content;
+        _content = nullptr;
+        _size = 0;
+        if (value._content) {
+            assign(value._content, value._size, value._type_id);
+        }
+        return *this;
+    }
+
+    std::string to_string() const
+    {
+        if (is_double()) {
+            double v;
+
+            get_content(v);
+            return std::to_string(v);
+        } else if (is_int()) {
+            int v;
+
+            get_content(v);
+            return std::to_string(v);
+        } else if (is_bool()) {
+            bool v;
+
+            get_content(v);
+            return v ? "true" : "false";
+        } else {
+            assert(false);
+        }
+    }
+
+    bool is_bool() const
+    { return _type_id == typeid(bool).hash_code(); }
+
+    bool is_int() const
+    { return _type_id == typeid(int).hash_code(); }
+
+    bool is_double() const
+    { return _type_id == typeid(double).hash_code(); }
+
+private:
+    void assign(const void* content, size_t size, size_t type_id)
+    {
+        _content = new char[size < 16 ? 16 : size];
+        std::memcpy(_content, content, size);
+        _size = size;
+        _type_id = type_id;
+
+    }
+
+    friend class boost::serialization::access;
+
+    template < class Archive >
+    void serialize(Archive & ar, const unsigned int version)
+    {
+        (void) version;
+
+        ar & _size;
+        if (Archive::is_loading::value) {
+            assert(_content == nullptr);
+            _content = new char[_size];
+        }
+        ar & boost::serialization::make_array < char >(_content, _size);
+        ar & _type_id;
+    }
+
+    char*  _content;
+    size_t _size;
+    size_t _type_id;
+};
+
+} }
+
+#endif

+ 0 - 96
src/artis/context/Values.hpp

@@ -1,96 +0,0 @@
-/**
- * @file artis/context/Values.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 __ARTIS_KERNEL_VALUES_HPP
-#define __ARTIS_KERNEL_VALUES_HPP
-
-#include <artis/kernel/Value.hpp>
-
-#include <map>
-
-#include <boost/serialization/serialization.hpp>
-#include <boost/serialization/map.hpp>
-
-namespace artis { namespace context {
-
-class Values
-{
-public:
-    Values()
-    { }
-
-    virtual ~Values()
-    { }
-
-    template < typename T >
-    void add_internal(unsigned int key, T value)
-    { _internals[key] = kernel::Value(value); }
-
-    template < typename T >
-    void add_state(unsigned int key, T value)
-    { _states[key] = kernel::Value(value); }
-
-    template < typename T >
-    void get_internal(unsigned int key, T& value) const
-    {
-        std::map < unsigned int, kernel::Value >::const_iterator it =
-            _internals.find(key);
-
-        if (it != _internals.end()) {
-            it->second.get_content(value);
-        } else {
-            assert(false);
-        }
-    }
-
-    template < typename T >
-    void get_state(unsigned int key, T& value) const
-    {
-        std::map < unsigned int, kernel::Value >::const_iterator it =
-            _states.find(key);
-
-        if (it != _states.end()) {
-            it->second.get_content(value);
-        } else {
-            assert(false);
-        }
-    }
-
-private:
-    friend class boost::serialization::access;
-
-    template < class Archive >
-    void serialize(Archive & ar, const unsigned int version)
-    {
-        (void) version;
-
-        ar & _internals;
-        ar & _states;
-    }
-
-    std::map < unsigned int, kernel::Value > _internals;
-    std::map < unsigned int, kernel::Value > _states;
-};
-
-} }
-
-#endif

+ 23 - 21
src/artis/kernel/AbstractAtomicModel.hpp

@@ -37,9 +37,9 @@ namespace artis { namespace kernel {
 
 template < typename T, typename U, typename V >
 class AbstractAtomicModel : public AbstractModel < U, V >,
-                            public States < T, U >,
-                            public Internals < T, U >,
-                            public Externals < T, U >
+                            public States < T, U, V >,
+                            public Internals < T, U, V >,
+                            public Externals < T, U, V >
 {
     typedef AbstractModel < U, V > type;
 
@@ -63,13 +63,13 @@ public:
             << "AFTER - "
             << AbstractAtomicModel < T, U, V >::path(this);
         utils::Trace < utils::DoubleTime >::trace().flush();
-        for (size_t i = 0; i < Internals < T, U >::size(); ++i) {
-            if (not Internals < T, U >::get(i).is_null()) {
+        for (size_t i = 0; i < Internals < T, U, V >::size(); ++i) {
+            if (not Internals < T, U, V >::get(i).is_null()) {
                 utils::Trace < utils::DoubleTime >::trace()
                     << utils::TraceElement < utils::DoubleTime >("KERNEL", t,
                                                                  utils::KERNEL)
-                    << Internals < T, U >::name(i) << " = "
-                    << Internals < T, U >::get(i).to_string(
+                    << Internals < T, U, V >::name(i) << " = "
+                    << Internals < T, U, V >::get(i).to_string(
                         dynamic_cast < const T* >(this));
                 utils::Trace < utils::DoubleTime >::trace().flush();
             }
@@ -90,13 +90,13 @@ public:
             << "BEFORE - "
             << AbstractAtomicModel < T, U, V >::path(this);
         utils::Trace < utils::DoubleTime >::trace().flush();
-        for (size_t i = 0; i < Internals < T, U >::size(); ++i) {
-            if (not Internals < T, U >::get(i).is_null()) {
+        for (size_t i = 0; i < Internals < T, U, V >::size(); ++i) {
+            if (not Internals < T, U, V >::get(i).is_null()) {
                 utils::Trace < utils::DoubleTime >::trace()
                     << utils::TraceElement < utils::DoubleTime >("KERNEL", t,
                                                                  utils::KERNEL)
-                    << Internals < T, U >::name(i) << " = "
-                    << Internals < T, U >::get(i).to_string(
+                    << Internals < T, U, V >::name(i) << " = "
+                    << Internals < T, U, V >::get(i).to_string(
                         dynamic_cast < const T* >(this));
                 utils::Trace < utils::DoubleTime >::trace().flush();
             }
@@ -108,7 +108,7 @@ public:
     }
 
     virtual bool check(typename U::type t) const
-    { return Externals < T, U >::check(t); }
+    { return Externals < T, U, V >::check(t); }
 
     virtual void compute(typename U::type t, bool update) = 0;
 
@@ -117,7 +117,7 @@ public:
         if (type::last_time != t) {
             throw utils::InvalidGet("Variable not computed");
         }
-        return Internals < T, U >::get(index);
+        return Internals < T, U, V >::get(index);
     }
 
     template < typename W >
@@ -126,7 +126,7 @@ public:
         if (type::last_time != t) {
             throw utils::InvalidGet("Variable not computed");
         }
-        Any value = Internals < T, U >::get(index);
+        Any value = Internals < T, U, V >::get(index);
 
         return static_cast < const T* >(this)->*(value.get < T, W >());
     }
@@ -137,7 +137,7 @@ public:
         if (type::last_time != t) {
             throw utils::InvalidGet("Variable not computed");
         }
-        Any value = Internals < T, U >::get(index);
+        Any value = Internals < T, U, V >::get(index);
 
         switch (value_type) {
         case DOUBLE:
@@ -171,24 +171,26 @@ public:
     { return type::last_time == t; }
 
     virtual bool is_updated() const
-    { return Externals < T, U >::updated; }
+    { return Externals < T, U, V >::updated; }
 
     virtual void restore(const context::State < U >& state)
     {
-        States < T, U >::restore(state);
-        Internals < T, U >::restore(state);
+        Externals < T, U, V >::restore(this, state);
+        Internals < T, U, V >::restore(this, state);
+        States < T, U, V >::restore(this, state);
         type::last_time = state.last_time();
     }
 
     virtual void save(context::State < U >& state) const
     {
-        States < T, U >::save(state);
-        Internals < T, U >::save(state);
+        Externals < T, U, V >::save(this, state);
+        Internals < T, U, V >::save(this, state);
+        States < T, U, V >::save(this, state);
         state.last_time(type::last_time);
     }
 
     virtual void stable()
-    { Externals < T, U >::updated = false; }
+    { Externals < T, U, V >::updated = false; }
 };
 
 } }

+ 40 - 38
src/artis/kernel/AbstractCoupledModel.hpp

@@ -38,9 +38,9 @@ namespace artis { namespace kernel {
 
 template < typename T, typename U, typename V, typename W >
 class AbstractCoupledModel : public AbstractModel < U, V >,
-                             public States < T, U >,
-                             public Internals < T, U >,
-                             public Externals < T, U >
+                             public States < T, U, V >,
+                             public Internals < T, U, V >,
+                             public Externals < T, U, V >
 {
     typedef AbstractModel < U, V > type;
     typedef std::map < int, type* > Submodels;
@@ -77,13 +77,13 @@ public:
             << "AFTER - "
             << AbstractCoupledModel < T, U, V, W >::path(this);
         utils::Trace < utils::DoubleTime >::trace().flush();
-        for (size_t i = 0; i < Internals < T, U >::size(); ++i) {
-            if (not Internals < T, U >::get(i).is_null()) {
+        for (size_t i = 0; i < Internals < T, U, V >::size(); ++i) {
+            if (not Internals < T, U, V >::get(i).is_null()) {
                 utils::Trace < utils::DoubleTime >::trace()
                     << utils::TraceElement < utils::DoubleTime >("KERNEL", t,
                                                                  utils::KERNEL)
-                    << Internals < T, U >::name(i) << " = "
-                    << Internals < T, U >::get(i).to_string(
+                    << Internals < T, U, V >::name(i) << " = "
+                    << Internals < T, U, V >::get(i).to_string(
                         dynamic_cast < const T* >(this));
                 utils::Trace < utils::DoubleTime >::trace().flush();
             }
@@ -116,13 +116,13 @@ public:
             << "BEFORE - "
             << AbstractCoupledModel < T, U, V, W >::path(this);
         utils::Trace < utils::DoubleTime >::trace().flush();
-        for (size_t i = 0; i < Internals < T, U >::size(); ++i) {
-            if (not Internals < T, U >::get(i).is_null()) {
+        for (size_t i = 0; i < Internals < T, U, V >::size(); ++i) {
+            if (not Internals < T, U, V >::get(i).is_null()) {
                 utils::Trace < utils::DoubleTime >::trace()
                     << utils::TraceElement < utils::DoubleTime >("KERNEL", t,
                                                                  utils::KERNEL)
-                    << Internals < T, U >::name(i) << " = "
-                    << Internals < T, U >::get(i).to_string(
+                    << Internals < T, U, V >::name(i) << " = "
+                    << Internals < T, U, V >::get(i).to_string(
                         dynamic_cast < const T* >(this));
                 utils::Trace < utils::DoubleTime >::trace().flush();
             }
@@ -141,7 +141,7 @@ public:
     { }
 
     virtual bool check(typename U::type t) const
-    { return Externals < T, U >::check(t); }
+    { return Externals < T, U, V >::check(t); }
 
     virtual void compute(typename U::type t, bool update) = 0;
 
@@ -154,7 +154,7 @@ public:
             if (type::last_time != t) {
                 throw utils::InvalidGet("Variable not computed");
             }
-            return Internals < T, U >::get(index);
+            return Internals < T, U, V >::get(index);
         } else {
             return it->second.first->get(t, it->second.second);
         }
@@ -170,7 +170,7 @@ public:
             if (type::last_time != t) {
                 throw utils::InvalidGet("Variable not computed");
             }
-            const Any& value = Internals < T, U >::get(index);
+            const Any& value = Internals < T, U, V >::get(index);
 
             return static_cast < const T* >(this)->*(value.get < T, Z >());
         } else {
@@ -189,7 +189,7 @@ public:
             submodel_internals.find(index);
 
         if (it == submodel_internals.end()) {
-            Any value = Internals < T, U >::get(index);
+            Any value = Internals < T, U, V >::get(index);
 
             switch (value_type) {
             case DOUBLE:
@@ -240,7 +240,7 @@ public:
     }
 
     virtual bool is_updated() const
-    { return Externals < T, U >::updated; }
+    { return Externals < T, U, V >::updated; }
 
     virtual const Node < U >* get_submodel(unsigned int index) const
     {
@@ -314,8 +314,9 @@ public:
             it->second->restore(state.get_substate(it->first));
             ++it;
         }
-        States < T, U >::restore(state);
-        Internals < T, U >::restore(state);
+        States < T, U, V >::restore(this, state);
+        Internals < T, U, V >::restore(this, state);
+        Externals < T, U, V >::restore(this, state);
     }
 
     virtual void save(context::State < U >& state) const
@@ -330,12 +331,13 @@ public:
             state.add_substate(it->first, substate);
             ++it;
         }
-        States < T, U >::save(state);
-        Internals < T, U >::save(state);
+        States < T, U, V >::save(this, state);
+        Internals < T, U, V >::save(this, state);
+        Externals < T, U, V >::save(this, state);
     }
 
     virtual void stable()
-    { Externals < T, U >::updated = false; }
+    { Externals < T, U, V >::updated = false; }
 
     void submodel(unsigned int index, type* model)
     {
@@ -348,23 +350,23 @@ public:
     }
 
 protected:
-    void change_internal(unsigned int index, double T::* var)
-    {
-        submodel_internals.erase(index);
-        Internals < T, U >::internal(index, var);
-    }
-
-    void change_internal(unsigned int index, int T::* var)
-    {
-        submodel_internals.erase(index);
-        Internals < T, U >::internalI(index, var);
-    }
-
-    void change_internal(unsigned int index, bool T::* var)
-    {
-        submodel_internals.erase(index);
-        Internals < T, U >::internalB(index, var);
-    }
+    // void change_internal(unsigned int index, double T::* var)
+    // {
+    //     submodel_internals.erase(index);
+    //     Internals < T, U, V >::internal(index, var);
+    // }
+
+    // void change_internal(unsigned int index, int T::* var)
+    // {
+    //     submodel_internals.erase(index);
+    //     Internals < T, U, V >::internalI(index, var);
+    // }
+
+    // void change_internal(unsigned int index, bool T::* var)
+    // {
+    //     submodel_internals.erase(index);
+    //     Internals < T, U, V >::internalB(index, var);
+    // }
 
     void internal_(unsigned int index, type* model, int sub_index)
     {

+ 0 - 1
src/artis/kernel/AbstractModel.hpp

@@ -29,7 +29,6 @@
 
 #include <boost/core/demangle.hpp>
 
-#include <iostream>
 #include <typeinfo>
 
 namespace artis { namespace kernel {

+ 58 - 77
src/artis/kernel/Value.hpp

@@ -1,5 +1,5 @@
 /**
- * @file artis/kernel/Value.hpp
+ * @file artis/kernel/Any.hpp
  * @author See the AUTHORS file
  */
 
@@ -20,17 +20,12 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __ARTIS_KERNEL_VALUE_HPP
-#define __ARTIS_KERNEL_VALUE_HPP
+#ifndef __ARTIS_KERNEL_ANY_HPP
+#define __ARTIS_KERNEL_ANY_HPP
 
-#include <boost/serialization/serialization.hpp>
-#include <boost/serialization/array.hpp>
+#include <artis/context/Value.hpp>
 
-#include <algorithm>
-#include <cstring>
-#include <typeinfo>
-
-#include <iostream>
+#include <string>
 
 namespace artis { namespace kernel {
 
@@ -70,13 +65,13 @@ public:
     { }
 
     virtual ~Any()
-    { if (this->ptr_) delete this->ptr_; }
+    { if (ptr_) delete ptr_; }
 
     void operator=(Any const& other)
     { Any(other).swap(*this); }
 
     void swap(Any& other)
-    { std::swap(this->ptr_, other.ptr_); }
+    { std::swap(ptr_, other.ptr_); }
 
     template < typename T, typename V >
     V T::* get() const
@@ -94,100 +89,86 @@ public:
     }
 
     template < typename T >
-    std::string to_string(const T* o) const
+    void restore(T* o, const context::Value& value)
+    {
+        if (value.is_double()) {
+            double v;
+
+            value.get_content(v);
+            put(o, v);
+        } else if (value.is_int()) {
+            int v;
+
+            value.get_content(v);
+            put(o, v);
+        } else if (value.is_bool()) {
+            bool v;
+
+            value.get_content(v);
+            put(o, v);
+        } else {
+            assert(false);
+        }
+    }
+
+    template < typename T >
+    context::Value save(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_));
+                return context::Value(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_));
+                    return context::Value(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 {
-                        return "NA";
+                        return context::Value(o->*(q_bool->value_));
                     }
                 }
             }
-        } else {
-            return "NA";
         }
+        assert(false);
     }
-};
-
-class Value
-{
-public:
-    Value() : _content(nullptr), _size(0)
-    { }
-
-    template < typename T >
-    Value(T value)
-    { assign(&value, sizeof(T), typeid(T).hash_code()); }
-
-    Value(void* content, size_t size)
-    { assign(content, size, typeid(void*).hash_code()); }
-
-    Value(const char* value, unsigned int size)
-    { assign(value, size * sizeof(char), typeid(char*).hash_code()); }
-
-    virtual ~Value()
-    { /* if (_content) delete[] _content; */ }
-
-    bool empty() const
-    { return _content == nullptr; }
 
     template < typename T >
-    void get_content(T& value) const
-    {
-        assert(_type_id == typeid(T).hash_code());
-
-        value = *(T*)(_content);
-    }
-
-    std::string to_string() const
-    {
-        return std::string();
-    }
-
-private:
-    void assign(const void* content, size_t size, size_t type_id)
+    std::string to_string(const T* o) const
     {
-        _content = new char[size];
-        std::memcpy(_content, content, size);
-        _size = size;
-        _type_id = type_id;
-    }
+        if (ptr_) {
+            data < T, double >* q_double =
+                dynamic_cast < data < T, double >* >(ptr_);
 
-    friend class boost::serialization::access;
+            if (q_double) {
+                return std::to_string(o->*(q_double->value_));
+            } else {
+                data < T, int >* q_int =
+                    dynamic_cast < data < T, int >* >(ptr_);
 
-    template < class Archive >
-    void serialize(Archive & ar, const unsigned int version)
-    {
-        (void) version;
+                if (q_int) {
+                    return std::to_string(o->*(q_int->value_));
+                } else {
+                    data < T, bool >* q_bool =
+                        dynamic_cast < data < T, bool >* >(ptr_);
 
-        ar & _size;
-        if (Archive::is_loading::value) {
-            assert(_content == nullptr);
-            _content = new char[_size];
+                    if (q_bool) {
+                        return o->*(q_bool->value_) ? "true": "false";
+                    } else {
+                        return "NA";
+                    }
+                }
+            }
+        } else {
+            return "NA";
         }
-        ar & boost::serialization::make_array < char >(_content, _size);
-        ar & _type_id;
     }
-
-    char*  _content;
-    size_t _size;
-    size_t _type_id;
 };
 
 } }

+ 2 - 2
src/artis/kernel/CMakeLists.txt

@@ -4,8 +4,8 @@ INCLUDE_DIRECTORIES(
 LINK_DIRECTORIES()
 
 SET(ARTIS_KERNEL_HPP AbstractAtomicModel.hpp AbstractCoupledModel.hpp
-  AbstractModel.hpp Externals.hpp Internals.hpp Macro.hpp Node.hpp
-  Simulator.hpp States.hpp Value.hpp)
+  AbstractModel.hpp Any.hpp Externals.hpp Internals.hpp Macro.hpp Node.hpp
+  Simulator.hpp States.hpp)
 
 SET(ARTIS_KERNEL_CPP Simulator.cpp)
 

+ 54 - 15
src/artis/kernel/Externals.hpp

@@ -23,22 +23,24 @@
 #ifndef __ARTIS_KERNEL_EXTERNALS_HPP
 #define __ARTIS_KERNEL_EXTERNALS_HPP
 
+#include <artis/kernel/Any.hpp>
 #include <artis/kernel/Macro.hpp>
+
 #include <vector>
 
 namespace artis { namespace kernel {
 
-template < typename T, typename U >
+template < typename T, typename U, typename V >
 class Externals
 {
-    template < typename V >
+    template < typename W >
     struct element
     {
         unsigned int index;
         const std::string name;
-        V T::* var;
+        W T::* var;
 
-        element(unsigned int index, const std::string& name, V T::* var) :
+        element(unsigned int index, const std::string& name, W T::* var) :
             index(index), name(name), var(var)
         { }
     };
@@ -64,10 +66,10 @@ public:
         return OK;
     }
 
-    template < typename V >
-    void E_(std::initializer_list < element < V > > list)
+    template < typename W >
+    void E_(std::initializer_list < element < W > > list)
     {
-        for (typename std::initializer_list < element < V > >::iterator it =
+        for (typename std::initializer_list < element < W > >::iterator it =
                  list.begin(); it != list.end(); ++it) {
             if (externals.size() <= it->index) {
                 externals.resize(it->index + 1, std::make_pair(-1, Any()));
@@ -78,8 +80,8 @@ public:
         }
     }
 
-    template < typename V >
-    void external_(unsigned int index, const std::string& name, V T::* var)
+    template < typename W >
+    void external_(unsigned int index, const std::string& name, W T::* var)
     {
         if (externals.size() <= index) {
             externals.resize(index + 1, std::make_pair(-1, Any()));
@@ -92,25 +94,62 @@ public:
     bool is_ready(typename U::type t, unsigned int index) const
     { return externals.at(index).first == t; }
 
-    template < typename V >
-    void put(typename U::type t, unsigned int index, V value)
+    template < typename W >
+    void put(typename U::type t, unsigned int index, W value)
     {
         if (externals.at(index).first != t) {
             Any v = externals.at(index).second;
 
-            v.put < T, V >(static_cast < T* >(this), value);
+            v.put < T, W >(static_cast < T* >(this), value);
             externals.at(index).first = t;
             updated = true;
         } else {
             Any v = externals.at(index).second;
 
-            if (static_cast < const T* >(this)->*(v.get < T, V >()) != value) {
-                v.put < T, V >(static_cast < T* >(this), value);
+            if (static_cast < const T* >(this)->*(v.get < T, W >()) != value) {
+                v.put < T, W >(static_cast < T* >(this), value);
                 updated = true;
             }
         }
     }
 
+    virtual void restore(AbstractModel < U, V >* model,
+                         const context::State < U >& state)
+    {
+        unsigned int index = 0;
+
+        for (typename std::vector < std::pair < typename U::type,
+                 Any > >::iterator it = externals.begin();
+             it != externals.end(); ++it) {
+            Any& value = it->second;
+
+            if (not value.is_null()) {
+                value.restore < T >(static_cast < T* >(model),
+                                    state.get_external(index));
+            }
+            ++index;
+        }
+    }
+
+    virtual void save(const AbstractModel < U, V >* model,
+                      context::State < U >& state) const
+    {
+        unsigned int index = 0;
+
+        for (typename std::vector < std::pair < typename U::type,
+                 Any > >::const_iterator it = externals.begin();
+             it != externals.end(); ++it) {
+            const Any& value = it->second;
+
+            if (not value.is_null()) {
+                state.add_external(index,
+                                   value.save < T >(
+                                       static_cast < const T* >(model)));
+            }
+            ++index;
+        }
+    }
+
     unsigned int size() const
     { return externals.size(); }
 
@@ -123,7 +162,7 @@ protected:
 #define External(index, var)                                    \
         external_(index, std::string(ESCAPEQUOTE(index)), var)
 
-#define Externals(V,L) E_< V >(UNWRAP2 L)
+#define Externals(W,L) E_< W >(UNWRAP2 L)
 
 } } // namespace artis kernel
 

+ 37 - 52
src/artis/kernel/Internals.hpp

@@ -23,25 +23,25 @@
 #ifndef __ARTIS_KERNEL_INTERNALS_HPP
 #define __ARTIS_KERNEL_INTERNALS_HPP
 
-#include <artis/kernel/Macro.hpp>
 #include <artis/context/State.hpp>
-#include <artis/kernel/Value.hpp>
+#include <artis/kernel/Any.hpp>
+#include <artis/kernel/Macro.hpp>
 
 #include <vector>
 
 namespace artis { namespace kernel {
 
-template < typename T, typename U >
+template < typename T, typename U, typename V >
 class Internals
 {
-    template < typename V >
+    template < typename W >
     struct element
     {
         unsigned int index;
         const std::string name;
-        V T::* var;
+        W T::* var;
 
-        element(unsigned int index, const std::string& name, V T::* var) :
+        element(unsigned int index, const std::string& name, W T::* var) :
             index(index), name(name), var(var)
         { }
     };
@@ -56,10 +56,10 @@ public:
     const Any& get(unsigned int index) const
     { return internals.at(index); }
 
-    template < typename V >
-    void I_(std::initializer_list < element < V > > list)
+    template < typename W >
+    void I_(std::initializer_list < element < W > > list)
     {
-        for (typename std::initializer_list <element < V > >::iterator it =
+        for (typename std::initializer_list <element < W > >::iterator it =
                  list.begin(); it != list.end(); ++it) {
             if (internals.size() <= it->index) {
                 internals.resize(it->index + 1);
@@ -70,8 +70,8 @@ public:
         }
     }
 
-    template < typename V >
-    void internal_(unsigned int index, const std::string& name, V T::* var)
+    template < typename W >
+    void internal_(unsigned int index, const std::string& name, W T::* var)
     {
         if (internals.size() <= index) {
             internals.resize(index + 1, Any());
@@ -84,50 +84,35 @@ public:
     const std::string& name(unsigned int index) const
     { return internal_names.at(index); }
 
-    virtual void restore(const context::State < U >& /* state */)
+    virtual void restore(AbstractModel < U, V >* model,
+                         const context::State < U >& state)
     {
-        // unsigned int index = 0;
-
-        // for (typename std::vector < Any >::iterator it =
-        //          internals.begin(); it != internals.end(); ++it) {
-        //     state.get_internal(index, *it);
-        //     ++index;
-        // }
-        // index = 0;
-        // for (typename std::vector < int T::* >::iterator it =
-        //          internalsI.begin(); it != internalsI.end(); ++it) {
-        //     state.get_internal(index, *it);
-        //     ++index;
-        // }
-        // index = 0;
-        // for (typename std::vector < double T::* >::iterator it =
-        //          internalsD.begin(); it != internalsD.end(); ++it) {
-        //     state.get_internal(index, *it);
-        //     ++index;
-        // }
+        unsigned int index = 0;
+
+        for (typename std::vector < Any >::iterator it = internals.begin();
+             it != internals.end(); ++it) {
+            if (not it->is_null()) {
+                it->restore < T >(static_cast < T* >(model),
+                                  state.get_internal(index));
+            }
+            ++index;
+        }
     }
 
-    virtual void save(context::State < U >& /* state */) const
+    virtual void save(const AbstractModel < U, V >* model,
+                      context::State < U >& state) const
     {
-        // unsigned int index = 0;
-
-        // for (typename std::vector < bool T::* >::const_iterator it =
-        //          internalsB.begin(); it != internalsB.end(); ++it) {
-        //     state.add_internal(index, *it);
-        //     ++index;
-        // }
-        // index = 0;
-        // for (typename std::vector < int T::* >::const_iterator it =
-        //          internalsI.begin(); it != internalsI.end(); ++it) {
-        //     state.add_internal(index, *it);
-        //     ++index;
-        // }
-        // index = 0;
-        // for (typename std::vector < double T::* >::const_iterator it =
-        //          internalsD.begin(); it != internalsD.end(); ++it) {
-        //     state.add_internal(index, *it);
-        //     ++index;
-        // }
+        unsigned int index = 0;
+
+        for (typename std::vector < Any >::const_iterator it =
+                 internals.begin(); it != internals.end(); ++it) {
+            if (not it->is_null()) {
+                state.add_internal(index,
+                                   it->save < T >(
+                                       static_cast < const T* >(model)));
+            }
+            ++index;
+        }
     }
 
     unsigned int size() const
@@ -141,7 +126,7 @@ private:
 #define Internal(index, var)                                    \
         internal_(index, std::string(ESCAPEQUOTE(index)), var)
 
-#define Internals(V,L) I_< V >(UNWRAP2 L)
+#define Internals(W,L) I_< W >(UNWRAP2 L)
 
 } } // namespace artis kernel
 

+ 1 - 1
src/artis/kernel/Node.hpp

@@ -23,7 +23,7 @@
 #ifndef __ARTIS_KERNEL_NODE_HPP
 #define __ARTIS_KERNEL_NODE_HPP
 
-#include <artis/kernel/Value.hpp>
+#include <artis/kernel/Any.hpp>
 
 #include <cassert>
 

+ 5 - 14
src/artis/kernel/Simulator.hpp

@@ -59,30 +59,21 @@ public:
     const observer::Observer < U, V >& observer() const
     { return _observer; }
 
-    void run(double begin, double end)
+    void run(const context::Context < U >& context)
     {
-        for (double t = begin; t <= end; ++t) {
-            (*_model)(t);
-            _observer.observe(t);
+        if (context.valid()) {
+            _model->restore(context.state());
         }
-    }
-
-    void restore(const context::Context < utils::DoubleTime >& context)
-    {
-        _model->restore(context.state());
-    }
-
-    void resume(const context::Context < utils::DoubleTime >& context)
-    {
         for (double t = context.begin(); t <= context.end(); t++) {
             (*_model)(t);
             _observer.observe(t);
         }
     }
 
-    void save(context::Context < utils::DoubleTime >& context) const
+    void save(context::Context < U >& context) const
     {
         _model->save(context.state());
+        context.saved();
     }
 
 private:

+ 36 - 51
src/artis/kernel/States.hpp

@@ -24,23 +24,23 @@
 #define __ARTIS_KERNEL_STATES_HPP
 
 #include <artis/context/State.hpp>
-#include <artis/kernel/Value.hpp>
+#include <artis/kernel/Any.hpp>
 
 #include <vector>
 
 namespace artis { namespace kernel {
 
-template < typename T, typename U >
+template < typename T, typename U, typename V >
 class States
 {
-    template < typename V >
+    template < typename W >
     struct element
     {
         unsigned int index;
         const std::string name;
-        V T::* var;
+        W T::* var;
 
-        element(unsigned int index, const std::string& name, V T::* var) :
+        element(unsigned int index, const std::string& name, W T::* var) :
             index(index), name(name), var(var)
         { }
     };
@@ -55,10 +55,10 @@ public:
     const Any& get(unsigned int index) const
     { return states.at(index); }
 
-    template < typename V >
-    void S_(std::initializer_list < element < V > > list)
+    template < typename W >
+    void S_(std::initializer_list < element < W > > list)
     {
-        for (typename std::initializer_list < element < V > >::iterator it =
+        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, Any());
@@ -69,54 +69,39 @@ public:
         }
     }
 
-    virtual void restore(const context::State < U >& /* state */)
+    virtual void restore(AbstractModel < U, V >* model,
+                         const context::State < U >& state)
     {
-        // unsigned int index = 0;
-
-        // for (typename std::vector < bool T::* >::iterator it =
-        //          statesB.begin(); it != statesB.end(); ++it) {
-        //     state.get_state(index, *it);
-        //     ++index;
-        // }
-        // index = 0;
-        // for (typename std::vector < int T::* >::iterator it =
-        //          statesI.begin(); it != statesI.end(); ++it) {
-        //     state.get_state(index, *it);
-        //     ++index;
-        // }
-        // index = 0;
-        // for (typename std::vector < double T::* >::iterator it =
-        //          statesD.begin(); it != statesD.end(); ++it) {
-        //     state.get_state(index, *it);
-        //     ++index;
-        // }
+        unsigned int index = 0;
+
+        for (typename std::vector < Any >::iterator it = states.begin();
+             it != states.end(); ++it) {
+            if (not it->is_null()) {
+                it->restore < T >(static_cast < T* >(model),
+                                  state.get_state(index));
+            }
+            ++index;
+        }
     }
 
-    virtual void save(context::State < U >& /* state */) const
+    virtual void save(const AbstractModel < U, V >* model,
+                      context::State < U >& state) const
     {
-        // unsigned int index = 0;
-
-        // for (typename std::vector < bool T::* >::const_iterator it =
-        //          statesB.begin(); it != statesB.end(); ++it) {
-        //     state.add_state(index, *it);
-        //     ++index;
-        // }
-        // index = 0;
-        // for (typename std::vector < int T::* >::const_iterator it =
-        //          statesI.begin(); it != statesI.end(); ++it) {
-        //     state.add_state(index, *it);
-        //     ++index;
-        // }
-        // index = 0;
-        // for (typename std::vector < double T::* >::const_iterator it =
-        //          statesD.begin(); it != statesD.end(); ++it) {
-        //     state.add_state(index, *it);
-        //     ++index;
-        // }
+        unsigned int index = 0;
+
+        for (typename std::vector < Any >::const_iterator it =
+                 states.begin(); it != states.end(); ++it) {
+            if (not it->is_null()) {
+                state.add_state(index,
+                                it->save < T >(
+                                    static_cast < const T* >(model)));
+            }
+            ++index;
+        }
     }
 
-    template < typename V >
-    void state_(unsigned int index, const std::string& name, V T::* var)
+    template < typename W >
+    void state_(unsigned int index, const std::string& name, W T::* var)
     {
         if (states.size() <= index) {
             states.resize(index + 1, Any());
@@ -134,7 +119,7 @@ private:
 #define State(index, var)                                    \
         state_(index, std::string(ESCAPEQUOTE(index)), var)
 
-#define States(V,L) S_< V >(UNWRAP2 L)
+#define States(W,L) S_< W >(UNWRAP2 L)
 
 } }
 

+ 0 - 1
src/artis/observer/View.hpp

@@ -24,7 +24,6 @@
 #define ARTIS_OBSERVER_VIEW_HPP
 
 #include <artis/kernel/AbstractModel.hpp>
-#include <artis/kernel/Value.hpp>
 #include <artis/utils/DoubleTime.hpp>
 
 #include <boost/lexical_cast.hpp>

+ 6 - 0
src/test/CMakeLists.txt

@@ -9,3 +9,9 @@ ADD_EXECUTABLE(artis-tests test.cpp)
 TARGET_LINK_LIBRARIES(artis-tests artis-lib ${Boost_LIBRARIES})
 
 INSTALL(TARGETS artis-tests DESTINATION bin)
+
+ADD_EXECUTABLE(artis-test-context test-context.cpp)
+
+TARGET_LINK_LIBRARIES(artis-test-context artis-lib ${Boost_LIBRARIES})
+
+INSTALL(TARGETS artis-test-context DESTINATION bin)

+ 109 - 0
src/test/test-context.cpp

@@ -0,0 +1,109 @@
+/**
+ * @file test/test-context.cpp
+ * @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/>.
+ */
+
+//#define CATCH_CONFIG_MAIN
+//#include <test/catch.hpp>
+
+#include <test/models.hpp>
+
+#include <artis/kernel/Simulator.hpp>
+#include <artis/utils/DateTime.hpp>
+
+#include <boost/archive/binary_oarchive.hpp>
+#include <boost/archive/binary_iarchive.hpp>
+
+#include <fstream>
+
+using namespace artis::kernel;
+
+typedef artis::kernel::Simulator < RootModel,
+                                   artis::utils::DoubleTime,
+                                   ModelParameters,
+                                   GlobalParameters > ASimulator;
+typedef artis::context::Context < artis::utils::DoubleTime > AContext;
+
+int main()
+{
+    GlobalParameters globalParameters;
+    ModelParameters modelParameters;
+
+    AContext context(artis::utils::DateTime::toJulianDayNumber("2016-1-1"),
+                     artis::utils::DateTime::toJulianDayNumber("2016-1-5"));
+
+    {
+        ASimulator simulator(new RootModel, globalParameters);
+
+        ::Trace::trace().clear();
+
+        simulator.init(artis::utils::DateTime::toJulianDayNumber("2016-1-1"),
+                       modelParameters);
+        simulator.run(context);
+
+        std::cout << ::Trace::trace().elements().to_string() << std::endl;
+
+        simulator.save(context);
+
+        std::ofstream os("state");
+        boost::archive::binary_oarchive oa(os);
+
+        oa << context;
+    }
+
+    std::cout << "==== PAUSE ====" << std::endl;
+
+    {
+        AContext new_context(context);
+        ASimulator simulator(new RootModel, globalParameters);
+
+        ::Trace::trace().clear();
+        new_context.begin(
+            artis::utils::DateTime::toJulianDayNumber("2016-1-6"));
+        new_context.end(
+            artis::utils::DateTime::toJulianDayNumber("2016-1-10"));
+        simulator.run(new_context);
+
+        std::cout << ::Trace::trace().elements().to_string() << std::endl;
+    }
+
+    std::cout << "==== PAUSE ====" << std::endl;
+
+    {
+        AContext new_context;
+        ASimulator simulator(new RootModel, globalParameters);
+
+        std::ifstream is("state");
+        boost::archive::binary_iarchive ia(is);
+
+        ia >> new_context;
+
+        ::Trace::trace().clear();
+        new_context.begin(
+            artis::utils::DateTime::toJulianDayNumber("2016-1-6"));
+        new_context.end(
+            artis::utils::DateTime::toJulianDayNumber("2016-1-10"));
+        simulator.run(new_context);
+
+        std::cout << ::Trace::trace().elements().to_string() << std::endl;
+    }
+
+    return 0;
+}

+ 5 - 2
src/test/test.cpp

@@ -53,6 +53,8 @@ typedef artis::builder::Builder < ::Factory,
                                   ModelParameters,
                                   GlobalParameters > ABuilder;
 
+typedef artis::context::Context < artis::utils::DoubleTime > AContext;
+
 class AView : public artis::observer::View < artis::utils::DoubleTime,
                                              ModelParameters >
 {
@@ -110,6 +112,8 @@ int main()
                      "] }"                                           \
                      "] }");
 
+    AContext context(artis::utils::DateTime::toJulianDayNumber("2016-1-1"),
+                     artis::utils::DateTime::toJulianDayNumber("2016-1-10"));
     ASimulator simulator(builder.build(), globalParameters);
 
     simulator.attachView("Root", new AView);
@@ -117,8 +121,7 @@ int main()
     ::Trace::trace().clear();
 
     simulator.init(0, modelParameters);
-    simulator.run(artis::utils::DateTime::toJulianDayNumber("2016-1-1"),
-                  artis::utils::DateTime::toJulianDayNumber("2016-1-10"));
+    simulator.run(context);
 
     std::cout << ::Trace::trace().elements().to_string() << std::endl;