diff --git a/src/lib/element-tracker.hpp b/src/lib/element-tracker.hpp new file mode 100644 index 000000000..e13537502 --- /dev/null +++ b/src/lib/element-tracker.hpp @@ -0,0 +1,115 @@ +/* + ELEMENT-TRACKER.hpp - registry for tracking instances automatically + + 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. + +*/ + + +/** @file element-tracker.hpp + ** Tracking instances automatically on creation and disposal. + ** Part of the Session interface is exposed as self-contained + ** interface modules -- both for notational convenience at the + ** usage site, and for keeping session implementation code manageable. + ** Clients access these modules as nested parts of the public Session interface + ** through references exposing just the respective interfaces, while the actual + ** implementation is located in-place (within the SesssionImpl object), packaged + ** into a non-public baseclass. + ** - the DefsManager acts as frontend to the system of default configurations + ** and config rules, allowing to retrieve the \em default version of various + ** kinds of objects + ** - the top-level Timeline (structural assets) act as facade and entry point + ** to the high-level-model (session contents). There is an table of timelines, + ** managed automatically and kept in sync with the session::Binding elements + ** located directly below model root. + ** - likewise there is an table of all Sequence (structural assets), which + ** correspond to the roots of track trees, attached below model root. + ** + ** \par maintaining the link between session, timelines and sequences + ** Timeline and Sequence are implemented as asset::Struct, causing them to be + ** maintained by the AssetManager, which in turn is attached to the session::Root + ** (WIP 3/2010: yet to be implemented). Creation and destruction of timelines and + ** sequences is closely connected to some structural changes within the model + ** - Timeline is related to session::Binding, where the timelines are leading + ** and the binding elements are dependent on both a timeline and a sequence + ** - Sequence is related to a Placement -- but only if attached + ** immediately below model root; here the tracks are leading and the sequences + ** are completely dependent. + ** In any case, ctor and dtor of Timeline and Sequence have to care for proper + ** registration into the SessionInterfaceModules for timelines and sequences + ** respectively. This is accomplished by using kind-of a backdoor, a SessionServices + ** (proc internal API) definition, allowing direct communication on implementation + ** level, without the need to expose this access point on the public session API. + ** The impl::ElementTracker implemented in this sourcefile here relieves these + ** calls to maintain a list of asset smart-ptrs + ** + ** @see SessionImpl + ** @see session-services.hpp + ** + */ + + +#ifndef LIB_ELEMENT_TRACKER_H +#define LIB_ELEMENT_TRACKER_H + +#include "lib/p.hpp" +#include "lib/ref-array-impl.hpp" + + + + +namespace lib { + + using lumiera::P; + + /** + * Custom implementation of the RefArray interface, + * used by the Session to keep track of all timelines + * and sequences. The registration/deregistration functions + * are accessible as SessionServices + */ + template + class ElementTracker + : public lib::RefArrayVectorWrapper > + { + public: + void + append (P const& asset) + { + UNIMPLEMENTED ("attach entry to session"); + } + + void + remove (ELM const& asset) + { + UNIMPLEMENTED ("detach entry from session"); + } + + bool + isRegistered (ELM const& asset) + { + UNIMPLEMENTED ("detect if the given element is indeed registered within this"); + } + }; + + + + + +} // namespace lib +#endif diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp index 6e0730b5e..6f5c29c10 100644 --- a/src/proc/assetmanager.hpp +++ b/src/proc/assetmanager.hpp @@ -89,7 +89,7 @@ namespace asset { bool known (IDA id, const Category& cat) ; /**remove the given asset from the internal DB. - * together with all its dependants */ + * together with all its dependents */ void remove (IDA id) ; /** extract a sorted list of all registered Assets */ diff --git a/src/proc/mobject/session/session-interface-modules.hpp b/src/proc/mobject/session/session-interface-modules.hpp index dbeea6ba0..02c691b30 100644 --- a/src/proc/mobject/session/session-interface-modules.hpp +++ b/src/proc/mobject/session/session-interface-modules.hpp @@ -67,8 +67,7 @@ #ifndef MOBJECT_SESSION_INTERFACE_MODULES_H #define MOBJECT_SESSION_INTERFACE_MODULES_H -#include "lib/p.hpp" -#include "lib/ref-array-impl.hpp" +#include "lib/element-tracker.hpp" @@ -76,39 +75,10 @@ namespace mobject { namespace session { - namespace impl { // impl: list of elements to track - - using lumiera::P; - - /** - * Custom implementation of the RefArray interface, - * used by the Session to keep track of all timelines - * and sequences. The registration/deregistration functions - * are accessible as SessionServices - */ - template - class ElementTracker - : public lib::RefArrayVectorWrapper > - { - public: - void - add (P const& asset) - { - UNIMPLEMENTED ("attach entry to session"); - } - - void - remove (P const& asset) - { - UNIMPLEMENTED ("detach entry from session"); - } - }; - - } //(End) impl list of elements to track - typedef impl::ElementTracker TimelineTracker; - typedef impl::ElementTracker SequenceTracker; + typedef lib::ElementTracker TimelineTracker; + typedef lib::ElementTracker SequenceTracker; /** 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 98772814e..221143c73 100644 --- a/tests/components/proc/mobject/session/session-element-tracker-test.cpp +++ b/tests/components/proc/mobject/session/session-element-tracker-test.cpp @@ -37,6 +37,7 @@ //#include "lib/util.hpp" //#include +#include //using util::isSameObject; //using util::contains; @@ -53,36 +54,96 @@ namespace test { int checksum = 0; - class AutoRegisteringDummy; - typedef lumiera::P PDummy; + using std::tr1::function; + using std::tr1::bind; + using std::tr1::ref; - class AutoRegisteringDummy + + template + class AutoRegistered + { + typedef lib::ElementTracker Registry; + typedef function RegistryLink; + + static RegistryLink getRegistry; + + public: + + template + static void + establishRegistryLink (FUN link) + { + AutoRegistered::getRegistry = link; + } + + static void + setRegistryInstance (Registry& registry_to_use) + { + establishRegistryLink (bind (ref(registry_to_use))); + } + + + typedef lumiera::P PTarget; + + static PTarget + create() + { + REQUIRE (getRegistry); + + PTarget newElement (new TAR()); + getRegistry().append (newElement); + + ENSURE (newElement); + ENSURE (getRegistry().isRegistered(*newElement)); + return newElement; + } + + + void + detach() + { + getRegistry().remove(*this); + + ENSURE (!getRegistry().isRegistered(*this)); + } + }; + + /** storage for the functor to link an AutoRegistered entity + * to the corresponding registration service */ + template + AutoRegistered::RegistryLink AutoRegistered::getRegistry; + + + /** + * Test Dummy: to be created through the inherited static #create(), + * managed by smart-ptr. Any Dummy instance gets automatically registered + * for tracking, and will be deregistered by invoking #unlink(). + * The link to the actual registration service has to be established at + * runtime once, by calling #establishRegistryLink or #setRegistryInstance + */ + struct Dummy + : AutoRegistered { const uint id_; public: - AutoRegisteringDummy() + Dummy() : id_(++checksum) { - TODO ("cause the registration"); + CHECK (getRegistry().isRegistered (*this)); } void unlink() { - TODO ("cause the deregistration"); + getRegistry().remove(*this); checksum -= id_; } - static PDummy create(); }; - inline PDummy - AutoRegisteringDummy::create() - { - return PDummy (new AutoRegisteringDummy); - } + } // using proc_interface::AssetManager; @@ -123,11 +184,16 @@ namespace test { { checksum = 0; { - impl::ElementTracker trackedDummies; + typedef Dummy AutoRegisteringDummy; + typedef lumiera::P PDummy; + typedef lib::ElementTracker DummyRegistry; + + DummyRegistry trackedDummies; CHECK (0 == checksum); CHECK (0 == trackedDummies.size()); + AutoRegisteringDummy::setRegistryInstance (trackedDummies); PDummy dummy1 = AutoRegisteringDummy::create(); PDummy dummy2 = AutoRegisteringDummy::create(); @@ -152,7 +218,7 @@ namespace test { CHECK (2 == dummy3.use_count()); // deliberately discard our reference, - // so the only remaining ref is in the tracker + // so the only remaining ref is within the registry dummy1.reset(); dummy2.reset(); CHECK (1 == trackedDummies[0].use_count());