2010-12-21 02:05:13 +01:00
|
|
|
/*
|
|
|
|
|
TIMEVALUE.hpp - basic definitions for time values and time intervals
|
|
|
|
|
|
|
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2010, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
|
|
|
|
published by the Free Software Foundation; either version 2 of
|
|
|
|
|
the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef LIB_TIME_TIMEVALUE_H
|
|
|
|
|
#define LIB_TIME_TIMEVALUE_H
|
|
|
|
|
|
2011-01-09 04:56:46 +01:00
|
|
|
#include "lib/error.hpp"
|
|
|
|
|
|
2010-12-22 04:49:57 +01:00
|
|
|
#include <boost/operators.hpp>
|
2010-12-31 05:59:53 +01:00
|
|
|
#include <boost/rational.hpp>
|
2010-12-28 05:22:20 +01:00
|
|
|
#include <cstdlib>
|
2010-12-21 02:05:13 +01:00
|
|
|
#include <string>
|
|
|
|
|
|
2010-12-22 04:49:57 +01:00
|
|
|
extern "C" {
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <gavl/gavltime.h>
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-21 02:05:13 +01:00
|
|
|
|
|
|
|
|
namespace lib {
|
|
|
|
|
namespace time {
|
|
|
|
|
|
2011-01-09 04:56:46 +01:00
|
|
|
namespace error = lumiera::error;
|
|
|
|
|
|
2011-06-11 20:20:20 +02:00
|
|
|
// forwards...
|
|
|
|
|
class FrameRate;
|
|
|
|
|
class TimeSpan;
|
|
|
|
|
class Mutation;
|
|
|
|
|
|
2010-12-21 02:05:13 +01:00
|
|
|
|
|
|
|
|
/**
|
2010-12-27 06:58:27 +01:00
|
|
|
* basic constant internal time value.
|
|
|
|
|
* These time values provide the implementation base
|
|
|
|
|
* for all further time types. They can be created by
|
|
|
|
|
* wrapping up a raw micro tick value (gavl_time_t),
|
|
|
|
|
* are totally ordered, but besides that,
|
|
|
|
|
* they are opaque and non-mutable.
|
|
|
|
|
* @note clients should prefer to use Time instances,
|
|
|
|
|
* which explicitly denote an Lumiera internal
|
|
|
|
|
* time value and are easier to use.
|
|
|
|
|
* @see TimeVar when full arithmetics are required
|
2010-12-21 02:05:13 +01:00
|
|
|
*/
|
|
|
|
|
class TimeValue
|
2010-12-27 02:04:34 +01:00
|
|
|
: boost::totally_ordered<TimeValue,
|
|
|
|
|
boost::totally_ordered<TimeValue, gavl_time_t> >
|
2010-12-22 04:49:57 +01:00
|
|
|
{
|
2010-12-26 23:00:34 +01:00
|
|
|
protected:
|
2010-12-27 05:55:15 +01:00
|
|
|
/** the raw (internal) time value
|
|
|
|
|
* used to implement the time types */
|
2010-12-22 04:49:57 +01:00
|
|
|
gavl_time_t t_;
|
|
|
|
|
|
|
|
|
|
|
2010-12-27 05:55:15 +01:00
|
|
|
/** Assigning of time values is not allowed,
|
|
|
|
|
* but derived classed might allow that */
|
|
|
|
|
TimeValue&
|
|
|
|
|
operator= (TimeValue const& o)
|
|
|
|
|
{
|
|
|
|
|
t_ = o.t_;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-04 02:43:01 +02:00
|
|
|
/** some subclasses may receive modification messages */
|
|
|
|
|
friend class Mutation;
|
|
|
|
|
|
2010-12-27 05:55:15 +01:00
|
|
|
public:
|
2011-01-08 20:01:26 +01:00
|
|
|
/** explicit limit of allowed time range */
|
|
|
|
|
static gavl_time_t limited (gavl_time_t raw);
|
|
|
|
|
|
|
|
|
|
|
2010-12-22 04:49:57 +01:00
|
|
|
explicit
|
|
|
|
|
TimeValue (gavl_time_t val=0)
|
2011-01-08 20:01:26 +01:00
|
|
|
: t_(limited (val))
|
2010-12-22 04:49:57 +01:00
|
|
|
{ }
|
|
|
|
|
|
2010-12-27 05:55:15 +01:00
|
|
|
/** copy initialisation allowed */
|
|
|
|
|
TimeValue (TimeValue const& o)
|
|
|
|
|
: t_(o.t_)
|
|
|
|
|
{ }
|
2010-12-22 04:49:57 +01:00
|
|
|
|
2011-01-06 13:31:13 +01:00
|
|
|
/** @internal to pass Time values to C functions */
|
|
|
|
|
friend gavl_time_t _raw (TimeValue const& time) { return time.t_; }
|
2011-01-08 20:01:26 +01:00
|
|
|
static TimeValue buildRaw_(gavl_time_t);
|
2011-01-06 13:31:13 +01:00
|
|
|
|
2010-12-22 04:49:57 +01:00
|
|
|
// Supporting totally_ordered
|
2010-12-26 23:00:34 +01:00
|
|
|
friend bool operator< (TimeValue const& t1, TimeValue const& t2) { return t1.t_ < t2.t_; }
|
|
|
|
|
friend bool operator< (TimeValue const& t1, gavl_time_t t2) { return t1.t_ < t2 ; }
|
|
|
|
|
friend bool operator> (TimeValue const& t1, gavl_time_t t2) { return t1.t_ > t2 ; }
|
|
|
|
|
friend bool operator== (TimeValue const& t1, TimeValue const& t2) { return t1.t_ == t2.t_; }
|
|
|
|
|
friend bool operator== (TimeValue const& t1, gavl_time_t t2) { return t1.t_ == t2 ; }
|
2010-12-22 04:49:57 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2010-12-27 05:55:15 +01:00
|
|
|
|
|
|
|
|
/** a mutable time value,
|
2010-12-27 06:58:27 +01:00
|
|
|
* behaving like a plain number,
|
|
|
|
|
* allowing copy and re-accessing
|
2010-12-28 07:24:54 +01:00
|
|
|
* @note supports scaling by a factor,
|
|
|
|
|
* which \em deliberately is chosen
|
|
|
|
|
* as int, not gavl_time_t, because the
|
2011-01-27 14:35:46 +01:00
|
|
|
* multiplying of times is meaningless.
|
2010-12-27 05:55:15 +01:00
|
|
|
*/
|
2010-12-22 04:49:57 +01:00
|
|
|
class TimeVar
|
|
|
|
|
: public TimeValue
|
2010-12-27 06:58:27 +01:00
|
|
|
, boost::additive<TimeVar,
|
|
|
|
|
boost::additive<TimeVar, TimeValue,
|
|
|
|
|
boost::multipliable<TimeVar, int>
|
|
|
|
|
> >
|
2010-12-22 04:49:57 +01:00
|
|
|
{
|
|
|
|
|
public:
|
2011-01-05 18:15:44 +01:00
|
|
|
TimeVar (TimeValue const& time = TimeValue())
|
2010-12-22 04:49:57 +01:00
|
|
|
: TimeValue(time)
|
|
|
|
|
{ }
|
|
|
|
|
|
2010-12-27 05:55:15 +01:00
|
|
|
// Allowing copy and assignment
|
|
|
|
|
TimeVar (TimeVar const& o)
|
|
|
|
|
: TimeValue(o)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
TimeVar&
|
|
|
|
|
operator= (TimeValue const& o)
|
|
|
|
|
{
|
|
|
|
|
t_ = TimeVar(o);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-05 18:15:44 +01:00
|
|
|
/** @internal diagnostics */
|
|
|
|
|
operator std::string () const;
|
2010-12-27 05:55:15 +01:00
|
|
|
|
|
|
|
|
// Supporting mixing with plain long int arithmetics
|
|
|
|
|
operator gavl_time_t () const { return t_; }
|
2010-12-22 04:49:57 +01:00
|
|
|
|
|
|
|
|
// Supporting additive
|
|
|
|
|
TimeVar& operator+= (TimeVar const& tx) { t_ += tx.t_; return *this; }
|
|
|
|
|
TimeVar& operator-= (TimeVar const& tx) { t_ -= tx.t_; return *this; }
|
|
|
|
|
|
|
|
|
|
// Supporting multiplication with integral factor
|
2012-04-24 05:06:05 +02:00
|
|
|
TimeVar& operator*= (int64_t fact) { t_ *= fact; return *this; }
|
2011-01-08 19:11:42 +01:00
|
|
|
|
2011-01-15 01:45:55 +01:00
|
|
|
// Supporting sign flip
|
2011-01-08 19:11:42 +01:00
|
|
|
TimeVar operator- () const { return TimeVar(*this)*=-1; }
|
2010-12-22 04:49:57 +01:00
|
|
|
|
|
|
|
|
// baseclass TimeValue is already totally_ordered
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2010-12-28 05:22:20 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Offset measures a distance in time.
|
|
|
|
|
* It may be used to relate two points in time,
|
|
|
|
|
* or to create a modification for time-like entities.
|
|
|
|
|
* Similar to (basic) time values, offsets can be compared,
|
2010-12-28 07:24:54 +01:00
|
|
|
* but are otherwise opaque and immutable. Yet they allow
|
|
|
|
|
* to build derived values, including
|
|
|
|
|
* - the \em absolute (positive) distance for this offset
|
|
|
|
|
* - a combined offset by chaining another offset
|
2010-12-28 05:22:20 +01:00
|
|
|
*/
|
|
|
|
|
class Offset
|
|
|
|
|
: public TimeValue
|
|
|
|
|
{
|
2011-01-22 23:20:12 +01:00
|
|
|
protected:
|
2011-01-27 14:35:46 +01:00
|
|
|
/** generally immutable,
|
|
|
|
|
* but derived classes allow some limited mutation
|
|
|
|
|
* through special API calls */
|
2011-01-22 23:20:12 +01:00
|
|
|
Offset&
|
2011-01-27 14:35:46 +01:00
|
|
|
operator= (Offset const& o)
|
2011-01-22 23:20:12 +01:00
|
|
|
{
|
|
|
|
|
TimeValue::operator= (o);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-28 05:22:20 +01:00
|
|
|
public:
|
|
|
|
|
explicit
|
|
|
|
|
Offset (TimeValue const& distance)
|
|
|
|
|
: TimeValue(distance)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
Offset (TimeValue const& origin, TimeValue const& target)
|
|
|
|
|
: TimeValue(TimeVar(target) -= origin)
|
|
|
|
|
{ }
|
|
|
|
|
|
2011-06-11 20:20:20 +02:00
|
|
|
Offset (int64_t count, FrameRate const& fps);
|
|
|
|
|
|
2011-06-04 17:16:29 +02:00
|
|
|
static const Offset ZERO;
|
|
|
|
|
|
2011-06-11 20:20:20 +02:00
|
|
|
|
2010-12-28 05:22:20 +01:00
|
|
|
TimeValue
|
|
|
|
|
abs() const
|
|
|
|
|
{
|
|
|
|
|
return TimeValue(std::llabs (t_));
|
|
|
|
|
}
|
2011-04-25 18:51:50 +02:00
|
|
|
|
|
|
|
|
// Supporting sign flip
|
|
|
|
|
Offset operator- () const;
|
2010-12-28 05:22:20 +01:00
|
|
|
};
|
|
|
|
|
|
2011-01-15 01:45:55 +01:00
|
|
|
//-- support linear offset chaining ---------------
|
|
|
|
|
|
|
|
|
|
inline Offset
|
|
|
|
|
operator+ (Offset const& start, Offset const& toChain)
|
|
|
|
|
{
|
|
|
|
|
TimeVar distance(start);
|
|
|
|
|
distance += toChain;
|
|
|
|
|
return Offset(distance);
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-17 00:49:58 +01:00
|
|
|
template<typename INT>
|
|
|
|
|
inline Offset
|
|
|
|
|
operator* (Offset const& distance, INT factor)
|
|
|
|
|
{
|
|
|
|
|
return factor*distance;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-24 05:06:05 +02:00
|
|
|
template<typename INT>
|
2011-01-15 01:45:55 +01:00
|
|
|
inline Offset
|
2012-04-24 05:06:05 +02:00
|
|
|
operator* (INT factor, Offset const& o)
|
2011-01-15 01:45:55 +01:00
|
|
|
{
|
|
|
|
|
TimeVar distance(o);
|
|
|
|
|
distance *= factor;
|
|
|
|
|
return Offset(distance);
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-25 01:56:16 +01:00
|
|
|
template<typename INTX>
|
|
|
|
|
inline Offset
|
|
|
|
|
operator* (boost::rational<INTX> factor, Offset const& o)
|
|
|
|
|
{
|
|
|
|
|
return boost::rational<int64_t>(factor.numerator(), factor.denominator()) * o;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-17 00:49:58 +01:00
|
|
|
/** stretch offset by a possibly fractional factor */
|
|
|
|
|
Offset
|
|
|
|
|
operator* (boost::rational<int64_t> factor, Offset const& o);
|
|
|
|
|
|
2011-01-15 01:45:55 +01:00
|
|
|
|
2012-03-17 00:49:58 +01:00
|
|
|
/** flip offset direction */
|
2011-04-25 18:51:50 +02:00
|
|
|
inline Offset
|
|
|
|
|
Offset::operator- () const
|
|
|
|
|
{
|
|
|
|
|
return -1 * (*this);
|
|
|
|
|
}
|
2010-12-28 05:22:20 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ======= specific Time entities ==================== */
|
|
|
|
|
|
2011-01-02 18:56:44 +01:00
|
|
|
/** rational representation of fractional seconds
|
|
|
|
|
* @warning do not mix up gavl_time_t and FSecs */
|
|
|
|
|
typedef boost::rational<long> FSecs;
|
2011-01-09 04:56:46 +01:00
|
|
|
|
|
|
|
|
|
2010-12-22 04:49:57 +01:00
|
|
|
/**
|
2010-12-28 05:22:20 +01:00
|
|
|
* Lumiera's internal time value datatype.
|
|
|
|
|
* This is a TimeValue, but now more specifically denoting
|
|
|
|
|
* a point in time, measured in reference to an internal
|
|
|
|
|
* (opaque) time scale.
|
|
|
|
|
*
|
|
|
|
|
* Lumiera Time provides some limited capabilities for
|
|
|
|
|
* direct manipulation; Time values can be created directly
|
2011-04-02 04:01:06 +02:00
|
|
|
* 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
|
2010-12-28 05:22:20 +01:00
|
|
|
* storage should be based on the (quantised) timecode
|
|
|
|
|
* formats though, which can be generated from time values.
|
|
|
|
|
*
|
2011-04-02 04:01:06 +02:00
|
|
|
* Similar to TimeValue, also Time objects are considered
|
|
|
|
|
* immutable values. As convenience shortcut, some operators
|
|
|
|
|
* are provided, creating a TimVar for further calculations.
|
2010-12-22 04:49:57 +01:00
|
|
|
*/
|
2010-12-27 02:04:34 +01:00
|
|
|
class Time
|
|
|
|
|
: public TimeValue
|
|
|
|
|
{
|
2011-01-22 23:20:12 +01:00
|
|
|
/// direct assignment prohibited
|
|
|
|
|
Time& operator= (Time const);
|
|
|
|
|
|
2011-03-31 18:43:50 +02:00
|
|
|
/// suppress possible direct conversions
|
|
|
|
|
Time(int);
|
|
|
|
|
|
2010-12-27 02:04:34 +01:00
|
|
|
public:
|
2010-12-27 05:55:15 +01:00
|
|
|
static const Time MAX ;
|
|
|
|
|
static const Time MIN ;
|
2011-05-16 04:37:03 +02:00
|
|
|
static const Time ZERO;
|
2010-12-27 05:55:15 +01:00
|
|
|
|
2011-12-09 01:00:50 +01:00
|
|
|
static const Time ANYTIME; ///< border condition marker value. #ANYTIME <= any time value
|
|
|
|
|
static const Time NEVER; ///< border condition marker value. #NEVER >= any time value
|
|
|
|
|
|
2010-12-27 02:04:34 +01:00
|
|
|
explicit
|
2010-12-28 05:22:20 +01:00
|
|
|
Time (TimeValue const& val =TimeValue(0))
|
2010-12-27 02:04:34 +01:00
|
|
|
: TimeValue(val)
|
|
|
|
|
{ }
|
|
|
|
|
|
2010-12-28 07:24:54 +01:00
|
|
|
Time (TimeVar const& calcResult)
|
|
|
|
|
: TimeValue(calcResult)
|
|
|
|
|
{ }
|
|
|
|
|
|
2011-03-31 18:43:50 +02:00
|
|
|
explicit
|
2011-01-02 18:56:44 +01:00
|
|
|
Time (FSecs const& fractionalSeconds);
|
2010-12-31 05:59:53 +01:00
|
|
|
|
2010-12-27 02:04:34 +01:00
|
|
|
Time ( long millis
|
|
|
|
|
, uint secs
|
|
|
|
|
, uint mins =0
|
|
|
|
|
, uint hours=0
|
|
|
|
|
);
|
2010-12-28 05:22:20 +01:00
|
|
|
|
|
|
|
|
/** @internal diagnostics */
|
|
|
|
|
operator std::string () const;
|
2011-01-07 16:28:13 +01:00
|
|
|
|
|
|
|
|
/** convenience start for time calculations */
|
|
|
|
|
TimeVar operator+ (TimeValue const& tval) const { return TimeVar(*this) + tval; }
|
|
|
|
|
TimeVar operator- (TimeValue const& tval) const { return TimeVar(*this) - tval; }
|
2011-01-22 02:35:58 +01:00
|
|
|
TimeVar operator- () const { return -TimeVar(*this); }
|
2010-12-27 02:04:34 +01:00
|
|
|
};
|
2010-12-22 04:49:57 +01:00
|
|
|
|
|
|
|
|
|
2010-12-28 05:22:20 +01:00
|
|
|
|
2011-01-09 09:49:48 +01:00
|
|
|
|
2010-12-28 05:22:20 +01:00
|
|
|
/**
|
|
|
|
|
* Duration is the internal Lumiera time metric.
|
|
|
|
|
* It is an absolute (positive) value, but can be
|
2011-04-04 02:07:09 +02:00
|
|
|
* promoted from an offset. While Duration generally
|
|
|
|
|
* is treated as immutable value, there is the
|
|
|
|
|
* possibility to send a \em Mutation message.
|
2010-12-28 05:22:20 +01:00
|
|
|
*/
|
|
|
|
|
class Duration
|
2011-06-08 02:12:38 +02:00
|
|
|
: public TimeValue
|
2010-12-22 04:49:57 +01:00
|
|
|
{
|
2011-01-22 23:20:12 +01:00
|
|
|
/// direct assignment prohibited
|
|
|
|
|
Duration& operator= (Duration const&);
|
|
|
|
|
|
2010-12-21 02:05:13 +01:00
|
|
|
public:
|
2010-12-28 05:22:20 +01:00
|
|
|
Duration (Offset const& distance)
|
2011-06-08 02:12:38 +02:00
|
|
|
: TimeValue(distance.abs())
|
2010-12-22 04:49:57 +01:00
|
|
|
{ }
|
2011-01-09 04:56:46 +01:00
|
|
|
|
2011-01-09 09:49:48 +01:00
|
|
|
explicit
|
2011-04-04 00:41:38 +02:00
|
|
|
Duration (TimeValue const& timeSpec)
|
2011-06-08 02:12:38 +02:00
|
|
|
: TimeValue(Offset(timeSpec).abs())
|
2011-01-09 09:49:48 +01:00
|
|
|
{ }
|
|
|
|
|
|
2011-03-31 18:43:50 +02:00
|
|
|
explicit
|
|
|
|
|
Duration (FSecs const& timeSpan_in_secs)
|
2011-06-08 02:12:38 +02:00
|
|
|
: TimeValue(Offset(Time(timeSpan_in_secs)).abs())
|
2011-03-31 18:43:50 +02:00
|
|
|
{ }
|
|
|
|
|
|
2011-01-09 09:49:48 +01:00
|
|
|
Duration (TimeSpan const& interval);
|
2011-06-11 20:20:20 +02:00
|
|
|
Duration (int64_t count, FrameRate const& fps);
|
2011-01-09 04:56:46 +01:00
|
|
|
|
|
|
|
|
static const Duration NIL;
|
2011-04-04 02:07:09 +02:00
|
|
|
|
|
|
|
|
void accept (Mutation const&);
|
2011-06-08 02:12:38 +02:00
|
|
|
|
|
|
|
|
/// Supporting backwards use as offset
|
|
|
|
|
Offset operator- () const;
|
|
|
|
|
|
2010-12-22 04:49:57 +01:00
|
|
|
};
|
2011-06-08 02:12:38 +02:00
|
|
|
|
|
|
|
|
//-- support using a Duration to build offsets ---------------
|
|
|
|
|
|
|
|
|
|
inline Duration
|
|
|
|
|
operator+ (Duration const& base, Duration const& toAdd)
|
|
|
|
|
{
|
|
|
|
|
return Offset(base) + Offset(toAdd);
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-17 00:49:58 +01:00
|
|
|
template<typename INT>
|
2011-06-08 02:12:38 +02:00
|
|
|
inline Offset
|
2012-03-17 00:49:58 +01:00
|
|
|
operator* (INT factor, Duration const& dur)
|
2011-06-08 02:12:38 +02:00
|
|
|
{
|
|
|
|
|
return factor * Offset(dur);
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-17 00:49:58 +01:00
|
|
|
template<typename INT>
|
2011-06-08 02:12:38 +02:00
|
|
|
inline Offset
|
2012-03-17 00:49:58 +01:00
|
|
|
operator* (Duration const& dur, INT factor)
|
2011-06-08 02:12:38 +02:00
|
|
|
{
|
|
|
|
|
return factor*dur;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Offset
|
|
|
|
|
Duration::operator- () const
|
|
|
|
|
{
|
|
|
|
|
return -1 * (*this);
|
|
|
|
|
}
|
2010-12-27 06:58:27 +01:00
|
|
|
|
2010-12-21 02:05:13 +01:00
|
|
|
|
|
|
|
|
|
2010-12-28 05:22:20 +01:00
|
|
|
/**
|
|
|
|
|
* A time interval anchored at a specific point in time.
|
|
|
|
|
* The start point of this timespan is also its nominal
|
|
|
|
|
* position, and the end point is normalised to happen
|
|
|
|
|
* never before the start point. A TimeSpan is enough
|
|
|
|
|
* to fully specify the temporal properties of an
|
|
|
|
|
* object within the model.
|
|
|
|
|
*
|
2011-04-02 04:01:06 +02:00
|
|
|
* 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
|
2010-12-28 05:22:20 +01:00
|
|
|
*/
|
2010-12-22 04:49:57 +01:00
|
|
|
class TimeSpan
|
|
|
|
|
: public Time
|
2011-04-04 00:41:38 +02:00
|
|
|
, boost::totally_ordered<TimeSpan>
|
2010-12-22 04:49:57 +01:00
|
|
|
{
|
|
|
|
|
Duration dur_;
|
|
|
|
|
|
|
|
|
|
public:
|
2011-04-04 00:41:38 +02:00
|
|
|
TimeSpan(TimeValue const& start, Duration const& length)
|
2010-12-22 04:49:57 +01:00
|
|
|
: Time(start)
|
|
|
|
|
, dur_(length)
|
|
|
|
|
{ }
|
2011-04-02 04:01:06 +02:00
|
|
|
|
2011-04-04 00:41:38 +02:00
|
|
|
TimeSpan(TimeValue const& start, Offset const& reference_distance)
|
|
|
|
|
: Time(start)
|
|
|
|
|
, dur_(reference_distance)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
TimeSpan(TimeValue const& start, TimeValue const& end)
|
|
|
|
|
: Time(start)
|
|
|
|
|
, dur_(Offset(start,end))
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
TimeSpan(TimeValue const& start, FSecs(duration_in_secs))
|
2011-04-02 04:01:06 +02:00
|
|
|
: Time(start)
|
|
|
|
|
, dur_(duration_in_secs)
|
|
|
|
|
{ }
|
|
|
|
|
|
2010-12-28 05:22:20 +01:00
|
|
|
|
2011-04-25 05:42:05 +02:00
|
|
|
Duration&
|
|
|
|
|
duration()
|
|
|
|
|
{
|
|
|
|
|
return dur_;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-09 09:49:48 +01:00
|
|
|
Duration
|
|
|
|
|
duration() const
|
2010-12-28 05:22:20 +01:00
|
|
|
{
|
|
|
|
|
return dur_;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-02 04:01:06 +02:00
|
|
|
Time
|
|
|
|
|
start() const
|
|
|
|
|
{
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-28 05:22:20 +01:00
|
|
|
Time
|
2011-01-09 09:49:48 +01:00
|
|
|
end() const
|
2010-12-28 05:22:20 +01:00
|
|
|
{
|
2011-05-16 04:02:26 +02:00
|
|
|
return TimeVar(*this) += dur_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
contains (TimeValue const& tp) const
|
|
|
|
|
{
|
|
|
|
|
return *this <= tp
|
|
|
|
|
&& tp < end();
|
2010-12-28 05:22:20 +01:00
|
|
|
}
|
2011-04-04 00:41:38 +02:00
|
|
|
|
2011-04-04 02:07:09 +02:00
|
|
|
/** may change start / duration */
|
|
|
|
|
void accept (Mutation const&);
|
|
|
|
|
|
|
|
|
|
|
2011-04-04 00:41:38 +02:00
|
|
|
/// Supporting extended total order, based on start and interval length
|
|
|
|
|
friend bool operator== (TimeSpan const& t1, TimeSpan const& t2) { return t1.t_==t2.t_ && t1.dur_==t2.dur_; }
|
|
|
|
|
friend bool operator< (TimeSpan const& t1, TimeSpan const& t2) { return t1.t_< t2.t_ ||
|
|
|
|
|
(t1.t_==t2.t_ && t1.dur_< t2.dur_);}
|
2010-12-22 04:49:57 +01:00
|
|
|
};
|
|
|
|
|
|
2010-12-21 02:05:13 +01:00
|
|
|
|
2011-01-09 04:56:46 +01:00
|
|
|
/**
|
|
|
|
|
* Framerate specified as frames per second.
|
|
|
|
|
* Implemented as rational number.
|
|
|
|
|
*/
|
|
|
|
|
class FrameRate
|
|
|
|
|
: public boost::rational<uint>
|
|
|
|
|
{
|
|
|
|
|
typedef boost::rational<uint> IFrac;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
FrameRate (uint fps) ;
|
|
|
|
|
FrameRate (uint num, uint denom);
|
|
|
|
|
FrameRate (IFrac const& fractionalRate);
|
|
|
|
|
|
|
|
|
|
// standard copy acceptable;
|
|
|
|
|
|
2011-01-09 05:51:26 +01:00
|
|
|
double asDouble() const;
|
|
|
|
|
|
2011-01-09 04:56:46 +01:00
|
|
|
static const FrameRate PAL;
|
|
|
|
|
static const FrameRate NTSC;
|
|
|
|
|
|
2013-06-15 04:02:48 +02:00
|
|
|
static const FrameRate HALTED;
|
|
|
|
|
|
2011-01-09 04:56:46 +01:00
|
|
|
/** duration of one frame */
|
|
|
|
|
Duration duration() const;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2011-01-08 20:01:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* == implementations == */
|
2011-01-09 04:56:46 +01:00
|
|
|
|
|
|
|
|
namespace { // implementation helpers...
|
|
|
|
|
|
|
|
|
|
template<typename NUM>
|
|
|
|
|
inline NUM
|
|
|
|
|
__ensure_nonzero (NUM n)
|
|
|
|
|
{
|
2011-01-09 11:41:08 +01:00
|
|
|
if (n == 0)
|
2013-06-15 04:02:48 +02:00
|
|
|
throw error::Logic ("Degenerated frame grid not allowed"
|
2011-01-09 04:56:46 +01:00
|
|
|
, error::LUMIERA_ERROR_BOTTOM_VALUE);
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
}//(End) implementation helpers
|
|
|
|
|
|
|
|
|
|
|
2011-01-08 20:01:26 +01:00
|
|
|
|
|
|
|
|
/** @internal applies a limiter on the provided
|
|
|
|
|
* raw time value to keep it within the arbitrary
|
|
|
|
|
* boundaries defined by (Time::MAX, Time::MIN).
|
|
|
|
|
* While Time entities are \c not a "safeInt"
|
|
|
|
|
* implementation, we limit new values and
|
|
|
|
|
* establish this safety margin to prevent
|
|
|
|
|
* wrap-around during time quantisation */
|
|
|
|
|
inline gavl_time_t
|
|
|
|
|
TimeValue::limited (gavl_time_t raw)
|
|
|
|
|
{
|
|
|
|
|
return raw > Time::MAX? Time::MAX.t_
|
|
|
|
|
: raw < Time::MIN? Time::MIN.t_
|
|
|
|
|
: raw;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-09 09:49:48 +01:00
|
|
|
inline
|
|
|
|
|
Duration::Duration (TimeSpan const& interval)
|
2011-06-08 02:12:38 +02:00
|
|
|
: TimeValue(interval.duration())
|
2011-01-09 09:49:48 +01:00
|
|
|
{ }
|
|
|
|
|
|
2011-01-09 04:56:46 +01:00
|
|
|
inline
|
|
|
|
|
FrameRate::FrameRate (uint fps)
|
|
|
|
|
: IFrac (__ensure_nonzero(fps))
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
inline
|
|
|
|
|
FrameRate::FrameRate (uint num, uint denom)
|
|
|
|
|
: IFrac (__ensure_nonzero(num), denom)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
inline
|
|
|
|
|
FrameRate::FrameRate (IFrac const& fractionalRate)
|
|
|
|
|
: IFrac (__ensure_nonzero(fractionalRate))
|
|
|
|
|
{ }
|
|
|
|
|
|
2011-01-09 05:51:26 +01:00
|
|
|
inline double
|
|
|
|
|
FrameRate::asDouble() const
|
|
|
|
|
{
|
|
|
|
|
return boost::rational_cast<double> (*this);
|
|
|
|
|
}
|
2011-01-09 11:41:08 +01:00
|
|
|
|
2011-01-09 05:51:26 +01:00
|
|
|
|
2011-01-09 04:56:46 +01:00
|
|
|
|
2011-01-08 20:01:26 +01:00
|
|
|
|
2010-12-21 02:05:13 +01:00
|
|
|
}} // lib::time
|
2011-01-09 04:56:46 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace util {
|
|
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
|
isnil (lib::time::Duration const& dur)
|
|
|
|
|
{
|
|
|
|
|
return 0 == dur;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2010-12-21 02:05:13 +01:00
|
|
|
#endif
|