summaryrefslogtreecommitdiff
path: root/core/pla_generate.hpp
blob: 7ae516926e47df702fc19dc90285fd0f06e763ea (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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#ifndef Vaz5kkzRinGGCeloVow8grqZI1c
#define Vaz5kkzRinGGCeloVow8grqZI1c

// HINT: simple schema, based on the fact the this PLA changes only
// props it does not depend on (read from)

#include <assert.h>

#include <boost/type_traits/is_same.hpp>
#include <boost/tuple/tuple.hpp>

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

namespace PLA_Generate_Impl {

  using namespace boost;
  using namespace boost::mpl;

  // local state
  //   general case: no action (and zero storage)
  template<typename Prop, typename CQ, typename DQ, bool quantMatch /* == false */>
  struct LocalState {
    template<typename PropComp, typename Context, typename MI, typename MQ>
    inline void process(PropComp &, Context, Time, MI &, MQ &) {}

    template <typename PropComp, typename Context>
    inline void commit(PropComp &, Context, Time) {}
  };
  
  //   matching case: get/set the value to local storage
  template<typename Prop, typename CQ, typename DQ>
  struct LocalState<Prop, CQ, DQ, true /* == quantMatch */> {
    typename Prop::type val;

    template<typename PropComp, typename Context, typename MI, typename MQ>
    inline void process(PropComp &pc, Context context, Time time,
			MI &indices, MQ &queues) {
      // calc new val and store locally
      // TODO: check generation of discrete properties
      ContinuousProperty_Generate<Prop, CQ, DQ>::
	eval(pc, context, time, val, indices, queues);
    }

    template <typename PropComp, typename Context>
    inline void commit(PropComp &pc, Context context, Time time) {
      // HINT: caller has to check if we should commit
      typedef typename Prop::quant Quant;
      Ptr<Quant> dst(context.template getptr<Quant>());
      PLA_Set<Prop> pla_set(time, dst, val); // TODO: omit time if Prop is discrete
      pc.call(pla_set);
    }
  };

  // generate action
  template<typename CQ, typename DQ, typename MI, typename MQ>
  struct PLA_Generate {
    // action types & consts
    typedef Void result_t;
    template<typename ContextProp, bool doWriteResults>
    struct local_state_t : LocalState<ContextProp, CQ, DQ,
				      or_<is_same<CQ, typename ContextProp::quant>,
					  is_same<DQ, typename ContextProp::quant>
					  >::value>
    {
      typedef ContextProp prop;
      static const bool write = doWriteResults;
    };
    typedef EmitContext<CQ, DQ> context_t;
    
    // action state & constructor
    context_t context;
    Time time;
    result_t result;

    MI &indices;
    MQ &queues;
    
    PLA_Generate(Time time, context_t context, MI &indices, MQ &queues)
      : context(context), time(time), indices(indices), queues(queues) {}
    
    // action methods
    template<typename PropComp, typename LocalData, typename LocalState>
    inline void pre(PropComp &pc, LocalData &, LocalState &state) {
      // if we have the correct quantity (and ought to write to it)
      typedef typename LocalState::prop Prop;
      typedef typename Prop::quant Quant;
      if (   (is_same<CQ, Quant>::value and ContinuousProperty_Generate
	      <Prop, CQ, DQ>::changesValue)
	  or (is_same<DQ, typename LocalState::prop::quant>::value and state.write))
	state.process(pc, context, time, indices, queues);
    }
    
    template<typename PropComp, typename _LocalData, typename LocalState>
    inline void post(PropComp &pc, _LocalData &data, LocalState &state) {
      typedef typename LocalState::prop Prop;
      typedef typename Prop::quant Quant;
      if (   (is_same<CQ, Quant>::value and ContinuousProperty_Generate
	      <Prop, CQ, DQ>::changesValue)
	  or (is_same<DQ, typename LocalState::prop::quant>::value and state.write))
	state.commit(pc, context, time); // ... store new value and time
    }

  private:
    PLA_Generate();
  };
}

using PLA_Generate_Impl::PLA_Generate;

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