Lumiera  0.pre.03
»edit your freedom«
control-policy.hpp
Go to the documentation of this file.
1 /*
2  CONTROL-POLICY.hpp - detail definition of actual time changing functionality
3 
4  Copyright (C)
5  2011, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
92 #ifndef LIB_TIME_CONTROL_POLICY_H
93 #define LIB_TIME_CONTROL_POLICY_H
94 
95 #include "lib/time/mutation.hpp"
96 #include "lib/time/timevalue.hpp"
97 
98 #include <boost/utility/enable_if.hpp>
99 #include <type_traits>
100 #include <functional>
101 
102 
103 namespace lib {
104 namespace time {
105 
106 namespace mutation {
107 
108  using boost::disable_if;
109  using std::__or_;
110  using std::is_same;
111  using std::placeholders::_1;
112  using std::function;
113  using std::bind;
114  using std::ref;
115 
116 
117 
118  namespace { // metaprogramming helpers to pick a suitable implementation branch...
119 
120  template<class T>
121  inline bool
122  isDuration()
123  {
124  return is_same<T, Duration>::value;
125  }
126 
127  template<class T>
128  inline bool
129  isTimeSpan()
130  {
131  return is_same<T, TimeSpan>::value;
132  }
133 
134  template<class T>
135  inline T const&
136  maybeMaterialise (T const& non_grid_aligned_TimeValue)
137  {
138  return non_grid_aligned_TimeValue;
139  }
140 
141 #ifdef LIB_TIME_TIMEQUANT_H
142  inline QuTime
143  maybeMaterialise (QuTime const& alignedTime)
144  {
145  PQuant const& grid(alignedTime);
146  return QuTime(grid->materialise(alignedTime), grid);
147  }
148 #endif //--quantised-time-support
149  }
150 
151 
157  template<class TI, class TAR>
158  struct Builder
159  {
160  static TI
161  buildChangedValue (TAR const& target)
162  {
163  return TI(target);
164  }
165  };
166  template<class TAR>
167  struct Builder<TimeSpan, TAR>
168  {
169  static TimeSpan
170  buildChangedValue (TAR const& target)
171  {
172  return TimeSpan (target, Duration::NIL);
173  }
174  };
175  template<>
177  {
178  static TimeSpan
179  buildChangedValue (Duration const& targetDuration)
180  {
181  return TimeSpan (Time::ZERO, targetDuration);
182  }
183  };
184  template<>
186  {
187  static TimeSpan
188  buildChangedValue (TimeSpan const& target)
189  {
190  return target;
191  }
192  };
193 #ifdef LIB_TIME_TIMEQUANT_H
194  template<class TAR>
195  struct Builder<QuTime, TAR>
196  {
197  static QuTime
198  buildChangedValue (TAR const& target)
199  {
200  return QuTime (target
202  );
203  }
204  };
205  template<>
206  struct Builder<QuTime, QuTime>
207  {
208  static QuTime
209  buildChangedValue (QuTime const& target)
210  {
211  return target;
212  }
213  };
214 #endif //--quantised-time-support
215 
216 
217 
218 
227  template<class TI, class TAR>
228  struct Link
229  : Mutation
230  , Builder<TI,TAR>
231  {
232 
233  template<class SRC>
234  static TI
235  processValueChange (TAR& target, SRC const& change)
236  {
237  imposeChange (target, maybeMaterialise(change));
238  return Link::buildChangedValue (maybeMaterialise(target));
239  }
240 
241  static TI
242  useLengthAsChange (TAR& target, TimeSpan const& change)
243  {
244  return processValueChange(target, change.duration());
245  }
246 
247  static TI
248  mutateLength (TimeSpan& target, Duration const& change)
249  {
250  imposeChange (target.duration(), change);
252  }
253 
254  static TimeSpan
255  mutateTimeSpan (TimeSpan& target, TimeSpan const& change)
256  {
257  imposeChange (target.duration(), change.duration());
258  imposeChange (target,change.start());
260  }
261 
262  static TI
263  dontChange (TAR& target)
264  {
265  return Link::buildChangedValue(target);
266  }
267  };
268 
269 
270 
285  template<class TI, class SRC, class TAR>
286  struct Policy
287  {
288  static function<TI(SRC const&)>
289  buildChangeHandler (TAR& target)
290  {
291  return bind (Link<TI,TAR>::template processValueChange<SRC>, ref(target), _1 );
292  }
293  };
294 
295 
296  // special treatment of Durations as target------------------------------------
297 
298  namespace {
299  template<class T>
301  : __or_< is_same<T,Duration>
302  , is_same<T,Offset>
303  , is_same<T,int>
304  >
305  { };
306 
307  template<class T>
309  : __or_< is_same<T,Duration>
310  , is_same<T,TimeSpan>
311  >
312  { };
313  }
314 
315 
322  template<class TI, class SRC>
323  struct Policy<TI,SRC, typename disable_if< canMutateDuration<SRC>,
324  Duration>::type>
325  {
326  static function<TI(SRC const&)>
327  buildChangeHandler (Duration& target)
328  {
329  return bind (Link<TI,Duration>::dontChange, ref(target) );
330  }
331  };
332 
339  template<class TAR>
340  struct Policy<Duration, typename disable_if< canReceiveDuration<TAR>,
341  Duration>::type, TAR>
342  {
343  static function<Duration(Duration const&)>
344  buildChangeHandler (TAR&)
345  {
346  return bind ( ignore_change_and_return_Zero );
347  }
348 
349  static Duration
350  ignore_change_and_return_Zero()
351  {
352  return Duration::NIL;
353  }
354  };
355 
356  template<class TI>
358  {
359  static function<TI(TimeSpan const&)>
360  buildChangeHandler (Duration& target)
361  {
362  return bind (Link<TI,Duration>::useLengthAsChange, ref(target), _1 );
363  }
364  };
365 
366 
367  // special treatment for TimeSpan values---------------------------------------
368 
369  template<class TI>
371  {
372  static function<TI(Duration const&)>
373  buildChangeHandler (TimeSpan& target)
374  {
375  return bind (Link<TI,TimeSpan>::mutateLength, ref(target), _1 );
376  }
377  };
378 
379  template<>
381  {
382  static function<TimeSpan(TimeSpan const&)>
383  buildChangeHandler (TimeSpan& target)
384  {
385  return bind (Link<TimeSpan,TimeSpan>::mutateTimeSpan, ref(target), _1 );
386  }
387  };
388 
389 
390 
391 }}} // namespace lib::time::mutation
392 #endif
Modifying time and timecode values.
Interface: an opaque change imposed onto some time value.
Definition: mutation.hpp:91
static const Duration NIL
constant to indicate "no duration"
Definition: timevalue.hpp:506
Implementation namespace for support and library code.
PQuant getDefaultGridFallback()
Definition: quantiser.cpp:38
Policy how to impose changes onto a connected target time value entity This policy will be parametris...
Duration is the internal Lumiera time metric.
Definition: timevalue.hpp:468
Implementation policy: how to build a new notification value of type TI, given a target time value en...
A time interval anchored at a specific point in time.
Definition: timevalue.hpp:573
a family of time value like entities and their relationships.
grid aligned time specification, referring to a specific scale.
Definition: timequant.hpp:90