diff --git a/src/lib/time/digxel.cpp b/src/lib/time/digxel.cpp deleted file mode 100644 index b841acf0e..000000000 --- a/src/lib/time/digxel.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - Timecode - implementation of fixed grid aligned time specifications - - Copyright (C) Lumiera.org - 2010, Hermann Vosseler - - 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/time/digxel.hpp" - - -namespace lib { -namespace time { - - - - - /** */ - - - -}} // lib::time - diff --git a/src/lib/time/digxel.hpp b/src/lib/time/digxel.hpp index 0d757be29..ac5f5f8f8 100644 --- a/src/lib/time/digxel.hpp +++ b/src/lib/time/digxel.hpp @@ -35,21 +35,23 @@ ** \par properties of a "Digxel" ** ** Semantically, it's a number or number component. It holds an internal numeric representation - ** and is implicitly convertible both to integrals and floating point numbers. This implicit - ** conversion is a compromise to support generic processing. + ** and is implicitly convertible back to the underlying numeric type (usually int or double). ** ** But at the same time, a Digxel has a definite textual format and the ability to present ** its numeric value formatted accordingly. To this end, the contract \em requires that ** numeric data pushed to the Digxel be kept within such limits to prevent exceeding the ** embedded formatting buffer. There is an assertion in debug mode, and a range check, - ** but the result will be just truncated, so this is clearly the caller's responsibility. - ** Digxel might be considered an implementation support class, and performance is important - ** to some limited degree; especially, formatted values will be cached. + ** but the result will be just truncated, so passing only sane values is clearly the + ** caller's responsibility. Digxel might be considered an implementation support class, + ** and performance is important to some limited degree; + ** especially, formatted values will be \em cached. ** - ** To support in-place modification, the digxel stores a mutation signal (functor) and exposes - ** a special \c mutate(newVal) function, which invokes this stored functor, if defined. Usually - ** this should invoke some internal recalculations, resulting in a new value being pushed to - ** the Digxel for display. + ** To support in-place modification, the digxel stores a mutation signal (functor). This + ** functor will be invoked, whenever a new value gets assigned. The actual functor is free + ** to cause side effects; the value returned from this functor will be the new value to set. + ** If not configured, the default implementation just accepts the given value unaltered. Usually + ** this mutation functor should invoke some internal recalculations, maybe resulting in a new + ** value being pushed to the Digxel for display. ** ** \par configuration ** the Digxel template can be configured to some degree to adjust the stored numeric data @@ -69,16 +71,15 @@ #include #include #include -#include ///////////TODO -#include #include +#include + +using std::string; namespace lib { namespace time { - using std::string; - namespace digxel { using util::cStr; @@ -86,27 +87,13 @@ namespace time { using boost::lexical_cast; typedef const char* CBuf; - - - template - struct ValTrait; - - template<> - struct ValTrait - { - static int asInt (int val) { return val; } - static double asDouble (int val) { return val; } - }; - - template<> - struct ValTrait - { - static int asInt (double val) { return std::floor(0.5+val); } ///< in accordance with Lumiera's time handling RfC - static double asDouble (double val) { return val; } - }; - + /** + * Default / base implementation for Digxel formatting. + * This formatter holds an inline buffer of limited size, + * receiving and caching the textual representation + */ template class PrintfFormatter { @@ -124,7 +111,7 @@ namespace time { } void clear() { printbuffer_[0] = '\0'; } - bool empty() { return ! bool(*printbuffer_); } + bool empty() { return '\0' == *printbuffer_; } size_t maxlen() const @@ -147,6 +134,11 @@ namespace time { } }; + + /** + * default configured Formatter implementations + * for some of the basic numeric types + */ template struct Formatter; @@ -154,8 +146,7 @@ namespace time { struct Formatter : PrintfFormatter { - Formatter() : PrintfFormatter("%5d") { } - + Formatter() : PrintfFormatter("%3d") { } }; template<> @@ -163,25 +154,46 @@ namespace time { : PrintfFormatter { Formatter() : PrintfFormatter("%06.3f") { } - }; + /* == other specialised Formatters == */ + struct SexaFormatter + : PrintfFormatter + { + SexaFormatter() : PrintfFormatter("%02d") { } + }; + + struct HexaFormatter + : PrintfFormatter + { + HexaFormatter() : PrintfFormatter("%02X") { } + }; + + } //(End) digxel configuration namespace + + + /** * A number element for building structured numeric displays. * The purpose is to represent parts of a numeric format, like - * e.g. the sexagesimal "digits" of a timecode display. Digxel + * e.g. the sexagesimal "digits" of a timecode display. A Digxel * - is customised by template parameters to a specific number format - * - requires that any number set must not overflow the format buffer + * - requires that any given number must not overflow the format buffer * - can receive new numbers by assignment + * - stores and these given value numerically * - will then format these numbers and cache the formatted representation - * - can store and invoke a mutation functor - * + * - can store and invoke a mutation functor to pre-process values on setting + * * @note comparisons are assumed to be not performance relevant + * @param NUM numeric type to be used for the value + * @param FMT a formatter and buffer holder type + * @see digxel::Formatter default printf based formatter * @see lib::time::TCode - * @todo WIP-WIP-WIP + * @see Digxel_test + * */ template< typename NUM , class FMT = digxel::Formatter @@ -208,7 +220,7 @@ namespace time { Digxel () : buffer_() - , value_() + , value_ () , mutator(use_newValue_as_is) { } @@ -219,6 +231,7 @@ namespace time { size_t maxlen() const { return buffer_.maxlen(); } + digxel::CBuf show() const { @@ -229,7 +242,7 @@ namespace time { void operator= (NUM n) { - NUM changedValue = mutator(n); + NUM changedValue = mutator(n); this->setValueRaw (changedValue); } @@ -248,13 +261,14 @@ namespace time { //---Supporting-totally_ordered--------- bool operator< (Digxel const& o) const { return value_ < NUM(o); } bool operator== (Digxel const& o) const { return value_ == NUM(o); } -// bool operator== (NUM n) const { return value_ == n ; } -// bool operator< (NUM n) const { return value_ < n ; } -// bool operator> (NUM n) const { return value_ > n ; } - }; + /* == predefined Digxel configurations == */ + typedef Digxel< int, digxel::SexaFormatter> SexaDigit; ///< for displaying time components (sexagesimal) + typedef Digxel HexaDigit; ///< for displaying a hex byte + + }} // lib::time #endif diff --git a/src/lib/time/quantiser.hpp b/src/lib/time/quantiser.hpp index 61b9e99d0..84881141a 100644 --- a/src/lib/time/quantiser.hpp +++ b/src/lib/time/quantiser.hpp @@ -32,6 +32,7 @@ //#include #include #include +#include namespace lib { @@ -39,6 +40,29 @@ namespace time { LUMIERA_ERROR_DECLARE (UNKNOWN_GRID); ///< referring to an undefined grid or scale in value quantisation + + namespace { // stashed here for later + + template + struct ValTrait; + + template<> + struct ValTrait + { + static int asInt (int val) { return val; } + static double asDouble (int val) { return val; } + }; + + template<> + struct ValTrait + { + static int asInt (double val) { return std::floor(0.5+val); } ///< in accordance with Lumiera's time handling RfC + static double asDouble (double val) { return val; } + }; + + } + + /** * Facility to create grid-aligned time values. * diff --git a/tests/40components.tests b/tests/40components.tests index b61a98aed..51b98cfb6 100644 --- a/tests/40components.tests +++ b/tests/40components.tests @@ -231,6 +231,26 @@ return: 0 END +TEST "A Digxel (numeric component)" Digxel_test < : Yes out: HasNested_Core : No diff --git a/tests/lib/time/digxel-configurations-test.cpp b/tests/lib/time/digxel-configurations-test.cpp new file mode 100644 index 000000000..185fd06a7 --- /dev/null +++ b/tests/lib/time/digxel-configurations-test.cpp @@ -0,0 +1,105 @@ +/* + DigxelConfigurations(Test) - verify predefined standard Digxel configurations + + Copyright (C) Lumiera.org + 2011, Hermann Vosseler + + 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/test/test-helper.hpp" +#include "lib/time/display.hpp" +#include "lib/time/digxel.hpp" +#include "lib/error.hpp" +#include "lib/util.hpp" + +#include +#include + +using lumiera::error::LUMIERA_ERROR_ASSERTION; +using util::isSameObject; +using lib::test::showType; +using std::rand; +using std::cout; +using std::endl; + + +namespace lib { +namespace time{ +namespace test{ + + + + + + + /*********************************************************************** + * @test verify correctness of the predefined standard Digxels. + * Some widely used standard configurations, including + * - default Digxel for int and double values + * - sexagesimal Digxel + * - hex byte Digxel + * - ...more to come + * @todo cover any newly added Digxel configurations. + */ + class DigxelConfigurations_test : public Test + { + virtual void + run (Arg) + { + verifyConfiguration > (123); + verifyConfiguration > (123.4567); + verifyConfiguration (42); + verifyConfiguration (-5); + verifyConfiguration (0xc); + verifyConfiguration (0x6f); + } + + + template + void + verifyConfiguration (VAL testval) + { + DIX digxel; + CHECK (0 == digxel); + cout << showType(digxel) << "--empty--"< #include +using lumiera::error::LUMIERA_ERROR_ASSERTION; using util::isSameObject; using std::rand; using std::cout; @@ -247,7 +248,7 @@ namespace test{ string formatted; #if false ///////////////////////////////////////////////////////////////////////////////////////////////TICKET #537 : restore throwing ASSERT VERIFY_ERROR (ASSERTION, formatted = digi.show() ); // should trigger assertion - formatted = digi.show(); // second time doesn't reformat + formatted = digi.show(); // second time doesn't reformat #endif ///////////////////////////////////////////////////////////////////////////////////////////////TICKET #537 : restore throwing ASSERT CHECK (formatted.length() <= digi.maxlen());