WIP: start drafing MObjectRef
This commit is contained in:
parent
78901837fc
commit
8a453bd52b
11 changed files with 303 additions and 46 deletions
|
|
@ -91,6 +91,7 @@ liblumiprocmobject_la_SOURCES = \
|
|||
$(liblumiprocmobject_la_srcdir)/builderfacade.cpp \
|
||||
$(liblumiprocmobject_la_srcdir)/interpolator.cpp \
|
||||
$(liblumiprocmobject_la_srcdir)/mobject.cpp \
|
||||
$(liblumiprocmobject_la_srcdir)/mobject-ref.cpp \
|
||||
$(liblumiprocmobject_la_srcdir)/parameter.cpp \
|
||||
$(liblumiprocmobject_la_srcdir)/paramprovider.cpp \
|
||||
$(liblumiprocmobject_la_srcdir)/placement-index.cpp \
|
||||
|
|
|
|||
52
src/proc/mobject/mobject-ref.cpp
Normal file
52
src/proc/mobject/mobject-ref.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
MobjectRef - active external reference to an MObject within the Session
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, 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.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
/** @file mobject-ref.cpp
|
||||
** Implementation part of the MObjectRef facility.
|
||||
** Any C++ client about to use a MObjectRef needs to be linked (dynamically) against
|
||||
** this implementation. Especially, this implementation allows to (re)-connect transparently
|
||||
** to the PlacementIndex within the session, so to establish a direct link to the Object
|
||||
** denoted by the reference.
|
||||
**
|
||||
** @see PlacementRef
|
||||
** @see PlacementIndex
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#include "proc/mobject/mobject-ref.hpp"
|
||||
#include "proc/mobject/mobject.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
|
||||
//#include <boost/format.hpp>
|
||||
//using boost::str;
|
||||
|
||||
namespace mobject {
|
||||
|
||||
/** */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace mobject
|
||||
126
src/proc/mobject/mobject-ref.hpp
Normal file
126
src/proc/mobject/mobject-ref.hpp
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
MOBJECT-REF.hpp - active external reference to an MObject within the Session
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, 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.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/** @file mobject-ref.hpp
|
||||
** A reference tag for accessing an object within the session externally,
|
||||
** from a separate Layer or from plugin code.
|
||||
**
|
||||
** @see MObject
|
||||
** @see Session
|
||||
** @see PlacementRef
|
||||
** @see PlacementIndex
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef MOBJECT_MOBJECT_REF_H
|
||||
#define MOBJECT_MOBJECT_REF_H
|
||||
|
||||
//#include "pre.hpp"
|
||||
//#include "proc/mobject/session/locatingpin.hpp"
|
||||
//#include "proc/asset/pipe.hpp"
|
||||
#include "lib/handle.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/placement-ref.hpp"
|
||||
|
||||
//#include <tr1/memory>
|
||||
|
||||
|
||||
namespace mobject {
|
||||
|
||||
// using std::tr1::shared_ptr;
|
||||
|
||||
|
||||
class MObject;
|
||||
|
||||
|
||||
/**
|
||||
* An active (smart-ptr like) external reference
|
||||
* to a specifically placed MObject "instance" within the session.
|
||||
*/
|
||||
template<class MO =MObject>
|
||||
class MORef
|
||||
: public lib::Handle<MO>
|
||||
{
|
||||
PlacementRef<MO> pRef_;
|
||||
|
||||
/** deleter function used to detach when refcount goes to zero */
|
||||
static void whenDead (MObject*);
|
||||
|
||||
public:
|
||||
|
||||
MO*
|
||||
operator-> () const
|
||||
{
|
||||
REQUIRE (smPtr_.get(), "Lifecycle-Error");
|
||||
ENSURE (INSTANCEOF (MO, smPtr_.get()));
|
||||
return smPtr_::operator-> ();
|
||||
}
|
||||
|
||||
Placement<MO>& getPlacement();
|
||||
|
||||
/* === Lifecycle === */
|
||||
|
||||
/** activate an MObject reference, based on an existing placement,
|
||||
* which needs to be contained (added to) the session. After checking
|
||||
* the validity of the placement, this MObjectRef shared ownership
|
||||
* of the referred MObject with the denoted placement.
|
||||
* @see #close() for detaching this MObjectRef
|
||||
*/
|
||||
MORef&
|
||||
activate (Placement<MO> const& placement)
|
||||
{
|
||||
pRef_ = placement;
|
||||
smPtr_.reset (placement, &whenDead);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** build and activate an MObject reference, based on anything
|
||||
* which might be assigned to an PlarementRef<MO> :
|
||||
* - any Placement
|
||||
* - any Placement-ID
|
||||
* - any Placement-Ref
|
||||
* - a plain LUID
|
||||
* @throws error::Invalid when the (directly or indirectly
|
||||
* referred placement isn't known to the session PlacementIndex,
|
||||
* or when the placement actually found has an incompatible dynamic type
|
||||
*/
|
||||
template<typename REF>
|
||||
MORef&
|
||||
activate (REF const& pRefID)
|
||||
{
|
||||
pRef_ = pRefID;
|
||||
smPtr_.reset (*pRef_, &whenDead);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
////////////////TODO currently just fleshing out the API....
|
||||
|
||||
|
||||
typedef MORef<MObject> MObjectRef;
|
||||
|
||||
|
||||
} // namespace mobject
|
||||
#endif
|
||||
|
|
@ -50,6 +50,7 @@ namespace mobject {
|
|||
using boost::scoped_ptr;
|
||||
using std::vector;
|
||||
|
||||
class MObject;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -62,13 +63,15 @@ namespace mobject {
|
|||
|
||||
public:
|
||||
typedef Placement<MObject> PlacementMO;
|
||||
typedef PlacementRef PRef;
|
||||
typedef PlacementRef<MObject> PRef;
|
||||
typedef PlacementMO::ID ID;
|
||||
|
||||
PlacementMO& find (ID) const;
|
||||
|
||||
template<class MO>
|
||||
Placement<MO>& find (PlacementMO::Id<MO>) const;
|
||||
Placement<MO>& find (PlacementMO::Id<MO>) const;
|
||||
template<class MO>
|
||||
Placement<MO>& find (PlacementRef<MO>) const;
|
||||
|
||||
PlacementMO& getScope (PlacementMO&) const;
|
||||
PlacementMO& getScope (ID) const;
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@
|
|||
|
||||
|
||||
|
||||
#ifndef MOBJECT_PLACEMENT__REF_H
|
||||
#define MOBJECT_PLACEMENT__REF_H
|
||||
#ifndef MOBJECT_PLACEMENT_REF_H
|
||||
#define MOBJECT_PLACEMENT_REF_H
|
||||
|
||||
//#include "pre.hpp"
|
||||
//#include "proc/mobject/session/locatingpin.hpp"
|
||||
|
|
@ -45,8 +45,11 @@ namespace mobject {
|
|||
// using std::tr1::shared_ptr;
|
||||
|
||||
|
||||
class MObject;
|
||||
|
||||
/**
|
||||
*/
|
||||
template<class MO =MObject>
|
||||
class PlacementRef
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ namespace mobject {
|
|||
//class Placement ;
|
||||
//typedef Placement<MObject> PMO;
|
||||
|
||||
template<class MO =MObject>
|
||||
class PlacementRef; ///TODO: as of 5/09 the idea is to phase out direct dependency on the placement class and recast those dependencies in terms of PlacementRef
|
||||
|
||||
|
||||
|
|
@ -116,7 +117,7 @@ namespace mobject {
|
|||
/* Factory functions for adding LocatingPins */
|
||||
|
||||
FixedLocation& operator() (Time start, Track track=0);
|
||||
RelativeLocation& operator() (PlacementRef& refObj, Time offset=Time(0)); //////////TODO: warning, just a dummy placeholder for now!!
|
||||
RelativeLocation& operator() (PlacementRef<>& refObj, Time offset=Time(0)); //////////TODO: warning, just a dummy placeholder for now!!
|
||||
|
||||
LocatingPin (const LocatingPin&);
|
||||
LocatingPin& operator= (const LocatingPin&);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,11 @@ PLANNED "DeleteClip_test" DeleteClip_test <<END
|
|||
END
|
||||
|
||||
|
||||
PLANNED "PlacementBasic_test" PlacementBasic_test <<END
|
||||
PLANNED "external MObject references" MObjectRef_test <<END
|
||||
END
|
||||
|
||||
|
||||
PLANNED "basic placement properties" PlacementBasic_test <<END
|
||||
END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ test_components_SOURCES = \
|
|||
$(testcomponents_srcdir)/proc/mobject/builder/buildertooltest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/builder/buildsegmenttest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/controller/rendersegmenttest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/mobject-ref-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placement-basic-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placement-hierarchy-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placement-index-test.cpp \
|
||||
|
|
|
|||
67
tests/components/proc/mobject/mobject-ref-test.cpp
Normal file
67
tests/components/proc/mobject/mobject-ref-test.cpp
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
MObjectRef(Test) - validating basic properties of the external MObject reference tag
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, 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/lumitime.hpp"
|
||||
#include "proc/mobject/mobject.hpp"
|
||||
#include "proc/mobject/mobject-ref.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/placement-ref.hpp"
|
||||
//#include "proc/mobject/explicitplacement.hpp"
|
||||
#include "proc/mobject/test-dummy-mobject.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
//using lumiera::Time;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
|
||||
|
||||
namespace mobject {
|
||||
namespace test {
|
||||
|
||||
using namespace mobject::test;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* @test properties and behaviour of the external reference-mechanism for
|
||||
* MObjects placed into the session.
|
||||
* @see mobject::Placement
|
||||
* @see mobject::MObject
|
||||
* @see mobject::PlacementRef_test
|
||||
*/
|
||||
class MObjectRef_test : public Test
|
||||
{
|
||||
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (MObjectRef_test, "unit session");
|
||||
|
||||
|
||||
}} // namespace mobject::test
|
||||
|
|
@ -38,40 +38,36 @@ using std::string;
|
|||
using std::cout;
|
||||
|
||||
|
||||
namespace mobject
|
||||
{
|
||||
namespace session
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
|
||||
/**
|
||||
* Create a Test Session configuration usable for various Tests.
|
||||
* This Session holds two Clips and corresponds to "Example1"
|
||||
* in the UML design. All changes are done to the (global)
|
||||
* current session.
|
||||
*/
|
||||
inline void
|
||||
buildTestsession1 ()
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a Test Session configuration usable for various Tests.
|
||||
* This Session holds two Clips and corresponds to "Example1"
|
||||
* in the UML design. All changes are done to the (global)
|
||||
* current session.
|
||||
*/
|
||||
inline void
|
||||
buildTestseesion1 ()
|
||||
{
|
||||
UNIMPLEMENTED ("Test-Session 1");
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Analyze the current (gloal) Session to verify the
|
||||
* configuration of "Test-Session 1"
|
||||
*/
|
||||
inline bool
|
||||
checkTestsession1 ()
|
||||
{
|
||||
UNIMPLEMENTED ("Test-Session 1");
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
const string SESSION1_CLIP("TODO: some sensible way to refer to a clip");
|
||||
|
||||
|
||||
} // namespace session
|
||||
|
||||
} // namespace mobject
|
||||
UNIMPLEMENTED ("Test-Session 1");
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Analyse the current (global) Session to verify the
|
||||
* configuration of "Test-Session 1"
|
||||
*/
|
||||
inline bool
|
||||
checkTestsession1 ()
|
||||
{
|
||||
UNIMPLEMENTED ("Test-Session 1");
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
const string SESSION1_CLIP("TODO: some sensible way to refer to a clip");
|
||||
|
||||
|
||||
}} // namespace mobject::session
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1930,7 +1930,7 @@ The general idea is, that each facade interface actually provides access to a sp
|
|||
|
||||
&rarr; overview [[MObject class hierarchy|MObjects]]</pre>
|
||||
</div>
|
||||
<div title="MObjectRef" modifier="Ichthyostega" modified="200905310321" created="200904242107" tags="SessionLogic GuiIntegration design draft discuss" changecount="19">
|
||||
<div title="MObjectRef" modifier="Ichthyostega" modified="200906020120" created="200904242107" tags="SessionLogic GuiIntegration design draft discuss" changecount="21">
|
||||
<pre>''The Problem of referring to an [[MObject]]'' stems from the object //as a concept// encompassing a wider scope then just the current implementation instance. If the object was just a runtime entity in memory, we could use a simple (language) reference or pointer. Actually, this isn't sufficient, as the object reference will pass LayerSeparationInterfaces, will be handed over to code not written in the same implementation language, will be included in an ''UNDO'' record for the UndoManager, and thus will need to be serialized and stored permanently within the SessionStorage.
|
||||
Moreover [[MObject instances|MObject]] have a 2-level structure: the core object holds just the properties in a strict sense, i.e. the properties which the object //owns.// Any properties due to putting the object into a specific context, i.e. all relation properties are represented as [[Placement]] of the object. Thus, when viewed from the client side, a reference to a specific ~MObject //instance,// actually denotes a //specific//&nbsp; Placement of this object into the Session.
|
||||
|
||||
|
|
@ -1957,7 +1957,7 @@ Presumably, none of the both models is usable as-is; rather we try to reconstruc
|
|||
|
||||
|
||||
!using ~MObject references
|
||||
~MObject references can be created directly from a given placement, or just from an {{{Placement::ID}}} tag. Creation can fail, because the validity of the reference is checked. In this respect, they behave exactly like PlacementRef, and indeed are just implemented on top of the latter. From this point onward, the referred ~MObject is kept alive by the reference &mdash; but note, this doesn't extend to the placement, which still may be modified or removed within the session without further notice. {{red{TODO investigate synchronisation guarantees or a locking mechanism}}} Thus, client code should never store direct references to the placement.
|
||||
~MObject references have a distinct lifecycle: usually, they are created //empty// (invalid ref, inactive state), followed by activating them by attachment to an existing placement within the session. Later on, the reference can be closed (detached, deactivated). Activation can be done either directly by a {{{Placement<MO>&}}}, or indirectly by any {{{Placement::ID}}} tag or even plain LUID denoting a placement known to the PlacementIndex embedded within the [[Session]]. Activation can fail, because the validity of the reference is checked. In this respect, they behave exactly like PlacementRef, and indeed are implemented on top of the latter. From this point onward, the referred ~MObject is kept alive by the reference &mdash; but note, this doesn't extend to the placement, which still may be modified or removed within the session without further notice. {{red{TODO investigate synchronisation guarantees or a locking mechanism}}} Thus, client code should never store direct references to the placement.
|
||||
|
||||
~MObject references have value semantics, i.e. they don't have an identity and can be copied feely. Dereferencing yields a direct (language) ref to the MObject, while the placement can be accessed by a separate function {{{getPlacement()}}}. Moreover, the MObjectRef instance provides a direct API to some of the most common query functions you could imagine to call on both the object and the placement (i.e. to find out about the start time, length, ....)
|
||||
|
||||
|
|
@ -2850,15 +2850,18 @@ On second sight, this problem seems to be quite nasty, because either we have to
|
|||
Consequently, we incorporate a random hash (implemented as {{{LUID}}}) into the individual placement, this way creating an distinguishable //placement identity,// which is retained on copying of the placement. The actual ID tag is complemented by a compile time type (template parameter), thus allowing to pass on additional context information through API calls.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="PlacementRef" modifier="Ichthyostega" modified="200905310325" created="200905090032" tags="def spec draft" changecount="8">
|
||||
<div title="PlacementRef" modifier="Ichthyostega" modified="200906020130" created="200905090032" tags="def spec draft" changecount="12">
|
||||
<pre>A generic reference mechanism for Placements, as added to the current session.
|
||||
While this reference itself is not tied to the actual memory layout (meaning it's //not// a disguised pointer), the implementation relies on a [[placement index facility|PlacementIndex]] for tracking and retrieving the actual Placement implementation object. As a plus, this approach allows to //reverse// the relation denoted by such a reference, inasmuch it is possible to retrieve all other placements referring to a given target placement. But for an (external) user, this link to an index implementation is kept transparent and implicit.
|
||||
|
||||
!implementation {{red{WIP}}}
|
||||
From the usage context it is clear that the PlacementRef needs to incorporate a simple ID as the only actual data in memory, so it can be downcasted to a POD and passed as such via LayerSeparationInterfaces. And, of course, this ID tag should be the one used by PlacementIndex for organising the Placement index entries, thus enabling the PlacementRef to be passed immediately to the underlying index for resolution. Thus, this design decision is interconnected with the implementation technique used for the index (&rarr; PlacementIndex). From the requirement of the ID tag to be contained in a fixed sized storage, and also from the expected kinds of queries Ichthyo (5/09) choose to incorporate a {{{LUID}}} as a random hash immediately into the placement and build the ID tag on top of it.
|
||||
From the usage context it is clear that the PlacementRef needs to incorporate a simple ID as the only actual data in memory, so it can be downcasted to a POD and passed as such via LayerSeparationInterfaces. And, of course, this ID tag should be the one used by PlacementIndex for organising the Placement index entries, thus enabling the PlacementRef to be passed immediately to the underlying index for resolution. Thus, this design decision is interconnected with the implementation technique used for the index (&rarr; PlacementIndex). From the requirement of the ID tag to be contained in a fixed sized storage, and also from the expected kinds of queries Ichthyo (5/09) choose to incorporate a {{{LUID}}} as a random hash immediately into the placement and build the ID tag on top of it.
|
||||
|
||||
!using placement references
|
||||
Placement references can be created directly from a given placement, or just from an {{{Placement::ID}}} tag. Creation and dereferencing can fail, because the validity of the reference is checked with the index. Placement references have value semantics. Dereferencing searches the denoted Placement via index, yielding a direct (language) ref. {{red{WIP}}}
|
||||
Placement references can be created directly from a given placement, or just from an {{{Placement::ID}}} tag. Creation and dereferencing can fail, because the validity of the reference is checked with the index. Placement references have value semantics. Dereferencing searches the denoted Placement via index, yielding a direct (language) ref.
|
||||
|
||||
Placement references mimic the behaviour of a real placement, i.e. they proxy the placement API (actually the passive, query-related part of placement's API functions), while directly forwarding calls to the pointee (~MObejct or subclass) when using {{{operator->()}}}. They can be copied and especially allow a lot of assignments (from placement, placement-ID or even plain LUID), even including a dynamic downcast on the pointee. Bottom line is that a placement ref can pretty much be used in place of a language ref to a real placement, which is crucial for implementing MObjectRef.
|
||||
{{red{WIP}}}
|
||||
</pre>
|
||||
</div>
|
||||
<div title="PlacementScope" modifier="Ichthyostega" modified="200905210132" created="200905120304" tags="SessionLogic spec draft" changecount="5">
|
||||
|
|
|
|||
Loading…
Reference in a new issue