From 0ea37402d2f41083fa0c26fcbc260dbd8a89b675 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 20 Oct 2013 03:19:36 +0200 Subject: [PATCH] Ticket #934: switch entire code-base to use the new Singleton factory lib::Depend works as drop-in replacement for lib::Singleton This changeset removes the convoluted special cases like SingletonSub and MockInjector. --- src/backend/engine/engine-config.cpp | 2 +- src/backend/engine/engine-config.h | 6 +- src/backend/engine/scheduler-frontend.cpp | 2 +- src/backend/engine/scheduler-frontend.hpp | 4 +- src/backend/enginefacade.cpp | 4 +- src/backend/media-access-facade.cpp | 2 +- src/backend/media-access-facade.hpp | 4 +- src/backend/netnodefacade.cpp | 4 +- src/backend/real-clock.hpp | 2 +- src/backend/scriptrunnerfacade.cpp | 4 +- src/common/advice/advice.cpp | 5 +- src/common/configfacade.cpp | 2 +- src/common/guifacade.cpp | 4 +- src/gui/gtk-lumiera.cpp | 4 +- src/gui/guistart.cpp | 2 +- src/gui/notification-service.cpp | 2 +- src/include/config-facade.h | 6 +- src/lib/depend.hpp | 47 +++- src/lib/multifact.hpp | 6 +- src/lib/singleton-factory.hpp | 143 ---------- src/lib/singleton-policies.hpp | 141 ---------- src/lib/singleton-preconfigure.hpp | 121 --------- src/lib/singleton-subclass.hpp | 177 ------------- src/lib/singleton.hpp | 83 ------ src/lib/test/mock-injector.hpp | 248 ------------------ src/lib/visitor-dispatcher.hpp | 8 +- src/proc/asset/db.hpp | 2 +- src/proc/assetmanager.cpp | 6 +- src/proc/assetmanager.hpp | 6 +- src/proc/config-resolver.cpp | 12 +- src/proc/config-resolver.hpp | 4 +- src/proc/control/command-registry.hpp | 4 +- src/proc/control/command.cpp | 2 +- src/proc/control/proc-dispatcher.cpp | 2 +- src/proc/control/proc-dispatcher.hpp | 4 +- src/proc/control/stypemanager.cpp | 2 +- src/proc/control/stypemanager.hpp | 6 +- .../engine/diagnostic-buffer-provider.cpp | 2 +- .../engine/diagnostic-buffer-provider.hpp | 6 +- src/proc/engine/engine-diagnostics.hpp | 2 +- src/proc/engine/engine-service.cpp | 2 +- src/proc/engine/engine-service.hpp | 4 +- src/proc/facade.cpp | 8 +- src/proc/mobject/session.hpp | 2 +- .../session/query/fake-configrules.hpp | 2 +- src/proc/mobject/session/scope-locator.hpp | 6 +- src/proc/mobject/session/scope.cpp | 2 +- .../mobject/session/sess-manager-impl.hpp | 2 +- src/proc/mobject/session/session.cpp | 5 +- src/proc/play/dummy-play-connection.cpp | 2 +- src/proc/play/dummy-player-service.cpp | 4 +- src/proc/play/output-director.cpp | 2 +- src/proc/play/output-director.hpp | 6 +- tests/40core.tests | 59 ++--- tests/core/backend/media-access-mock.cpp | 4 +- .../proc/engine/dispatcher-interface-test.cpp | 4 +- .../mobject/session/query-resolver-test.cpp | 4 +- .../session/session-service-access-test.cpp | 6 +- tests/core/proc/mobject/session/testclip.cpp | 4 +- tests/library/singleton-subclass-test.cpp | 43 ++- tests/library/singleton-test.cpp | 56 +--- tests/library/singleton-testmock-test.cpp | 81 +----- tests/library/visitingtoolconcept.cpp | 14 +- 63 files changed, 217 insertions(+), 1198 deletions(-) delete mode 100644 src/lib/singleton-factory.hpp delete mode 100644 src/lib/singleton-policies.hpp delete mode 100644 src/lib/singleton-preconfigure.hpp delete mode 100644 src/lib/singleton-subclass.hpp delete mode 100644 src/lib/singleton.hpp delete mode 100644 src/lib/test/mock-injector.hpp diff --git a/src/backend/engine/engine-config.cpp b/src/backend/engine/engine-config.cpp index 79477e7ce..f66d2de27 100644 --- a/src/backend/engine/engine-config.cpp +++ b/src/backend/engine/engine-config.cpp @@ -50,7 +50,7 @@ namespace engine { /** storage for the Singleton accessor */ - lib::Singleton EngineConfig::get; + lib::Depend EngineConfig::get; /** build up a new engine configuration set, diff --git a/src/backend/engine/engine-config.h b/src/backend/engine/engine-config.h index 22f71d89a..302ad867c 100644 --- a/src/backend/engine/engine-config.h +++ b/src/backend/engine/engine-config.h @@ -32,7 +32,7 @@ #ifdef __cplusplus /* ============== C++ Interface ================= */ #include "lib/time/timevalue.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" namespace backend{ @@ -64,14 +64,14 @@ namespace engine { EngineConfig(); ~EngineConfig(); - friend class lib::singleton::StaticCreate; + friend class lib::DependencyFactory::InstanceHolder; public: /** access point to the Engine Interface. * @internal this is an facade interface for internal use * by the player. Client code should use the Player. */ - static lib::Singleton get; + static lib::Depend get; //////////////////////////////////////////////////////////////////// TODO: find out about required configuration and tweaking values diff --git a/src/backend/engine/scheduler-frontend.cpp b/src/backend/engine/scheduler-frontend.cpp index 7d516159c..629849492 100644 --- a/src/backend/engine/scheduler-frontend.cpp +++ b/src/backend/engine/scheduler-frontend.cpp @@ -29,7 +29,7 @@ namespace engine { /** storage for the (singleton) scheduler access frontend */ - lib::Singleton SchedulerFrontend::instance; + lib::Depend SchedulerFrontend::instance; diff --git a/src/backend/engine/scheduler-frontend.hpp b/src/backend/engine/scheduler-frontend.hpp index 1b7524ad6..c0452c681 100644 --- a/src/backend/engine/scheduler-frontend.hpp +++ b/src/backend/engine/scheduler-frontend.hpp @@ -26,7 +26,7 @@ -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/time/timevalue.hpp" #include "backend/engine/job.h" @@ -59,7 +59,7 @@ namespace engine { * @internal this is an facade interface for internal use * by the player. Client code should use the Player. */ - static lib::Singleton instance; + static lib::Depend instance; /** diff --git a/src/backend/enginefacade.cpp b/src/backend/enginefacade.cpp index d99ad83fa..f93e309fe 100644 --- a/src/backend/enginefacade.cpp +++ b/src/backend/enginefacade.cpp @@ -22,7 +22,7 @@ #include "backend/enginefacade.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include @@ -67,7 +67,7 @@ namespace backend { }; namespace { - lib::Singleton theDescriptor; + lib::Depend theDescriptor; } diff --git a/src/backend/media-access-facade.cpp b/src/backend/media-access-facade.cpp index a04cd76f7..d35a8a1e1 100644 --- a/src/backend/media-access-facade.cpp +++ b/src/backend/media-access-facade.cpp @@ -32,7 +32,7 @@ namespace backend { /** storage for the SingletonFactory * (actually a lumiera::test::MockInjector) */ - Singleton MediaAccessFacade::instance; + lib::Depend MediaAccessFacade::instance; diff --git a/src/backend/media-access-facade.hpp b/src/backend/media-access-facade.hpp index 9604360af..e3a4b124b 100644 --- a/src/backend/media-access-facade.hpp +++ b/src/backend/media-access-facade.hpp @@ -26,7 +26,7 @@ #include "lib/error.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/time/timevalue.hpp" #include @@ -57,7 +57,7 @@ namespace backend { public: typedef void* ChanHandle; - static Singleton instance; + static lib::Depend instance; /** request for testing the denoted files accessibility * @param name path and filename of the media file. diff --git a/src/backend/netnodefacade.cpp b/src/backend/netnodefacade.cpp index 99f64e1bb..e084958ed 100644 --- a/src/backend/netnodefacade.cpp +++ b/src/backend/netnodefacade.cpp @@ -22,7 +22,7 @@ #include "backend/netnodefacade.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include @@ -66,7 +66,7 @@ namespace backend { }; namespace { - lib::Singleton theDescriptor; + lib::Depend theDescriptor; } diff --git a/src/backend/real-clock.hpp b/src/backend/real-clock.hpp index 4d1ad49eb..c25b71276 100644 --- a/src/backend/real-clock.hpp +++ b/src/backend/real-clock.hpp @@ -44,7 +44,7 @@ #include "lib/error.hpp" //#include "lib/handle.hpp" #include "lib/time/timevalue.hpp" -//#include "lib/singleton.hpp" +//#include "lib/depend.hpp" //#include "proc/engine/buffer-provider.hpp" //#include "lib/iter-source.hpp" //#include "lib/sync.hpp" diff --git a/src/backend/scriptrunnerfacade.cpp b/src/backend/scriptrunnerfacade.cpp index a36d70fea..118d79061 100644 --- a/src/backend/scriptrunnerfacade.cpp +++ b/src/backend/scriptrunnerfacade.cpp @@ -22,7 +22,7 @@ #include "backend/scriptrunnerfacade.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include @@ -67,7 +67,7 @@ namespace backend { }; namespace { - lib::Singleton theDescriptor; + lib::Depend theDescriptor; } diff --git a/src/common/advice/advice.cpp b/src/common/advice/advice.cpp index ffd8a1547..6271ad6ca 100644 --- a/src/common/advice/advice.cpp +++ b/src/common/advice/advice.cpp @@ -91,7 +91,7 @@ #include "lib/error.hpp" #include "lib/del-stash.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/symbol.hpp" #include "lib/sync.hpp" #include "lib/util.hpp" @@ -102,7 +102,6 @@ #include using lib::Symbol; -using lib::Singleton; using lib::DelStash; using util::unConst; @@ -254,7 +253,7 @@ namespace advice { /** hidden implementation-level access to the AdviceSystem */ - Singleton aSys; + lib::Depend aSys; } //(End) AdviceSystem implementation diff --git a/src/common/configfacade.cpp b/src/common/configfacade.cpp index e1796465b..1130fe78e 100644 --- a/src/common/configfacade.cpp +++ b/src/common/configfacade.cpp @@ -73,7 +73,7 @@ namespace lumiera { /** storage for the single system-wide config facade instance */ - lib::Singleton Config::instance; + lib::Depend Config::instance; Config::Config () diff --git a/src/common/guifacade.cpp b/src/common/guifacade.cpp index 5e1c4599d..c9b0c048c 100644 --- a/src/common/guifacade.cpp +++ b/src/common/guifacade.cpp @@ -25,7 +25,7 @@ #include "include/guinotification-facade.h" #include "lib/sync.hpp" #include "lib/error.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/functor-util.hpp" #include "common/instancehandle.hpp" @@ -164,7 +164,7 @@ namespace gui { } }; - lib::Singleton theDescriptor; + lib::Depend theDescriptor; } // (End) impl details diff --git a/src/gui/gtk-lumiera.cpp b/src/gui/gtk-lumiera.cpp index c44e737fd..0865da862 100644 --- a/src/gui/gtk-lumiera.cpp +++ b/src/gui/gtk-lumiera.cpp @@ -26,7 +26,7 @@ #include "gui/workspace/workspace-window.hpp" #include "gui/controller/controller.hpp" #include "gui/model/project.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/symbol.hpp" #include "include/config-facade.h" @@ -56,7 +56,7 @@ typedef std::vector UVector; namespace { /** storage for the Main Application object */ - lib::Singleton theApplicationInstance; + lib::Depend theApplicationInstance; Literal KEY_TITLE = "Lumiera.title"; Literal KEY_VERSION = "Lumiera.version"; diff --git a/src/gui/guistart.cpp b/src/gui/guistart.cpp index b5b5ee6e9..8905c7858 100644 --- a/src/gui/guistart.cpp +++ b/src/gui/guistart.cpp @@ -55,7 +55,7 @@ #include "gui/display-service.hpp" #include "common/subsys.hpp" #include "backend/thread-wrapper.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" extern "C" { #include "common/interface.h" diff --git a/src/gui/notification-service.cpp b/src/gui/notification-service.cpp index a27d5a641..366a3e13a 100644 --- a/src/gui/notification-service.cpp +++ b/src/gui/notification-service.cpp @@ -22,7 +22,7 @@ #include "gui/notification-service.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "include/logging.h" #include "lib/util.hpp" diff --git a/src/include/config-facade.h b/src/include/config-facade.h index 564c49533..a903b6485 100644 --- a/src/include/config-facade.h +++ b/src/include/config-facade.h @@ -44,7 +44,7 @@ #ifdef __cplusplus /* ============== C++ Interface ================= */ -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/symbol.hpp" #include @@ -67,13 +67,13 @@ namespace lumiera { public: static string get (lib::Literal key); - static lib::Singleton instance; + static lib::Depend instance; private: Config(); ~Config(); - friend class lib::singleton::StaticCreate; + friend class lib::DependencyFactory::InstanceHolder; }; diff --git a/src/lib/depend.hpp b/src/lib/depend.hpp index f91957c60..2ed7e5eac 100644 --- a/src/lib/depend.hpp +++ b/src/lib/depend.hpp @@ -31,6 +31,49 @@ This code is heavily inspired by +/** @file depend.hpp + ** Singleton services and Dependency Injection. + ** The Singleton Pattern provides a single access point to a class or + ** service and exploits this ubiquitous access point to limit the number of objects + ** of this type to a single shared instance. Within Lumiera, we mostly employ a + ** factory template for this purpose; the intention is to use on-demand initialisation + ** and a standardised lifecycle. In the default configuration, this \c Depend factory + ** maintains a singleton instance of type TY. The possibility to install other factory + ** functions allows for subclass creation and various other kinds of service management. + ** + ** + ** \par Why Singletons? Inversion-of-Control and Dependency Injection + ** + ** Singletons are frequently over-used, and often they serve as disguised + ** global variables to support a procedural programming style. As a remedy, typically + ** the use of a »Dependency Injection Container« is promoted. And -- again typically -- + ** these DI containers tend to evolve into heavyweight universal tools and substitute + ** the original problem by metadata hell. + ** + ** Thus, for Lumiera, the choice to use Singletons was deliberate: we understand the + ** Inversion-of-Control principle, yet we want to stay just below the level of building + ** a central application manager core. At the usage site, we access a factory for some + ** service by name, where the »name« is actually the type name of an interface + ** or facade. Singleton is used as an implementation of this factory, when the service + ** is self-contained and can be brought up lazily. + ** + ** \par Conventions, Lifecycle and Unit Testing + ** + ** Usually we place an instance of the singleton factory (or some other kind of factory) + ** as a static variable within the interface class describing the service or facade. + ** As a rule, everything accessible as Singleton is sufficiently self-contained to come + ** up any time -- even prior to \c main(). But at shutdown, any deregistration must be + ** done explicitly using a lifecycle hook. Destructors aren't allowed to do any significant + ** work besides releasing references, and we acknowledge that singletons can be released + ** in \em arbitrary order. + ** + ** @see Depend + ** @see DependencyFactory + ** @see singleton-test.cpp + ** @see dependency-factory-test.cpp + */ + + #ifndef LIB_DEPEND_H #define LIB_DEPEND_H @@ -49,8 +92,8 @@ namespace lib { /** * Access point to singletons and other kinds of dependencies. - * Actually this is a Factory object, which is typically placed into a static field - * of the Singleton (target) class or some otherwise suitable interface. + * Actually this is a Factory object, which is typically placed into a + * static field of the Singleton (target) class or some otherwise suitable interface. * @note uses static fields internally, so all factory instances share pInstance_ * @remark there is an ongoing discussion regarding the viability of the * Double Checked Locking pattern, which requires either the context of a clearly defined diff --git a/src/lib/multifact.hpp b/src/lib/multifact.hpp index 5d4a273b6..bce8133c7 100644 --- a/src/lib/multifact.hpp +++ b/src/lib/multifact.hpp @@ -59,7 +59,7 @@ #include "lib/error.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "util.hpp" #include @@ -223,9 +223,9 @@ namespace lib { */ template class Singleton - : lib::Singleton + : lib::Depend { - typedef lib::Singleton SingFac; + typedef lib::Depend SingFac; Creator createSingleton_accessFunction() diff --git a/src/lib/singleton-factory.hpp b/src/lib/singleton-factory.hpp deleted file mode 100644 index 493efb64e..000000000 --- a/src/lib/singleton-factory.hpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - SINGLETON-FACTORY.hpp - template for implementing the singleton pattern - - 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. - -==================================================================== -This code is heavily inspired by - The Loki Library (loki-lib/trunk/include/loki/Singleton.h) - Copyright (c) 2001 by Andrei Alexandrescu - Loki code accompanies the book: - Alexandrescu, Andrei. "Modern C++ Design: Generic Programming - and Design Patterns Applied". - Copyright (c) 2001. Addison-Wesley. ISBN 0201704315 - -*/ - - - -#ifndef LIB_SINGLETON_FACTORY_H -#define LIB_SINGLETON_FACTORY_H - - -#include "lib/singleton-policies.hpp" // several Policies usable together with SingletonFactory - -#include "lib/nobug-init.hpp" -#include "lib/sync-classlock.hpp" - -namespace lib { - - /** - * A configurable Template for implementing Singletons. - * Actually this is a Factory object, which could be placed into a static field - * of the Singleton (target) class or used directly. - * @note internally uses static fields, so all factory instances share pInstance_ - * @note there is an ongoing discussion regarding Double Checked Locking pattern, - * which in this case boils down to the question: does \c pthread_mutex_lock/unlock - * constitute a memory barrier, such as to force any memory writes done within - * the singleton ctor to be flushed and visible to other threads when releasing - * the lock? To my understanding, the answer is yes. See - * http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap04.html#tag_04_10 - * @param SI the class of the Singleton instance - * @param Create policy defining how to create/destroy the instance - * @param Life policy defining how to manage Singleton Lifecycle - */ - template - < class SI - , template class Create = singleton::StaticCreate - , template class Life = singleton::AutoDestroy - > - class SingletonFactory - { - typedef lib::ClassLock ThreadLock; - - static SI* volatile pInstance_; - static bool isDead_; - - - public: - /** Interface to be used by SingletonFactory's clients. - * Manages internally the instance creation, lifecycle - * and access handling in a multithreaded context. - * @return "the" single instance of class S - */ - SI& operator() () - { - if (!pInstance_) - { - ThreadLock guard; - - if (!pInstance_) - { - if (isDead_) - { - Life::onDeadReference(); - isDead_ = false; - } - pInstance_ = Create::create(); - Life::scheduleDelete (&destroy); - } } - ENSURE (pInstance_); - ENSURE (!isDead_); - return *pInstance_; - } - - private: - /** @internal helper used to delegate destroying the single instance - * to the Create policy, at the same time allowing the Life policy - * to control the point in the Application lifecycle when the - * destruction of this instance occurs. - */ - static void destroy() - { - REQUIRE (!isDead_); - Create::destroy (pInstance_); - pInstance_ = 0; - isDead_ = true; - } - }; - - - // Storage for SingletonFactory's static fields... - template - < class SI, - template class C, - template class L - > - SI* volatile SingletonFactory::pInstance_; - - template - < class SI, - template class C, - template class L - > - bool SingletonFactory::isDead_; - - - -///// Question: can we get rid of the static fields? -///// this is tricky because of invoking the destructors. If we rely on instance vars, -///// the object may already have been released when the runtime system calls the -///// destructors of static objects at shutdown. -///// It seems this would either cost us much of the flexibility or get complicated -///// to a point where we could as well implement our own Dependency Injection Manager. -///// But the whole point of my pervasive use of this singleton template is to remain -///// below this borderline of integration ("IoC yes, but avoid DI"). - -} // namespace lib -#endif diff --git a/src/lib/singleton-policies.hpp b/src/lib/singleton-policies.hpp deleted file mode 100644 index feea95b3a..000000000 --- a/src/lib/singleton-policies.hpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - SINGLETON-POLICIES.hpp - how to manage creation, lifecycle and multithreading - - 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. - -==================================================================== -This code is heavily inspired by - The Loki Library (loki-lib/trunk/include/loki/Singleton.h) - Copyright (c) 2001 by Andrei Alexandrescu - Loki code accompanies the book: - Alexandrescu, Andrei. "Modern C++ Design: Generic Programming - and Design Patterns Applied". - Copyright (c) 2001. Addison-Wesley. ISBN 0201704315 - -*/ - - - -#ifndef LIB_SINGLETON_POLICIES_H -#define LIB_SINGLETON_POLICIES_H - -#include "lib/nobug-init.hpp" -#include "lib/error.hpp" - -#include - - -namespace lib { -namespace singleton { - - - /* === several Policies usable in conjunction with lib::Singleton === */ - - /** - * Policy to place the Singleton instance into a statically allocated buffer - */ - template - class StaticCreate - { - public: - static S* create () - { -#if NOBUG_MODE_ALPHA - static uint callCount = 0; - ASSERT ( 0 == callCount++ ); -#endif - static char buff[sizeof(S)]; - return new(buff) S(); - } - static void destroy (S* pSi) - { - pSi-> ~S(); - } - }; - - - /** - * Policy for creating the Singleton instance heap allocated - */ - template - class HeapCreate - { - public: - static S* create () { return new S; } - static void destroy (S* pS) { delete pS; } - }; - - - - - - typedef void (*DelFunc)(void); - using std::vector; - - /** - * Policy relying on the compiler/runtime system for Singleton Lifecycle - */ - template - class AutoDestroy - { - class DeleteTrigger - { - vector dels_; - - public: - void schedule (DelFunc del) - { - dels_.push_back(del); - } - ~DeleteTrigger() - { - vector::iterator del = dels_.begin(); - for ( ; del != dels_.end(); ++del ) - (*del)(); // invoke deleter function - } - }; - - public: - /** implements the Singleton removal by calling - * the provided deleter function(s) at application shutdown, - * relying on the runtime system to call destructors of static - * objects. Because this Policy class can be shared between - * several Singletons, we need to memorise all registered - * deleter functions for calling them at shutdown. - */ - static void - scheduleDelete (DelFunc kill_the_singleton) - { - REQUIRE (kill_the_singleton); - static DeleteTrigger finally; - finally.schedule (kill_the_singleton); - } - - static void - onDeadReference () - { - throw lumiera::error::Logic ("Trying to access a Singleton instance that has " - "already been released or finished its lifecycle."); - } - }; - - - - -}} // namespace lib::singleton -#endif diff --git a/src/lib/singleton-preconfigure.hpp b/src/lib/singleton-preconfigure.hpp deleted file mode 100644 index 32973ad90..000000000 --- a/src/lib/singleton-preconfigure.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - SINGLETON-PRECONFIGURE - declare the configuration of some Singleton types in advance - - 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 singleton-preconfigure.hpp - ** Pre-configuration of some Singleton types, done by template specialisation. - ** Typically the client code just includes singleton.h and uses the Singleton - ** type. But in some cases, we want to configure specific (dependency injection) - ** behaviour at a central location. At some point, we may well have a full blown - ** Dependency Manager, but for the moment using just some specialised Singleton - ** type for some instances seems sufficient. - ** - ** One reason why one wants special Singleton behaviour is testing: Without - ** altering the executable, for running some tests we need to inject a Test Mock - ** in place of some service object, so we can verify the behaviour of the code - ** using this service. For this, we mix lumiera::test::MockInjector - ** into the actual Singleton type. - ** - ** @note we declare the specialisations into the target namespace - ** - ** @see SingletonFactory - ** @see SingletonTestMock_test - */ - - -#ifndef LIB_SINGLETON_PRECONFIGURE_H -#define LIB_SINGLETON_PRECONFIGURE_H - -#include "lib/test/mock-injector.hpp" - - -namespace lib { - - /** - * Default Singleton configuration - * @note all Policy template parameters taking default values - */ - template - class Singleton - : public SingletonFactory - { } - ; - - - /* ********************************************************************** */ - /* Forward declarations of all Classes we want to specialise the template */ - /* ********************************************************************** */ - - namespace test { - class TestSingletonO; - using lib::Singleton; - - } // namespace test -} // namespace lumiera - -namespace backend { - class MediaAccessFacade; - using lib::Singleton; - -} // namespace backend - -namespace proc { -namespace engine { - class EngineService; - using lib::Singleton; -}} - - - - - - /* ************************** */ - /* Specialisation Definitions */ - /* ************************** */ - -namespace lib { - - using test::MockInjector; - - - template<> - class Singleton - : public MockInjector - { }; - - - template<> - class Singleton - : public MockInjector - { }; - - - template<> - class Singleton - : public MockInjector - { }; - -} // namespace lib - - - - -#endif diff --git a/src/lib/singleton-subclass.hpp b/src/lib/singleton-subclass.hpp deleted file mode 100644 index 386fc9f59..000000000 --- a/src/lib/singleton-subclass.hpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - SINGLETON-SUBCLASS.hpp - variant of the singleton (factory) creating a subclass - - 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 singleton-subclass.hpp - ** Specialised SingletonFactory creating subclasses of the nominal type. - ** The rationale is to be able to defer the decision what type to create - ** down to the point where the singleton factory is actually created. - ** Thus the code using the singleton need not know the implementation - ** class, but nevertheless gets an non-virtual access function to the - ** singleton instance (which can be inlined), and the compiler is - ** still able to spot type errors. Maybe someone knows a less - ** contrived solution fulfilling the same criteria....? - ** - ** @see configrules.cpp usage example - ** @see SingletonSubclass_test - */ - - -#ifndef LIB_SINGLETON_SUBCLASS_H -#define LIB_SINGLETON_SUBCLASS_H - - -#include "lib/singleton.hpp" - -#include -#include - - -namespace lib { - - using boost::scoped_ptr; - - - namespace singleton { - - /** - * Helper template to use the general policy classes of the lib::Singleton, - * but change the way they are parametrised on-the-fly. - */ - template class POL, class I> - struct Adapter - { - - struct Link - { - virtual ~Link() {} - virtual I* create () = 0; ///< @note compiler will check if the actual type is assignable... - virtual void destroy (I* pSi) = 0; - }; - - template - struct TypedLink : Link - { - virtual S* create () { return POL::create (); } // covariance checked! - virtual void destroy (I* pSi) { POL::destroy (static_cast (pSi)); } - }; - - - struct My_scoped_ptr : scoped_ptr ///< implementation detail: defeat static initialisation - { - using scoped_ptr::get; - My_scoped_ptr() : scoped_ptr (get()? get() : 0) {} ///< bypass if already configured - }; - - /** we configure this link \e later, when the singleton factory - * is actually created, to point at the desired implementation subclass. - */ - static My_scoped_ptr link; - - /** Forwarding Template used to configure the basic SingletonFactory */ - template - struct Adapted - { - static II* create () { return link->create (); } - static void destroy (II* pSi) { link->destroy (pSi); } - }; - }; - - template class A, class I> - typename Adapter::My_scoped_ptr Adapter::link; // note: use special ctor (due to static init order!) - - - /** type-information used to configure the factory instance - * with the concrete implementation type to be created. */ - template - struct UseSubclass - { }; - - } // namespace singleton - - - - - /** - * Special variant of the SingletonFactory with the option of actually creating - * a subclass or wrap the product in some way. For the user code, it should behave - * exactly like the standard SingletonFactory. The configuration of the product - * actually to be created is delayed until the ctor call, so it can be hidden - * away to the implementation of a class using the SingletonFactory. - * - * @see configrules.cpp usage example - */ - template - < class SI // the class to use as Interface for the Singleton - , template class Create = singleton::StaticCreate // how to create/destroy the instance - , template class Life = singleton::AutoDestroy // how to manage Singleton Lifecycle - > - class SingletonSubclassFactory - : public SingletonFactory< SI - , singleton::Adapter::template Adapted - , Life - > - { - public: - /** The singleton-factory ctor configures what concrete type to create. - * It takes type information passed as dummy parameter and installs - * a trampoline object in the static field of class Adapter to perform - * the necessary up/downcasts. This allows to use whatever policy - * class is desired, but parametrises this policy template with - * the concrete type to be created. (only the "create" policy - * needs to know the actual class, because it allocates storage) - */ - template - SingletonSubclassFactory (singleton::UseSubclass&) - { - typedef typename singleton::Adapter Adapter; - typedef typename Adapter::template TypedLink TypedLink; - - if (!Adapter::link) - Adapter::link.reset (new TypedLink); - -#ifdef DEBUG - else - REQUIRE ( typeid(*Adapter::link) == typeid(new TypedLink), - "If using several instances of the sub-class-creating " - "singleton factory, all *must* be configured to create " - "objects of exactly the same implementation type!"); -#endif - } - }; - - - /** - * Default Singleton configuration (subclass creating factory) - * @note all Policy template parameters taking default values - */ - template - struct SingletonSub - : public SingletonSubclassFactory - { - template - SingletonSub (TY ref) : SingletonSubclassFactory(ref) {} - }; - - -} // namespace lib - -#endif diff --git a/src/lib/singleton.hpp b/src/lib/singleton.hpp deleted file mode 100644 index 56c3cb6ee..000000000 --- a/src/lib/singleton.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - SINGLETON.hpp - configuration header for singleton factory - - 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 singleton.hpp - ** Factory for creating Singleton instances. - ** The Singleton Pattern provides a single access point to a class or - ** service and exploits this ubiquitous access point to limit the number of objects - ** of this type to a single shared instance. Within Lumiera, we mostly employ a - ** factory template; the intention is to use on-demand initialisation and a - ** standardised lifecycle. - ** - ** This configuration header just pulls in some other implementation headers in - ** the right order. The basic class template for creating singletons resides in - ** singleton-factory.hpp, besides we need policy classes defining how to create - ** the singleton objects and how to manage singleton lifecycle. Finally, - ** we want to preconfigure singleton factories for some important facilities; - ** e.g. sometimes we want to include a hook for injecting Test Mock instances. - ** - ** You'll find the default Policies in singleton-factory.hpp and the default - ** definition of type lumiera::singleton in singleton-preconfigure.hpp - ** - ** \par Why Singletons? Inversion-of-Control and Dependency Injection - ** - ** Singletons are frequently over-used, and often they serve as disguised - ** global variables to support a procedural programming style. As a remedy, typically - ** the use of a »Dependency Injection Container« is promoted. And -- again typically -- - ** these DI containers tend to evolve into heavyweight universal tools and substitute - ** the original problem by metadata hell. - ** - ** Thus, for Lumiera, the choice to use Singletons was deliberate: we understand the - ** Inversion-of-Control principle, yet we want to stay just below the level of building - ** a central application manager core. At the usage site, we access a factory for some - ** service by name, where the »name« is actually the type name of an interface - ** or facade. Singleton is used as an implementation of this factory, when the service - ** is self-contained and can be brought up lazily. - ** - ** \par Conventions, Lifecycle and Unit Testing - ** - ** Usually we place an instance of the singleton factory (or some other kind of factory) - ** as a static variable within the interface class describing the service or facade. - ** As a rule, everything accessible as Singleton is sufficiently self-contained to come - ** up any time -- even prior to \c main(). But at shutdown, any deregistration must be - ** done explicitly using a lifecycle hook. Destructors aren't allowed to do any significant - ** work besides releasing references, and we acknowledge that singletons can be released - ** in \em arbitrary order. - ** - ** @see SingletonFactory - ** @see singleton::StaticCreate - ** @see singleton::AutoDestroy - ** @see singletontest.hpp - ** @see SingletonTestMock_test - */ - - -#ifndef LIB_SINGLETON_H -#define LIB_SINGLETON_H - - -#include "lib/singleton-policies.hpp" -#include "lib/singleton-factory.hpp" -#include "lib/singleton-preconfigure.hpp" - - -#endif diff --git a/src/lib/test/mock-injector.hpp b/src/lib/test/mock-injector.hpp deleted file mode 100644 index 086cd478d..000000000 --- a/src/lib/test/mock-injector.hpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - MOCK-INJECTOR.hpp - replacement singleton factory for injecting Test-Mock objects - - 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 mock-injector.hpp - ** Support for unit-testing with a mock implementation of some singleton service. - ** Using a Singleton to access a global service (instead of using a dependency injection - ** framework) has the downside of making unit-tests hard to write. When the code to be - ** tested accesses the global service, usually, several further services must be available. - ** Usually this (and the lack of flexibility) counts as the main arguments against using - ** Singletons. Yet still our current analysis (as of 2011) for Lumiera is that this - ** drawback doesn't justify all the overhead of writing our own dependency-injection - ** container (given the lack of pre-existing suitable C++ implementations). - ** - ** lib::test::MockInjector provides a mechanism to overcome this problem. Given - ** a Singleton service, it allows to install a subclass of the service interface - ** temporarily as a mock implementation. As an additional convenience shortcut, - ** the Use4Test template can be used as a scoped variable to automate this process - ** of installing and removing the mock service within the call scope of a single test - ** method or test object. - ** - ** \par prerequisites - ** The Singleton needs to be managed and accessed through Lumiera's lib::Singleton - ** factory. Moreover, an explicit template specialisation to use MockInjector instead - ** of the plain lib::SingletonFactory needs to be given globally, for the service interface - ** to use. For this template specialisation, a forward declaration of the service is - ** sufficient. See singleton-preconfigure.hpp for examples. - ** - ** The Mock implementation of the service needs to be default constructible and - ** assignment compatible to the service interface. Moreover, the mock implementation class - ** must expose a typedef \c ServiceInterface pointing to this interface. The instance of - ** the mock service implementation will be created in heap memory and managed by a static - ** smart-ptr variable; it will be destroyed when leaving the scope marked by Use4Test. - ** - ** @see SingletonFactory - ** @see SingletonTestMock_test - ** @see MediaAccessMock_test usage example - */ - - -#ifndef LUMIERA_TEST_MOCK_INJECTOR_H -#define LUMIERA_TEST_MOCK_INJECTOR_H - - -#include "lib/singleton-factory.hpp" -#include "lib/meta/duck-detector.hpp" - -#include -#include -#include -#include - - -namespace lib { - template - class Singleton; // forward decl; see singleton-preconfigure - - -namespace test{ - - using boost::scoped_ptr; - - /** - * Special SingletonFactory allowing to inject some instance of the Singleton - * class, thus shadowing "the" (default) Singleton instance temporarily. - * This allows installing a Mock Subclass of the Singleton for running tests, - * while the Singleton can be used as usual in production code. - * @note we use the default policies or SingletonFactory - */ - template - class MockInjector : public SingletonFactory - { - static scoped_ptr mock_; - - public: - /** Overwriting the normal Singleton creation Interface - * to return some mock if defined, falling back to the - * default Singleton creation behaviour else. - */ - SI& operator() () - { - if (mock_) - return *mock_; - else - return SingletonFactory::operator() (); - } - - void injectSubclass (SI* mockobj) - { - TRACE_IF (mockobj, test, "Singleton: installing Mock object"); - TRACE_IF (!mockobj, test, "Singleton: removing Mock object"); - mock_.reset (mockobj); - } - - - MockInjector () {}; - - // MockInjector objects may be copied freely (no object fields) - }; - - /** embedded static var to hold onto a configured mock implementation */ - template - scoped_ptr MockInjector::mock_; - - - - - - - /** Details of creating and accessing mock instances, * - * especially for services implemented as Singleton. */ - namespace mock { - - using boost::enable_if; - using lib::meta::Yes_t; - using lib::meta::No_t; - - /** - * Metafunction: does the Type in question - * give us a clue about what service interface to use? - */ - template - class defines_ServiceInterface - { - META_DETECT_NESTED (ServiceInterface); - - public: - enum{ value = HasNested_ServiceInterface::value - }; - }; - - /** - * Trait template: getting the types of the - * Service interface and SingletonFactory - */ - template - struct SingletonAccess - { - typedef No_t ServiceInterface; - typedef No_t Factory; - }; - - template - struct SingletonAccess >::type> - { - typedef typename IMP::ServiceInterface ServiceInterface; - typedef lib::Singleton Factory; - }; - - - /** - * A Metafunction to find out, if a type in question - * is used as Singleton and especially has been configured - * to inject Mock implementations defined as Subclasses. - */ - template - class is_Singleton_with_MockInjector - { - typedef typename SingletonAccess::ServiceInterface Interface; - typedef typename SingletonAccess::Factory SingletonFactory; - - META_DETECT_MEMBER (injectSubclass); - public: - - enum{ value = defines_ServiceInterface::value - && HasMember_injectSubclass::value - }; - }; - - - /** - * Policy-Trait: How to access and inject - * a mock service implementation? - */ - template - struct AccessPoint - { - BOOST_STATIC_ASSERT (is_Singleton_with_MockInjector::value ); - }; // Hint: (1) the mock needs a typedef pointing to the ServiceInterface - // (2) prepare the Singleton-Factory for injecting a Mock implementation... - // look into singleton-preconfigure.hpp for examples! - - template - struct AccessPoint >::type> - { - typedef typename SingletonAccess::Factory ServiceAccessPoint; - - static void - activateMock() - { - ServiceAccessPoint().injectSubclass (new MOCK()); - } - static void - deactivateMock() - { - ServiceAccessPoint().injectSubclass (0); - } - }; - }//(End) details of injecting the mock implementation - - - - - /** - * Scoped object for installing/deinstalling a mocked service automatically. - * Placing a suitably specialised instance of this template into a local scope - * will inject the corresponding mock installation and remove it when the - * control flow leaves this scope. - * @param MOCK the concrete mock implementation to inject. It needs to - * subclass the service interface and expose a typedef \c ServiceInterace - */ - template - struct Use4Test - : boost::noncopyable - { - Use4Test() - { - mock::AccessPoint::activateMock(); - } - - ~Use4Test() - { - mock::AccessPoint::deactivateMock(); - } - }; - - - -}} // namespace lib::test -#endif diff --git a/src/lib/visitor-dispatcher.hpp b/src/lib/visitor-dispatcher.hpp index fba85bf1a..32501d015 100644 --- a/src/lib/visitor-dispatcher.hpp +++ b/src/lib/visitor-dispatcher.hpp @@ -28,7 +28,7 @@ #include "lib/error.hpp" #include "lib/util.hpp" #include "lib/sync-classlock.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/util.hpp" #include @@ -38,7 +38,7 @@ namespace lib { namespace visitor { using lib::ClassLock; - using lib::Singleton; + using lib::Depend; template class Tag; @@ -180,7 +180,7 @@ namespace visitor { public: - static Singleton > instance; + static Depend > instance; inline ReturnType forwardCall (TAR& target, TOOL& tool) @@ -208,7 +208,7 @@ namespace visitor { /** storage for the dispatcher table(s) */ template - Singleton > Dispatcher::instance; + Depend > Dispatcher::instance; diff --git a/src/proc/asset/db.hpp b/src/proc/asset/db.hpp index 8605a0f59..bafad229f 100644 --- a/src/proc/asset/db.hpp +++ b/src/proc/asset/db.hpp @@ -102,7 +102,7 @@ namespace asset { clear(); } - friend class lib::singleton::StaticCreate; + friend class lib::DependencyFactory::InstanceHolder; public: diff --git a/src/proc/assetmanager.cpp b/src/proc/assetmanager.cpp index ad34e5794..5fa82b886 100644 --- a/src/proc/assetmanager.cpp +++ b/src/proc/assetmanager.cpp @@ -36,7 +36,7 @@ using std::tr1::placeholders::_1; using boost::format; using util::for_each; -using lib::Singleton; +using lib::Depend; using lib::Sync; @@ -84,10 +84,10 @@ namespace asset { /** get at the system-wide asset manager instance. * Implemented as singleton. */ - Singleton AssetManager::instance; + Depend AssetManager::instance; AssetManager::AssetManager () - : registry (Singleton() ()) + : registry (Depend() ()) { } diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp index 4ed24eb5b..7ddcf646e 100644 --- a/src/proc/assetmanager.hpp +++ b/src/proc/assetmanager.hpp @@ -46,7 +46,7 @@ #include "proc/asset.hpp" #include "lib/error.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include @@ -74,7 +74,7 @@ namespace asset { public: - static lib::Singleton instance; + static lib::Depend instance; /** provide the unique ID for given Asset::Ident tuple */ static ID getID (const Asset::Ident&); @@ -126,7 +126,7 @@ namespace asset { AssetManager (); - friend class lib::singleton::StaticCreate; + friend class lib::DependencyFactory::InstanceHolder; }; diff --git a/src/proc/config-resolver.cpp b/src/proc/config-resolver.cpp index d8dab278a..0c71a1069 100644 --- a/src/proc/config-resolver.cpp +++ b/src/proc/config-resolver.cpp @@ -30,16 +30,10 @@ namespace proc { - namespace { - - /** type of the actual ConfigRules implementation to use */ - lib::singleton::UseSubclass typeinfo; - } - - - /** Singleton factory instance, parametrised to actual impl. type. */ - lib::SingletonSub ConfigResolver::instance (typeinfo); + using lib::buildSingleton; + /** Singleton factory instance, configured with the actual implementation type. */ + lib::Depend ConfigResolver::instance (buildSingleton()); } // namespace proc diff --git a/src/proc/config-resolver.hpp b/src/proc/config-resolver.hpp index 75b0e47f9..34e29da2b 100644 --- a/src/proc/config-resolver.hpp +++ b/src/proc/config-resolver.hpp @@ -48,7 +48,7 @@ #include "common/query.hpp" #include "common/config-rules.hpp" -#include "lib/singleton-subclass.hpp" +#include "lib/depend.hpp" // types for explicit specialisations.... #include "proc/mobject/session/track.hpp" @@ -87,7 +87,7 @@ namespace proc { { public: - static lib::SingletonSub instance; + static lib::Depend instance; }; diff --git a/src/proc/control/command-registry.hpp b/src/proc/control/command-registry.hpp index c749a2dbc..3fbe51170 100644 --- a/src/proc/control/command-registry.hpp +++ b/src/proc/control/command-registry.hpp @@ -58,7 +58,7 @@ #define CONTROL_COMMAND_REGISTRY_H #include "lib/error.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/sync.hpp" #include "include/logging.h" #include "lib/util.hpp" @@ -129,7 +129,7 @@ namespace control { public: - static lib::Singleton instance; + static lib::Depend instance; ~CommandRegistry() diff --git a/src/proc/control/command.cpp b/src/proc/control/command.cpp index 6489a3fee..bd4fd5d3f 100644 --- a/src/proc/control/command.cpp +++ b/src/proc/control/command.cpp @@ -98,7 +98,7 @@ namespace control { /** storage for the singleton factory used to access CommandRegistry */ - lib::Singleton CommandRegistry::instance; + lib::Depend CommandRegistry::instance; Command::~Command() { } diff --git a/src/proc/control/proc-dispatcher.cpp b/src/proc/control/proc-dispatcher.cpp index 6d558678a..a5755863a 100644 --- a/src/proc/control/proc-dispatcher.cpp +++ b/src/proc/control/proc-dispatcher.cpp @@ -53,7 +53,7 @@ namespace control { } /** storage for Singleton access */ - lib::Singleton ProcDispatcher::instance; + lib::Depend ProcDispatcher::instance; diff --git a/src/proc/control/proc-dispatcher.hpp b/src/proc/control/proc-dispatcher.hpp index 14f76d09e..19a32d32f 100644 --- a/src/proc/control/proc-dispatcher.hpp +++ b/src/proc/control/proc-dispatcher.hpp @@ -37,7 +37,7 @@ //#include "lib/symbol.hpp" #include "proc/control/command.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" //#include @@ -57,7 +57,7 @@ namespace control { { public: - static lib::Singleton instance; + static lib::Depend instance; void activate(); void deactivate(); diff --git a/src/proc/control/stypemanager.cpp b/src/proc/control/stypemanager.cpp index 5b386c99b..bcfaa5fbe 100644 --- a/src/proc/control/stypemanager.cpp +++ b/src/proc/control/stypemanager.cpp @@ -46,7 +46,7 @@ namespace control { /** access the system-wide stream type manager instance. * Implemented as singleton. */ - lib::Singleton STypeManager::instance; + lib::Depend STypeManager::instance; void diff --git a/src/proc/control/stypemanager.hpp b/src/proc/control/stypemanager.hpp index d59120b65..db526d493 100644 --- a/src/proc/control/stypemanager.hpp +++ b/src/proc/control/stypemanager.hpp @@ -26,7 +26,7 @@ #include "proc/streamtype.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include @@ -44,7 +44,7 @@ namespace control { boost::scoped_ptr reg_; public: - static lib::Singleton instance; + static lib::Depend instance; typedef StreamType::ImplFacade ImplFacade; @@ -79,7 +79,7 @@ namespace control { STypeManager() ; ~STypeManager(); - friend class lib::singleton::StaticCreate; + friend class lib::DependencyFactory::InstanceHolder; /** Lifecycle: reset all type registration information * to the generic pristine default state. This includes diff --git a/src/proc/engine/diagnostic-buffer-provider.cpp b/src/proc/engine/diagnostic-buffer-provider.cpp index e681cdc0c..3258e2f86 100644 --- a/src/proc/engine/diagnostic-buffer-provider.cpp +++ b/src/proc/engine/diagnostic-buffer-provider.cpp @@ -33,7 +33,7 @@ namespace engine { /** Storage for the diagnostics frontend */ - lib::Singleton DiagnosticBufferProvider::diagnostics; + lib::Depend DiagnosticBufferProvider::diagnostics; diff --git a/src/proc/engine/diagnostic-buffer-provider.hpp b/src/proc/engine/diagnostic-buffer-provider.hpp index 9d1f3f303..444ba0cc4 100644 --- a/src/proc/engine/diagnostic-buffer-provider.hpp +++ b/src/proc/engine/diagnostic-buffer-provider.hpp @@ -31,7 +31,7 @@ #include "lib/error.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/util.hpp" #include "proc/engine/type-handler.hpp" #include "proc/engine/buffer-provider.hpp" @@ -63,7 +63,7 @@ namespace engine { { boost::scoped_ptr pImpl_; - static lib::Singleton diagnostics; + static lib::Depend diagnostics; TrackingHeapBlockProvider& reset(); @@ -73,7 +73,7 @@ namespace engine { DiagnosticBufferProvider(); ~DiagnosticBufferProvider(); - friend class lib::singleton::StaticCreate; + friend class lib::DependencyFactory::InstanceHolder; public: /** build a new Diagnostic Buffer Provider instance, diff --git a/src/proc/engine/engine-diagnostics.hpp b/src/proc/engine/engine-diagnostics.hpp index a29b051b7..6d761997a 100644 --- a/src/proc/engine/engine-diagnostics.hpp +++ b/src/proc/engine/engine-diagnostics.hpp @@ -48,7 +48,7 @@ //#include "common/instancehandle.hpp" //#include "lib/singleton-ref.hpp" //#include "lib/polymorphic-value.hpp" -//#include "lib/singleton.hpp" +//#include "lib/depend.hpp" // #include //#include diff --git a/src/proc/engine/engine-service.cpp b/src/proc/engine/engine-service.cpp index 1121970fd..a9833d592 100644 --- a/src/proc/engine/engine-service.cpp +++ b/src/proc/engine/engine-service.cpp @@ -54,7 +54,7 @@ namespace engine{ /** storage for the EngineService interface object */ - lib::Singleton EngineService::instance; + lib::Depend EngineService::instance; diff --git a/src/proc/engine/engine-service.hpp b/src/proc/engine/engine-service.hpp index edad93c03..cc094f5d9 100644 --- a/src/proc/engine/engine-service.hpp +++ b/src/proc/engine/engine-service.hpp @@ -60,7 +60,7 @@ //#include "common/instancehandle.hpp" //#include "lib/singleton-ref.hpp" #include "lib/polymorphic-value.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" // #include //#include @@ -136,7 +136,7 @@ namespace engine{ * @internal this is an facade interface for internal use * by the player. Client code should use the Player. */ - static lib::Singleton instance; + static lib::Depend instance; virtual ~EngineService() { } diff --git a/src/proc/facade.cpp b/src/proc/facade.cpp index e1339d05e..a2a1d02a5 100644 --- a/src/proc/facade.cpp +++ b/src/proc/facade.cpp @@ -22,7 +22,7 @@ #include "proc/facade.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "proc/play/output-director.hpp" #include @@ -151,9 +151,9 @@ namespace proc { }; namespace { - lib::Singleton theBuilderDescriptor; - lib::Singleton theSessionDescriptor; - lib::Singleton thePlayOutDescriptor; + lib::Depend theBuilderDescriptor; + lib::Depend theSessionDescriptor; + lib::Depend thePlayOutDescriptor; } diff --git a/src/proc/mobject/session.hpp b/src/proc/mobject/session.hpp index b60ef247a..b0155b134 100644 --- a/src/proc/mobject/session.hpp +++ b/src/proc/mobject/session.hpp @@ -53,7 +53,7 @@ #include "proc/mobject/mobject-ref.hpp" #include "common/query/defs-manager.hpp" ////////////////////////////TICKET #643 forward declare this? #include "lib/ref-array.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/symbol.hpp" #include "lib/p.hpp" diff --git a/src/proc/mobject/session/query/fake-configrules.hpp b/src/proc/mobject/session/query/fake-configrules.hpp index c790fa12b..7ab8d68c1 100644 --- a/src/proc/mobject/session/query/fake-configrules.hpp +++ b/src/proc/mobject/session/query/fake-configrules.hpp @@ -283,7 +283,7 @@ namespace session { { protected: MockConfigRules (); ///< to be used only by the singleton factory - friend class lib::singleton::StaticCreate; + friend class lib::DependencyFactory::InstanceHolder; virtual ~MockConfigRules() {} diff --git a/src/proc/mobject/session/scope-locator.hpp b/src/proc/mobject/session/scope-locator.hpp index cf6c083d3..bec11aee9 100644 --- a/src/proc/mobject/session/scope-locator.hpp +++ b/src/proc/mobject/session/scope-locator.hpp @@ -28,7 +28,7 @@ #include "proc/mobject/session/scope-query.hpp" #include "proc/mobject/placement.hpp" #include "lib/iter-source.hpp" ////////////////////TICKET #493 : the bare interface would be sufficient here -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include @@ -63,7 +63,7 @@ namespace session { scoped_ptr focusStack_; public: - static lib::Singleton instance; + static lib::Depend instance; ScopePath& currPath(); ScopePath& pushPath(); @@ -94,7 +94,7 @@ namespace session { protected: ScopeLocator(); - friend class lib::singleton::StaticCreate; + friend class lib::DependencyFactory::InstanceHolder; private: lumiera::QueryResolver const& theResolver(); diff --git a/src/proc/mobject/session/scope.cpp b/src/proc/mobject/session/scope.cpp index ba5e8424d..88ab80f71 100644 --- a/src/proc/mobject/session/scope.cpp +++ b/src/proc/mobject/session/scope.cpp @@ -111,7 +111,7 @@ namespace session { /** Storage holding the single ScopeLocator instance */ - lib::Singleton ScopeLocator::instance; + lib::Depend ScopeLocator::instance; /** @internal the one (and only) access point diff --git a/src/proc/mobject/session/sess-manager-impl.hpp b/src/proc/mobject/session/sess-manager-impl.hpp index dc340af39..a39f903cd 100644 --- a/src/proc/mobject/session/sess-manager-impl.hpp +++ b/src/proc/mobject/session/sess-manager-impl.hpp @@ -47,7 +47,7 @@ namespace session { scoped_ptr lifecycle_; SessManagerImpl() throw(); - friend class lib::singleton::StaticCreate; + friend class lib::DependencyFactory::InstanceHolder; ~SessManagerImpl() ; diff --git a/src/proc/mobject/session/session.cpp b/src/proc/mobject/session/session.cpp index 28e447013..cf5c7b758 100644 --- a/src/proc/mobject/session/session.cpp +++ b/src/proc/mobject/session/session.cpp @@ -37,7 +37,7 @@ //#include "common/query/defs-manager.hpp" #include "lib/symbol.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" @@ -45,7 +45,6 @@ namespace proc { namespace mobject { using lib::Symbol; - using lib::Singleton; using session::SessManager; using session::SessManagerImpl; using session::SessionImplAPI; @@ -67,7 +66,7 @@ namespace mobject { * you use dot-notation, while you access the session object * via arrow notation (e.g. \code Session::current->getFixture() ) */ - SessManager& Session::current = Singleton()(); + SessManager& Session::current = lib::Depend()(); /** special access point allowing Proc-Layer internals diff --git a/src/proc/play/dummy-play-connection.cpp b/src/proc/play/dummy-play-connection.cpp index 065cd0b40..82c31ccc7 100644 --- a/src/proc/play/dummy-play-connection.cpp +++ b/src/proc/play/dummy-play-connection.cpp @@ -24,7 +24,7 @@ #include "proc/play/dummy-play-connection.hpp" //#include "proc/play/dummy-image-generator.hpp" //#include "proc/play/tick-service.hpp" -//#include "lib/singleton.hpp" +//#include "lib/depend.hpp" //#include //#include diff --git a/src/proc/play/dummy-player-service.cpp b/src/proc/play/dummy-player-service.cpp index 1ca67f2c6..9669af14a 100644 --- a/src/proc/play/dummy-player-service.cpp +++ b/src/proc/play/dummy-player-service.cpp @@ -24,7 +24,7 @@ #include "proc/play/dummy-player-service.hpp" #include "proc/engine/worker/dummy-image-generator.hpp" #include "proc/engine/worker/tick-service.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" extern "C" { #include "common/interfacedescriptor.h" @@ -92,7 +92,7 @@ namespace proc { } }; - lib::Singleton theDummyPlayerDescriptor; + lib::Depend theDummyPlayerDescriptor; diff --git a/src/proc/play/output-director.cpp b/src/proc/play/output-director.cpp index 0bcbebc26..e74489850 100644 --- a/src/proc/play/output-director.cpp +++ b/src/proc/play/output-director.cpp @@ -41,7 +41,7 @@ namespace play { /** storage for the single application wide OutputDirector instance */ - lib::Singleton OutputDirector::instance; + lib::Depend OutputDirector::instance; /** bring up the framework for handling input/output connections. diff --git a/src/proc/play/output-director.hpp b/src/proc/play/output-director.hpp index 2783b097c..a9cd9a217 100644 --- a/src/proc/play/output-director.hpp +++ b/src/proc/play/output-director.hpp @@ -36,7 +36,7 @@ #include "lib/error.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "proc/play/output-manager.hpp" #include "common/subsys.hpp" #include "lib/sync.hpp" @@ -78,7 +78,7 @@ namespace play { scoped_ptr player_; public: - static lib::Singleton instance; + static lib::Depend instance; bool connectUp() ; void triggerDisconnect(SigTerm) throw(); @@ -88,7 +88,7 @@ namespace play { private: OutputDirector() ; ~OutputDirector() ; - friend class lib::singleton::StaticCreate; + friend class lib::DependencyFactory::InstanceHolder; void bringDown (SigTerm completedSignal); diff --git a/tests/40core.tests b/tests/40core.tests index e46c259df..de08344b2 100644 --- a/tests/40core.tests +++ b/tests/40core.tests @@ -594,28 +594,6 @@ out: '§&Ω%€' --> '' END -TEST "SingletonSubclass_test" SingletonSubclass_test 13 <... out: checking ScopedPtrHolder... @@ -666,16 +644,33 @@ END TEST "Singleton_test" Singleton_test 23 < testCases; + lib::Depend testCases; } // (end) implementation namespace diff --git a/tests/core/proc/engine/dispatcher-interface-test.cpp b/tests/core/proc/engine/dispatcher-interface-test.cpp index 6eeb4fef8..c4867e91f 100644 --- a/tests/core/proc/engine/dispatcher-interface-test.cpp +++ b/tests/core/proc/engine/dispatcher-interface-test.cpp @@ -31,7 +31,7 @@ #include "proc/play/timings.hpp" #include "lib/time/timevalue.hpp" //#include "lib/time/timequant.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/itertools.hpp" #include "lib/util-coll.hpp" #include "lib/util.hpp" @@ -117,7 +117,7 @@ namespace test { } }; - lib::Singleton mockDispatcher; + lib::Depend mockDispatcher; #if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #880 #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #890 diff --git a/tests/core/proc/mobject/session/query-resolver-test.cpp b/tests/core/proc/mobject/session/query-resolver-test.cpp index abb37e8c1..6920833a3 100644 --- a/tests/core/proc/mobject/session/query-resolver-test.cpp +++ b/tests/core/proc/mobject/session/query-resolver-test.cpp @@ -23,7 +23,7 @@ #include "lib/test/run.hpp" #include "lib/test/test-helper.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "common/query/query-resolver.hpp" @@ -167,7 +167,7 @@ namespace test{ }; - lib::Singleton testResolver; + lib::Depend testResolver; QueryResolver& buildTestQueryResolver () diff --git a/tests/core/proc/mobject/session/session-service-access-test.cpp b/tests/core/proc/mobject/session/session-service-access-test.cpp index a96436e8b..3944ff04d 100644 --- a/tests/core/proc/mobject/session/session-service-access-test.cpp +++ b/tests/core/proc/mobject/session/session-service-access-test.cpp @@ -24,7 +24,7 @@ #include "lib/test/run.hpp" #include "proc/mobject/session.hpp" #include "lib/meta/generator.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include #include #include @@ -35,7 +35,7 @@ namespace mobject { namespace session { namespace test { - using lib::Singleton; + using lib::Depend; using boost::lexical_cast; using std::ostream; using std::string; @@ -202,7 +202,7 @@ namespace test { uint TSessionImpl::magic_; - TSessManager& TSession::current = Singleton()(); + TSessManager& TSession::current = Depend()(); //note: already during static initialisation template<> diff --git a/tests/core/proc/mobject/session/testclip.cpp b/tests/core/proc/mobject/session/testclip.cpp index 1f9141f3a..216d869f2 100644 --- a/tests/core/proc/mobject/session/testclip.cpp +++ b/tests/core/proc/mobject/session/testclip.cpp @@ -26,7 +26,7 @@ #include "backend/media-access-mock.hpp" #include "proc/asset/media.hpp" #include "proc/asset/clip.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/time/timevalue.hpp" namespace proc { @@ -72,7 +72,7 @@ namespace test { { } }; - lib::Singleton testbed_1; // invoke ctor when creating first TestClip... + lib::Depend testbed_1; // invoke ctor when creating first TestClip... diff --git a/tests/library/singleton-subclass-test.cpp b/tests/library/singleton-subclass-test.cpp index 293209e2f..ef75ee781 100644 --- a/tests/library/singleton-subclass-test.cpp +++ b/tests/library/singleton-subclass-test.cpp @@ -27,12 +27,13 @@ #include "lib/util.hpp" #include "test-target-obj.hpp" -#include "lib/singleton-subclass.hpp" +#include "lib/depend.hpp" #include #include using boost::lexical_cast; +using util::isSameObject; using util::_Fmt; using util::isnil; using std::string; @@ -42,7 +43,7 @@ using std::cout; namespace lib { namespace test{ - using lumiera::error::LUMIERA_ERROR_ASSERTION; + using lumiera::error::LUMIERA_ERROR_LIFECYCLE; /** * Target object to be instantiated as Singleton @@ -61,8 +62,7 @@ namespace test{ Interface () : TestTargetObj(cnt) {} virtual ~Interface() {} - friend class singleton::StaticCreate; - friend class singleton::HeapCreate; + friend class DependencyFactory::InstanceHolder; }; int Interface::cnt = 0; @@ -87,9 +87,9 @@ namespace test{ * subclasses (implementation classes) without coupling the * caller to the concrete class type. * Expected results: an instance of the subclass is created. - * @see lib::Singleton - * @see lib::SingletonSubclassFactory - * @see lib::singleton::Adapter + * @see lib::Depend + * @see lib::buildSingleton() + * @see lib/dependency-factory.hpp */ class SingletonSubclass_test : public Test { @@ -104,29 +104,24 @@ namespace test{ Interface::setCountParam(num); // marker to declare the concrete type to be created - singleton::UseSubclass typeinfo; + DependencyFactory::InstanceConstructor factoryFunction = buildSingleton(); // define an instance of the Singleton factory, // specialised to create the concrete Type passed in - SingletonSubclassFactory instance (typeinfo); + Depend instance (factoryFunction); // Now use the Singleton factory... // Note: we get the Base type Interface& t1 = instance(); Interface& t2 = instance(); - CHECK ( &t1 == &t2, "not a Singleton, got two different instances." ); + CHECK (isSameObject (t1, t2), "not a Singleton, got two different instances." ); cout << "calling a non-static method on the Singleton-" << t1.identify() << "\n" << string (t1) << "\n"; -///////////////////////////////////////////////////////////////////////////////TODO: find a way to configure NoBug to throw in case of assertion -///////////////////////////////////////////////////////////////////////////////TODO: just for the proc tests. Also find a better way to configure -///////////////////////////////////////////////////////////////////////////////TODO: the non-release check. Then re-enable these checks... -//#ifdef DEBUG -// verify_error_detection (); -//#endif + verify_error_detection (); } @@ -134,19 +129,11 @@ namespace test{ void verify_error_detection () { + VERIFY_ERROR (LIFECYCLE, Depend instance (buildSingleton()) ); + VERIFY_ERROR (LIFECYCLE, Depend instance (buildSingleton()) ); - singleton::UseSubclass more_special_type; - - VERIFY_ERROR (ASSERTION, SingletonSubclassFactory instance (more_special_type) ); - /* in debug mode, an attempt to re-configure an already - * configured SingletonSubclassFactory with another type - * should be detected and spotted by assertion failure */ - - - // Note: the following won't compile, because the "subclass" isn't a subclass... - // - // singleton::UseSubclass yet_another_type; - // SingletonSubclassFactory instance (yet_another_type); + Depend newFactory; + CHECK ( INSTANCEOF (Impl, &newFactory() )); // works as before } }; diff --git a/tests/library/singleton-test.cpp b/tests/library/singleton-test.cpp index b70dbe62d..4c82c17d1 100644 --- a/tests/library/singleton-test.cpp +++ b/tests/library/singleton-test.cpp @@ -26,7 +26,7 @@ #include "lib/util.hpp" #include "test-target-obj.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include #include @@ -58,8 +58,7 @@ namespace test{ protected: TargetObj () : TestTargetObj(cnt) {} - friend class singleton::StaticCreate; - friend class singleton::HeapCreate; + friend class DependencyFactory::InstanceHolder; }; int TargetObj::cnt = 0; @@ -72,54 +71,25 @@ namespace test{ /******************************************************************* * @test implement a Singleton class using our Singleton Template. - * Expected results: no memory leaks. - * @see lib::Singleton - * @see lib::singleton::StaticCreate - * @see lib::singleton::HeapCreate + * Expected results: single instance created in static memory, + * single instance properly destroyed, no memory leaks. + * @see lib::Depend + * @see lib::DependencyFactory::InstanceHolder */ class Singleton_test : public Test { - typedef function InstanceAccessFunc; - InstanceAccessFunc instance; - virtual void run(Arg arg) + virtual void + run (Arg arg) { uint num= isnil(arg)? 1 : lexical_cast(arg[1]); - testStaticallyAllocatedSingleton (num++); - testHeapAllocatedSingleton (num++); - } - - - /** @test parametrise the Singleton creation such as to create - * the single TargetObj instance as a static variable. - */ - void testStaticallyAllocatedSingleton (uint num) - { - SingletonFactory single; - instance = single; - useInstance (num, "statically allocated"); - } - - /** @test parametrise the Singleton creation such as to create - * the single TargetObj instance allocated on the Heap - * and deleted automatically at application shutdown. - */ - void testHeapAllocatedSingleton (uint num) - { - SingletonFactory single; - instance = single; - useInstance (num, "heap allocated"); - } - - - - void useInstance (uint num, string kind) - { - cout << _Fmt("testing TargetObj(%d) as Singleton(%s)\n") % num % kind; + Depend singleton; + + cout << _Fmt("testing TargetObj(%d) as Singleton\n") % num; TargetObj::setCountParam(num); - TargetObj& t1 = instance(); - TargetObj& t2 = instance(); + TargetObj& t1 = singleton(); + TargetObj& t2 = singleton(); CHECK (isSameObject(t1, t2), "not a Singleton, got two different instances." ); diff --git a/tests/library/singleton-testmock-test.cpp b/tests/library/singleton-testmock-test.cpp index 44107ce12..f20b26808 100644 --- a/tests/library/singleton-testmock-test.cpp +++ b/tests/library/singleton-testmock-test.cpp @@ -23,7 +23,7 @@ #include "lib/test/run.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include "lib/util.hpp" #include @@ -108,46 +108,28 @@ namespace test{ /******************************************************************* * @test inject a Mock object into the Singleton Factory, * to be returned and used in place of the original object. - * Expected results: Mock(s) called, no memory leaks. - * @see lib::Singleton - * @see lib::singleton::Static + * This test covers the full usage cycle: first access the + * Client Object, then replace it by two different mocks, + * and finally restore the original Client Object. + * @see lib::Depend + * @see lib::test::Depend4Test + * @see DependencyFactory_test */ class SingletonTestMock_test : public Test { - Singleton sing; - void run (Arg arg) { - string scenario = isnil(arg)? "default" : arg[1]; + Depend sing; - if (scenario == "default") - injectBoth(); - else - if (scenario == "noMock") - noMock(); - else - if (scenario == "onlyMock") - onlyMock(); - else - if (scenario == "firstMock") - firstMock(); - } - - - /** @test complete use sequence: first access the Client Object, - * then replace it by two different mocks, and finally - * restore the original Client Object - */ - void - injectBoth () - { sing().doIt(); sing().doIt(); CHECK (sing().getCnt() == 2); - sing.injectSubclass (new Mock_1); + Mock_1 mock_1; + TestSingletonO* original = + sing.injectReplacement (&mock_1); sing().doIt(); sing().doIt(); sing().doIt(); @@ -155,51 +137,16 @@ namespace test{ sing().doIt(); CHECK (sing().getCnt() == 5); - sing.injectSubclass (new Mock_2); + Mock_2 mock_2; + sing.injectReplacement (&mock_2); sing().doIt(); CHECK (sing().getCnt() == 1); - sing.injectSubclass (0); // un-shadowing original instance + sing.injectReplacement (original); // un-shadowing original instance CHECK (sing().getCnt() == 2); sing().doIt(); CHECK (sing().getCnt() == 3); } - - - /** @test just use Singleton Factory normally without any Mock. */ - void - noMock () - { - sing().doIt(); - } - - - /** @test inject the Mock prior to using the Singleton Factory, - * thus the original Client Object shouldn't be created.*/ - void - onlyMock () - { - sing.injectSubclass (new Mock_1); - sing().doIt(); - } - - - /** @test inject the Mock prior to using the Singleton Factory, - * but then reset the Mock, so following calls should - * create the original Client Object. - */ - void - firstMock () - { - sing.injectSubclass (new Mock_1); - sing().doIt(); - sing().doIt(); - CHECK (sing().getCnt() == 2); - - sing.injectSubclass (0); - sing().doIt(); - CHECK (sing().getCnt() == 1); - } }; diff --git a/tests/library/visitingtoolconcept.cpp b/tests/library/visitingtoolconcept.cpp index 676672d7d..f9d7158f3 100644 --- a/tests/library/visitingtoolconcept.cpp +++ b/tests/library/visitingtoolconcept.cpp @@ -54,22 +54,20 @@ #include "lib/test/run.hpp" -#include "lib/singleton.hpp" +#include "lib/depend.hpp" #include #include #include -using lib::Singleton; using boost::format; using std::string; using std::cout; -namespace lumiera - { - namespace visitor_concept_draft - { +namespace lumiera { + namespace visitor_concept_draft { + // ================================================================== Library ==== @@ -223,7 +221,7 @@ namespace lumiera public: - static Singleton > instance; + static lib::Depend > instance; inline ReturnType forwardCall (TAR& target, TOOL& tool) @@ -251,7 +249,7 @@ namespace lumiera /** storage for the dispatcher table(s) */ template - Singleton > Dispatcher::instance; + lib::Depend > Dispatcher::instance;