From 8a453bd52b162767340590237c77c7023e48cea0 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 2 Jun 2009 03:31:52 +0200 Subject: [PATCH] WIP: start drafing MObjectRef --- src/proc/Makefile.am | 1 + src/proc/mobject/mobject-ref.cpp | 52 ++++++++ src/proc/mobject/mobject-ref.hpp | 126 ++++++++++++++++++ src/proc/mobject/placement-index.hpp | 7 +- src/proc/mobject/placement-ref.hpp | 7 +- src/proc/mobject/session/locatingpin.hpp | 3 +- tests/43session.tests | 6 +- tests/components/Makefile.am | 1 + .../proc/mobject/mobject-ref-test.cpp | 67 ++++++++++ .../proc/mobject/session/testsession1.hpp | 66 +++++---- wiki/renderengine.html | 13 +- 11 files changed, 303 insertions(+), 46 deletions(-) create mode 100644 src/proc/mobject/mobject-ref.cpp create mode 100644 src/proc/mobject/mobject-ref.hpp create mode 100644 tests/components/proc/mobject/mobject-ref-test.cpp diff --git a/src/proc/Makefile.am b/src/proc/Makefile.am index b1f8a7946..677ddda75 100644 --- a/src/proc/Makefile.am +++ b/src/proc/Makefile.am @@ -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 \ diff --git a/src/proc/mobject/mobject-ref.cpp b/src/proc/mobject/mobject-ref.cpp new file mode 100644 index 000000000..8758de088 --- /dev/null +++ b/src/proc/mobject/mobject-ref.cpp @@ -0,0 +1,52 @@ +/* + MobjectRef - active external reference to an MObject within the Session + + Copyright (C) Lumiera.org + 2008, 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. + +* *****************************************************/ + + +/** @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 +//using boost::str; + +namespace mobject { + + /** */ + + + + + +} // namespace mobject diff --git a/src/proc/mobject/mobject-ref.hpp b/src/proc/mobject/mobject-ref.hpp new file mode 100644 index 000000000..2c368932c --- /dev/null +++ b/src/proc/mobject/mobject-ref.hpp @@ -0,0 +1,126 @@ +/* + MOBJECT-REF.hpp - active external reference to an MObject within the Session + + Copyright (C) Lumiera.org + 2009, 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. + +*/ + + +/** @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 + + +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 MORef + : public lib::Handle + { + PlacementRef 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& 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 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 : + * - 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 + MORef& + activate (REF const& pRefID) + { + pRef_ = pRefID; + smPtr_.reset (*pRef_, &whenDead); + return *this; + } + + }; + ////////////////TODO currently just fleshing out the API.... + + + typedef MORef MObjectRef; + + +} // namespace mobject +#endif diff --git a/src/proc/mobject/placement-index.hpp b/src/proc/mobject/placement-index.hpp index a5fea0800..9afccdcf4 100644 --- a/src/proc/mobject/placement-index.hpp +++ b/src/proc/mobject/placement-index.hpp @@ -50,6 +50,7 @@ namespace mobject { using boost::scoped_ptr; using std::vector; + class MObject; /** @@ -62,13 +63,15 @@ namespace mobject { public: typedef Placement PlacementMO; - typedef PlacementRef PRef; + typedef PlacementRef PRef; typedef PlacementMO::ID ID; PlacementMO& find (ID) const; template - Placement& find (PlacementMO::Id) const; + Placement& find (PlacementMO::Id) const; + template + Placement& find (PlacementRef) const; PlacementMO& getScope (PlacementMO&) const; PlacementMO& getScope (ID) const; diff --git a/src/proc/mobject/placement-ref.hpp b/src/proc/mobject/placement-ref.hpp index d04c7c3af..5f5e8baf5 100644 --- a/src/proc/mobject/placement-ref.hpp +++ b/src/proc/mobject/placement-ref.hpp @@ -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 PlacementRef { public: diff --git a/src/proc/mobject/session/locatingpin.hpp b/src/proc/mobject/session/locatingpin.hpp index fa63cb2c3..fb09a0432 100644 --- a/src/proc/mobject/session/locatingpin.hpp +++ b/src/proc/mobject/session/locatingpin.hpp @@ -68,6 +68,7 @@ namespace mobject { //class Placement ; //typedef Placement PMO; + template 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&); diff --git a/tests/43session.tests b/tests/43session.tests index 5b34fbdb2..a06c7558b 100644 --- a/tests/43session.tests +++ b/tests/43session.tests @@ -25,7 +25,11 @@ PLANNED "DeleteClip_test" DeleteClip_test < + + 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 + +//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 diff --git a/tests/components/proc/mobject/session/testsession1.hpp b/tests/components/proc/mobject/session/testsession1.hpp index 166fd1c02..4928c2b23 100644 --- a/tests/components/proc/mobject/session/testsession1.hpp +++ b/tests/components/proc/mobject/session/testsession1.hpp @@ -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 diff --git a/wiki/renderengine.html b/wiki/renderengine.html index a40b3db97..ff4258b84 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -1930,7 +1930,7 @@ The general idea is, that each facade interface actually provides access to a sp &rarr; overview [[MObject class hierarchy|MObjects]] -
+
''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.
 
-
+
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}}}