From bdb21c4aa8560a34971e25d89d85cfb266cabb25 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 10 Mar 2010 05:44:57 +0100 Subject: [PATCH] draft required functionality for the element-tracker --- src/proc/asset.cpp | 2 +- src/proc/asset/clip.cpp | 50 ++++++----- .../session/session-element-tracker-test.cpp | 83 ++++++++++++++++++- wiki/renderengine.html | 14 +++- 4 files changed, 116 insertions(+), 33 deletions(-) diff --git a/src/proc/asset.cpp b/src/proc/asset.cpp index 25f0da1d2..44af7ae67 100644 --- a/src/proc/asset.cpp +++ b/src/proc/asset.cpp @@ -142,7 +142,7 @@ namespace asset { * assets to do so with the link to this asset. * @note we don't release upward links to parent assets, * thus effectively keeping the parents alive, because - * frequently these accessible parent assets are part + * frequently the accessibility of parent assets is part * of our own contract. (e.g. media for clip assets) */ void diff --git a/src/proc/asset/clip.cpp b/src/proc/asset/clip.cpp index 68bb96d14..ebfb2fa8d 100644 --- a/src/proc/asset/clip.cpp +++ b/src/proc/asset/clip.cpp @@ -27,35 +27,33 @@ using std::tr1::static_pointer_cast; -namespace asset - { +namespace asset { - namespace + namespace { + + /** @internal derive a sensible asset ident tuple + * when creating a asset::Clip based on some asset::Media + * @todo getting this one correct is important for handling creation + * of multiple clip instances from one media. Means we + * have still to figure out a sensible concept... + */ + const Asset::Ident + createClipIdent (const Media& mediaref) { - /** @internal derive a sensible asset ident tuple - * when creating a asset::Clip based on some asset::Media - * @todo getting this one correct is important for handling creation - * of multiple clip instances from one media. Means we - * have still to figure out a sensible concept... - */ - const Asset::Ident - createClipIdent (const Media& mediaref) - { - string name (mediaref.ident.name + "-clip"); // TODO something sensible here; append number, sanitise etc. - Category category (mediaref.ident.category); - category.setPath(CLIP_SUBFOLDER); - return Asset::Ident (name, category, - mediaref.ident.org, - mediaref.ident.version ); - - } - - Media::PClipMO - createClipMO (const Clip& thisClipAsset, const Media& mediaChannel) - { - return mobject::MObject::create (thisClipAsset,mediaChannel); - } + string name (mediaref.ident.name + "-clip"); // TODO something sensible here; append number, sanitise etc. + Category category (mediaref.ident.category); + category.setPath(CLIP_SUBFOLDER); + return Asset::Ident (name, category, + mediaref.ident.org, + mediaref.ident.version ); } + + Media::PClipMO + createClipMO (const Clip& thisClipAsset, const Media& mediaChannel) + { + return mobject::MObject::create (thisClipAsset,mediaChannel); + } + } diff --git a/tests/components/proc/mobject/session/session-element-tracker-test.cpp b/tests/components/proc/mobject/session/session-element-tracker-test.cpp index e59c6a1a5..98772814e 100644 --- a/tests/components/proc/mobject/session/session-element-tracker-test.cpp +++ b/tests/components/proc/mobject/session/session-element-tracker-test.cpp @@ -25,10 +25,12 @@ //#include "proc/mobject/session.hpp" //#include "proc/mobject/mobject-ref.hpp" //#include "proc/mobject/session/binding.hpp" -//#include "proc/mobject/session/fixture.hpp" // TODO only temporarily needed +//#include "proc/mobject/session/fixture.hpp" //#include "proc/assetmanager.hpp" +#include "proc/mobject/session/session-interface-modules.hpp" #include "proc/asset/timeline.hpp" #include "proc/asset/sequence.hpp" +#include "lib/p.hpp" //#include "proc/asset/pipe.hpp" //#include "lib/lumitime.hpp" //#include "lib/query.hpp" @@ -38,6 +40,7 @@ //using util::isSameObject; //using util::contains; +//using util::isnil; //using std::string; //using std::cout; @@ -46,6 +49,42 @@ namespace mobject { namespace session { namespace test { + namespace { // yet another accounting dummy + + int checksum = 0; + + class AutoRegisteringDummy; + + typedef lumiera::P PDummy; + + class AutoRegisteringDummy + { + const uint id_; + + public: + AutoRegisteringDummy() + : id_(++checksum) + { + TODO ("cause the registration"); + } + + void + unlink() + { + TODO ("cause the deregistration"); + checksum -= id_; + } + + static PDummy create(); + }; + + inline PDummy + AutoRegisteringDummy::create() + { + return PDummy (new AutoRegisteringDummy); + } + + } // using proc_interface::AssetManager; // using proc_interface::PAsset; @@ -82,7 +121,47 @@ namespace test { void verify_trackingMechanism() { - UNIMPLEMENTED ("use a test dummy class and do a dry run of the ElementTracker"); + checksum = 0; + { + impl::ElementTracker trackedDummies; + + CHECK (0 == checksum); + CHECK (0 == trackedDummies.size()); + + PDummy dummy1 = AutoRegisteringDummy::create(); + PDummy dummy2 = AutoRegisteringDummy::create(); + + CHECK (2 == trackedDummies.size()); + CHECK (dummy1 == trackedDummies[0]); + CHECK (dummy2 == trackedDummies[1]); + + PDummy dummy3 = AutoRegisteringDummy::create(); + CHECK (3 == trackedDummies.size()); + CHECK (dummy3 == trackedDummies[2]); + + CHECK (1+2+3 == checksum); + + dummy2.unlink(); + CHECK (1 + 3 == checksum); + CHECK (2 == trackedDummies.size()); + CHECK (dummy1 == trackedDummies[0]); + CHECK (dummy3 == trackedDummies[1]); + + CHECK (1 == dummy2.use_count()); + CHECK (2 == dummy1.use_count()); + CHECK (2 == dummy3.use_count()); + + // deliberately discard our reference, + // so the only remaining ref is in the tracker + dummy1.reset(); + dummy2.reset(); + CHECK (1 == trackedDummies[0].use_count()); + CHECK (1 == trackedDummies[1].use_count()); + CHECK (1 + 3 == checksum); + + // now the tracker goes out of scope... + } + CHECK (0 == checksum); // ...remaining elements have been unlinked } diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 7f0a983da..f184f297b 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -4149,7 +4149,7 @@ The session and the models rely on dependent objects beeing kept updated and con → see [[details here...|ModelDependencies]] -
+
"Session Interface", when used in a more general sense, denotes a compound of several interfaces and facilities, together forming the primary access point to the user visible contents and state of the editing project.
 * the API of the session class
 * the accompanying management interface (SessionManager API)
@@ -4186,9 +4186,15 @@ To the contrary, the ''generic'' API is related to a //current location (state),
 * to add
 * to destroy
 
+!!exploring session contents
+Typically, the list of timelines serves as starting point for exploring the model. Basically, any kind of object could be attached everywhere, but both the GUI and the Builder rely on assumptions regarding the [[overall model structure|HighLevelModel]] — silently ignoring content not in line. This corresponds to the //dedicated API functions// on specific kinds of objects, which allow to retrieve content according to this assumed structure conveniently and with strong typing. From the timeline and the sequence linked to it you'll get the root track, and from there the sub-tracks and the clips located on them, which in turn may have attachments (effects, transitions, labels).
+On the other hand, arbitrary structures can be retrieved using the //generic API:// Contents can be discovered on the QueryFocus, which automatically follows the //point of mutation,// but can be moved to any point using the {{{QueryFocus::attach(obj)}}} function.
+
+!!queries and defaults
+Queries can retrieve the immediate children, or the complete contents of a scope (depth-first). The results can be filtered by type. The intention is to extend this later to arbitrary logical queries, using some kind of resolution engine. Besides these queries, [[default configured objects|DefaultsManagement]] can be retrieved or defined through the defaults manager, which is accessible as a self-contained component on the public session API. Defaults can be used to establish a standard way of doing things on a per-project base.
 
 {{red{WIP ... just emerging}}}
-!!!discovery and mutations
+!!discovery and mutations
 The discovery functions available on these ~APIs are wired such as to return suitably typed MObjectRef instances always. These are small value objects and can be used to invoke operations (both query and mutating) on the underlying object within the session. Raw placement references aren't exposed on these outward interfaces.
 
 While this protects against accessing dangling references, it can't prevent clients from invoking any mutating operation directly on these references. It would be conceivable, by using proxies, to create and invoke commands automatically. But we rather don't want to go this route, because
@@ -4199,9 +4205,9 @@ While this protects against accessing dangling references, it can't prevent clie
 {{red{WIP}}}As of 2/10, I am considering to add a protection against invoking an mutation accidentally, thus bypassing the command frontend and the ProcDispatcher. This would not only be annoying (no UNDO), but potentially dangerous, because all of the session internals are not threadsafe by design.
 The considered solution would be to treat this situation as if an authorisation is required; this authorisation for mutation could be checked by a »wormhole&laqou;-like context access. Of course, in our case we're not dealing with real access restrictions, just a safeguard: While command execution creates such an authorisation token automatically, a client actually wanting to invoke an mutation operations bypassing the command frontend, would need to set up such a token explicitly and manually.
 
-!!!adding and destroying
+!!adding and destroying
 Objects can be added and destroyed directly on the top level session API. The actual memory management of the object instances works automatically, based on reference counts. (Even after purging an object from the session, it may still be indirectly in use by an ongoing render process).
-When adding an object, a [[scope|PlacementScope]] needs to be specified. Thus it makes sense to provide the {{{add()}}}-operation on the dedicated API of individual session parts, while the generic {{{add()}}}-call on the top-level session API relies on the current QueryFocus to determine the location where to add an object. Besides, as we're always adding the [[Placement]] of an object into the session, this placement may specify an additional constraint or tie to a specific scope; resolving the placement thus may cause the object to move to another location
+When adding an object, a [[scope|PlacementScope]] needs to be specified. Thus it makes sense to provide {{{add()}}}-operations on the dedicated API of individual session parts, while the generic {{{attach()}}}-call on the top-level session API relies on the current QueryFocus to determine the location where to add an object. Besides, as we're always adding the [[Placement]] of an object into the session, this placement may specify an additional constraint or tie to a specific scope; resolving the placement thus may cause the object to move to another location
 
 
 !!!{{red{Questions}}}