finished reworking Placement (hierarchy and ID)
This commit is contained in:
parent
e8c25fca0a
commit
d49eea6e5d
10 changed files with 140 additions and 70 deletions
|
|
@ -26,6 +26,7 @@
|
|||
#include "proc/mobject/mobject.hpp"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <typeinfo>
|
||||
|
||||
using boost::format;
|
||||
using boost::str;
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ namespace mobject {
|
|||
* which is subject to placement.
|
||||
* @note we don't provide operator*
|
||||
*/
|
||||
virtual MObject *
|
||||
MObject *
|
||||
operator-> () const
|
||||
{
|
||||
ENSURE (*this);
|
||||
|
|
@ -193,7 +193,7 @@ namespace mobject {
|
|||
friend class session::MObjectFactory;
|
||||
|
||||
public:
|
||||
virtual MO*
|
||||
MO*
|
||||
operator-> () const
|
||||
{
|
||||
ENSURE (INSTANCEOF (MO, this->get()));
|
||||
|
|
|
|||
|
|
@ -29,7 +29,19 @@ PLANNED "PlacementBasic_test" PlacementBasic_test <<END
|
|||
END
|
||||
|
||||
|
||||
PLANNED "PlacementHierarchy_test" PlacementHierarchy_test <<END
|
||||
TEST "hierarchical placement types" PlacementHierarchy_test <<END
|
||||
out: sizeof\( \w+ \) = \d{2}
|
||||
out: Placement.+mobject.+test.+TestSubMO1.+. use-cnt=1 .*
|
||||
out: Placement.+mobject.+test.+TestSubMO2.+. use-cnt=1 .*
|
||||
out: Placement.+mobject.+test.+TestSubMO21.+ use-cnt=2 .*
|
||||
out: Placement.+mobject.+test.+TestSubMO21.+ use-cnt=2 .*
|
||||
out: Placement.+mobject.+session.+Clip.+.... use-cnt=2 .*
|
||||
out: TestSubMO1\(ID= \d{3}\)
|
||||
out: TestSubMO2\(ID= \d{3}\)
|
||||
out: TestSubMO21\(ID= \d{3}\)
|
||||
out: specialAPI()
|
||||
out: specialAPI()
|
||||
out: pID\(\w{16}\)
|
||||
END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ namespace asset
|
|||
ASSERT (c1 == c2);
|
||||
|
||||
PPipe pipe3 = Pipe::query ("pipe("+pID2+")");
|
||||
//////////////////////////////////////////////////////////////TODO: er macht eine Neue, anstatt die Bestehende zu finden
|
||||
//////////////////////////////////////////////////////////////TODO: that's broken; creating a new one instead to find the existing one, as it should be
|
||||
ASSERT (pipe3 == pipe2);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,10 +33,8 @@ using util::isnil;
|
|||
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
namespace asset{
|
||||
namespace test {
|
||||
|
||||
|
||||
|
||||
|
|
@ -59,7 +57,7 @@ namespace asset
|
|||
|
||||
typedef TestAsset<Asset> TA;
|
||||
typedef TA::PA PTestA;
|
||||
|
||||
|
||||
|
||||
/** @test check operation of basic asset dependency support
|
||||
*/
|
||||
|
|
@ -149,12 +147,12 @@ namespace asset
|
|||
a2->enable(true);
|
||||
ASSERT (a1->isActive());
|
||||
ASSERT (a2->isActive());
|
||||
|
||||
|
||||
a3->enable(false);
|
||||
ASSERT (a1->isActive());
|
||||
ASSERT (a2->isActive());
|
||||
ASSERT (!a3->isActive()); // no dependency...
|
||||
|
||||
|
||||
a1->enable(false);
|
||||
a3->enable();
|
||||
ASSERT (!a1->isActive());
|
||||
|
|
@ -210,6 +208,4 @@ namespace asset
|
|||
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace asset
|
||||
}} // namespace asset::test
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ namespace mobject {
|
|||
ExplicitPlacement expla = pc.resolve();
|
||||
ASSERT (expla.time == 1);
|
||||
ASSERT (!expla.chain.isOverdetermined());
|
||||
//ASSERT (*expla == *pc); ////////////////////////TODO: define equality on placements
|
||||
//ASSERT (*expla == *pc); ////////////////////////TODO: define equality on placements (Trac #119)
|
||||
|
||||
// now overconstraining with another Placement
|
||||
pc.chain(Time(2));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
PlacementHierarchy(Test) - concept draft how to deal with the MObject hierarchy in Placements
|
||||
PlacementHierarchy(Test) - cooperating hierarchical placement types
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
|
@ -22,47 +22,40 @@
|
|||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
//#include "proc/asset/media.hpp"
|
||||
//#include "proc/mobject/session.hpp"
|
||||
//#include "proc/mobject/session/edl.hpp"
|
||||
//#include "proc/mobject/session/testclip.hpp"
|
||||
//#include "proc/mobject/placement.hpp"
|
||||
//#include "proc/mobject/placement-ref.hpp"
|
||||
//#include "proc/mobject/explicitplacement.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "proc/mobject/test-dummy-mobject.hpp"
|
||||
#include "lib/hash-indexed.hpp"
|
||||
#include "proc/mobject/session/clip.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/asset/media.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <tr1/memory>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
using lib::HashIndexed;
|
||||
|
||||
using std::tr1::shared_ptr;
|
||||
using boost::format;
|
||||
using boost::str;
|
||||
//using lumiera::Time;
|
||||
//using util::contains;
|
||||
using lib::HashIndexed;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::rand;
|
||||
using std::endl;
|
||||
|
||||
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
namespace test {
|
||||
|
||||
using session::Clip;
|
||||
using lib::test::showSizeof;
|
||||
using namespace mobject::test;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* @test Currently (5/09) this is a concept draft separate of any existing types.
|
||||
* The intention is to rework the Placement implementation based on the
|
||||
* outcomes of this experiment. When doing so, this test could later on
|
||||
* serve to document and cover the corresponding Placement properties.
|
||||
/***************************************************************************************
|
||||
* @test creating placements specifically typed, forming an hierarchy of placement types
|
||||
* which loosely mirrors the hierarchy of the pointee types. Assignments between
|
||||
* placement of differing type, while still sharing ownership.
|
||||
* @see mobject::Placement
|
||||
* @see mobject::MObject#create
|
||||
* @see lib::hash::HashIndexed
|
||||
*/
|
||||
class PlacementHierarchy_test : public Test
|
||||
{
|
||||
|
|
@ -70,32 +63,99 @@ namespace test {
|
|||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
TestPlacement<TestSubMO1> pSub1(*new TestSubMO1);
|
||||
TestPlacement<TestSubMO2> pSub2(*new TestSubMO2);
|
||||
TestPlacement<TestSubMO21> pSub3(*new TestSubMO21);
|
||||
typedef Placement<MObject> PMObj;
|
||||
typedef TestPlacement<> PDummy;
|
||||
typedef TestPlacement<TestSubMO1> PSub1;
|
||||
typedef TestPlacement<TestSubMO2> PSub2;
|
||||
typedef TestPlacement<TestSubMO21,TestSubMO2> PSub21;
|
||||
|
||||
TestPlacement<DummyMO> pSubM (pSub3);
|
||||
PSub1 pSub1(*new TestSubMO1);
|
||||
PSub2 pSub2(*new TestSubMO2);
|
||||
PSub21 pSub3(*new TestSubMO21);
|
||||
|
||||
/////////////////////////////////TODO
|
||||
format fmt ("sizeof( %s ) = %d\n");
|
||||
cout << fmt % "Pla<Sub1>" % sizeof(pSub1);
|
||||
cout << fmt % "Pla<Sub2>" % sizeof(pSub2);
|
||||
cout << fmt % "Pla<Sub3>" % sizeof(pSub3);
|
||||
PDummy pSubM (pSub3);
|
||||
|
||||
PMObj pClip = asset::Media::create("test-1", asset::VIDEO)->createClip();
|
||||
|
||||
ASSERT (INSTANCEOF (Placement<MObject>, &pSub1));
|
||||
ASSERT (INSTANCEOF (Placement<MObject>, &pSub2));
|
||||
ASSERT (INSTANCEOF (Placement<MObject>, &pSub3));
|
||||
ASSERT (INSTANCEOF (Placement<MObject>, &pSubM));
|
||||
|
||||
ASSERT (INSTANCEOF (Placement<DummyMO>, &pSub1));
|
||||
ASSERT (INSTANCEOF (Placement<DummyMO>, &pSub2));
|
||||
ASSERT (INSTANCEOF (Placement<DummyMO>, &pSub3));
|
||||
|
||||
ASSERT (INSTANCEOF (TestPlacement<DummyMO>, &pSub1));
|
||||
ASSERT (INSTANCEOF (TestPlacement<DummyMO>, &pSub2));
|
||||
ASSERT (INSTANCEOF (TestPlacement<DummyMO>, &pSub3));
|
||||
|
||||
ASSERT ( INSTANCEOF (TestPlacement<TestSubMO2>, &pSub3));
|
||||
|
||||
// the following won't succeed...
|
||||
// ASSERT (INSTANCEOF (TestPlacement<TestSubMO21>, &pSub2)); // parent not instance of subclass
|
||||
// ASSERT (INSTANCEOF (TestPlacement<TestSubMO2>, &pSub1)); // separate branch in the hierarchy
|
||||
|
||||
cout << showSizeof(pSub1) << endl;
|
||||
cout << showSizeof(pSub2) << endl;
|
||||
cout << showSizeof(pSub3) << endl;
|
||||
cout << showSizeof(pSubM) << endl;
|
||||
cout << showSizeof(pClip) << endl;
|
||||
|
||||
ASSERT (sizeof(pSub1) == sizeof(pSub3));
|
||||
ASSERT (sizeof(pClip) == sizeof(pSub3));
|
||||
|
||||
cout << string(pSub1) << endl;
|
||||
cout << string(pSub2) << endl;
|
||||
cout << string(pSub3) << endl;
|
||||
cout << string(pSubM) << endl;
|
||||
cout << string(pClip) << endl;
|
||||
cout << pSub1->operator string() << endl;
|
||||
cout << pSub2->operator string() << endl;
|
||||
cout << pSubM->operator string() << endl;
|
||||
|
||||
cout << string(pSub1) << "\n";
|
||||
cout << string(pSub2) << "\n";
|
||||
cout << string(pSubM) << "\n";
|
||||
cout << pSub1->operator string() << "\n";
|
||||
cout << pSub2->operator string() << "\n";
|
||||
cout << pSubM->operator string() << "\n";
|
||||
pSub3->specialAPI();
|
||||
|
||||
cout << format_PlacementID(pSub1) << "\n";
|
||||
cout << format_PlacementID(pSub2) << "\n";
|
||||
cout << format_PlacementID(pSub3) << "\n";
|
||||
cout << format_PlacementID(pSubM) << "\n";
|
||||
ASSERT (2 == pSubM.use_count());
|
||||
ASSERT (2 == pSub3.use_count());
|
||||
pClip = pSubM; // slicing and shared ownership
|
||||
ASSERT (3 == pSubM.use_count());
|
||||
ASSERT (3 == pSub3.use_count());
|
||||
ASSERT (3 == pClip.use_count());
|
||||
|
||||
cout << "Hurgha!\n";
|
||||
|
||||
// now do a brute-force re-interpretation
|
||||
// note this is still protected by an ASSERT on the operator->()
|
||||
PSub21& hijacked = reinterpret_cast<PSub21&> (pClip);
|
||||
|
||||
hijacked->specialAPI();
|
||||
ASSERT (3 == hijacked.use_count());
|
||||
ASSERT (hijacked.getID() == pSub3.getID());
|
||||
|
||||
cout << format_PlacementID(pSub1) << endl;
|
||||
cout << format_PlacementID(pSub2) << endl;
|
||||
cout << format_PlacementID(pSub3) << endl;
|
||||
cout << format_PlacementID(pSubM) << endl;
|
||||
cout << format_PlacementID(pClip) << endl;
|
||||
|
||||
pClip = pSub1;
|
||||
ASSERT (2 == pSubM.use_count());
|
||||
ASSERT (2 == pSub3.use_count());
|
||||
|
||||
ASSERT (2 == pClip.use_count());
|
||||
ASSERT (2 == pSub1.use_count());
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////TODO: find a way to configure NoBug to throw in case of assertion
|
||||
///////////////////////////////////////////////////////////////////////////////TODO: configure NoBug specifically for the testsuite
|
||||
// try
|
||||
// {
|
||||
// hijacked->specialAPI();
|
||||
// NOTREACHED;
|
||||
// }
|
||||
// catch (...)
|
||||
// {
|
||||
// ASSERT (lumiera_error () == error::LUMIERA_ERROR_ASSERTION);
|
||||
// }
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ namespace test {
|
|||
struct TestSubMO21 : TestSubMO2
|
||||
{
|
||||
virtual operator string() const { return display("TestSubMO21"); }
|
||||
void specialAPI() { cout << "specialAPI()\n";}
|
||||
virtual void specialAPI() const { cout << "specialAPI()\n";}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ namespace test {
|
|||
: TestPlacement<B>(dummyObj)
|
||||
{ }
|
||||
|
||||
virtual DMO*
|
||||
DMO *
|
||||
operator-> () const
|
||||
{
|
||||
ENSURE (INSTANCEOF (DMO, this->get()));
|
||||
|
|
|
|||
|
|
@ -76,12 +76,12 @@ namespace test{
|
|||
ASSERT (2 == sizeof (rmpf2));
|
||||
ASSERT (3 == sizeof (rmpf3));
|
||||
|
||||
cout << showSizeof((size_t)42,"theUniverse") << endl;
|
||||
cout << showSizeof<char>("just a char") << endl;
|
||||
cout << showSizeof(murpf) << endl;
|
||||
cout << showSizeof(rmpf1) << endl;
|
||||
cout << showSizeof(rmpf2) << endl;
|
||||
cout << showSizeof<Wrmpf3>() << endl;
|
||||
cout << showSizeof((size_t)42, "theUniverse") << endl;
|
||||
cout << showSizeof<char>("just a char") << endl;
|
||||
cout << showSizeof(murpf) << endl;
|
||||
cout << showSizeof(rmpf1) << endl;
|
||||
cout << showSizeof(rmpf2) << endl;
|
||||
cout << showSizeof<Wrmpf3>() << endl;
|
||||
|
||||
Wrmpf1 *p1 = &rmpf1;
|
||||
Wrmpf1 *p2 = 0;
|
||||
|
|
|
|||
|
|
@ -579,7 +579,7 @@ For every Asset we generate a __Ident tuple__ and a long ID (hash) derived from
|
|||
<div title="AssetManager" modifier="Ichthyostega" created="200709200300" changecount="1">
|
||||
<pre>The Asset Manager provides an Interface to some internal Database holding all Assets in the current Session and System state. It may be a real Database at some point (and for the moment it's a Hashtable). Each [[Asset]] is registered automatically with the Asset Manager; it can be queried either by it's //identification tuple// or by it's unique ID.</pre>
|
||||
</div>
|
||||
<div title="AttachedPlacementProblem" modifier="Ichthyostega" modified="200905120332" created="200801111305" tags="SessionLogic impl draft dynamic" changecount="14">
|
||||
<div title="AttachedPlacementProblem" modifier="Ichthyostega" modified="200905292133" created="200801111305" tags="SessionLogic impl draft dynamic" changecount="15">
|
||||
<pre>Placing an MObject relatively to another object such that it should be handled as //attached//&nbsp; to the latter results in several design and implementation challenges. Actually, such an attachment creates a cluster of objects. The typical use case is that of an effect attached to a clip or processing pipe.
|
||||
* attachment is not a globally fixed relation between objects, rather, it typically exists only for some limited time span (e.g. the duration of the basic clip the effect is attached to)
|
||||
* the order of attachment is important and the attached placement may create a fork in the signal flow, so we need a way for specifying reproducibly how the resulting wiring should be
|
||||
|
|
@ -592,7 +592,7 @@ The first step towards an solution is to isolate the problem; obviously we don't
|
|||
|
||||
!!Implementation notes
|
||||
Attachment is managed within the participating placements, mostly by special [[locating pins|LocatingPin]]. Attachment doesn't necessarily nail down an attached object to a specific position, rather the behaviour depends on the type of the object and the locating pins actually involved, especially on their order and priority. For example, if an {{{Placement<Effect>}}} doesn't contain any locating pin defining a temporal position, then the attachment will result in the placement inheriting the temporal placement of the //attachment head// (i.e. the clip this effect has been attached to). But, if on the contrary the effect in question //does// have an additional locating pin, for example relative to another object or even to a fixed time position, this one will "win" and determine the start position of the effect &mdash; it may even move the effect out of the time interval covered by the clip, in which case the attachment has no effect on the clip's processing pipe.
|
||||
The attachment relation is hierarchical and has a clearly defined //active// and //passive// side: The attachment head is the parent node in a tree, but plays the role of the passive partner, to which the child nodes attach. But note, this does not mean we are limited to a single attachment head. Actually, each placement has a list of locating pins and thus can attach to several other placements. For example, a transition attaches to at least two local pipes (clips).
|
||||
The attachment relation is hierarchical and has a clearly defined //active// and //passive// side: The attachment head is the parent node in a tree, but plays the role of the passive partner, to which the child nodes attach. But note, this does not mean we are limited to a single attachment head. Actually, each placement has a list of locating pins and thus can attach to several other placements. For example, a transition attaches to at least two local pipes (clips). {{red{TODO: unresolved design problem; seems to contradict the PlacementScope}}}
|
||||
|
||||
!!!!Relation to memory management
|
||||
Attachment on itself does //not// keep an object alive. Rather, it's a direct reference and has to be taken into account when deleting an object. On the other hand, processing nodes in the render engine never depend on placements &mdsash; they always refer directly to the MObject instance or even the underlying asset. In the case of MObject instances, the pointer from within the engine will //share ownership// with the placement (remember: both are derived from {{{boost::shared_ptr}}}).
|
||||
|
|
@ -2969,7 +2969,7 @@ We need a way of addressing existing [[pipes|Pipe]]. Besides, as the Pipes and T
|
|||
<<tasksum end>>
|
||||
</pre>
|
||||
</div>
|
||||
<div title="PlanningSessionInMem" modifier="Ichthyostega" modified="200905291920" created="200904252258" tags="impl SessionLogic draft" changecount="16">
|
||||
<div title="PlanningSessionInMem" modifier="Ichthyostega" modified="200905310301" created="200904252258" tags="impl SessionLogic draft" changecount="19">
|
||||
<pre>//This page is a scrapbook for working out the implementation of the [[Session Datastructure in Memory|SessionDataMem]]//
|
||||
This is a difficult untertaking, because there are several dependencies (most of which aren't fully designed yet as of 5/09)
|
||||
* the GUI uses an adapted version of the HighLevelModel; these datastructures are intended to be backed by the Session
|
||||
|
|
@ -2993,8 +2993,9 @@ This is a difficult untertaking, because there are several dependencies (most of
|
|||
<<task >> specify the editing operations
|
||||
|
||||
!Interface
|
||||
<<task>>evaluate models for the [[reference problem|MObjectRef]]
|
||||
<<task 2 3 3>> implement an hash-ID to be incorporated into placements
|
||||
<<task 1 1 1>> evaluate models for the [[reference problem|MObjectRef]]
|
||||
<<task 2 3 3>> implement an hash-ID
|
||||
<<task 1 2 2>> incorporate this ID into class Placement
|
||||
<<task 1 1 0>> implement PlacementRef
|
||||
<<task 2 2 0>> implement MObjectRef
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue