Parcourir la source

Add save/restore mecanisms

Eric Ramat il y a 4 ans
Parent
commit
aafce12776

+ 66 - 42
src/artis-star/common/Any.hpp

@@ -92,6 +92,11 @@ namespace artis {
                 if (value.is_type<double>()) {
                     double v;
 
+                    value(v);
+                    put(o, v);
+                } else if (value.is_type<unsigned int>()) {
+                    unsigned int v;
+
                     value(v);
                     put(o, v);
                 } else if (value.is_type<int>()) {
@@ -107,6 +112,11 @@ namespace artis {
                 } else if (value.is_type<std::vector<double> >()) {
                     std::vector<double> v;
 
+                    value(v);
+                    put(o, v);
+                } else if (value.is_type<std::vector<unsigned int> >()) {
+                    std::vector<unsigned int> v;
+
                     value(v);
                     put(o, v);
                 } else if (value.is_type<std::vector<int> >()) {
@@ -134,39 +144,46 @@ namespace artis {
                     if (q_double) {
                         return common::Value(o->*(q_double->value_));
                     } else {
-                        data<T, int>* q_int =
-                                dynamic_cast < data<T, int>* >(ptr_);
+                        data<T, unsigned int>* q_uint =
+                                dynamic_cast < data<T, unsigned int>* >(ptr_);
 
-                        if (q_int) {
-                            return common::Value(o->*(q_int->value_));
+                        if (q_uint) {
+                            return common::Value(o->*(q_uint->value_));
                         } else {
-                            data<T, bool>* q_bool =
-                                    dynamic_cast < data<T, bool>* >(ptr_);
+                            data<T, int>* q_int =
+                                    dynamic_cast < data<T, int>* >(ptr_);
 
-                            if (q_bool) {
-                                return common::Value(o->*(q_bool->value_));
+                            if (q_int) {
+                                return common::Value(o->*(q_int->value_));
                             } else {
-                                data<T, std::vector<double> >* q_double_v =
-                                        dynamic_cast < data<T, std::vector<
-                                                double> >* >(ptr_);
+                                data<T, bool>* q_bool =
+                                        dynamic_cast < data<T, bool>* >(ptr_);
 
-                                if (q_double_v) {
-                                    return common::Value(o->*(q_double_v->value_));
+                                if (q_bool) {
+                                    return common::Value(o->*(q_bool->value_));
                                 } else {
-                                    data<T, std::vector<int> >* q_int_v =
+                                    data<T, std::vector<double> >* q_double_v =
                                             dynamic_cast < data<T, std::vector<
-                                                    int> >* >(ptr_);
+                                                    double> >* >(ptr_);
 
-                                    if (q_int_v) {
-                                        return common::Value(o->*(q_int_v->value_));
+                                    if (q_double_v) {
+                                        return common::Value(o->*(q_double_v->value_));
                                     } else {
-                                        data<T, std::vector<bool> >* q_bool_v =
+                                        data<T, std::vector<int> >* q_int_v =
                                                 dynamic_cast < data<T, std::vector<
-                                                        bool> >* >(ptr_);
+                                                        int> >* >(ptr_);
 
-                                        if (q_bool_v) {
-                                            return common::Value(
-                                                    o->*(q_bool_v->value_));
+                                        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_));
+                                            }
                                         }
                                     }
                                 }
@@ -188,40 +205,47 @@ namespace artis {
                     if (q_double) {
                         return std::to_string(o->*(q_double->value_));
                     } else {
-                        data<T, int>* q_int =
-                                dynamic_cast < data<T, int>* >(ptr_);
+                        data<T, unsigned int>* q_uint =
+                                dynamic_cast < data<T, unsigned int>* >(ptr_);
 
-                        if (q_int) {
-                            return std::to_string(o->*(q_int->value_));
+                        if (q_uint) {
+                            return std::to_string(o->*(q_uint->value_));
                         } else {
-                            data<T, bool>* q_bool =
-                                    dynamic_cast < data<T, bool>* >(ptr_);
+                            data<T, int>* q_int =
+                                    dynamic_cast < data<T, int>* >(ptr_);
 
-                            if (q_bool) {
-                                return o->*(q_bool->value_) ? "true" : "false";
+                            if (q_int) {
+                                return std::to_string(o->*(q_int->value_));
                             } else {
-                                data<T, std::vector<double> >* q_double_v =
-                                        dynamic_cast < data<T, std::vector<
-                                                double> >* >(ptr_);
+                                data<T, bool>* q_bool =
+                                        dynamic_cast < data<T, bool>* >(ptr_);
 
-                                if (q_double_v) {
-                                    return "";
+                                if (q_bool) {
+                                    return o->*(q_bool->value_) ? "true" : "false";
                                 } else {
-                                    data<T, std::vector<int> >* q_int_v =
+                                    data<T, std::vector<double> >* q_double_v =
                                             dynamic_cast < data<T, std::vector<
-                                                    int> >* >(ptr_);
+                                                    double> >* >(ptr_);
 
-                                    if (q_int_v) {
+                                    if (q_double_v) {
                                         return "";
                                     } else {
-                                        data<T, std::vector<bool> >* q_bool_v =
+                                        data<T, std::vector<int> >* q_int_v =
                                                 dynamic_cast < data<T, std::vector<
-                                                        bool> >* >(ptr_);
+                                                        int> >* >(ptr_);
 
-                                        if (q_bool_v) {
+                                        if (q_int_v) {
                                             return "";
                                         } else {
-                                            return "NA";
+                                            data<T, std::vector<bool> >* q_bool_v =
+                                                    dynamic_cast < data<T, std::vector<
+                                                            bool> >* >(ptr_);
+
+                                            if (q_bool_v) {
+                                                return "";
+                                            } else {
+                                                return "NA";
+                                            }
                                         }
                                     }
                                 }

+ 22 - 9
src/artis-star/common/Coordinator.hpp

@@ -59,7 +59,8 @@ namespace artis {
             virtual const Model<Time>* get_submodel(unsigned int index) const
             {
                 const GraphManager<Time>& graph_manager = get_graph_manager();
-                typename common::ModelMap<Time>::const_iterator it = graph_manager.child_map().find(index);
+                typename common::ModelMap<Time>::const_iterator it = graph_manager.child_map().find(
+                        index);
 
                 if (it != graph_manager.child_map().end()) {
                     return it->second;
@@ -71,7 +72,8 @@ namespace artis {
             virtual const Model<Time>* get_submodel(unsigned int index, unsigned int rank) const
             {
                 const GraphManager<Time>& graph_manager = get_graph_manager();
-                typename common::ModelsMap<Time>::const_iterator it = graph_manager.children_map().find(index);
+                typename common::ModelsMap<Time>::const_iterator it = graph_manager.children_map().find(
+                        index);
 
                 if (it != graph_manager.children_map().end() and it->second.size() > rank) {
                     return it->second.at(rank);
@@ -83,7 +85,8 @@ namespace artis {
             virtual unsigned int get_submodel_number(unsigned int index) const
             {
                 const GraphManager<Time>& graph_manager = get_graph_manager();
-                typename common::ModelsMap<Time>::const_iterator it = graph_manager.children_map().find(index);
+                typename common::ModelsMap<Time>::const_iterator it = graph_manager.children_map().find(
+                        index);
 
                 if (it != graph_manager.children_map().end()) {
                     return it->second.size();
@@ -99,7 +102,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) {
                     Coordinator<Time>::add_in_port(*it);
                 }
             }
@@ -113,16 +118,22 @@ namespace artis {
 
             void output_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) {
                     Coordinator<Time>::add_out_port(*it);
                 }
             }
 
-            void restore(const common::context::State<Time>& state) {
+            void restore(const common::context::State<Time>& state)
+            {
+                Model<Time>::restore(state);
                 get_graph_manager().restore(state);
             }
 
-            void save(common::context::State<Time>& state) const {
+            void save(common::context::State<Time>& state) const
+            {
+                Model<Time>::save(state);
                 get_graph_manager().save(state);
             }
 
@@ -135,11 +146,13 @@ namespace artis {
             }
 
 // DEVS methods
-            virtual common::Value observe(const typename Time::type& t, unsigned int index) const = 0;
+            virtual common::Value
+            observe(const typename Time::type& t, unsigned int index) const = 0;
 
             virtual void output(const typename Time::type& t) = 0;
 
-            virtual void post_event(const typename Time::type& t, const common::ExternalEvent<Time>& event) = 0;
+            virtual void
+            post_event(const typename Time::type& t, const common::ExternalEvent<Time>& event) = 0;
 
             virtual typename Time::type dispatch_events(const common::Bag<Time>& bag,
                     const typename Time::type& t) = 0;

+ 7 - 4
src/artis-star/common/GraphManager.hpp

@@ -74,15 +74,18 @@ namespace artis {
 
             void restore(const common::context::State<Time>& state)
             {
-                for(auto& child: _children) {
-                    child->restore(state);
+                for(typename common::ModelMap<Time>::iterator it = _child_map.begin(); it != _child_map.end(); ++it) {
+                    it->second->restore(state.get_substate(it->first));
                 }
             }
 
             void save(common::context::State<Time>& state) const
             {
-                for(const auto& child: _children) {
-                    child->save(state);
+                for(typename common::ModelMap<Time>::const_iterator it = _child_map.begin(); it != _child_map.end(); ++it) {
+                    context::State<Time> substate;
+
+                    it->second->save(substate);
+                    state.add_substate(it->first, substate);
                 }
             }
 

+ 10 - 6
src/artis-star/common/Model.hpp

@@ -195,9 +195,17 @@ namespace artis {
                 return (_parent != nullptr ? _parent->path() : "") + ":" + get_name();
             }
 
-            virtual void restore(const common::context::State<Time>& state) = 0;
+            virtual void restore(const common::context::State<Time>& state)
+            {
+                _tl = state.last_time();
+                _tn = state.next_time();
+            }
 
-            virtual void save(common::context::State<Time>& state) const = 0;
+            virtual void save(common::context::State<Time>& state) const
+            {
+                state.last_time(_tl);
+                state.next_time(_tn);
+            }
 
             void set_parent(Model<Time>* parent) { _parent = parent; }
 
@@ -238,10 +246,6 @@ 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;

+ 9 - 6
src/artis-star/common/RootCoordinator.hpp

@@ -64,17 +64,21 @@ namespace artis {
 
             virtual ~RootCoordinator() { }
 
-            void attachView(const std::string& name, observer::View<Time>* view) { _observer.attachView(name, view); }
+            void attachView(const std::string& name, observer::View<Time>* view)
+            {
+                _observer.attachView(name, view);
+            }
 
             const observer::Observer<Time>& observer() const { return _observer; }
 
             void run(const common::context::Context<Time>& context)
             {
                 _observer.init();
-                _tn = _root.start(_tn);
                 if (context.valid()) {
-// TODO
-//                    _root->restore(context.state());
+                    _root.restore(context.state());
+                    _tn = _root.get_tn();
+                } else {
+                    _tn = _root.start(_tn);
                 }
                 while (_tn <= _t_max) {
                     _root.output(_tn);
@@ -85,8 +89,7 @@ namespace artis {
 
             void save(common::context::Context<Time>& context) const
             {
-// TODO
-//                _root->save(context.state());
+                _root.save(context.state());
                 context.saved();
             }
 

+ 9 - 9
src/artis-star/common/States.hpp

@@ -38,7 +38,8 @@ namespace artis {
 
         template<typename Time, typename Dyn>
         class States {
-            template<typename W>
+        public:
+            template<class W>
             struct element {
                 unsigned int index;
                 const std::string name;
@@ -49,7 +50,6 @@ namespace artis {
                         index(index), name(name), var(var) { }
             };
 
-        public:
             States() { }
 
             virtual ~States() { }
@@ -60,7 +60,7 @@ namespace artis {
 
             unsigned int state_number() const { return states.size(); }
 
-            template<typename W>
+            template<class W>
             void S_(std::initializer_list<element<W> > list)
             {
                 for (typename std::initializer_list<element<W> >::iterator it =
@@ -100,7 +100,7 @@ namespace artis {
                 }
             }
 
-            template<typename W>
+            template<class W>
             void state_(unsigned int index, const std::string& name, W Dyn::* var)
             {
                 if (states.size() <= index) {
@@ -116,12 +116,12 @@ namespace artis {
             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)
-
     }
 }
 
+#define DECLARE_STATE(index, var)                                    \
+        this->state_(index, std::string(ESCAPEQUOTE(index)), var)
+
+#define DECLARE_STATES(W, L) this-> template S_< W >(UNWRAP2 L)
+
 #endif

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

@@ -48,8 +48,6 @@ namespace artis {
 
                 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; }

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

@@ -49,16 +49,6 @@ namespace artis {
 
                 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);
@@ -69,16 +59,6 @@ namespace artis {
                     _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);

+ 1 - 46
src/artis-star/common/context/StateValues.hpp

@@ -44,38 +44,8 @@ namespace artis {
 
                 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 =
@@ -91,18 +61,7 @@ namespace artis {
 
                 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: [ ";
+                    std::string str = "states: [ ";
                     for (std::map<unsigned int, Value>::const_iterator it =
                             _states.begin(); it != _states.end(); ++it) {
                         str += it->second.to_string() + " ";
@@ -119,13 +78,9 @@ namespace artis {
                 {
                     (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;
             };
 

+ 0 - 4
src/artis-star/kernel/dtss/Dynamics.hpp

@@ -91,15 +91,11 @@ 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:

+ 9 - 1
src/artis-star/kernel/pdevs/Coordinator.hpp

@@ -71,7 +71,15 @@ namespace artis {
                 return ss.str();
             }
 
-            typename Time::type start(const typename Time::type& t)
+            void restore(const common::context::State<Time>& state)
+            {
+                common::Coordinator<Time>::restore(state);
+                for (auto& child : _graph_manager.children()) {
+                    _event_table.init(child->get_tn(), child);
+                }
+            }
+
+                typename Time::type start(const typename Time::type& t)
             {
 
 #ifdef WITH_TRACE

+ 0 - 4
src/artis-star/kernel/pdevs/Dynamics.hpp

@@ -134,15 +134,11 @@ 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:

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

@@ -78,11 +78,13 @@ namespace artis {
 
             virtual void restore(const common::context::State<Time>& state)
             {
+                common::Simulator<Time>::restore(state);
                 _dynamics.restore(state);
             }
 
             virtual void save(common::context::State<Time>& state) const
             {
+                common::Simulator<Time>::save(state);
                 _dynamics.save(state);
             }
 

+ 22 - 7
src/artis-star/kernel/pdevs/qss/Derivative.hpp

@@ -36,6 +36,10 @@ namespace artis {
 
             template<class Time, class Dyn, class Parameters = common::NoParameters>
             class Derivative : public artis::pdevs::Dynamics<Time, Dyn, Parameters> {
+                typedef enum {
+                    INIT, WAIT, RESPONSE
+                } State;
+
             public:
                 enum inputs {
                     IN
@@ -45,10 +49,24 @@ namespace artis {
                     OUT
                 };
 
+                enum states {
+                    STATE, INPUT_NUMBER, OUTPUT_VALUE, LAST_OUTPUT
+                };
+
+                typedef Derivative<Time, Dyn, Parameters> type;
+
                 Derivative(const std::string& name, const Context<Time, Dyn, Parameters>& context)
                         :
                         artis::pdevs::Dynamics<Time, Dyn, Parameters>(name, context)
                 {
+                    DECLARE_STATES(int,
+                            ((STATE, &type::_state)));
+                    DECLARE_STATES(unsigned int,
+                            ((INPUT_NUMBER, &type::_input_number)));
+                    DECLARE_STATES(double,
+                            ((OUTPUT_VALUE, &type::_output_value),
+                                    (LAST_OUTPUT, &type::_output_value)));
+
                     this->input_port({IN, "in"});
                     this->output_port({OUT, "out"});
                 }
@@ -80,10 +98,11 @@ namespace artis {
                                 IntegratorData data;
 
                                 event.data()(data);
-                                this->get(event.port_index()).put(dynamic_cast<Dyn*>(this), data.value);
+                                this->get(event.port_index() + 4).put(dynamic_cast<Dyn*>(this),
+                                        data.value);
                                 switch (_state) {
                                 case INIT:
-                                    if (_input_number == this->state_number()) {
+                                    if (_input_number == this->state_number() - 4) {
                                         _output_value = compute();
                                         _state = RESPONSE;
                                     }
@@ -154,11 +173,7 @@ namespace artis {
                 }
 
             private:
-                typedef enum {
-                    INIT, WAIT, RESPONSE
-                } State;
-
-                State _state;
+                int _state;
                 unsigned int _input_number;
                 double _output_value;
                 double _last_output;

+ 54 - 34
src/artis-star/kernel/pdevs/qss/Integrator.hpp

@@ -41,6 +41,15 @@ namespace artis {
             template<class Time>
             class Integrator
                     : public artis::pdevs::Dynamics<Time, Integrator<Time>, IntegratorParameters> {
+
+                typedef enum {
+                    INIT,
+                    WAIT_FOR_QUANTA,
+                    WAIT_FOR_X_DOT,
+                    WAIT_FOR_BOTH,
+                    RUNNING
+                } State;
+
             public:
                 enum inputs {
                     QUANTA = 1, X_DOT
@@ -54,14 +63,40 @@ namespace artis {
                     VALUE
                 } Observable;
 
+                enum states {
+                    STATE,
+                    LAST_OUT_DATE,
+                    UP_THRESHOLD,
+                    DOWN_THRESHOLD,
+                    LAST_OUT_VALUE,
+                    INIT_VALUE,
+                    CURRENT_VALUE,
+                    EXPECTED_VALUE,
+                    ARCHIVE_X_DOT,
+                    ARCHIVE_DATE
+                };
+
                 Integrator(const std::string& name,
                         const Context<Time, Integrator<Time>, IntegratorParameters>& context)
                         :
                         artis::pdevs::Dynamics<Time, Integrator<Time>, IntegratorParameters>(name,
                                 context)
                 {
-                    this->input_ports({{QUANTA, "quanta"},
-                                       {X_DOT,  "x_dot"}});
+                    DECLARE_STATES(int, ((STATE, &Integrator<Time>::_state)));
+                    DECLARE_STATES(typename Time::type,
+                            ((LAST_OUT_DATE, &Integrator<Time>::_last_output_date)));
+                    DECLARE_STATES(double, ((UP_THRESHOLD, &Integrator<Time>::_up_threshold),
+                            (DOWN_THRESHOLD, &Integrator<Time>::_down_threshold),
+                            (LAST_OUT_VALUE, &Integrator<Time>::_last_output_value),
+                            (INIT_VALUE, &Integrator<Time>::_init_value),
+                            (CURRENT_VALUE, &Integrator<Time>::_current_value),
+                            (EXPECTED_VALUE, &Integrator<Time>::_expected_value)));
+                    DECLARE_STATES(std::vector < double >, ((ARCHIVE_X_DOT, &Integrator<Time>::_archive_x_dot)));
+                    DECLARE_STATES(std::vector <typename Time::type >, ((ARCHIVE_DATE, &Integrator<Time>::_archive_date)));
+
+                    this->input_ports({
+                            {QUANTA, "quanta"},
+                            {X_DOT,  "x_dot"}});
                     this->output_port({OUT, "out"});
                     this->observable({VALUE, "value"});
 
@@ -81,15 +116,14 @@ namespace artis {
                 {
                     switch (_state) {
                     case RUNNING: {
-                        record_t record;
-                        double last_derivative_value = _archive.back().x_dot;
+                        double last_derivative_value = _archive_x_dot.back();
 
                         _last_output_value = _expected_value;
                         _last_output_date = time;
-                        _archive.clear();
-                        record.date = time;
-                        record.x_dot = last_derivative_value;
-                        _archive.push_back(record);
+                        _archive_x_dot.clear();
+                        _archive_date.clear();
+                        _archive_x_dot.push_back(last_derivative_value);
+                        _archive_date.push_back(time);
                         _current_value = _expected_value;
                         _state = WAIT_FOR_QUANTA;
                         break;
@@ -125,12 +159,10 @@ namespace artis {
                                 }
                                 if (event.on_port(X_DOT)) {
                                     DerivativeData data;
-                                    record_t record;
 
                                     event.data()(data);
-                                    record.date = t;
-                                    record.x_dot = data.x_dot;
-                                    _archive.push_back(record);
+                                    _archive_x_dot.push_back(data.x_dot);
+                                    _archive_date.push_back(t);
                                     if (_state == WAIT_FOR_X_DOT) {
                                         _state = RUNNING;
                                     }
@@ -159,9 +191,9 @@ namespace artis {
                     switch (_state) {
                     case RUNNING:
 
-                        assert(_archive.size() > 0);
+                        assert(_archive_date.size() > 0);
 
-                        current_derivative = _archive.back().x_dot;
+                        current_derivative = _archive_x_dot.back();
                         if (current_derivative == 0) {
                             return Time::infinity;
                         }
@@ -220,19 +252,19 @@ namespace artis {
                 {
                     double val = _last_output_value;
 
-                    if (_archive.size() > 0) {
-                        for (size_t i = 0; i < _archive.size() - 1; i++) {
+                    if (_archive_date.size() > 0) {
+                        for (size_t i = 0; i < _archive_date.size() - 1; i++) {
                             val +=
-                                    (_archive[i + 1].date - _archive[i].date) * _archive[i].x_dot;
+                                    (_archive_date[i + 1] - _archive_date[i]) * _archive_x_dot[i];
                         }
-                        val += (time - _archive.back().date) * _archive.back().x_dot;
+                        val += (time - _archive_date.back()) * _archive_x_dot.back();
                     }
                     return val;
                 }
 
                 double expected_value(const typename Time::type& /* time */) const
                 {
-                    double current_derivative = _archive.back().x_dot;
+                    double current_derivative = _archive_x_dot.back();
 
                     if (current_derivative == 0) {
                         return _current_value;
@@ -242,20 +274,7 @@ namespace artis {
                     return _down_threshold;
                 }
 
-                typedef enum {
-                    INIT,
-                    WAIT_FOR_QUANTA,
-                    WAIT_FOR_X_DOT,
-                    WAIT_FOR_BOTH,
-                    RUNNING
-                } State;
-
-                struct record_t {
-                    double x_dot;
-                    typename Time::type date;
-                };
-
-                State _state;
+                int _state;
 
                 typename Time::type _last_output_date;
 
@@ -267,7 +286,8 @@ namespace artis {
                 double _current_value;
                 double _expected_value;
 
-                std::deque<record_t> _archive;
+                std::vector<double> _archive_x_dot;
+                std::vector<typename Time::type> _archive_date;
             };
 
         }

+ 20 - 7
src/artis-star/kernel/pdevs/qss/Quantifier.hpp

@@ -55,12 +55,23 @@ namespace artis {
                     OUT = 1
                 };
 
+                enum states {
+                    STATE, ADAPTIVE_STATE, STEP_NUMBER, OFFSET, UP_THRESHOLD, DOWN_THRESHOLD
+                };
+
                 Quantifier(const std::string& name,
                         const Context<Time, Quantifier<Time>, QuantifierParameters>& context)
                         :
                         artis::pdevs::Dynamics<Time, Quantifier<Time>, QuantifierParameters>(name,
                                 context)
                 {
+                    DECLARE_STATES(int,
+                            ((STATE, &Quantifier<Time>::_state), (ADAPTIVE_STATE, &Quantifier<Time>::_adaptive_state)));
+                    DECLARE_STATES(unsigned int,
+                            ((STEP_NUMBER, &Quantifier<Time>::_step_number)));
+                    DECLARE_STATES(double,
+                            ((OFFSET, &Quantifier<Time>::_offset), (UP_THRESHOLD, &Quantifier<Time>::_up_threshold), (DOWN_THRESHOLD, &Quantifier<Time>::_down_threshold)));
+
                     this->input_port({IN, "in"});
                     this->output_port({OUT, "out"});
                     this->observables({{UP,    "up"},
@@ -341,21 +352,23 @@ namespace artis {
                     typename Time::type date;
                 };
 
-                State _state;
-                AdaptiveState _adaptive_state;
+                // parameters
                 bool _adaptive;
                 bool _zero_init_offset;
-
-                double _offset;
+                unsigned int _past_length;
                 double _step_size;
 
-                long int _step_number;
+                // state
+                int _state;
+                int _adaptive_state;
+
+                unsigned int _step_number; // long int
+
+                double _offset;
                 double _up_threshold;
                 double _down_threshold;
 
                 std::deque<record_t> _archive;
-
-                unsigned int _past_length;
             };
 
         }

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

@@ -61,11 +61,13 @@ namespace artis {
 
             virtual void restore(const common::context::State<Time>& state)
             {
+                common::Simulator<Time>::restore(state);
                 _dynamics.restore(state);
             }
 
             virtual void save(context::State<Time>& state) const
             {
+                common::Simulator<Time>::save(state);
                 _dynamics.save(state);
             }