Eric Ramat 1 anno fa
parent
commit
f687e12b1f

+ 4 - 1
src/artis-star/common/RootCoordinator.hpp

@@ -88,6 +88,9 @@ public :
     } else {
       _tn = _root.start(_tn);
     }
+    if (_tn > context.begin()) {
+      _observer.observe(context.begin(), _tn, false);
+    }
     while (_tn <= _t_max) {
       typename Time::type next_tn;
 
@@ -96,7 +99,7 @@ public :
 
       assert(next_tn >= _tn);
 
-      _observer.observe(_tn, _t_max < next_tn ? _t_max : next_tn);
+      _observer.observe(_tn, _t_max < next_tn ? _t_max : next_tn, _t_max < next_tn);
       _tn = next_tn;
     }
   }

+ 22 - 11
src/artis-star/common/observer/Observer.hpp

@@ -40,7 +40,7 @@ public:
   typedef std::map<std::string, View<Time> *> Views;
 
   Observer(const common::Model<Time> *model)
-    : _step(0), _model(model) {}
+    : _step(0), _model(model), _last_time(0), _init(false) {}
 
   virtual ~Observer() {
     for (typename Views::iterator it = _views.begin(); it != _views.end(); ++it) {
@@ -54,13 +54,13 @@ public:
   }
 
   Views *cloneViews() const {
-    Views *v = new Views();
+    auto view = new Views();
 
     for (typename Views::const_iterator it = _views.begin();
          it != _views.end(); ++it) {
-      (*v)[it->first] = it->second->clone();
+      (*view)[it->first] = it->second->clone();
     }
-    return v;
+    return view;
   }
 
   const View<Time> &view(const std::string &name) const {
@@ -69,18 +69,27 @@ public:
 
   const Views &views() const { return _views; }
 
-  void init() {}
+  void init() { }
 
-  void observe(double t, double next_t) {
+  void observe(double t, double next_t, bool finish) {
     if (_step == 0) {
       observe(t);
+      _last_time = t;
     } else {
-      double time = std::floor((t + epsilon) / _step) * _step;
+      if (not _init) {
+        observe(t);
+        _last_time = t;
+        _init = true;
+      }
+
+      double next_last_time = std::floor((_last_time + _step + epsilon) / _step) * _step;
 
-      while (time < next_t and std::abs(time - next_t) > epsilon) {
-        observe(time);
-        time += _step;
-        time = std::floor((time + epsilon) / _step) * _step;
+      if (t <= next_last_time and (next_t > next_last_time or finish)) {
+        do {
+          observe(next_last_time);
+          _last_time = next_last_time;
+          next_last_time = std::floor((_last_time + _step + epsilon) / _step) * _step;
+        } while (t < next_last_time and next_t > next_last_time);
       }
     }
   }
@@ -105,6 +114,8 @@ private:
   double _step;
   const common::Model<Time> *_model;
   Views _views;
+  double _last_time;
+  bool _init;
 };
 
 }

+ 8 - 8
src/artis-star/common/observer/View.hpp

@@ -194,7 +194,7 @@ public:
                 selector_name, variable_index);
       }
     } else {
-      if (model) {
+      if (model != nullptr) {
         observe(time, model, selector_name, variable_index);
       }
     }
@@ -210,7 +210,7 @@ public:
 
         observe(it->second, i, time, model, it->first, it->second.back());
       } else {
-        if (model) {
+        if (model != nullptr) {
           observe(time, model, it->first, it->second.back());
         }
       }
@@ -221,13 +221,13 @@ public:
       auto it = _values.begin();
 
       while (it != _values.end() and ok) {
-        const auto &v = it->second.begin()->second;
+        const auto &value = it->second.begin()->second;
 
-        if (v.back().second.is_null()) {
+        if (value.back().second.is_null()) {
           ++it;
         } else {
-          if (v.size() > 1) {
-            if (v.back().second == v[v.size() - 2].second) {
+          if (value.size() > 1) {
+            if (value.back().second == value[value.size() - 2].second) {
               ++it;
             } else {
               ok = false;
@@ -238,8 +238,8 @@ public:
         }
       }
       if (ok) {
-        for (auto &v: _values) {
-          v.second.begin()->second.pop_back();
+        for (auto &value: _values) {
+          value.second.begin()->second.pop_back();
         }
       }
     }

+ 1 - 1
tests/common_observe.cpp

@@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(Common_Observe_TestCase_2)
   view->selector("value", {MyDynamics::vars::VALUE});
   observer.attachView("global", view);
   observer.init();
-  observer.observe(0, 1);
+  observer.observe(0, 1, true);
 
   BOOST_REQUIRE_EQUAL(observer.views().at("global")->get("value").back().second, ref);
   BOOST_REQUIRE_EQUAL(observer.view("global").get("value").back().second, ref);