From b42e5c859fccb7f379ea210524ba0ade35434610 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 23 Nov 2010 03:40:11 +0100 Subject: [PATCH] Test-driven brainstorming: how should output mapping be used? --- src/proc/mobject/output-mapping.hpp | 2 +- tests/components/Makefile.am | 1 + .../proc/mobject/output-mapping-test.cpp | 160 ++++++++++++++++++ wiki/renderengine.html | 4 +- 4 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 tests/components/proc/mobject/output-mapping-test.cpp diff --git a/src/proc/mobject/output-mapping.hpp b/src/proc/mobject/output-mapping.hpp index 6c7021153..ee35cb036 100644 --- a/src/proc/mobject/output-mapping.hpp +++ b/src/proc/mobject/output-mapping.hpp @@ -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 + template class OutputMapping { public: diff --git a/tests/components/Makefile.am b/tests/components/Makefile.am index aed92cb4e..ea5d1fddb 100644 --- a/tests/components/Makefile.am +++ b/tests/components/Makefile.am @@ -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 \ diff --git a/tests/components/proc/mobject/output-mapping-test.cpp b/tests/components/proc/mobject/output-mapping-test.cpp new file mode 100644 index 000000000..b0d8a3153 --- /dev/null +++ b/tests/components/proc/mobject/output-mapping-test.cpp @@ -0,0 +1,160 @@ +/* + OutputMapping(Test) - verify generic output designation mapping + + 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/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 +//#include + +//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 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 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 diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 4652500d2..5f6b9a674 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -3012,7 +3012,7 @@ Any external output sink is managed as a [[slot|DisplayerSlot]] in the ~OutputMa → see also the PlayerDummy -
+
An output mapping serves to //resolve//  [[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//  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.