diff --git a/src/lib/time/mutation.cpp b/src/lib/time/mutation.cpp index 3a8ae6681..6555c22b4 100644 --- a/src/lib/time/mutation.cpp +++ b/src/lib/time/mutation.cpp @@ -104,7 +104,7 @@ namespace time { /** * concrete time value mutation: - * impose fixed new start time. + * set a new overall duration for an extended timespan. */ class SetNewDuration : public ClonableMutation @@ -143,6 +143,46 @@ namespace time { }; + /** + * concrete time value mutation: + * adjust the given time entity by an offset amount. + */ + class ImposeOffsetMutation + : public ClonableMutation + { + Offset adjustment_; + + virtual void + change (Duration& target) const + { + imposeChange (target, TimeVar(target)+=adjustment_); + } + + + virtual void + change (TimeSpan& target) const + { + imposeChange (target, TimeVar(target)+=adjustment_); + } + + + /** @note the re-quantisation happens automatically + * when the (changed) QuTime is materialised */ + virtual void + change (QuTime& target) const + { + imposeChange (target, TimeVar(target)+=adjustment_); + } + + + public: + explicit + ImposeOffsetMutation (Offset adj) + : adjustment_(adj) + { } + }; + + /** Convenience factory to yield a simple Mutation changing the absolute start time. * This whole procedure might look quite inefficient, but actually most of the @@ -170,6 +210,17 @@ namespace time { } + /** Convenience factory: simple Mutation to adjust the duration or length of a timespan + * @throw error::Logic when attempting to change the "duration" of a quantised time point + * @return EncapsulatedMutation, carrying the new duration value to impose + */ + EncapsulatedMutation + Mutation::adjust (Offset change) + { + return EncapsulatedMutation::build (change); + } + + EncapsulatedMutation Mutation::nudge (int adjustment) { diff --git a/src/lib/time/mutation.hpp b/src/lib/time/mutation.hpp index fd66bb010..13c1b6bca 100644 --- a/src/lib/time/mutation.hpp +++ b/src/lib/time/mutation.hpp @@ -105,6 +105,7 @@ namespace time { static EncapsulatedMutation changeTime (Time); static EncapsulatedMutation changeDuration (Duration); + static EncapsulatedMutation adjust (Offset); static EncapsulatedMutation nudge (int adjustment); protected: diff --git a/src/lib/time/timevalue.hpp b/src/lib/time/timevalue.hpp index d7fe90b30..aa08c00ca 100644 --- a/src/lib/time/timevalue.hpp +++ b/src/lib/time/timevalue.hpp @@ -198,6 +198,9 @@ namespace time { { return TimeValue(std::llabs (t_)); } + + // Supporting sign flip + Offset operator- () const; }; //-- support linear offset chaining --------------- @@ -224,6 +227,11 @@ namespace time { return factor*distance; } + inline Offset + Offset::operator- () const + { + return -1 * (*this); + } diff --git a/src/proc/asset/meta.hpp b/src/proc/asset/meta.hpp index 77e08b71a..9ac73ea4f 100644 --- a/src/proc/asset/meta.hpp +++ b/src/proc/asset/meta.hpp @@ -48,7 +48,7 @@ ** and can be another already existing asset::Meta (inheriting from meta::Descriptor) ** Generally this yields a Builder object, which can be used for outfitting the new ** or changed metadata entry, finally \em committing this builder to yield a new - ** asset::Meta (which, in case of a mutation, might superseede an existin one). + ** asset::Meta (which, in case of a mutation, might supersede an existing one). ** ** @see asset.hpp explanation of assets in general ** @see MetaFactory creating concrete asset::Meta instances @@ -120,7 +120,8 @@ namespace asset { public: static MetaFactory create; - virtual const ID& getID() const ///< @return ID of kind Meta + /** @return ID of kind Meta */ + virtual const ID& getID() const { return static_cast& > (Asset::getID()); } diff --git a/tests/lib/time/time-mutation-test.cpp b/tests/lib/time/time-mutation-test.cpp index 3a973763b..65bd35612 100644 --- a/tests/lib/time/time-mutation-test.cpp +++ b/tests/lib/time/time-mutation-test.cpp @@ -157,9 +157,30 @@ namespace test{ void - mutate_by_Offset (TimeValue o, Offset change) + mutate_by_Offset (TimeValue original, Offset change) { - TestValues t(o); + TestValues t(original); + TimeValue& should_be(t.var+=change); // use as ref for verification + + CHECK (t.span == original); + CHECK (t.span != should_be); + t.span.accept (Mutation::adjust (change)); + CHECK (t.span == should_be); + + t.dur.accept (Mutation::adjust (change)); + CHECK (t.dur == should_be); + + t.quant.accept (Mutation::adjust (change)); + CHECK (t.quant == should_be); + + // adjustment is cumulative + EncapsulatedMutation back_off = Mutation::adjust (-change); + t.span.accept (back_off); + CHECK (t.span == original); + t.span.accept (back_off); + t.span.accept (back_off); + t.span.accept (back_off); + CHECK (t.span == Time(original) - 3*change); }