diff --git a/src/lib/time/timevalue.hpp b/src/lib/time/timevalue.hpp index 014d3283d..315f192cb 100644 --- a/src/lib/time/timevalue.hpp +++ b/src/lib/time/timevalue.hpp @@ -240,18 +240,15 @@ namespace time { * * Lumiera Time provides some limited capabilities for * direct manipulation; Time values can be created directly - * from \c (h,m,s,ms) specification and there is an string - * representation intended for internal use (reporting and - * debugging). Any real output, formatting and persistent + * from \c (ms,sec,min,hour) specification and there is an + * string representation intended for internal use (reporting + * and debugging). Any real output, formatting and persistent * storage should be based on the (quantised) timecode * formats though, which can be generated from time values. * - * Non constant Time objects can receive an encapsulated - * \em mutation message, which is also the basis for - * changing time spans, durations and for re-aligning - * quantised values to some other grid. - * - * @todo define these mutations + * Similar to TimeValue, also Time objects are considered + * immutable values. As convenience shortcut, some operators + * are provided, creating a TimVar for further calculations. */ class Time : public TimeValue @@ -300,10 +297,8 @@ namespace time { /** * Duration is the internal Lumiera time metric. * It is an absolute (positive) value, but can be - * promoted from an offset. Similar to Time, - * Duration can receive mutation messages. - * - * @todo define these mutations + * promoted from an offset. Like plain TimeValue, + * Duration is an immutable value. */ class Duration : public Offset @@ -342,8 +337,13 @@ namespace time { * to fully specify the temporal properties of an * object within the model. * - * Similar to Time and Duration, a TimeSpan may - * also receive an (opaque) mutation message. + * As an exception to the generally immutable Time + * entities, a non constant TimeSpan may receive + * \em mutation messages, both for the start point + * and the duration. This allows for changing + * position and length of objects in the timeline. + * + * @todo define these mutations */ class TimeSpan : public Time @@ -351,11 +351,16 @@ namespace time { Duration dur_; public: - TimeSpan(Time start, Duration length) + TimeSpan(TimeValue start, Duration length) : Time(start) , dur_(length) { } - ///////////TODO creating timespans needs to be more convenient.... + + TimeSpan(TimeValue start, FSecs(duration_in_secs)) + : Time(start) + , dur_(duration_in_secs) + { } + Duration duration() const @@ -363,6 +368,12 @@ namespace time { return dur_; } + Time + start() const + { + return *this; + } + Time end() const { diff --git a/tests/lib/time/time-value-test.cpp b/tests/lib/time/time-value-test.cpp index e73354ea8..06cb251e7 100644 --- a/tests/lib/time/time-value-test.cpp +++ b/tests/lib/time/time-value-test.cpp @@ -71,11 +71,12 @@ namespace test{ checkBasicTimeValues (ref); checkMutableTime (ref); - checkTimeConveniance (ref); + checkTimeConvenience (ref); verify_invalidFramerateProtection(); createOffsets (ref); buildDuration (ref); buildTimeSpan (ref); + compareTimeSpan (ref); } @@ -159,7 +160,7 @@ namespace test{ * especially by the canonical Time values. */ void - checkTimeConveniance (TimeValue org) + checkTimeConvenience (TimeValue org) { Time o1(org); TimeVar v(org); @@ -296,15 +297,91 @@ namespace test{ CHECK (theLength == Offset(org,five).abs()); Time endpoint = interval.end(); - TimeSpan successor (endpoint, Duration(Time(0,2,0,0))); + TimeSpan successor (endpoint, FSecs(2)); CHECK (Offset(interval,endpoint) == Offset(org,five).abs()); CHECK (Offset(endpoint,successor.end()) == Duration(successor)); - cout << "Interval-1: " << interval - << " Interval-2: " << successor + cout << "Interval-1: " << interval + << " Interval-2: " << successor << " End point: " << successor.end() - << endl; + << endl; + } + + + void + compareTimeSpan (TimeValue org) + { + TimeSpan span1 (Time(org), Duration(Time(org))); + TimeSpan span2 (Time(org), Offset(org, TimeValue(0))); + TimeSpan span3 (Time(org), FSecs(5,2)); + TimeSpan span4 (Time(org), FSecs(5,-2)); + + CHECK (span1 == span2); + CHECK (span2 == span1); + CHECK (span3 == span4); + CHECK (span4 == span3); + + CHECK (span1 != span3); + CHECK (span3 != span1); + CHECK (span1 != span4); + CHECK (span4 != span1); + CHECK (span2 != span3); + CHECK (span3 != span2); + CHECK (span2 != span4); + CHECK (span4 != span2); + + // especially note that creating a TimeSpan + // based on offset will take the offset absolute + CHECK (span1.end() == span2.end()); + CHECK (span3.end() == span4.end()); + + // Verify the extended order on time intervals + TimeSpan span1x (Time(org)+Time(org), Duration(Time(org))); // starting later than span1 + TimeSpan span3y (Time(org), FSecs(2)); // shorter than span3 + TimeSpan span3z (Time(org)+Time(org), FSecs(2)); // starting later and shorter than span3 + + CHECK (span1 != span1x); + CHECK (span3 != span3y); + CHECK (span3 != span3z); + + CHECK ( span1 < span1x); + CHECK ( span1 <= span1x); + CHECK (!(span1 > span1x)); + CHECK (!(span1 >= span1x)); + + CHECK ( span3 > span3y); + CHECK ( span3 >= span3y); + CHECK (!(span3 < span3y)); + CHECK (!(span3 <= span3y)); + + CHECK ( span3 < span3z); // Note: the start point takes precedence on comparison + CHECK ( span3y < span3z); + + // Verify this order is really different + // than the basic ordering of time values + CHECK (span1 < span1x); + CHECK (span1.duration() == span1x.duration()); + CHECK (span1.start() < span1x.start()); + CHECK (span1.end() < span1x.end()); + + CHECK (span3 > span3y); + CHECK (span3.duration() > span3y.duration()); + CHECK (span3.start() == span3y.start()); + CHECK (span3.end() == span3y.end()); + CHECK (Time(span3) == Time(span3y)); + + CHECK (span3 < span3z); + CHECK (span3.duration() > span3z.duration()); + CHECK (span3.start() < span3z.start()); + CHECK (span3.end() < span3z.end()); + CHECK (Time(span3) < Time(span3z)); + + CHECK (span3y < span3z); + CHECK (span3y.duration() == span3z.duration()); + CHECK (span3y.start() < span3z.start()); + CHECK (span3.end() < span3z.end()); + CHECK (Time(span3) < Time(span3z)); } };