WIP idea how to represent support for some timecode formats
concrete quantiser instances need a way to state support for just some timecode formats -- yet I dont want to push vectors aroud all over the place
This commit is contained in:
parent
aa5c78a30f
commit
2c90335b1d
9 changed files with 217 additions and 41 deletions
47
src/lib/meta/no-instance.hpp
Normal file
47
src/lib/meta/no-instance.hpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
NO-INSTANCE.hpp - marker for pure metaprogramming types
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2011, 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_META_NO_INSTANCE_H
|
||||
#define LIB_META_NO_INSTANCE_H
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace meta{
|
||||
|
||||
/**
|
||||
* An Entity never to be instantiated.
|
||||
* Marker baseclass for elements used for metaprogramming only.
|
||||
* Every attempt to instantiate such an element will cause an
|
||||
* compilation failure
|
||||
*/
|
||||
template<class X>
|
||||
struct NoInstance
|
||||
{
|
||||
NoInstance() { BOOST_STATIC_ASSERT(!sizeof(X)); }
|
||||
NoInstance (NoInstance const&) { BOOST_STATIC_ASSERT(!sizeof(X)); }
|
||||
};
|
||||
|
||||
}} // namespace lib::meta
|
||||
#endif
|
||||
|
|
@ -25,6 +25,9 @@
|
|||
#define LIB_TIME_FORMATS_H
|
||||
|
||||
#include "lib/time/timevalue.hpp"
|
||||
#include "lib/meta/no-instance.hpp"
|
||||
#include "lib/meta/typelist.hpp"
|
||||
#include "lib/meta/generator.hpp"
|
||||
|
||||
//#include <boost/operators.hpp>
|
||||
#include <tr1/memory>
|
||||
|
|
@ -48,27 +51,11 @@ namespace time {
|
|||
typedef std::tr1::shared_ptr<const Quantiser> PQuant;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* descriptor for a time representation format (ABC).
|
||||
* A time format describes how to specify time; it allows
|
||||
* to format a time value and to parse a textual representation.
|
||||
* @note while Format is an generic descriptor, the actual
|
||||
* TCode (timecode) values are time values, which \em
|
||||
* use a specific format, given as template parameter
|
||||
*
|
||||
* @todo WIP-WIP-WIP
|
||||
*/
|
||||
class Format
|
||||
{
|
||||
|
||||
public:
|
||||
virtual ~Format();
|
||||
};
|
||||
|
||||
|
||||
namespace format {
|
||||
|
||||
using lib::meta::NoInstance; // the following types are for metaprogramming only...
|
||||
|
||||
|
||||
/**
|
||||
* Frame count as timecode format.
|
||||
* An integral number used to count frames
|
||||
|
|
@ -78,7 +65,7 @@ namespace time {
|
|||
* underlying framerate/quantisation remains implicit.
|
||||
*/
|
||||
struct Frames
|
||||
: Format
|
||||
: NoInstance<Frames>
|
||||
{
|
||||
static void rebuild (FrameNr&, QuantR, TimeValue const&);
|
||||
static TimeValue evaluate (FrameNr const&, QuantR);
|
||||
|
|
@ -92,7 +79,7 @@ namespace time {
|
|||
* frame number within the actual second.
|
||||
*/
|
||||
struct Smpte
|
||||
: Format
|
||||
: NoInstance<Smpte>
|
||||
{
|
||||
static void rebuild (SmpteTC&, QuantR);
|
||||
static TimeValue evaluate (SmpteTC const&, QuantR);
|
||||
|
|
@ -107,7 +94,7 @@ namespace time {
|
|||
* floating point milliseconds value instead of the frame count
|
||||
*/
|
||||
struct Hms
|
||||
: Format
|
||||
: NoInstance<Hms>
|
||||
{
|
||||
static void rebuild (HmsTC&, QuantR);
|
||||
static TimeValue evaluate (HmsTC const&, QuantR);
|
||||
|
|
@ -124,7 +111,7 @@ namespace time {
|
|||
* decimal format, not the usual sexagesimal time format
|
||||
*/
|
||||
struct Seconds
|
||||
: Format
|
||||
: NoInstance<Seconds>
|
||||
{
|
||||
static void rebuild (Secs&, QuantR);
|
||||
static TimeValue evaluate (Secs const&, QuantR);
|
||||
|
|
@ -163,5 +150,39 @@ namespace time {
|
|||
|
||||
|
||||
|
||||
using lumiera::typelist::Types;
|
||||
|
||||
/**
|
||||
* Denote support for a specific (timecode) format.
|
||||
* This helper can be used to configure a selection of specific
|
||||
* timecode formats to be or not to be supported by some facility.
|
||||
* Formats are described by the format descriptor types defined in
|
||||
* this header (or elsewhere for additional formats). This helper
|
||||
* establishes an numeric ID at runtime and uses a bitset to keep
|
||||
* track of the support for a given format.
|
||||
*
|
||||
* @todo WIP-WIP-WIP
|
||||
*/
|
||||
class Supported
|
||||
{
|
||||
public:
|
||||
template<typename TY>
|
||||
static Supported
|
||||
formats();
|
||||
|
||||
template<class F>
|
||||
bool
|
||||
check();
|
||||
};
|
||||
|
||||
struct SupportStandardTimecode
|
||||
: Supported
|
||||
{
|
||||
SupportStandardTimecode()
|
||||
: Supported(formats<Types<Hms,Smpte,Frames,Seconds> >())
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
}}} // lib::time::format
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ namespace time {
|
|||
virtual ~Grid(); ///< this is an Interface
|
||||
|
||||
|
||||
virtual TimeValue gridAlign (TimeValue const& raw) const =0;
|
||||
virtual long gridPoint (TimeValue const& raw) const =0;
|
||||
virtual TimeValue gridAlign (TimeValue const& raw) const =0;
|
||||
virtual TimeValue timeOf (long gridPoint) const =0;
|
||||
virtual TimeValue timeOf (FSecs, int =0) const =0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -66,28 +66,29 @@ namespace time {
|
|||
|
||||
/**
|
||||
* Facility to create grid-aligned time values.
|
||||
* Effectively, a quantiser exposes the value Grid API, but
|
||||
* additionally also manages a set of supported (display) formats or
|
||||
* "time code" formats. Plus there is an static API to fetch a suitable
|
||||
* quantiser instance by-name; actually this utilises a hidden link to
|
||||
* the Lumiera session. Time quantisation and timecode handling explicitly
|
||||
* relies on this Quantiser interface.
|
||||
*
|
||||
* @todo WIP-WIP-WIP
|
||||
*/
|
||||
class Quantiser
|
||||
: public Grid
|
||||
{
|
||||
typedef std::vector<Format*> _FormatTable;
|
||||
typedef _FormatTable::const_iterator _SrcIter;
|
||||
typedef lib::PtrDerefIter<_SrcIter> _Iter;
|
||||
|
||||
public:
|
||||
|
||||
template<class FMT>
|
||||
bool supports() const;
|
||||
|
||||
typedef _Iter iterator;
|
||||
iterator getSupportedFormats() const;
|
||||
|
||||
|
||||
//------Grid-API----------------------------------------------
|
||||
virtual TimeValue gridAlign (TimeValue const& raw) const =0;
|
||||
virtual long gridPoint (TimeValue const& raw) const =0;
|
||||
virtual TimeValue gridAlign (TimeValue const& raw) const =0;
|
||||
virtual TimeValue timeOf (long gridPoint) const =0;
|
||||
virtual TimeValue timeOf (FSecs, int =0) const =0;
|
||||
};
|
||||
|
|
@ -116,8 +117,8 @@ namespace time {
|
|||
FixedFrameQuantiser (Duration const& frame_duration, TimeValue referencePoint =TimeValue(0));
|
||||
|
||||
|
||||
TimeValue gridAlign (TimeValue const&) const;
|
||||
long gridPoint (TimeValue const&) const;
|
||||
TimeValue gridAlign (TimeValue const&) const;
|
||||
TimeValue timeOf (long gridPoint) const;
|
||||
TimeValue timeOf (FSecs, int =0) const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ namespace lib {
|
|||
namespace time {
|
||||
|
||||
|
||||
Format::~Format() { } // emit VTable here....
|
||||
TCode::~TCode() { }
|
||||
TCode::~TCode() { } // emit VTable here....
|
||||
|
||||
namespace format {
|
||||
|
||||
|
|
|
|||
|
|
@ -22,13 +22,27 @@
|
|||
|
||||
|
||||
/** @file typed-counter.hpp
|
||||
** Creating sets of type-based contexts.
|
||||
** Creating series of type-based contexts.
|
||||
** The idea is to get a "slot" for any given type, so we can build
|
||||
** tables or families of implementations based on these types. Currently,
|
||||
** the slot allocation is based on static variables and thus is global.
|
||||
** This leads to a waste of slots, as the various clients of this service
|
||||
** typically will utilise different sets of types.
|
||||
** @todo WIP WIP... this is the first, preliminary version of a facility,
|
||||
** tables or families of implementations based on these types. Each of
|
||||
** those "slots" can be addressed by a distinct (compile time) type, but
|
||||
** at the same time holds a numeric ID (runtime assigned on demand). This
|
||||
** setup allows to bridge between metaprogramming and (runtime) dispatcher tables.
|
||||
**
|
||||
** Each such series of type-id-slots is associated to a distinct usage context.
|
||||
** Those usage contexts are discerned by the template parameter \c XY. Each of
|
||||
** these usage contexts uses a separate numbering scheme on his own, i.e. every
|
||||
** new type encountered at runtime gets the next higher ID number (slot).
|
||||
** @warning the actual ID numbers depend on the sequence of first encountering
|
||||
** a given type. If this sequence isn't reproducible between runs, then
|
||||
** also the generated type-IDs aren't reproducible. Thus its advisable
|
||||
** \em not to rely on any specific numeric value here, but always just
|
||||
** access the service through the type slots.
|
||||
** @note Locking is based on a class lock per usage context, but a lock needs
|
||||
** only be acquired to allocate a new ID number (double checked locking).
|
||||
** Thus lock contention is considered not to be a problem, yet we need
|
||||
** actually to verify this by real measurements (as of 2011)
|
||||
** @todo 2010 ... this is the first, preliminary version of a facility,
|
||||
** which is expected to get quite important for custom allocation management.
|
||||
**
|
||||
** @see typed-counter-test.cpp
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ namespace meta {
|
|||
lib::time::FixedFrameQuantiser frameGrid_;
|
||||
|
||||
/* == grid API forwarded to embedded quantiser == */
|
||||
TimeValue gridAlign (TimeValue const& rawTime) const { return frameGrid_.gridAlign (rawTime); }
|
||||
long gridPoint (TimeValue const& rawTime) const { return frameGrid_.gridPoint (rawTime); }
|
||||
TimeValue gridAlign (TimeValue const& rawTime) const { return frameGrid_.gridAlign (rawTime); }
|
||||
TimeValue timeOf (long gridPoint) const { return frameGrid_.timeOf (gridPoint); }
|
||||
TimeValue timeOf (FSecs gridTime, int gridOffset =0) const { return frameGrid_.timeOf (gridTime,gridOffset); }
|
||||
|
||||
|
|
|
|||
|
|
@ -80,8 +80,8 @@ namespace meta {
|
|||
|
||||
public:
|
||||
//--------Grid-API------------------------------------
|
||||
TimeValue gridAlign (TimeValue const& raw) const =0;
|
||||
long gridPoint (TimeValue const& raw) const =0;
|
||||
TimeValue gridAlign (TimeValue const& raw) const =0;
|
||||
TimeValue timeOf (long gridPoint) const =0;
|
||||
TimeValue timeOf (FSecs, int =0) const =0;
|
||||
|
||||
|
|
|
|||
94
tests/lib/time/format-support-test.cpp
Normal file
94
tests/lib/time/format-support-test.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
FormatSupport(Test) - verify the configuration to support a specific format
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2011, 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.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/time/formats.hpp"
|
||||
|
||||
//#include <iostream>
|
||||
//#include <cstdlib>
|
||||
|
||||
//using std::rand;
|
||||
//using std::cout;
|
||||
//using std::endl;
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace time {
|
||||
namespace format{
|
||||
namespace test {
|
||||
|
||||
namespace {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* @test check how support for a specific timecode format
|
||||
* can be enabled and detected. Actually this test
|
||||
* verifies a simple metaprogramming facility,
|
||||
* which allows to check type support at runtime.
|
||||
*/
|
||||
class FormatSupport_test : public Test
|
||||
{
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
SupportStandardTimecode just_fine;
|
||||
Supported just_smpte = Supported::formats<Types<Smpte> >();
|
||||
Supported just_simple = Supported::formats<Types<Frames,Seconds> >();
|
||||
|
||||
Supported& support1 (just_fine);
|
||||
Supported& support2 (just_smpte);
|
||||
Supported& support3 (just_simple);
|
||||
|
||||
CHECK ( support1.check<Hms>());
|
||||
CHECK ( support1.check<Smpte>());
|
||||
CHECK ( support1.check<Frames>());
|
||||
CHECK ( support1.check<Seconds>());
|
||||
|
||||
CHECK (!support2.check<Hms>());
|
||||
CHECK ( support2.check<Smpte>());
|
||||
CHECK (!support2.check<Frames>());
|
||||
CHECK (!support2.check<Seconds>());
|
||||
|
||||
CHECK (!support3.check<Hms>());
|
||||
CHECK (!support3.check<Smpte>());
|
||||
CHECK ( support3.check<Frames>());
|
||||
CHECK ( support3.check<Seconds>());
|
||||
|
||||
// format support descriptors are assignable
|
||||
just_smpte = just_simple;
|
||||
CHECK (support2.check<Hms>() == support3.check<Hms>());
|
||||
CHECK (support2.check<Smpte>() == support3.check<Smpte>());
|
||||
CHECK (support2.check<Frames>() == support3.check<Frames>());
|
||||
CHECK (support2.check<Seconds>() == support3.check<Seconds>());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (FormatSupport_test, "unit common");
|
||||
|
||||
|
||||
|
||||
}}}} // namespace lib::time::format::test
|
||||
Loading…
Reference in a new issue