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) Lumiera.org
5  2011, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
101 #ifndef LIB_TIME_CONTROL_POLICY_H
102 #define LIB_TIME_CONTROL_POLICY_H
103 
104 #include "lib/time/mutation.hpp"
105 #include "lib/time/timevalue.hpp"
106 
107 #include <boost/utility/enable_if.hpp>
108 #include <type_traits>
109 #include <functional>
110 
111 
112 namespace lib {
113 namespace time {
114 
115 namespace mutation {
116 
117  using boost::disable_if;
118  using std::__or_;
119  using std::is_same;
120  using std::placeholders::_1;
121  using std::function;
122  using std::bind;
123  using std::ref;
124 
125 
126 
127  namespace { // metaprogramming helpers to pick a suitable implementation branch...
128 
129  template<class T>
130  inline bool
131  isDuration()
132  {
133  return is_same<T, Duration>::value;
134  }
135 
136  template<class T>
137  inline bool
138  isTimeSpan()
139  {
140  return is_same<T, TimeSpan>::value;
141  }
142 
143  template<class T>
144  inline T const&
145  maybeMaterialise (T const& non_grid_aligned_TimeValue)
146  {
147  return non_grid_aligned_TimeValue;
148  }
149 
150 #ifdef LIB_TIME_TIMEQUANT_H
151  inline QuTime
152  maybeMaterialise (QuTime const& alignedTime)
153  {
154  PQuant const& grid(alignedTime);
155  return QuTime(grid->materialise(alignedTime), grid);
156  }
157 #endif //--quantised-time-support
158  }
159 
160 
166  template<class TI, class TAR>
167  struct Builder
168  {
169  static TI
170  buildChangedValue (TAR const& target)
171  {
172  return TI(target);
173  }
174  };
175  template<class TAR>
176  struct Builder<TimeSpan, TAR>
177  {
178  static TimeSpan
179  buildChangedValue (TAR const& target)
180  {
181  return TimeSpan (target, Duration::NIL);
182  }
183  };
184  template<>
186  {
187  static TimeSpan
188  buildChangedValue (Duration const& targetDuration)
189  {
190  return TimeSpan (Time::ZERO, targetDuration);
191  }
192  };
193  template<>
195  {
196  static TimeSpan
197  buildChangedValue (TimeSpan const& target)
198  {
199  return target;
200  }
201  };
202 #ifdef LIB_TIME_TIMEQUANT_H
203  template<class TAR>
204  struct Builder<QuTime, TAR>
205  {
206  static QuTime
207  buildChangedValue (TAR const& target)
208  {
209  return QuTime (target
211  );
212  }
213  };
214  template<>
215  struct Builder<QuTime, QuTime>
216  {
217  static QuTime
218  buildChangedValue (QuTime const& target)
219  {
220  return target;
221  }
222  };
223 #endif //--quantised-time-support
224 
225 
226 
227 
236  template<class TI, class TAR>
237  struct Link
238  : Mutation
239  , Builder<TI,TAR>
240  {
241 
242  template<class SRC>
243  static TI
244  processValueChange (TAR& target, SRC const& change)
245  {
246  imposeChange (target, maybeMaterialise(change));
247  return Link::buildChangedValue (maybeMaterialise(target));
248  }
249 
250  static TI
251  useLengthAsChange (TAR& target, TimeSpan const& change)
252  {
253  return processValueChange(target, change.duration());
254  }
255 
256  static TI
257  mutateLength (TimeSpan& target, Duration const& change)
258  {
259  imposeChange (target.duration(), change);
261  }
262 
263  static TimeSpan
264  mutateTimeSpan (TimeSpan& target, TimeSpan const& change)
265  {
266  imposeChange (target.duration(), change.duration());
267  imposeChange (target,change.start());
269  }
270 
271  static TI
272  dontChange (TAR& target)
273  {
274  return Link::buildChangedValue(target);
275  }
276  };
277 
278 
279 
294  template<class TI, class SRC, class TAR>
295  struct Policy
296  {
297  static function<TI(SRC const&)>
298  buildChangeHandler (TAR& target)
299  {
300  return bind (Link<TI,TAR>::template processValueChange<SRC>, ref(target), _1 );
301  }
302  };
303 
304 
305  // special treatment of Durations as target------------------------------------
306 
307  namespace {
308  template<class T>
310  : __or_< is_same<T,Duration>
311  , is_same<T,Offset>
312  , is_same<T,int>
313  >
314  { };
315 
316  template<class T>
318  : __or_< is_same<T,Duration>
319  , is_same<T,TimeSpan>
320  >
321  { };
322  }
323 
324 
331  template<class TI, class SRC>
332  struct Policy<TI,SRC, typename disable_if< canMutateDuration<SRC>,
333  Duration>::type>
334  {
335  static function<TI(SRC const&)>
336  buildChangeHandler (Duration& target)
337  {
338  return bind (Link<TI,Duration>::dontChange, ref(target) );
339  }
340  };
341 
348  template<class TAR>
349  struct Policy<Duration, typename disable_if< canReceiveDuration<TAR>,
350  Duration>::type, TAR>
351  {
352  static function<Duration(Duration const&)>
353  buildChangeHandler (TAR&)
354  {
355  return bind ( ignore_change_and_return_Zero );
356  }
357 
358  static Duration
359  ignore_change_and_return_Zero()
360  {
361  return Duration::NIL;
362  }
363  };
364 
365  template<class TI>
367  {
368  static function<TI(TimeSpan const&)>
369  buildChangeHandler (Duration& target)
370  {
371  return bind (Link<TI,Duration>::useLengthAsChange, ref(target), _1 );
372  }
373  };
374 
375 
376  // special treatment for TimeSpan values---------------------------------------
377 
378  template<class TI>
380  {
381  static function<TI(Duration const&)>
382  buildChangeHandler (TimeSpan& target)
383  {
384  return bind (Link<TI,TimeSpan>::mutateLength, ref(target), _1 );
385  }
386  };
387 
388  template<>
390  {
391  static function<TimeSpan(TimeSpan const&)>
392  buildChangeHandler (TimeSpan& target)
393  {
394  return bind (Link<TimeSpan,TimeSpan>::mutateTimeSpan, ref(target), _1 );
395  }
396  };
397 
398 
399 
400 }}} // namespace lib::time::mutation
401 #endif
Modifying time and timecode values.
Interface: an opaque change imposed onto some time value.
Definition: mutation.hpp:100
static const Duration NIL
constant to indicate "no duration"
Definition: timevalue.hpp:515
Implementation namespace for support and library code.
PQuant getDefaultGridFallback()
Definition: quantiser.cpp:47
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:477
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:582
a family of time value like entities and their relationships.
grid aligned time specification, referring to a specific scale.
Definition: timequant.hpp:99