summaryrefslogtreecommitdiff
path: root/core/pla_evolve.hpp
blob: 032d9d4b4ab3c883cf51a4edd9a4b5131df71199 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#ifndef FznMZXtH9pg7npfVO7D248udzM8
#define FznMZXtH9pg7npfVO7D248udzM8

#include <assert.h>

#include <boost/type_traits/is_same.hpp>

#include "context.hpp"
#include "continuous_property.hpp"
#include "template_helpers.hpp"
#include "pla_set.hpp"
#include "time.hpp"

// local state
//   general case: no action (and zero storage)
template<typename Prop, typename Quant1, typename Quant2>
struct PLA_Evolve_LocalState {
  template <typename PropComp, typename Context, typename LocalData>
  inline void evolve(PropComp &pc, Context context, LocalData &data, Time newTime) {
    DO_NOT_CALL;
  }

  template <typename PropComp, typename Context>
  inline void commit(PropComp &pc, Context context, Time time) {
    DO_NOT_CALL;
  }
};

//   matching case: get/set the value to local storage
template<typename Prop, typename Quant>
struct PLA_Evolve_LocalState<Prop, Quant, Quant> {
  typename Prop::type val;

  template <typename PropComp, typename Context, typename LocalData>
  inline void evolve(PropComp &pc, Context context, LocalData &data, Time newTime) {
    // calc time difference (= time amount we evolve)
    Time oldTime = data.data.getTime(newTime, context.template getptr<Quant>()());
    Time dt = newTime - oldTime;
    assert(dt >= 0);

    // calc new val and store locally
    val = ContinuousProperty_Evolve<PropComp, Prop, Quant, Context>::
      eval(pc, context, oldTime, dt);
  }

  template <typename PropComp, typename Context>
  inline void commit(PropComp &pc, Context context, Time time) {
    Ptr<Quant> dst(context.template getptr<Quant>());
    PLA_Set<Prop> pla_set(time, dst, val);
    pc.call(pla_set);
  }
};

// evolve action
template<typename Quant, typename Context = ContinuousContext<Quant> >
struct PLA_Evolve {
  // action types & consts
  typedef Void result_t;
  template<typename ContextProp, bool _doWriteResults>
  struct local_state_t
    : PLA_Evolve_LocalState<ContextProp, Quant, typename ContextProp::quant>
  {
    typedef ContextProp prop;
  };

  // action state & constructor
  typedef typename Quant::instance_ptr_t instance_ptr_t;
  Context context;
  Time newTime;
  result_t result;

  PLA_Evolve(Context context, Time newTime) : context(context), newTime(newTime) {}

  // action methods
  template<typename PropComp, typename LocalData, typename LocalState>
  inline void pre(PropComp &pc, LocalData &data, LocalState &state) {
    // if we have the correct quantity ...
    if (boost::is_same<Quant, typename LocalState::prop::quant>::value)
      state.evolve(pc, context, data, newTime); // ... evolve it
  }

  template<typename _PropComp, typename _LocalData, typename LocalState>
  inline void post(_PropComp &pc, _LocalData &data, LocalState &state) {
    // if we have the correct quantity ...
    if (boost::is_same<Quant, typename LocalState::prop::quant>::value)
      state.commit(pc, context, newTime); // ... store new value and time
  }
  
private:
    PLA_Evolve();
};

#endif // FznMZXtH9pg7npfVO7D248udzM8
contact: Jan Huwald // Impressum