diff --git a/src/lib/time/control.hpp b/src/lib/time/control.hpp index 60809e53d..ba9fba5ce 100644 --- a/src/lib/time/control.hpp +++ b/src/lib/time/control.hpp @@ -62,27 +62,15 @@ #include "lib/meta/util.hpp" #include "lib/time/mutation.hpp" #include "lib/time/timevalue.hpp" -//#include "lib/symbol.hpp" -//#include -//#include -//#include #include #include #include -//#include namespace lib { namespace time { -//using lib::Symbol; -//using std::string; -//using lib::Literal; - - -//LUMIERA_ERROR_DECLARE (INVALID_MUTATION); ///< Changing a time value in this way was not designated - namespace mutation { using boost::enable_if; @@ -94,17 +82,23 @@ namespace time { using std::tr1::ref; - template - struct Mutabor; - /** * Implementation building block: impose changes to a Time element. - * The Mutator supports attaching a target time entity (through - * the Mutation interface), which then will be subject to any - * received value changes, offsets and grid nudging. - * - * @todo WIP-WIP-WIP + * The purpose of the Mutator is to attach a target time entity, + * which then will be subject to any received value changes, + * offsets and grid nudging. The actual attachment is to be + * performed in a subclass, by using the Mutation interface. + * When attaching to a target, the Mutator will be outfitted + * with a set of suitable functors, incorporating the specific + * behaviour for the concrete combination of input changes + * ("source values") and target object type. This works by + * binding to the appropriate implementation functionality, + * guided by a templated policy class. After installing + * these functors, these decisions remains opaque and + * encapsulated within the functor objects, so the + * mutator object doesn't need to carry this + * type information on the interface */ template class Mutator @@ -114,18 +108,6 @@ namespace time { typedef function Ofsetter; typedef function Nudger; - static TI imposeValueChange(TimeValue& target, TI const&); - static TI imposeOffset (TimeValue& target, Offset const&); - static TI imposeNudge (TimeValue& target, int); - - static TI changeDuration (Duration& target, TI const&); -// static TI nudgeDuration (Duration& target, int); - - template - struct MutationPolicy; - - friend class Mutabor; - protected: mutable ValueSetter setVal_; mutable Ofsetter offset_; @@ -140,66 +122,84 @@ namespace time { ,error::LUMIERA_ERROR_UNCONNECTED); } - public: - // using default construction and copy template void bind_to (TAR& target) const; void unbind(); + // using default construction and copy }; + + + /** + * Implementation building block: propagate changes to listeners. + * The Propagator manages a set of callback signals, allowing to + * propagate notifications for changed Time values. + * + * There are no specific requirements on the acceptable listeners, + * besides exposing a function-call operator to feed the changed + * time value to. Both Mutator and Propagator employ one primary + * template parameter, which is the type of the time values + * to be fed in and propagated. + */ template - struct Mutabor + class Propagator { + typedef function ChangeSignal; + typedef std::vector ListenerList; - static void - imposeChange (TimeValue& target, TI const& newVal) + ListenerList listeners_; + + public: + /** install notification receiver */ + template + void + attach (SIG const& toNotify) { - Mutator::imposeChange (target,newVal); + ChangeSignal newListener (ref(toNotify)); + listeners_.push_back (newListener); + } + + /** disconnect any observers */ + void + disconnnect() + { + listeners_.clear(); + } + + /** publish a change */ + TI + operator() (TI const& changedVal) const + { + typedef typename ListenerList::const_iterator Iter; + Iter p = listeners_.begin(); + Iter e = listeners_.end(); + + for ( ; p!=e; ++p ) + (*p) (changedVal); + return changedVal; } }; - namespace { // metaprogramming helpers to pick the suitable Instantiation... - - template - struct isDurationZ - { - static const bool value = is_sameType::value; - }; - template - struct isTimeSpanZ - { - static const bool value = is_sameType::value; - }; - template - struct isQuTime - { - static const bool value = is_sameType::value; - }; - - template - struct isSpecialCase - { - static const bool value = isDurationZ::value; - }; + namespace { // metaprogramming helpers to pick suitable implementation branch... template inline bool isDuration() - { - return is_sameType::value; - } + { + return is_sameType::value; + } template inline bool isTimeSpan() - { - return is_sameType::value; - } + { + return is_sameType::value; + } template inline T const& @@ -207,6 +207,7 @@ namespace time { { return non_grid_aligned_TimeValue; } + #ifdef LIB_TIME_TIMEQUQNT_H inline QuTime maybeMaterialise (QuTime const& alignedTime) @@ -233,7 +234,7 @@ namespace time { static TimeSpan buildChangedValue (TAR const& target) { - return TimeSpan (target, Duration::NIL); /////////////TODO how to feed the "new value" duration???? + return TimeSpan (target, Duration::NIL); } }; template<> @@ -278,7 +279,7 @@ namespace time { #endif template - struct Adap + struct Link : Mutator , Builder { @@ -328,7 +329,7 @@ namespace time { static function buildChangeHandler (TAR& target) { - return bind (Adap::template processValueChange, ref(target), _1 ); + return bind (Link::template processValueChange, ref(target), _1 ); } }; @@ -350,9 +351,9 @@ namespace time { static const bool value = is_sameType::value || is_sameType::value; }; - } + template struct Policy, Duration>::type> @@ -360,7 +361,7 @@ namespace time { static function buildChangeHandler (Duration& target) { - return bind (Adap::dontChange, ref(target) ); + return bind (Link::dontChange, ref(target) ); } }; @@ -381,23 +382,13 @@ namespace time { } }; -// template -// struct Policy -// { -// static function -// buildChangeHandler (Duration& target) -// { -// return bind (Adap::template processValueChange, ref(target), _1 ); -// } -// }; - template struct Policy { static function buildChangeHandler (Duration& target) { - return bind (Adap::useLengthAsChange, ref(target), _1 ); + return bind (Link::useLengthAsChange, ref(target), _1 ); } }; @@ -409,7 +400,7 @@ namespace time { static function buildChangeHandler (TimeSpan& target) { - return bind (Adap::mutateLength, ref(target), _1 ); + return bind (Link::mutateLength, ref(target), _1 ); } }; @@ -419,201 +410,11 @@ namespace time { static function buildChangeHandler (TimeSpan& target) { - return bind (Adap::mutateTimeSpan, ref(target), _1 ); + return bind (Link::mutateTimeSpan, ref(target), _1 ); } }; -/* - template - struct Policy - { - static function - buildChangeHandler (TAR& target) - { - return bind (Adap::imposeOffset, ref(target), _1 ); - } - }; - - template - struct Policy - { - static function - buildChangeHandler (TAR& target) - { - return bind (Adap::imposeNudge, ref(target), _1 ); - } - }; -*/ - - template - TI - Mutator::imposeValueChange (TimeValue& target, TI const& newVal) - { - return TI (Mutation::imposeChange (target,newVal)); - } - template - TI - Mutator::imposeOffset (TimeValue& target, Offset const& off) - { - return TI (Mutation::imposeChange (target, TimeVar(target)+off)); - } - template - TI - Mutator::imposeNudge (TimeValue& target, int off_by_steps) - { - return TI (Mutation::imposeChange (target, TimeVar(target)+Time(FSecs(off_by_steps)))); //////////////////TICKET #810 - } - - // special cases... - template - TI - Mutator::changeDuration (Duration&, TI const&) - { - return TI (Time::ZERO); - } - template<> - Duration - Mutator::changeDuration (Duration& target, Duration const& changedDur) - { - return Duration (Mutation::imposeChange (target,changedDur)); - } - template<> - TimeSpan - Mutator::changeDuration (Duration& target, TimeSpan const& timeSpan_to_impose) - { - return TimeSpan (timeSpan_to_impose.start() - ,Duration(Mutation::imposeChange (target,timeSpan_to_impose.duration())) - ); - } - - template<> - TimeSpan - Mutator::imposeValueChange (TimeValue& target, TimeSpan const& newVal) - { - Mutation::imposeChange (target,newVal); - return newVal; - } - template<> - TimeSpan - Mutator::imposeOffset (TimeValue& target, Offset const& off) - { - return TimeSpan (Mutation::imposeChange (target, TimeVar(target)+off), Duration::NIL); - } - template<> - TimeSpan - Mutator::imposeNudge (TimeValue& target, int off_by_steps) - { - return TimeSpan (Mutation::imposeChange (target, TimeVar(target)+Time(FSecs(off_by_steps))), Duration::NIL); - } - - -#ifdef LIB_TIME_TIMEQUQNT_H - template<> - QuTime - Mutator::changeDuration (Duration&, QuTime const& irrelevantChange) - { - return QuTime (Time::ZERO, PQuant(irrelevantChange)); - } - template<> - QuTime - Mutator::imposeValueChange (TimeValue& target, QuTime const& grid_aligned_Value_to_set) - { - PQuant quantiser (grid_aligned_Value_to_set); - TimeValue appliedChange = quantiser->materialise(grid_aligned_Value_to_set); - Mutation::imposeChange (target, appliedChange); - return QuTime (target, quantiser); - } - template<> - QuTime - Mutator::imposeOffset (TimeValue& target, Offset const& off) - { - return QuTime (Mutation::imposeChange (target, TimeVar(target)+off) - ,getDefaultGridFallback() //////////////////TICKET #810 - ); - } - template<> - QuTime - Mutator::imposeNudge (TimeValue& target, int off_by_steps) - { - return QuTime (Mutation::imposeChange (target, TimeVar(target)+Time(FSecs(off_by_steps))) - ,getDefaultGridFallback() //////////////////TICKET #810 - ); - } -#endif //(End)quantisation special case - - template - template - struct Mutator::MutationPolicy< typename disable_if< isSpecialCase, - TI>::type, TAR> - { - static function - buildChangeHandler (TAR& target) - { - return bind (Mutator::imposeValueChange, ref(target), _1 ); - } - }; - - template - template - struct Mutator::MutationPolicy - { - static function - buildChangeHandler (TAR& target) - { - return bind (Mutator::imposeOffset, ref(target), _1 ); - } - }; - - template - template - struct Mutator::MutationPolicy - { - static function - buildChangeHandler (TAR& target) - { - return bind (Mutator::imposeNudge, ref(target), _1 ); - } - }; - - - //special cases for changing Durations.... - - template - template - struct Mutator::MutationPolicy< typename enable_if< isDurationZ, - TI>::type, TAR> - { - static function - buildChangeHandler (Duration& target) - { - return bind (Mutator::changeDuration, ref(target), _1 ); - } - }; - - // -// template -// template -// struct Mutator::MutationPolicy -// { -// static function -// buildChangeHandler (Duration& target) -// { -// return bind (Mutator::changeDuration, ref(target), _1 ); -// } -// }; - -// template -// template<> -// struct Mutator::MutationPolicy -// { -// static function -// buildChangeHandler (Duration& target) -// { -// return bind (Mutator::nudgeDuration, ref(target), _1 ); -// } -// }; - @@ -637,59 +438,12 @@ namespace time { nudge_ = Nudger(); } - - - /** - * Implementation building block: propagate changes to listeners. - * The Propagator manages a set of callback signals, allowing to - * propagate notifications for changed Time values. - * - * @todo WIP-WIP-WIP - */ - template - class Propagator - { - typedef function ChangeSignal; - typedef std::vector ListenerList; - - ListenerList listeners_; - - public: - /** install notification receiver */ - template - void - attach (SIG const& toNotify) - { - ChangeSignal newListener (ref(toNotify)); - listeners_.push_back (newListener); - } - - /** disconnect any observers */ - void - disconnnect() - { - listeners_.clear(); - } - - /** publish a change */ - TI - operator() (TI const& changedVal) const - { - typedef typename ListenerList::const_iterator Iter; - Iter p = listeners_.begin(); - Iter e = listeners_.end(); - - for ( ; p!=e; ++p ) - (*p) (changedVal); - return changedVal; - } - }; } /** - * Frontend/Interface: controller-element for retrieving and - * changing running time values + * Frontend/Interface: controller-element to retrieve + * and change running time values * * @see time::Mutation * @see time::TimeSpan#accept(Mutation const&) @@ -725,7 +479,7 @@ namespace time { - /* === implementation === */ + /* === forward to implementation === */ template void