Test-driven brainstorming: how should output mapping be used?
This commit is contained in:
parent
a43bd239cb
commit
b42e5c859f
4 changed files with 164 additions and 3 deletions
|
|
@ -41,7 +41,7 @@ namespace mobject {
|
|||
* This is an Interface, intended to be used in the signature
|
||||
* of API functions either providing or requiring a Mapping.
|
||||
*/
|
||||
template<class FUNC>
|
||||
template<class DEF>
|
||||
class OutputMapping
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ test_components_SOURCES = \
|
|||
$(testcomponents_srcdir)/proc/mobject/controller/rendersegmenttest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/mobject-interface-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/mobject-ref-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/output-mapping-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placement-basic-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placement-hierarchy-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placement-object-identity-test.cpp \
|
||||
|
|
|
|||
160
tests/components/proc/mobject/output-mapping-test.cpp
Normal file
160
tests/components/proc/mobject/output-mapping-test.cpp
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
OutputMapping(Test) - verify generic output designation mapping
|
||||
|
||||
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.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
//#include "proc/asset/media.hpp"
|
||||
//#include "proc/mobject/session.hpp"
|
||||
//#include "proc/mobject/session/testclip.hpp"
|
||||
#include "proc/asset/pipe.hpp"
|
||||
//#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/output-mapping.hpp"
|
||||
#include "lib/util.hpp"
|
||||
//#include "proc/mobject/session/mobjectfactory.hpp" ////TODO: avoidable?
|
||||
|
||||
//#include <boost/format.hpp>
|
||||
//#include <iostream>
|
||||
|
||||
//using boost::format;
|
||||
//using lumiera::Time;
|
||||
//using util::contains;
|
||||
using util::isnil;
|
||||
//using std::string;
|
||||
//using std::cout;
|
||||
|
||||
|
||||
namespace mobject {
|
||||
namespace test {
|
||||
|
||||
//using asset::VIDEO;
|
||||
using asset::Pipe;
|
||||
using asset::PPipe;
|
||||
|
||||
namespace {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* @test create a synthetic / example mapping to verify
|
||||
* generic mapping behaviour
|
||||
*
|
||||
* @see mobject::OutputDesignation
|
||||
* @see mobject::session::Binding
|
||||
*/
|
||||
class OutputMapping_test : public Test
|
||||
{
|
||||
struct DummyDef
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
typedef OutputMapping<DummyDef> Mapping;
|
||||
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
map_and_retrieve();
|
||||
instance_copy();
|
||||
default_mapping();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
map_and_retrieve()
|
||||
{
|
||||
Mapping map;
|
||||
CHECK (isnil (map));
|
||||
|
||||
PPipe p1 = Pipe::query("id(hairy)");
|
||||
PPipe p2 = Pipe::query("id(furry)");
|
||||
PPipe pX = Pipe::query("");
|
||||
|
||||
map[p1] = p2;
|
||||
CHECK (!isnil (map));
|
||||
CHECK (1 == map.size());
|
||||
CHECK (map[p1] == "furry");
|
||||
CHECK (map[p1].isDefined());
|
||||
|
||||
CHECK (!map[pX].isDefined());
|
||||
CHECK (!map[p2].isDefined());
|
||||
VERIFY_ERROR (UNKNOWN_MAPPING, map[pX] );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
instance_copy()
|
||||
{
|
||||
Mapping m1;
|
||||
|
||||
PPipe p1 = Pipe::query("id(hairy)");
|
||||
PPipe p2 = Pipe::query("id(furry)");
|
||||
PPipe pX = Pipe::query("");
|
||||
|
||||
m1[pX] = p1;
|
||||
Mapping m2(m1);
|
||||
CHECK (!isnil (m2));
|
||||
CHECK (1 == m2.size());
|
||||
CHECK (m1[p1] == "hairy");
|
||||
CHECK (m2[p1] == "hairy");
|
||||
|
||||
m1[pX] = p2;
|
||||
CHECK (m1[p1] == "furry");
|
||||
CHECK (m2[p1] == "hairy");
|
||||
|
||||
m2 = m1;
|
||||
CHECK (m1[p1] == "furry");
|
||||
CHECK (m2[p1] == "furry");
|
||||
|
||||
m1.clear();
|
||||
CHECK (isnil(m1));
|
||||
CHECK (!isnil(m2));
|
||||
CHECK (m2[p1] == "furry");
|
||||
CHECK (!m1[p1].isDefined());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
default_mapping()
|
||||
{
|
||||
Mapping map;
|
||||
CHECK (isnil (map));
|
||||
|
||||
PPipe p1 = Pipe::query("stream(hairy)");
|
||||
PPipe p2 = Pipe::query("stream(furry)");
|
||||
|
||||
CHECK (map[p1] == "master(hairy)");
|
||||
CHECK (map[p2] == "master(furry)");
|
||||
|
||||
Query<Pipe> special_bus ("stream(furry), ord(2)");
|
||||
CHECK (map[special_bus] == "master.2(furry)");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (OutputMapping_test, "unit session");
|
||||
|
||||
|
||||
|
||||
}} // namespace mobject::test
|
||||
|
|
@ -3012,7 +3012,7 @@ Any external output sink is managed as a [[slot|DisplayerSlot]] in the ~OutputMa
|
|||
&rarr; see also the PlayerDummy
|
||||
</pre>
|
||||
</div>
|
||||
<div title="OutputMapping" modifier="Ichthyostega" modified="201011220305" created="201011080238" tags="Model spec draft" changecount="21">
|
||||
<div title="OutputMapping" modifier="Ichthyostega" modified="201011230136" created="201011080238" tags="Model spec draft" changecount="22">
|
||||
<pre>An output mapping serves to //resolve//&nbsp; [[output designations|OutputDesignation]].
|
||||
|
||||
!Mapping situations
|
||||
|
|
@ -3039,7 +3039,7 @@ All these mapping steps are listed here, because they exhibit a common pattern.
|
|||
* there is an //unconnected//&nbsp; state.
|
||||
|
||||
!Implementation notes
|
||||
Thus the mapping is a copyable value object, based on a associative array. It may be attached to a model object and persisted alongside. The mapping is assumed to run a defaults query when necessary. To allow for that, it should be configured with a query template (string). Frequently, special //default pipe// markers will be used at places, where no distinct pipe-~ID is explicitly specified. Besides that, invocations might supply additional predicates (e.g. {{{ord(2)}}} to denote "the second stream of this kind") to hint the defaults resolution. Moreover, the mapping needs a way to retrieve the set of possible results, allowing to filter the results of the rules based default. Mappings might be defined explicitly. Instead of storing a //bottom value,// an {{{isDefined()}}} predicate might be preferable.
|
||||
Thus the mapping is a copyable value object, based on a associative array. It may be attached to a model object and persisted alongside. The mapping is assumed to run a defaults query when necessary. To allow for that, it should be configured with a query template (string). Frequently, special //default pipe// markers will be used at places, where no distinct pipe-ID is explicitly specified. Besides that, invocations might supply additional predicates (e.g. {{{ord(2)}}} to denote "the second stream of this kind") to hint the defaults resolution. Moreover, the mapping needs a way to retrieve the set of possible results, allowing to filter the results of the rules based default. Mappings might be defined explicitly. Instead of storing a //bottom value,// an {{{isDefined()}}} predicate might be preferable.
|
||||
|
||||
First and foremost, mapping can be seen as a //functional abstraction.// As it's used at implementation level, encapsulation of detail types in't the primary concern, so it's a candidate for generic programming. But there //is// a concern better to be concealed at the usage site, namely accessing the rules system. Thus mapping leads itself to the frequently used implementation pattern where there is a generic frontend as header, calling into opaque functions embedded within a separate compilation unit.
|
||||
</pre>
|
||||
|
|
|
|||
Loading…
Reference in a new issue