From 7fc462209ee8dbf8fdd40cfd4c2866a7fc421b86 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 18 Dec 2010 00:58:19 +0100 Subject: [PATCH] some naming cleanup and namespace indentation fixes --- src/lib/Makefile.am | 12 +- ...tioncluster.cpp => allocation-cluster.cpp} | 2 +- ...tioncluster.hpp => allocation-cluster.hpp} | 12 +- ...letonfactory.hpp => singleton-factory.hpp} | 22 +- src/lib/singleton-policies.hpp | 138 +++++++ ...nfigure.hpp => singleton-preconfigure.hpp} | 10 +- src/lib/singleton.hpp | 14 +- src/lib/singletonpolicies.hpp | 138 ------- src/lib/sync-classlock.hpp | 2 +- src/lib/test/mockinjector.hpp | 2 +- src/proc/Makefile.am | 6 +- src/proc/engine/nodefactory.cpp | 2 +- src/proc/engine/nodewiring.hpp | 2 +- src/proc/mobject/session.hpp | 2 +- .../{defsmanager.cpp => defs-manager.cpp} | 4 +- src/proc/mobject/session/defs-manager.hpp | 128 ++++++ .../{defsregistry.hpp => defs-registry.hpp} | 265 ++++++------ src/proc/mobject/session/defsmanager.hpp | 130 ------ src/proc/mobject/session/root.cpp | 2 +- .../mobject/session/sess-manager-impl.cpp | 2 +- .../session/session-interface-modules.hpp | 2 +- src/proc/mobject/session/session.cpp | 2 +- tests/components/Makefile.am | 6 +- .../proc/control/command-use1-test.cpp | 4 +- .../proc/engine/node-basic-test.cpp | 2 +- .../proc/mobject/placement-basic-test.cpp | 110 +++-- .../session/defs-manager-impl-test.cpp | 176 ++++++++ .../mobject/session/defs-manager-test.cpp | 204 +++++++++ .../session/defs-registry-impl-test.cpp | 292 +++++++++++++ .../mobject/session/defsmanagerimpltest.cpp | 172 -------- .../proc/mobject/session/defsmanagertest.cpp | 197 --------- .../mobject/session/defsregistryimpltest.cpp | 296 ------------- tests/lib/Makefile.am | 4 +- tests/lib/allocation-cluster-test.cpp | 234 +++++++++++ tests/lib/allocationclustertest.cpp | 236 ----------- tests/lib/scoped-holder-transfer-test.cpp | 391 +++++++++--------- ...cktest.cpp => singleton-testmock-test.cpp} | 0 tests/lib/typed-allocation-manager-test.cpp | 2 +- tests/lib/vector-transfer-test.cpp | 248 ++++++----- 39 files changed, 1732 insertions(+), 1741 deletions(-) rename src/lib/{allocationcluster.cpp => allocation-cluster.cpp} (99%) rename src/lib/{allocationcluster.hpp => allocation-cluster.hpp} (96%) rename src/lib/{singletonfactory.hpp => singleton-factory.hpp} (91%) create mode 100644 src/lib/singleton-policies.hpp rename src/lib/{singletonpreconfigure.hpp => singleton-preconfigure.hpp} (92%) delete mode 100644 src/lib/singletonpolicies.hpp rename src/proc/mobject/session/{defsmanager.cpp => defs-manager.cpp} (97%) create mode 100644 src/proc/mobject/session/defs-manager.hpp rename src/proc/mobject/session/{defsregistry.hpp => defs-registry.hpp} (64%) delete mode 100644 src/proc/mobject/session/defsmanager.hpp create mode 100644 tests/components/proc/mobject/session/defs-manager-impl-test.cpp create mode 100644 tests/components/proc/mobject/session/defs-manager-test.cpp create mode 100644 tests/components/proc/mobject/session/defs-registry-impl-test.cpp delete mode 100644 tests/components/proc/mobject/session/defsmanagerimpltest.cpp delete mode 100644 tests/components/proc/mobject/session/defsmanagertest.cpp delete mode 100644 tests/components/proc/mobject/session/defsregistryimpltest.cpp create mode 100644 tests/lib/allocation-cluster-test.cpp delete mode 100644 tests/lib/allocationclustertest.cpp rename tests/lib/{singletontestmocktest.cpp => singleton-testmock-test.cpp} (100%) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 74911c158..9837f7da3 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -35,7 +35,7 @@ liblumiera_la_LIBADD = \ liblumiera_la_SOURCES = \ $(liblumiera_la_srcdir)/advice/advice.cpp \ $(liblumiera_la_srcdir)/advice/binding.cpp \ - $(liblumiera_la_srcdir)/allocationcluster.cpp \ + $(liblumiera_la_srcdir)/allocation-cluster.cpp \ $(liblumiera_la_srcdir)/cmdline.cpp \ $(liblumiera_la_srcdir)/condition.c \ $(liblumiera_la_srcdir)/error.c \ @@ -69,8 +69,8 @@ noinst_HEADERS += \ $(liblumiera_la_srcdir)/advice.hpp \ $(liblumiera_la_srcdir)/advice/binding.hpp \ $(liblumiera_la_srcdir)/advice/index.hpp \ - $(liblumiera_la_srcdir)/allocationcluster.hpp \ - $(liblumiera_la_srcdir)/allocationcluster.hpp \ + $(liblumiera_la_srcdir)/allocation-cluster.hpp \ + $(liblumiera_la_srcdir)/allocation-cluster.hpp \ $(liblumiera_la_srcdir)/condition.h \ $(liblumiera_la_srcdir)/error.h \ $(liblumiera_la_srcdir)/error.hpp \ @@ -103,9 +103,9 @@ noinst_HEADERS += \ $(liblumiera_la_srcdir)/scoped-holder.hpp \ $(liblumiera_la_srcdir)/singleton-subclass.hpp \ $(liblumiera_la_srcdir)/singleton.hpp \ - $(liblumiera_la_srcdir)/singletonfactory.hpp \ - $(liblumiera_la_srcdir)/singletonpolicies.hpp \ - $(liblumiera_la_srcdir)/singletonpreconfigure.hpp \ + $(liblumiera_la_srcdir)/singleton-factory.hpp \ + $(liblumiera_la_srcdir)/singleton-policies.hpp \ + $(liblumiera_la_srcdir)/singleton-preconfigure.hpp \ $(liblumiera_la_srcdir)/sync-classlock.hpp \ $(liblumiera_la_srcdir)/sync.hpp \ $(liblumiera_la_srcdir)/sync.hpp \ diff --git a/src/lib/allocationcluster.cpp b/src/lib/allocation-cluster.cpp similarity index 99% rename from src/lib/allocationcluster.cpp rename to src/lib/allocation-cluster.cpp index 7e186ec93..605e15a5c 100644 --- a/src/lib/allocationcluster.cpp +++ b/src/lib/allocation-cluster.cpp @@ -21,7 +21,7 @@ * *****************************************************/ -#include "lib/allocationcluster.hpp" +#include "lib/allocation-cluster.hpp" #include "lib/error.hpp" #include "lib/util.hpp" #include "lib/sync.hpp" diff --git a/src/lib/allocationcluster.hpp b/src/lib/allocation-cluster.hpp similarity index 96% rename from src/lib/allocationcluster.hpp rename to src/lib/allocation-cluster.hpp index 638aa0564..12f9e9a9f 100644 --- a/src/lib/allocationcluster.hpp +++ b/src/lib/allocation-cluster.hpp @@ -1,5 +1,5 @@ /* - ALLOCATIONCLUSTER.hpp - allocating and owning a pile of objects + ALLOCATION-CLUSTER.hpp - allocating and owning a pile of objects Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -20,7 +20,7 @@ */ -/** @file allocationcluster.hpp +/** @file allocation-cluster.hpp ** Memory management for the low-level model (render nodes network). ** The model is organised into temporal segments, which are considered ** to be structurally constant and uniform. The objects within each @@ -35,17 +35,17 @@ ** templates, and thus need to be in the header. This way they can ** exploit the type information available in call context. This ** information is passed to generic implementation functions - ** defined in allocationcluster.cpp . In a similar vein, the + ** defined in allocation-cluster.cpp . In a similar vein, the ** AllocationCluster::MemoryManger is just forward declared. ** - ** @see allocationclustertest.cpp + ** @see allocation-cluster-test.cpp ** @see builder::ToolFactory ** @see frameid.hpp */ -#ifndef LIB_ALLOCATIONCLUSTER_H -#define LIB_ALLOCATIONCLUSTER_H +#ifndef LIB_ALLOCATION_CLUSTER_H +#define LIB_ALLOCATION_CLUSTER_H #include #include diff --git a/src/lib/singletonfactory.hpp b/src/lib/singleton-factory.hpp similarity index 91% rename from src/lib/singletonfactory.hpp rename to src/lib/singleton-factory.hpp index 65a6a3bd8..5f5070aa4 100644 --- a/src/lib/singletonfactory.hpp +++ b/src/lib/singleton-factory.hpp @@ -1,5 +1,5 @@ /* - SINGLETONFACTORY.hpp - template for implementing the singleton pattern + SINGLETON-FACTORY.hpp - template for implementing the singleton pattern Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -31,11 +31,11 @@ This code is heavily inspired by -#ifndef LIB_SINGLETONFACTORY_H -#define LIB_SINGLETONFACTORY_H +#ifndef LIB_SINGLETON_FACTORY_H +#define LIB_SINGLETON_FACTORY_H -#include "lib/singletonpolicies.hpp" // several Policies usable together with SingletonFactory +#include "lib/singleton-policies.hpp" // several Policies usable together with SingletonFactory #include "lib/nobug-init.hpp" #include "include/logging.h" @@ -45,9 +45,9 @@ This code is heavily inspired by namespace lib { /** - * A configurable Template for implementing Singletons. + * 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. + * 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 @@ -71,7 +71,7 @@ namespace lib { static PType pInstance_; static bool isDead_; - + public: /** Interface to be used by SingletonFactory's clients. @@ -84,7 +84,7 @@ namespace lib { if (!pInstance_) { ThreadLock guard SIDEEFFECT; - + if (!pInstance_) { if (isDead_) @@ -114,15 +114,15 @@ namespace lib { isDead_ = true; } }; - - // Storage for SingletonFactory's static fields... + + // Storage for SingletonFactory's static fields... template < class SI, template class C, template class L > - typename SingletonFactory::PType + typename SingletonFactory::PType SingletonFactory::pInstance_; template diff --git a/src/lib/singleton-policies.hpp b/src/lib/singleton-policies.hpp new file mode 100644 index 000000000..7c688c829 --- /dev/null +++ b/src/lib/singleton-policies.hpp @@ -0,0 +1,138 @@ +/* + 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 + This 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 placing the Singleton instance into a statically allocated buffer + */ + template + struct StaticCreate + { + 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 + struct HeapCreate + { + 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 + struct AutoDestroy + { + /** implements the Singleton removal by calling + * the provided deleter function(s) at application shutdown, + * relying on the runtime system calling 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) + { + class DeleteTrigger + { + vector dels_; + + public: + void schedule (DelFunc del) + { + dels_.push_back(del); + } + ~DeleteTrigger() + { + vector::iterator i = dels_.begin(); + for ( ; i != dels_.end(); ++i ) + (*i)(); // invoke deleter function + } + }; + + REQUIRE (kill_the_singleton); + static DeleteTrigger finally; + finally.schedule (kill_the_singleton); + } + + static void + onDeadReference () + { + throw lumiera::error::Logic ("Trying to access the a Singleton instance that has " + "already been released or finished its lifecycle."); + } + }; + + + + +}} // namespace lib::singleton +#endif diff --git a/src/lib/singletonpreconfigure.hpp b/src/lib/singleton-preconfigure.hpp similarity index 92% rename from src/lib/singletonpreconfigure.hpp rename to src/lib/singleton-preconfigure.hpp index b7c39fa83..5101c634e 100644 --- a/src/lib/singletonpreconfigure.hpp +++ b/src/lib/singleton-preconfigure.hpp @@ -1,5 +1,5 @@ /* - SINGLETONPRECONFIGURE - declare the configuration of some Singleton types in advance + SINGLETON-PRECONFIGURE - declare the configuration of some Singleton types in advance Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -20,7 +20,7 @@ */ -/** @file singletonpreconfigure.hpp +/** @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) @@ -37,12 +37,12 @@ ** @note we declare the specialisations into the target namespace ** ** @see SingletonFactory - ** @see singletontestmocktest.hpp + ** @see SingletonTestMock_test */ -#ifndef LIB_SINGLETONPRECONFIGURE_H -#define LIB_SINGLETONPRECONFIGURE_H +#ifndef LIB_SINGLETON_PRECONFIGURE_H +#define LIB_SINGLETON_PRECONFIGURE_H #include "lib/test/mockinjector.hpp" diff --git a/src/lib/singleton.hpp b/src/lib/singleton.hpp index d2f82bd9e..f7af5ddba 100644 --- a/src/lib/singleton.hpp +++ b/src/lib/singleton.hpp @@ -24,19 +24,19 @@ ** Factory for creating Singleton instances. ** This configuration header just pulls in some other implementation headers in ** the right order. The basic class template for creating singletons resides in - ** singletonfactory.hpp, besides we need policy classes defining how to create + ** 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 singletonfactory.hpp and the default - ** definition of type lumiera::singleton in singletonpreconfigure.hpp + ** You'll find the default Policies in singleton-factory.hpp and the default + ** definition of type lumiera::singleton in singleton-preconfigure.hpp ** ** @see SingletonFactory ** @see singleton::StaticCreate ** @see singleton::AutoDestroy ** @see singletontest.hpp - ** @see singletontestmocktest.hpp + ** @see SingletonTestMock_test */ @@ -44,9 +44,9 @@ #define LIB_SINGLETON_H -#include "lib/singletonpolicies.hpp" -#include "lib/singletonfactory.hpp" -#include "lib/singletonpreconfigure.hpp" +#include "lib/singleton-policies.hpp" +#include "lib/singleton-factory.hpp" +#include "lib/singleton-preconfigure.hpp" #endif diff --git a/src/lib/singletonpolicies.hpp b/src/lib/singletonpolicies.hpp deleted file mode 100644 index 49cb27223..000000000 --- a/src/lib/singletonpolicies.hpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - SINGLETONPOLICIES.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 - This 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_SINGLETONPOLICIES_H -#define LIB_SINGLETONPOLICIES_H - -#include "lib/nobug-init.hpp" -#include "lib/error.hpp" - -#include - - -namespace lib { - namespace singleton { - - - /* === several Policies usable in conjunction with lib::Singleton === */ - - /** - * Policy placing the Singleton instance into a statically allocated buffer - */ - template - struct StaticCreate - { - static S* create () - { -#ifdef DEBUG - 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 - struct HeapCreate - { - 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 - struct AutoDestroy - { - /** implements the Singleton removal by calling - * the provided deleter function(s) at application shutdown, - * relying on the runtime system calling 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) - { - class DeleteTrigger - { - vector dels_; - - public: - void schedule (DelFunc del) - { - dels_.push_back(del); - } - ~DeleteTrigger() - { - vector::iterator i = dels_.begin(); - for ( ; i != dels_.end(); ++i ) - (*i)(); // invoke deleter func - } - }; - - REQUIRE (kill_the_singleton); - static DeleteTrigger finally; - finally.schedule (kill_the_singleton); - } - - static void - onDeadReference () - { - throw lumiera::error::Logic ("Trying to access the a Singleton instance that has " - "already been released or finished its lifecycle."); - } - }; - - - - -}} // namespace lib::singleton -#endif diff --git a/src/lib/sync-classlock.hpp b/src/lib/sync-classlock.hpp index 350e0c615..60ffba9bd 100644 --- a/src/lib/sync-classlock.hpp +++ b/src/lib/sync-classlock.hpp @@ -29,7 +29,7 @@ ** ** @note simply using the ClassLock may cause a Monitor object (with a mutex) to be ** created at static initialisation and destroyed on application shutdown. - ** @see singletonfactory.hpp usage example + ** @see singleton-factory.hpp usage example */ diff --git a/src/lib/test/mockinjector.hpp b/src/lib/test/mockinjector.hpp index 32a647988..dbc47d3ed 100644 --- a/src/lib/test/mockinjector.hpp +++ b/src/lib/test/mockinjector.hpp @@ -26,7 +26,7 @@ #define LUMIERA_TEST_MOCKINJECTOR_H -#include "lib/singletonfactory.hpp" +#include "lib/singleton-factory.hpp" #include diff --git a/src/proc/Makefile.am b/src/proc/Makefile.am index d8e58f786..4d0cdc17f 100644 --- a/src/proc/Makefile.am +++ b/src/proc/Makefile.am @@ -155,7 +155,7 @@ liblumiprocmobjectsession_la_SOURCES = \ $(liblumiprocmobjectsession_la_srcdir)/clip.cpp \ $(liblumiprocmobjectsession_la_srcdir)/compoundclip.cpp \ $(liblumiprocmobjectsession_la_srcdir)/constraint.cpp \ - $(liblumiprocmobjectsession_la_srcdir)/defsmanager.cpp \ + $(liblumiprocmobjectsession_la_srcdir)/defs-manager.cpp \ $(liblumiprocmobjectsession_la_srcdir)/effect.cpp \ $(liblumiprocmobjectsession_la_srcdir)/fixedlocation.cpp \ $(liblumiprocmobjectsession_la_srcdir)/fixture.cpp \ @@ -237,8 +237,8 @@ noinst_HEADERS += \ $(liblumiproc_la_srcdir)/mobject/session/clip.hpp \ $(liblumiproc_la_srcdir)/mobject/session/compoundclip.hpp \ $(liblumiproc_la_srcdir)/mobject/session/constraint.hpp \ - $(liblumiproc_la_srcdir)/mobject/session/defsmanager.hpp \ - $(liblumiproc_la_srcdir)/mobject/session/defsregistry.hpp \ + $(liblumiproc_la_srcdir)/mobject/session/defs-manager.hpp \ + $(liblumiproc_la_srcdir)/mobject/session/defs-registry.hpp \ $(liblumiproc_la_srcdir)/mobject/session/effect.hpp \ $(liblumiproc_la_srcdir)/mobject/session/fixedlocation.hpp \ $(liblumiproc_la_srcdir)/mobject/session/fixture.hpp \ diff --git a/src/proc/engine/nodefactory.cpp b/src/proc/engine/nodefactory.cpp index 52aceb647..eb3ec1913 100644 --- a/src/proc/engine/nodefactory.cpp +++ b/src/proc/engine/nodefactory.cpp @@ -23,7 +23,7 @@ #include "proc/engine/nodefactory.hpp" #include "proc/mobject/session/effect.hpp" -#include "lib/allocationcluster.hpp" +#include "lib/allocation-cluster.hpp" #include "proc/engine/nodewiring.hpp" diff --git a/src/proc/engine/nodewiring.hpp b/src/proc/engine/nodewiring.hpp index 79a7cb0d1..9f263ab06 100644 --- a/src/proc/engine/nodewiring.hpp +++ b/src/proc/engine/nodewiring.hpp @@ -26,7 +26,7 @@ #include "proc/engine/procnode.hpp" -#include "lib/allocationcluster.hpp" +#include "lib/allocation-cluster.hpp" #include "proc/engine/nodewiring-def.hpp" //#include diff --git a/src/proc/mobject/session.hpp b/src/proc/mobject/session.hpp index b60821096..22dd59bdf 100644 --- a/src/proc/mobject/session.hpp +++ b/src/proc/mobject/session.hpp @@ -51,7 +51,7 @@ #include "proc/mobject/placement.hpp" #include "proc/mobject/mobject-ref.hpp" -#include "proc/mobject/session/defsmanager.hpp" ////////////////////////////TICKET #643 forward declare this? +#include "proc/mobject/session/defs-manager.hpp" ////////////////////////////TICKET #643 forward declare this? #include "lib/ref-array.hpp" #include "lib/singleton.hpp" #include "lib/symbol.hpp" diff --git a/src/proc/mobject/session/defsmanager.cpp b/src/proc/mobject/session/defs-manager.cpp similarity index 97% rename from src/proc/mobject/session/defsmanager.cpp rename to src/proc/mobject/session/defs-manager.cpp index 0c5c134b1..5dd350947 100644 --- a/src/proc/mobject/session/defsmanager.cpp +++ b/src/proc/mobject/session/defs-manager.cpp @@ -21,8 +21,8 @@ * *****************************************************/ -#include "proc/mobject/session/defsmanager.hpp" -#include "proc/mobject/session/defsregistry.hpp" +#include "proc/mobject/session/defs-manager.hpp" +#include "proc/mobject/session/defs-registry.hpp" #include "common/configrules.hpp" #include "lib/error.hpp" diff --git a/src/proc/mobject/session/defs-manager.hpp b/src/proc/mobject/session/defs-manager.hpp new file mode 100644 index 000000000..0fbcb1ab5 --- /dev/null +++ b/src/proc/mobject/session/defs-manager.hpp @@ -0,0 +1,128 @@ +/* + DEFS-MANAGER.hpp - access to preconfigured default objects and definitions + + 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. + +*/ + + +#ifndef MOBJECT_SESSION_DEFS_MANAGER_H +#define MOBJECT_SESSION_DEFS_MANAGER_H + + +#include "lib/p.hpp" +#include "lib/query.hpp" + +#include +#include + + + +namespace mobject { +namespace session { + + + using lumiera::P; + using boost::scoped_ptr; + + namespace impl { class DefsRegistry; } + + + /** + * Organise a collection of preconfigured default objects. + * For various kinds of objects we can tweak the default parametrisation + * as part of the general session configuration. A ref to an instance of + * this class is accessible through the current session and can be used + * to fill in parts of the configuration of new objects, if the user + * code didn't give more specific parameters. Necessary sub-objects + * will be created on demand, and any default configuration, once + * found, will be remembered and stored with the current session. + * + * @note while the logic of defaults handling can be considered + * roughly final, as of 12/09 most of the actual object + * handling is placeholder code. + */ + class DefsManager : private boost::noncopyable + { + scoped_ptr defsRegistry; + + public: + + DefsManager () throw(); + ~DefsManager (); + + /** common access point: retrieve the default object fulfilling + * some given conditions. May silently trigger object creation. + * @throw error::Config in case no solution is possible, which + * is considered \e misconfiguration. + */ + template + P operator() (lumiera::Query const&); + + + /** search through the registered defaults, never create anything. + * @return object fulfilling the query, \c empty ptr if not found. + */ + template + P search (lumiera::Query const&); + + /** retrieve an object fulfilling the query and register it as default. + * The resolution is delegated to the ConfigQuery system (which may cause + * creation of new object instances) + * @return object fulfilling the query, \c empty ptr if no solution. + */ + template + P create (lumiera::Query const&); + + /** register the given object as default, after ensuring it fulfils the + * query. The latter may cause some properties of the object to be set, + * trigger creation of additional objects, and may fail altogether. + * @return true if query was successful and object is registered as default + * @note only a weak ref to the object is stored + */ + template + bool define (P const&, lumiera::Query const& =lumiera::Query()); + + /** remove the defaults registration of the given object, if there was such + * @return false if nothing has been changed because the object wasn't registered + */ + template + bool forget (P const&); + + +// Q: can we have something along the line of...? +// +// template +// < class TAR, ///< the target to query for +// template class SMP ///< smart pointer class to wrap the result +// > +// SMP operator() (const lumiera::Query&); + +// 12/09: according to my current knowledge of template metaprogramming, the answer is "no", +// but we could use a traits template to set up a fixed association of smart pointers +// and kinds of target object. This would allow to define a templated operator() returning +// the result wrapped into the right holder. But currently I don't see how to build a sensible +// implementation infrastructure backing such an interface. +//////////TICKET #452 + + }; + + + +}} // namespace mobject::session +#endif diff --git a/src/proc/mobject/session/defsregistry.hpp b/src/proc/mobject/session/defs-registry.hpp similarity index 64% rename from src/proc/mobject/session/defsregistry.hpp rename to src/proc/mobject/session/defs-registry.hpp index 1ceabfc0a..a6fc169cb 100644 --- a/src/proc/mobject/session/defsregistry.hpp +++ b/src/proc/mobject/session/defs-registry.hpp @@ -1,5 +1,5 @@ /* - DEFSREGISTRY.hpp - implementation of the default object store + DEFS-REGISTRY.hpp - implementation of the default object store Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,23 +21,23 @@ */ -/** @file defsregistry.hpp +/** @file defs-registry.hpp ** A piece of implementation code factored out into a separate header (include). - ** Only used in defsmanager.cpp and for the unit tests. We can't place it into - ** a separate compilation unit, because defsmanager.cpp defines some explicit + ** Only used in defs-manager.cpp and for the unit tests. We can't place it into + ** a separate compilation unit, because defs-manager.cpp defines some explicit ** template instantiation, which cause the different Slots of the DefsrRegistry#table_ ** to be filled with data and defaults for the specific Types. ** ** @see mobject::session::DefsManager - ** @see defsregistryimpltest.cpp + ** @see DefsRegistryImpl_test ** */ -#ifndef MOBJECT_SESSION_DEFSREGISTRY_H -#define MOBJECT_SESSION_DEFSREGISTRY_H +#ifndef MOBJECT_SESSION_DEFS_REGISTRY_H +#define MOBJECT_SESSION_DEFS_REGISTRY_H #include "lib/sync-classlock.hpp" @@ -55,131 +55,131 @@ namespace mobject { - namespace session { +namespace session { + + using lumiera::P; + using lumiera::Query; + using lib::ClassLock; + using std::tr1::weak_ptr; + + using std::string; + using boost::format; + using boost::lambda::_1; + using boost::lambda::var; + + namespace impl { - using lumiera::P; - using lumiera::Query; - using lib::ClassLock; - using std::tr1::weak_ptr; + namespace { + uint maxSlots (0); ///< number of different registered Types + format dumpRecord ("%2i| %64s --> %s\n"); + } - using std::string; - using boost::format; - using boost::lambda::_1; - using boost::lambda::var; - namespace impl { - - namespace { - uint maxSlots (0); ///< number of different registered Types - format dumpRecord ("%2i| %64s --> %s\n"); - } - - - struct TableEntry - { - virtual ~TableEntry() {}; - }; - - /** we maintain an independent defaults registry - * for every participating kind of object. */ - typedef std::vector< P > Table; - - - /** - * holding a single "default object" entry - */ - template - struct Record - { - uint degree; - Query query; - weak_ptr objRef; - - Record (const Query& q, const P& obj) - : degree (lumiera::query::countPred (q)), - query (q), - objRef (obj) - { } - - - struct Search ///< Functor searching for a specific object - { - Search (const P& obj) - : obj_(obj) { } - - const P& obj_; - - bool - operator() (const Record& rec) - { - P storedObj (rec.objRef.lock()); - return storedObj && (storedObj == obj_); - } - }; - - struct OrderRelation - { - inline bool - operator() (Record one, Record two) ///< @note doesn't touch the objRef - { - return ( one.degree < two.degree - ||(one.degree == two.degree && one.query < two.query) - ); - } - }; + struct TableEntry + { + virtual ~TableEntry() {}; + }; + + /** we maintain an independent defaults registry + * for every participating kind of object. */ + typedef std::vector< P > Table; + + + /** + * holding a single "default object" entry + */ + template + struct Record + { + uint degree; + Query query; + weak_ptr objRef; + + Record (const Query& q, const P& obj) + : degree (lumiera::query::countPred (q)), + query (q), + objRef (obj) + { } + + + struct Search ///< Functor searching for a specific object + { + Search (const P& obj) + : obj_(obj) { } - operator string () const { return str (dumpRecord % degree % query % dumpObj()); } - string dumpObj () const { P o (objRef.lock()); return o? string(*o):"dead"; } - }; - - /** every new kind of object (Type) creates a new - * slot in the main Table holding all registered - * default objects. Each slot actually holds a - * separate tree (set) of registry entries - */ - template - struct Slot : public TableEntry - { - typedef typename Record::OrderRelation Ordering; - typedef std::set, Ordering> Registry; - - Registry registry; - static size_t index; ///< where to find this Slot in every Table - - static Registry& - access (Table& table) + const P& obj_; + + bool + operator() (const Record& rec) { - if ( !index - || index > table.size() - ||!table[index-1]) - createSlot (table); - - ASSERT (0 < index && index<=table.size() && table[index-1]); - Slot* item = static_cast (table[index-1].get()); - return item->registry; + P storedObj (rec.objRef.lock()); + return storedObj && (storedObj == obj_); } - - private: - static void - createSlot (Table& table) - { - ClassLock guard(); - if (!index) - index = ++maxSlots; - if (index > table.size()) - table.resize (index); - table[index-1].reset(new Slot); - } - }; + }; + struct OrderRelation + { + inline bool + operator() (Record one, Record two) ///< @note doesn't touch the objRef + { + return ( one.degree < two.degree + ||(one.degree == two.degree && one.query < two.query) + ); + } + }; - // static vars to organise one Table Slot per type.... - template - size_t Slot::index (0); - - + operator string () const { return str (dumpRecord % degree % query % dumpObj()); } + string dumpObj () const { P o (objRef.lock()); return o? string(*o):"dead"; } + }; + + /** every new kind of object (Type) creates a new + * slot in the main Table holding all registered + * default objects. Each slot actually holds a + * separate tree (set) of registry entries + */ + template + struct Slot : public TableEntry + { + typedef typename Record::OrderRelation Ordering; + typedef std::set, Ordering> Registry; + + Registry registry; + static size_t index; ///< where to find this Slot in every Table + + static Registry& + access (Table& table) + { + if ( !index + || index > table.size() + ||!table[index-1]) + createSlot (table); + + ASSERT (0 < index && index<=table.size() && table[index-1]); + Slot* item = static_cast (table[index-1].get()); + return item->registry; + } + + private: + static void + createSlot (Table& table) + { + ClassLock guard(); + if (!index) + index = ++maxSlots; + if (index > table.size()) + table.resize (index); + table[index-1].reset(new Slot); + } + }; + // static vars to organise one Table Slot per type.... + template + size_t Slot::index (0); + + + + /** * @internal Helper for organising preconfigured default objects. * Maintains a collection of objects known or encountered as "default" @@ -235,8 +235,8 @@ namespace mobject { public: P operator* () { return ptr; } bool hasNext () { return next || findNext(); } - Iter operator++ (int) { Iter tmp=*this; operator++(); return tmp; } - Iter& operator++ () + Iter operator++ (int) { Iter tmp=*this; operator++(); return tmp; } + Iter& operator++ () { ptr=findNext(); next.reset(); @@ -332,16 +332,13 @@ namespace mobject { return res; } }; - - - - } // (End) impl namespace - - using impl::DefsRegistry; - } // namespace mobject::session - -} // namespace mobject - + + } // (End) impl namespace + + using impl::DefsRegistry; + + +}} // namespace mobject::session #endif diff --git a/src/proc/mobject/session/defsmanager.hpp b/src/proc/mobject/session/defsmanager.hpp deleted file mode 100644 index 7d904b6b8..000000000 --- a/src/proc/mobject/session/defsmanager.hpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - DEFSMANAGER.hpp - access to preconfigured default objects and definitions - - 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. - -*/ - - -#ifndef MOBJECT_SESSION_DEFSMANAGER_H -#define MOBJECT_SESSION_DEFSMANAGER_H - - -#include "lib/p.hpp" -#include "lib/query.hpp" - -#include -#include - - - -namespace mobject { - namespace session { - - - using lumiera::P; - using boost::scoped_ptr; - - namespace impl { class DefsRegistry; } - - - /** - * Organise a collection of preconfigured default objects. - * For various kinds of objects we can tweak the default parametrisation - * as part of the general session configuration. A ref to an instance of - * this class is accessible through the current session and can be used - * to fill in parts of the configuration of new objects, if the user - * code didn't give more specific parameters. Necessary sub-objects - * will be created on demand, and any default configuration, once - * found, will be remembered and stored with the current session. - * - * @note while the logic of defaults handling can be considered - * roughly final, as of 12/09 most of the actual object - * handling is placeholder code. - */ - class DefsManager : private boost::noncopyable - { - scoped_ptr defsRegistry; - - public: - - DefsManager () throw(); - ~DefsManager (); - - /** common access point: retrieve the default object fulfilling - * some given conditions. May silently trigger object creation. - * @throw error::Config in case no solution is possible, which - * is considered \e misconfiguration. - */ - template - P operator() (lumiera::Query const&); - - - /** search through the registered defaults, never create anything. - * @return object fulfilling the query, \c empty ptr if not found. - */ - template - P search (lumiera::Query const&); - - /** retrieve an object fulfilling the query and register it as default. - * The resolution is delegated to the ConfigQuery system (which may cause - * creation of new object instances) - * @return object fulfilling the query, \c empty ptr if no solution. - */ - template - P create (lumiera::Query const&); - - /** register the given object as default, after ensuring it fulfils the - * query. The latter may cause some properties of the object to be set, - * trigger creation of additional objects, and may fail altogether. - * @return true if query was successful and object is registered as default - * @note only a weak ref to the object is stored - */ - template - bool define (P const&, lumiera::Query const& =lumiera::Query()); - - /** remove the defaults registration of the given object, if there was such - * @return false if nothing has been changed because the object wasn't registered - */ - template - bool forget (P const&); - - -// Q: can we have something along the line of...? -// -// template -// < class TAR, ///< the target to query for -// template class SMP ///< smart pointer class to wrap the result -// > -// SMP operator() (const lumiera::Query&); - -// 12/09: according to my current knowledge of template metaprogramming, the answer is "no", -// but we could use a traits template to set up a fixed association of smart pointers -// and kinds of target object. This would allow to define a templated operator() returning -// the result wrapped into the right holder. But currently I don't see how to build a sensible -// implementation infrastructure backing such an interface. -//////////TICKET #452 - - }; - - - - } // namespace mobject::session - -} // namespace mobject -#endif diff --git a/src/proc/mobject/session/root.cpp b/src/proc/mobject/session/root.cpp index d3133c2da..5b6aa6290 100644 --- a/src/proc/mobject/session/root.cpp +++ b/src/proc/mobject/session/root.cpp @@ -22,7 +22,7 @@ #include "proc/mobject/session/root.hpp" -#include "proc/mobject/session/defsmanager.hpp" +#include "proc/mobject/session/defs-manager.hpp" namespace mobject { diff --git a/src/proc/mobject/session/sess-manager-impl.cpp b/src/proc/mobject/session/sess-manager-impl.cpp index 0c9d1b5bc..d0e4c4cc4 100644 --- a/src/proc/mobject/session/sess-manager-impl.cpp +++ b/src/proc/mobject/session/sess-manager-impl.cpp @@ -40,7 +40,7 @@ #include "proc/mobject/session.hpp" #include "proc/mobject/session/sess-manager-impl.hpp" -#include "proc/mobject/session/defsmanager.hpp" +#include "proc/mobject/session/defs-manager.hpp" #include "proc/mobject/session/lifecycle-advisor.hpp" #include "proc/asset/timeline.hpp" #include "lib/error.hpp" diff --git a/src/proc/mobject/session/session-interface-modules.hpp b/src/proc/mobject/session/session-interface-modules.hpp index 9e03cad4c..daa05b18f 100644 --- a/src/proc/mobject/session/session-interface-modules.hpp +++ b/src/proc/mobject/session/session-interface-modules.hpp @@ -73,7 +73,7 @@ #include "lib/element-tracker.hpp" #include "proc/asset/timeline.hpp" #include "proc/asset/sequence.hpp" -#include "proc/mobject/session/defsmanager.hpp" +#include "proc/mobject/session/defs-manager.hpp" #include "proc/mobject/session/element-query.hpp" diff --git a/src/proc/mobject/session/session.cpp b/src/proc/mobject/session/session.cpp index a1ff4c737..891ba1349 100644 --- a/src/proc/mobject/session/session.cpp +++ b/src/proc/mobject/session/session.cpp @@ -32,7 +32,7 @@ #include "proc/mobject/session.hpp" -#include "proc/mobject/session/defsmanager.hpp" +#include "proc/mobject/session/defs-manager.hpp" #include "proc/mobject/session/session-impl.hpp" #include "proc/mobject/session/sess-manager-impl.hpp" diff --git a/tests/components/Makefile.am b/tests/components/Makefile.am index 84a87d88a..2de68311a 100644 --- a/tests/components/Makefile.am +++ b/tests/components/Makefile.am @@ -85,9 +85,9 @@ test_components_SOURCES = \ $(testcomponents_srcdir)/proc/mobject/placement-object-identity-test.cpp \ $(testcomponents_srcdir)/proc/mobject/placement-ref-test.cpp \ $(testcomponents_srcdir)/proc/mobject/session/addcliptest.cpp \ - $(testcomponents_srcdir)/proc/mobject/session/defsmanagerimpltest.cpp \ - $(testcomponents_srcdir)/proc/mobject/session/defsmanagertest.cpp \ - $(testcomponents_srcdir)/proc/mobject/session/defsregistryimpltest.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/defs-manager-impl-test.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/defs-manager-test.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/defs-registry-impl-test.cpp \ $(testcomponents_srcdir)/proc/mobject/session/deletecliptest.cpp \ $(testcomponents_srcdir)/proc/mobject/session/placement-index-query-test.cpp \ $(testcomponents_srcdir)/proc/mobject/session/placement-index-test.cpp \ diff --git a/tests/components/proc/control/command-use1-test.cpp b/tests/components/proc/control/command-use1-test.cpp index aae370d4f..949fcfffd 100644 --- a/tests/components/proc/control/command-use1-test.cpp +++ b/tests/components/proc/control/command-use1-test.cpp @@ -127,7 +127,7 @@ namespace test { CHECK ( 0 == command1::check_); VERIFY_ERROR (INVALID_ARGUMENTS, com.bind ("foo") ); - com.bind (random()); // note: run-time type check only + com.bind (random()); // note: run-time type check only CHECK ( com.canExec()); CHECK (!com.canUndo()); com(); @@ -159,7 +159,7 @@ namespace test { def.operation (command1::operate) .captureUndo (command1::capture); - CHECK (!def); // undo functor still missing + CHECK (!def); // undo functor still missing VERIFY_ERROR (INVALID_COMMAND, Command::get("test.command1.2") ); def.operation (command1::operate) diff --git a/tests/components/proc/engine/node-basic-test.cpp b/tests/components/proc/engine/node-basic-test.cpp index 7cd47d650..8e973cc1a 100644 --- a/tests/components/proc/engine/node-basic-test.cpp +++ b/tests/components/proc/engine/node-basic-test.cpp @@ -28,7 +28,7 @@ #include "proc/engine/stateproxy.hpp" #include "proc/engine/buffhandle.hpp" #include "proc/mobject/session/effect.hpp" -#include "lib/allocationcluster.hpp" +#include "lib/allocation-cluster.hpp" //#include //#include diff --git a/tests/components/proc/mobject/placement-basic-test.cpp b/tests/components/proc/mobject/placement-basic-test.cpp index 44a79b6e8..150907b62 100644 --- a/tests/components/proc/mobject/placement-basic-test.cpp +++ b/tests/components/proc/mobject/placement-basic-test.cpp @@ -30,10 +30,8 @@ #include "lib/util.hpp" #include "proc/mobject/session/mobjectfactory.hpp" ////TODO: avoidable? -//#include #include -//using boost::format; using lumiera::Time; using util::contains; using std::string; @@ -41,61 +39,57 @@ using std::cout; namespace mobject { - namespace session { - namespace test { - - using asset::VIDEO; - - - - /******************************************************************* - * @test basic behaviour of Placements and access to MObjects. - * @see mobject::Placement - * @see mobject::MObject#create - * @see mobject::Placement#addPlacement - * @see mobject::Placement#resolve - */ - class PlacementBasic_test : public Test +namespace session { +namespace test { + + using asset::VIDEO; + + + + /******************************************************************* + * @test basic behaviour of Placements and access to MObjects. + * @see mobject::Placement + * @see mobject::MObject#create + * @see mobject::Placement#addPlacement + * @see mobject::Placement#resolve + */ + class PlacementBasic_test : public Test + { + typedef shared_ptr PM; + typedef shared_ptr PCA; + + virtual void + run (Arg) { - typedef shared_ptr PM; - typedef shared_ptr PCA; - - virtual void - run (Arg) - { - // create Clip-MObject, which is wrapped into a placement (smart ptr) - PM media = asset::Media::create("test-1", VIDEO); - PCA clipAsset = Media::create(*media); - Placement pc = MObject::create (*clipAsset, *media); - - // use of the Clip-MObject interface by dereferencing the placement - PM clip_media = pc->getMedia(); - CHECK (clip_media->ident.category.hasKind (VIDEO)); - - // using the Placement interface - // TODO: how to handle insufficiently determinated Placement? Throw? - FixedLocation & fixloc = pc.chain(Time(1)); // TODO: the track?? - ExplicitPlacement expla = pc.resolve(); - CHECK (expla.time == Time(1)); - CHECK (!expla.chain.isOverdetermined()); + // create Clip-MObject, which is wrapped into a placement (smart ptr) + PM media = asset::Media::create("test-1", VIDEO); + PCA clipAsset = Media::create(*media); + Placement pc = MObject::create (*clipAsset, *media); + + // use of the Clip-MObject interface by dereferencing the placement + PM clip_media = pc->getMedia(); + CHECK (clip_media->ident.category.hasKind (VIDEO)); + + // using the Placement interface + // TODO: how to handle insufficiently determinated Placement? Throw? + FixedLocation & fixloc = pc.chain(Time(1)); // TODO: the track?? + ExplicitPlacement expla = pc.resolve(); + CHECK (expla.time == Time(1)); + CHECK (!expla.chain.isOverdetermined()); // CHECK (*expla == *pc); ////////////////////////////////////////////TICKET #511 define equivalence of locating chains and solutions - - // now overconstraining with another Placement - pc.chain(Time(2)); - ExplicitPlacement expla2 = pc.resolve(); - CHECK (expla2.time == Time(2)); // the latest addition wins - CHECK (expla2.chain.isOverdetermined()); - } - }; - - - /** Register this test class... */ - LAUNCHER (PlacementBasic_test, "unit session"); - - - - } // namespace test - - } // namespace session - -} // namespace mobject + + // now overconstraining with another Placement + pc.chain(Time(2)); + ExplicitPlacement expla2 = pc.resolve(); + CHECK (expla2.time == Time(2)); // the latest addition wins + CHECK (expla2.chain.isOverdetermined()); + } + }; + + + /** Register this test class... */ + LAUNCHER (PlacementBasic_test, "unit session"); + + + +}}} // namespace mobject::session::test diff --git a/tests/components/proc/mobject/session/defs-manager-impl-test.cpp b/tests/components/proc/mobject/session/defs-manager-impl-test.cpp new file mode 100644 index 000000000..f3cc8d5e0 --- /dev/null +++ b/tests/components/proc/mobject/session/defs-manager-impl-test.cpp @@ -0,0 +1,176 @@ +/* + DefsManagerImpl(Test) - checking implementation details of the defaults manager + + 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. + +* *****************************************************/ + + +#include "pre_a.hpp" + +#include "lib/test/run.hpp" +#include "lib/util.hpp" + +#include "proc/asset.hpp" +#include "proc/asset/pipe.hpp" +#include "proc/asset/struct.hpp" +#include "common/configrules.hpp" +#include "proc/assetmanager.hpp" +#include "proc/mobject/session.hpp" +#include "lib/streamtype.hpp" + +#include + +using boost::format; +using util::isnil; +using std::string; + + +namespace mobject { +namespace session { +namespace test { + + using lib::Symbol; + using asset::Asset; + using asset::AssetManager; + using asset::Pipe; + using asset::PPipe; + using asset::Struct; + using lumiera::Query; + using lumiera::query::normaliseID; + + using lumiera::ConfigRules; + using lumiera::query::QueryHandler; + using lumiera::StreamType; + + + + /** shortcut: query for given Pipe-ID */ + bool + find (const string& pID) + { + return Session::current->defaults.search (Query ("pipe("+pID+")")); + } + + + format pattern ("dummy_%s_%i"); + + /** create a random new ID */ + string + newID (Symbol prefix) + { + return str (pattern % prefix % std::rand()); + } + + + + + /************************************************************************ + * @test verify some general assumptions regarding implementation details + * of the the defaults manager. + * @see DefsManager_test for the "big picture" + */ + class DefsManagerImpl_test : public Test + { + virtual void + run(Arg) + { + define_and_search(); + string pipeID = create(); + forget(pipeID); + } + + + + + void + define_and_search () + { + string sID = newID ("stream"); + StreamType::ID stID (sID); + + // create Pipes explicitly + // (without utilising default queries) + PPipe pipe1 = Struct::retrieve.newPipe (newID("pipe"), newID("stream")); + PPipe pipe2 = Struct::retrieve.newPipe (newID("pipe"), sID ); + + CHECK (pipe1 != pipe2); + CHECK (stID == pipe2->getStreamID()); + + CHECK (!find (pipe1->getPipeID()), "accidental clash of random test-IDs"); + CHECK (!find (pipe2->getPipeID()), "accidental clash of random test-IDs"); + + // now declare that these objects should be considered "default" +lumiera::query::setFakeBypass(""); /////////////////////////////////////////////////TODO mock resolution + CHECK (Session::current->defaults.define (pipe1, Query (""))); // unrestricted default + +lumiera::query::setFakeBypass("stream("+sID+")"); ///////////////////////////////////TODO mock resolution + CHECK (Session::current->defaults.define (pipe2, Query ("stream("+sID+")"))); + + CHECK ( find (pipe1->getPipeID()), "failure declaring object as default"); + CHECK ( find (pipe2->getPipeID()), "failure declaring object as default"); + + CHECK (stID != pipe1->getStreamID(), "accidental clash"); + CHECK (!Session::current->defaults.define (pipe1, Query ("stream("+sID+")"))); + // can't be registered with this query, due to failure caused by wrong stream-ID + } + + + const string& + create() + { + string sID = newID ("stream"); + Query query_for_streamID ("stream("+sID+")"); + + // issue a ConfigQuery directly, without involving the DefaultsManager + QueryHandler& typeHandler = ConfigRules::instance(); + PPipe pipe1; + typeHandler.resolve (pipe1, query_for_streamID); + CHECK (pipe1); + + CHECK (!find (pipe1->getPipeID())); + PPipe pipe2 = Session::current->defaults.create (query_for_streamID); + CHECK (pipe2); + CHECK (pipe2 == pipe1); + CHECK ( find (pipe1->getPipeID())); // now declared as "default Pipe" for this stream-ID + + return pipe1->getPipeID(); + } + + + void + forget (string pID) + { + PPipe pipe = Pipe::query ("pipe("+pID+")"); + REQUIRE (find (pipe->getPipeID()), "need an object registered as default"); + long cnt = pipe.use_count(); + + // now de-register the pipe as "default Pipe" + CHECK (Session::current->defaults.forget (pipe)); + CHECK (!find (pipe->getPipeID())); + CHECK (cnt == pipe.use_count()); // indicates DefaultsManager holding only a weak ref. + } + }; + + + /** Register this test class... */ + LAUNCHER (DefsManagerImpl_test, "function session"); + + + +}}} // namespace mobject::session::test diff --git a/tests/components/proc/mobject/session/defs-manager-test.cpp b/tests/components/proc/mobject/session/defs-manager-test.cpp new file mode 100644 index 000000000..3f9ae390e --- /dev/null +++ b/tests/components/proc/mobject/session/defs-manager-test.cpp @@ -0,0 +1,204 @@ +/* + DefsManager(Test) - checking basic behaviour of the defaults manager + + 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. + +* *****************************************************/ + + +#include "pre_a.hpp" + +#include "lib/test/run.hpp" +#include "lib/symbol.hpp" +#include "lib/query.hpp" +#include "lib/util.hpp" + +#include "proc/asset.hpp" +#include "proc/asset/pipe.hpp" +#include "proc/asset/struct.hpp" +#include "proc/assetmanager.hpp" +#include "proc/mobject/session.hpp" +#include "lib/streamtype.hpp" + +#include + +using boost::format; +using util::isnil; +using std::string; + + + +namespace mobject { +namespace session { +namespace test { + + using util::cStr; + using lib::Symbol; + using asset::ID; + using asset::Asset; + using asset::AssetManager; + using asset::Pipe; + using asset::PPipe; + using asset::Struct; + using lumiera::Query; + using lumiera::query::normaliseID; + using lumiera::StreamType; + + + /** shortcut: run just a query + * without creating new instances + */ + bool + find (Query& q) + { + return Session::current->defaults.search (q); + } + + + + + /*********************************************************************** + * @test basic behaviour of the defaults manager ("the big picture") + * - retrieving a "default" object repeatedly + * - retrieving a more constrained "default" object + * - failure registers a new "default" + * - instance management + * + * Using pipe assets as an example. The defaults manager shouldn't + * interfere with memory management (it holds weak refs). + */ + class DefsManager_test : public Test + { + virtual void + run (Arg arg) + { + string pipeID = isnil(arg)? "Black Hole" : arg[1]; + string streamID = 2>arg.size()? "teststream" : arg[2]; + + normaliseID (pipeID); + normaliseID (streamID); + + retrieveSimpleDefault (pipeID); + retrieveConstrainedDefault (pipeID, streamID); + failureCreatesNewDefault(); + verifyRemoval(); + } + + + + + void + retrieveSimpleDefault (string) + { + PPipe pipe1 = Pipe::query (""); // "the default pipe" + PPipe pipe2; + + // several variants to query for "the default pipe" + pipe2 = Pipe::query (""); + CHECK (pipe2 == pipe1); + pipe2 = Pipe::query ("default(X)"); + CHECK (pipe2 == pipe1); + pipe2 = Session::current->defaults(Query ()); + CHECK (pipe2 == pipe1); + pipe2 = asset::Struct::retrieve (Query ()); + CHECK (pipe2 == pipe1); + pipe2 = asset::Struct::retrieve (Query ("default(P)")); + CHECK (pipe2 == pipe1); + } + + + void + retrieveConstrainedDefault (string pID, string sID) + { + PPipe pipe1 = Pipe::query (""); // "the default pipe" + CHECK ( pipe1->getStreamID() != StreamType::ID(sID), + "stream-ID \"%s\" not suitable for test, because " + "the default-pipe \"%s\" happens to have the same " + "stream-ID. We need it to be different", + sID.c_str(), pID.c_str() + ); + + string query_for_sID ("stream("+sID+")"); + PPipe pipe2 = Pipe::query (query_for_sID); + CHECK (pipe2->getStreamID() == StreamType::ID(sID)); + CHECK (pipe2 != pipe1); + CHECK (pipe2 == Pipe::query (query_for_sID)); // reproducible + } + + + void + failureCreatesNewDefault() + { + PPipe pipe1 = Session::current->defaults(Query ()); // "the default pipe" + + string new_pID (str (format ("dummy_%s_%i") + % pipe1->getPipeID() + % std::rand() + )); // make random new pipeID + Query query_for_new ("pipe("+new_pID+")"); + + CHECK (!find (query_for_new)); // check it doesn't exist + PPipe pipe2 = Session::current->defaults (query_for_new); // triggers creation + CHECK ( find (query_for_new)); // check it exists now + + CHECK (pipe1 != pipe2); + CHECK (pipe2 == Session::current->defaults (query_for_new)); + } + + + /** verify the defaults manager holds only weak refs, + * so if an object goes out of scope, any defaults entries + * are purged silently + */ + void + verifyRemoval() + { + Symbol pID ("some_pipe"); + Query query_for_pID ("pipe("+pID+")"); + size_t hash; + { + // create new pipe and declare it to be a default + PPipe pipe1 = Struct::retrieve.newInstance (pID); + Session::current->defaults.define(pipe1); + + CHECK (2 == pipe1.use_count()); // the pipe1 smart-ptr and the AssetManager + hash = pipe1->getID(); + } + // pipe1 out of scope.... + // AssetManager now should hold the only ref + ID assetID (hash); + + AssetManager& aMang (AssetManager::instance()); + CHECK ( aMang.known (assetID)); + aMang.remove (assetID); + CHECK (!aMang.known (assetID)); + + + CHECK (!find(query_for_pID)); // bare default-query should fail... + PPipe pipe2 = Session::current->defaults (query_for_pID); // triggers re-creation + CHECK ( find(query_for_pID)); // should succeed again + } + }; + + + + /** Register this test class... */ + LAUNCHER (DefsManager_test, "function session"); + + +}}} // namespace mobject::session::test diff --git a/tests/components/proc/mobject/session/defs-registry-impl-test.cpp b/tests/components/proc/mobject/session/defs-registry-impl-test.cpp new file mode 100644 index 000000000..8025bfbf0 --- /dev/null +++ b/tests/components/proc/mobject/session/defs-registry-impl-test.cpp @@ -0,0 +1,292 @@ +/* + DefsRegistryImpl(Test) - verifying correct behaviour of the defaults registry + + 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. + +* *****************************************************/ + + +#include "lib/test/run.hpp" +#include "lib/util.hpp" + +#include "proc/mobject/session/defs-registry.hpp" +#include "lib/factory.hpp" +#include "lib/query.hpp" +#include "lib/p.hpp" + +#include "../lib/query/querydiagnostics.hpp" + +#include +#include +#include + +using lumiera::P; +using lumiera::Query; +using lumiera::query::test::garbage_query; +using util::isnil; + +using boost::scoped_ptr; +using boost::format; +using std::string; +using std::rand; +using std::map; + + + +namespace mobject { +namespace session { +namespace test { + + format typePatt ("Dummy<%2i>"); + format instancePatt ("obj_%s_%i"); + format predicatePatt ("%s_%2i( %s )"); + + + + /** create a random new ID */ + string + newID (string prefix) + { + return str (instancePatt % prefix % rand()); + } + + + /** template for generating some different test types */ + template + struct Dummy + { + static string name; + string instanceID; + operator string () const { return instanceID; } + bool operator== (const Dummy& odu) const { return this == &odu; } + + + Dummy () : instanceID (newID (name)) {} + }; + + template + string Dummy::name = str (typePatt % I); + + + + + + + /************************************************************************ + * @test build an registry table (just for this test) configured for + * some artificial test Types. Register some entries and verify + * the intended behaviour of the storage structure. + * @see DefsManagerImpl_test for checking the implementation details + * in the actual context used in Lumiera. + */ + class DefsRegistryImpl_test : public Test + { + scoped_ptr reg_; + + typedef lumiera::P > O; + typedef lumiera::P > P; + + typedef Query > Q13; + typedef Query > Q23; + + typedef DefsRegistry::Iter > Iter13; + typedef DefsRegistry::Iter > Iter23; + + + // fabricating Objects wrapped into smart-ptrs + lib::factory::RefcountFac > oFac; + lib::factory::RefcountFac > pFac; + + O o1, o2, o3; + Q13 q1, q2, q3, q4, q5; + map ps; + + public: + DefsRegistryImpl_test () + : o1 (oFac()), o2 (oFac()), o3 (oFac()), + q1 (garbage_query (1)), + q2 (garbage_query (2)), + q3 (garbage_query (3)), + q4 (garbage_query (4)), + q5 (garbage_query (5)) + { } + + + virtual void + run (Arg) + { + this->reg_.reset (new DefsRegistry); + + fill_table (); + check_query (); + check_remove (); + } + + + + + void + fill_table () + { + // at start the registry is indeed empty + // thus a query doesn't yield any results.... + CHECK ( ! *(reg_->candidates(Q13 ("something"))) ); + + reg_->put (o1, q5); + reg_->put (o2, q4); + reg_->put (o3, q3); + reg_->put (o3, q2); + reg_->put (o2, q1); + reg_->put (o1, Q13()); // the empty query + + ps.clear(); + for (int i=0; i<100; ++i) + { + P px (pFac()); + Q23 qx (garbage_query()); + ps[qx] = px; + reg_->put (px, qx); + px->instanceID = qx; + } + } + + + void + check_query () + { + Iter13 i (reg_->candidates(Q13 ("irrelevant query"))); + CHECK ( i.hasNext()); + CHECK ( *i++ == o1); // ordered according to the degree of the queries + CHECK ( *i++ == o2); + CHECK ( *i++ == o3); + CHECK ( *i++ == o3); + CHECK ( *i++ == o2); + CHECK ( *i == o1); + CHECK (!i.hasNext()); + CHECK (! *++i ); // null after end + + i = reg_->candidates(q3); + CHECK ( *i++ == o3); // found by direct match + CHECK ( *i++ == o1); // followed by the ordered enumeration + CHECK ( *i++ == o2); + CHECK ( *i++ == o3); + CHECK ( *i++ == o3); + CHECK ( *i++ == o2); + CHECK ( *i++ == o1); + CHECK (!i.hasNext()); + + i = reg_->candidates(Q13()); + CHECK ( *i++ == o1); // found by direct match to the empty query + CHECK ( *i++ == o1); + CHECK ( *i++ == o2); + CHECK ( *i++ == o3); + CHECK ( *i++ == o3); + CHECK ( *i++ == o2); + CHECK ( *i++ == o1); + CHECK (!i.hasNext()); + + uint d=0; + uint d_prev=0; + Iter23 j = reg_->candidates(Q23 ("some crap")); + for ( ; *j ; ++j ) + { + CHECK ( *j ); + Q23 qx ((*j)->instanceID); + CHECK ( ps[qx] == (*j)); + d = lumiera::query::countPred (qx); + CHECK ( d_prev <= d ); + d_prev = d; + } + CHECK (!j.hasNext()); + + // calling with an arbitrary (registered) query + // yields the corresponding object at start of the enumeration + j = reg_->candidates(ps.begin()->first); + CHECK ( *j == ps.begin()->second); + + } + + + void + check_remove () + { + reg_->forget (o2); + + Iter13 i (reg_->candidates(q4)); + CHECK ( i.hasNext()); + CHECK ( *i++ == o1); // ordered according to the degree of the queries + // but the o2 entries are missing + CHECK ( *i++ == o3); + CHECK ( *i++ == o3); + // missing + CHECK ( *i == o1); + CHECK (!i.hasNext()); + + o3.reset(); // killing the only reference.... + // expires the weak ref in the registry + + i = reg_->candidates(Q13 ("something")); + CHECK ( i.hasNext()); + CHECK ( *i++ == o1); // ordered according to the degree of the queries + // but now also the o3 entries are missing... + CHECK ( *i == o1); + CHECK (!i.hasNext()); + + CHECK ( reg_->put (o1, q5)); // trying to register the same object at the same place + // doesn't change anything (but counts as "success") + i = reg_->candidates(q5); + CHECK ( *i++ == o1); // direct match + CHECK ( *i++ == o1); + CHECK ( *i++ == o1); + CHECK (!i.hasNext()); + + CHECK (!reg_->put (o2, q5)); // trying to (re)register o2 with a existing query + // counts as failure (nothing changes) + i = reg_->candidates(q5); + CHECK ( *i++ == o1); // direct match + CHECK ( *i++ == o1); + CHECK ( *i++ == o1); + CHECK (!i.hasNext()); + + CHECK ( reg_->put (o2, q2)); // trying to (re)register o2 with another query succeeds + i = reg_->candidates(q2); + CHECK ( *i++ == o2); // direct match + CHECK ( *i++ == o1); + CHECK ( *i++ == o2); // inserted here in the dataset + CHECK ( *i++ == o1); + CHECK (!i.hasNext()); + + CHECK ( reg_->forget (o1)); + CHECK (!reg_->forget (o1)); // failure, because it's already removed + CHECK ( reg_->forget (o2)); + + o3 = oFac(); // another object is another object (it's irrelevant...) + + i = reg_->candidates(q2); + CHECK (! (*i)); // empty + } + + }; + + + /** Register this test class... */ + LAUNCHER (DefsRegistryImpl_test, "function session"); + + + +}}} // namespace mobject::session::test diff --git a/tests/components/proc/mobject/session/defsmanagerimpltest.cpp b/tests/components/proc/mobject/session/defsmanagerimpltest.cpp deleted file mode 100644 index 164dc9b9a..000000000 --- a/tests/components/proc/mobject/session/defsmanagerimpltest.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - DefsManagerImpl(Test) - checking implementation details of the defaults manager - - 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. - -* *****************************************************/ - - -#include "pre_a.hpp" - -#include "lib/test/run.hpp" -#include "lib/util.hpp" - -#include "proc/asset.hpp" -#include "proc/asset/pipe.hpp" -#include "common/configrules.hpp" -#include "proc/assetmanager.hpp" -#include "proc/mobject/session.hpp" -#include "lib/streamtype.hpp" - -#include - -using boost::format; -using util::isnil; -using std::string; - - -namespace asset { - namespace test { - - using mobject::Session; - using lib::Symbol; - using lumiera::Query; - using lumiera::query::normaliseID; - - using lumiera::ConfigRules; - using lumiera::query::QueryHandler; - using lumiera::StreamType; - - - - /** shortcut: query for given Pipe-ID */ - bool - find (const string& pID) - { - return Session::current->defaults.search (Query ("pipe("+pID+")")); - } - - - format pattern ("dummy_%s_%i"); - - /** create a random new ID */ - string - newID (Symbol prefix) - { - return str (pattern % prefix % std::rand()); - } - - - - - /************************************************************************ - * @test verify some general assumptions regarding implementation details - * of the the defaults manager. - * @see DefsManager_test for the "big picture" - */ - class DefsManagerImpl_test : public Test - { - virtual void - run(Arg) - { - define_and_search(); - string pipeID = create(); - forget(pipeID); - } - - - - - void - define_and_search () - { - string sID = newID ("stream"); - StreamType::ID stID (sID); - - // create Pipes explicitly - // (without utilising default queries) - PPipe pipe1 = Struct::retrieve.newPipe (newID("pipe"), newID("stream")); - PPipe pipe2 = Struct::retrieve.newPipe (newID("pipe"), sID ); - - CHECK (pipe1 != pipe2); - CHECK (stID == pipe2->getStreamID()); - - CHECK (!find (pipe1->getPipeID()), "accidental clash of random test-IDs"); - CHECK (!find (pipe2->getPipeID()), "accidental clash of random test-IDs"); - - // now declare that these objects should be considered "default" -lumiera::query::setFakeBypass(""); /////////////////////////////////////////////////TODO mock resolution - CHECK (Session::current->defaults.define (pipe1, Query (""))); // unrestricted default - -lumiera::query::setFakeBypass("stream("+sID+")"); ///////////////////////////////////TODO mock resolution - CHECK (Session::current->defaults.define (pipe2, Query ("stream("+sID+")"))); - - CHECK ( find (pipe1->getPipeID()), "failure declaring object as default"); - CHECK ( find (pipe2->getPipeID()), "failure declaring object as default"); - - CHECK (stID != pipe1->getStreamID(), "accidental clash"); - CHECK (!Session::current->defaults.define (pipe1, Query ("stream("+sID+")"))); - // can't be registered with this query, due to failure caused by wrong stream-ID - } - - - const string& - create() - { - string sID = newID ("stream"); - Query query_for_streamID ("stream("+sID+")"); - - // issue a ConfigQuery directly, without involving the DefaultsManager - QueryHandler& typeHandler = ConfigRules::instance(); - PPipe pipe1; - typeHandler.resolve (pipe1, query_for_streamID); - CHECK (pipe1); - - CHECK (!find (pipe1->getPipeID())); - PPipe pipe2 = Session::current->defaults.create (query_for_streamID); - CHECK (pipe2); - CHECK (pipe2 == pipe1); - CHECK ( find (pipe1->getPipeID())); // now declared as "default Pipe" for this stream-ID - - return pipe1->getPipeID(); - } - - - void - forget (string pID) - { - PPipe pipe = Pipe::query ("pipe("+pID+")"); - REQUIRE (find (pipe->getPipeID()), "need an object registered as default"); - long cnt = pipe.use_count(); - - // now de-register the pipe as "default Pipe" - CHECK (Session::current->defaults.forget (pipe)); - CHECK (!find (pipe->getPipeID())); - CHECK (cnt == pipe.use_count()); // indicates DefaultsManager holding only a weak ref. - } - }; - - - /** Register this test class... */ - LAUNCHER (DefsManagerImpl_test, "function session"); - - - - } // namespace test - -} // namespace asset diff --git a/tests/components/proc/mobject/session/defsmanagertest.cpp b/tests/components/proc/mobject/session/defsmanagertest.cpp deleted file mode 100644 index 5f41fb462..000000000 --- a/tests/components/proc/mobject/session/defsmanagertest.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - DefsManager(Test) - checking basic behaviour of the defaults manager - - 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. - -* *****************************************************/ - - -#include "pre_a.hpp" - -#include "lib/test/run.hpp" -#include "lib/symbol.hpp" -#include "lib/query.hpp" -#include "lib/util.hpp" - -#include "proc/asset.hpp" -#include "proc/asset/pipe.hpp" -#include "proc/assetmanager.hpp" -#include "proc/mobject/session.hpp" -#include "lib/streamtype.hpp" - -#include - -using boost::format; -using util::isnil; -using std::string; - - - -namespace asset { -namespace test { - - using util::cStr; - using lib::Symbol; - using mobject::Session; - using lumiera::Query; - using lumiera::query::normaliseID; - using lumiera::StreamType; - - - /** shortcut: run just a query - * without creating new instances - */ - bool - find (Query& q) - { - return Session::current->defaults.search (q); - } - - - - - /*********************************************************************** - * @test basic behaviour of the defaults manager ("the big picture") - * - retrieving a "default" object repeatedly - * - retrieving a more constrained "default" object - * - failure registers a new "default" - * - instance management - * - * Using pipe assets as an example. The defaults manager shouldn't - * interfere with memory management (it holds weak refs). - */ - class DefsManager_test : public Test - { - virtual void - run (Arg arg) - { - string pipeID = isnil(arg)? "Black Hole" : arg[1]; - string streamID = 2>arg.size()? "teststream" : arg[2] ; - - normaliseID (pipeID); - normaliseID (streamID); - - retrieveSimpleDefault (pipeID); - retrieveConstrainedDefault (pipeID, streamID); - failureCreatesNewDefault(); - verifyRemoval(); - } - - - - - void - retrieveSimpleDefault (string) - { - PPipe pipe1 = Pipe::query (""); // "the default pipe" - PPipe pipe2; - - // several variants to query for "the default pipe" - pipe2 = Pipe::query (""); - CHECK (pipe2 == pipe1); - pipe2 = Pipe::query ("default(X)"); - CHECK (pipe2 == pipe1); - pipe2 = Session::current->defaults(Query ()); - CHECK (pipe2 == pipe1); - pipe2 = asset::Struct::retrieve (Query ()); - CHECK (pipe2 == pipe1); - pipe2 = asset::Struct::retrieve (Query ("default(P)")); - CHECK (pipe2 == pipe1); - } - - - void - retrieveConstrainedDefault (string pID, string sID) - { - PPipe pipe1 = Pipe::query (""); // "the default pipe" - CHECK ( pipe1->getStreamID() != StreamType::ID(sID), - "stream-ID \"%s\" not suitable for test, because " - "the default-pipe \"%s\" happens to have the same " - "stream-ID. We need it to be different", - sID.c_str(), pID.c_str() - ); - - string query_for_sID ("stream("+sID+")"); - PPipe pipe2 = Pipe::query (query_for_sID); - CHECK (pipe2->getStreamID() == StreamType::ID(sID)); - CHECK (pipe2 != pipe1); - CHECK (pipe2 == Pipe::query (query_for_sID)); // reproducible - } - - - void - failureCreatesNewDefault() - { - PPipe pipe1 = Session::current->defaults(Query ()); // "the default pipe" - - string new_pID (str (format ("dummy_%s_%i") - % pipe1->getPipeID() - % std::rand() - )); // make random new pipeID - Query query_for_new ("pipe("+new_pID+")"); - - CHECK (!find (query_for_new)); // check it doesn't exist - PPipe pipe2 = Session::current->defaults (query_for_new); // triggers creation - CHECK ( find (query_for_new)); // check it exists now - - CHECK (pipe1 != pipe2); - CHECK (pipe2 == Session::current->defaults (query_for_new)); - } - - - /** verify the defaults manager holds only weak refs, - * so if an object goes out of scope, any defaults entries - * are purged silently - */ - void - verifyRemoval() - { - Symbol pID ("some_pipe"); - Query query_for_pID ("pipe("+pID+")"); - size_t hash; - { - // create new pipe and declare it to be a default - PPipe pipe1 = Struct::retrieve.newInstance (pID); - Session::current->defaults.define(pipe1); - - CHECK (2 == pipe1.use_count()); // the pipe1 smart-ptr and the AssetManager - hash = pipe1->getID(); - } - // pipe1 out of scope.... - // AssetManager now should hold the only ref - ID assetID (hash); - - AssetManager& aMang (AssetManager::instance()); - CHECK ( aMang.known (assetID)); - aMang.remove (assetID); - CHECK (!aMang.known (assetID)); - - - CHECK (!find(query_for_pID)); // bare default-query should fail... - PPipe pipe2 = Session::current->defaults (query_for_pID); // triggers re-creation - CHECK ( find(query_for_pID)); // should succeed again - } - }; - - - - /** Register this test class... */ - LAUNCHER (DefsManager_test, "function session"); - - -}} // namespace asset::test diff --git a/tests/components/proc/mobject/session/defsregistryimpltest.cpp b/tests/components/proc/mobject/session/defsregistryimpltest.cpp deleted file mode 100644 index a9e12b28b..000000000 --- a/tests/components/proc/mobject/session/defsregistryimpltest.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/* - DefsRegistryImpl(Test) - verifying correct behaviour of the defaults registry - - 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. - -* *****************************************************/ - - -#include "lib/test/run.hpp" -#include "lib/util.hpp" - -#include "proc/mobject/session/defsregistry.hpp" -#include "lib/factory.hpp" -#include "lib/query.hpp" -#include "lib/p.hpp" - -#include "../lib/query/querydiagnostics.hpp" - -#include -#include -#include - -using lumiera::P; -using lumiera::Query; -using lumiera::query::test::garbage_query; -using util::isnil; - -using boost::scoped_ptr; -using boost::format; -using std::string; -using std::rand; -using std::map; - - - -namespace mobject { - namespace session { - namespace test { - - format typePatt ("Dummy<%2i>"); - format instancePatt ("obj_%s_%i"); - format predicatePatt ("%s_%2i( %s )"); - - - - /** create a random new ID */ - string - newID (string prefix) - { - return str (instancePatt % prefix % rand()); - } - - - /** template for generating some different test types */ - template - struct Dummy - { - static string name; - string instanceID; - operator string () const { return instanceID; } - bool operator== (const Dummy& odu) const { return this == &odu; } - - - Dummy () : instanceID (newID (name)) {} - }; - - template - string Dummy::name = str (typePatt % I); - - - - - - - /************************************************************************ - * @test build an registry table (just for this test) configured for - * some artificial test Types. Register some entries and verify - * the intended behaviour of the storage structure. - * @see DefsManagerImpl_test for checking the implementation details - * in the actual context used in Lumiera. - */ - class DefsRegistryImpl_test : public Test - { - scoped_ptr reg_; - - typedef lumiera::P > O; - typedef lumiera::P > P; - - typedef Query > Q13; - typedef Query > Q23; - - typedef DefsRegistry::Iter > Iter13; - typedef DefsRegistry::Iter > Iter23; - - - // fabricating Objects wrapped into smart-ptrs - lib::factory::RefcountFac > oFac; - lib::factory::RefcountFac > pFac; - - O o1, o2, o3; - Q13 q1, q2, q3, q4, q5; - map ps; - - public: - DefsRegistryImpl_test () - : o1 (oFac()), o2 (oFac()), o3 (oFac()), - q1 (garbage_query (1)), - q2 (garbage_query (2)), - q3 (garbage_query (3)), - q4 (garbage_query (4)), - q5 (garbage_query (5)) - { } - - - virtual void - run (Arg) - { - this->reg_.reset (new DefsRegistry); - - fill_table (); - check_query (); - check_remove (); - } - - - - - void - fill_table () - { - // at start the registry is indeed empty - // thus a query doesn't yield any results.... - CHECK ( ! *(reg_->candidates(Q13 ("something"))) ); - - reg_->put (o1, q5); - reg_->put (o2, q4); - reg_->put (o3, q3); - reg_->put (o3, q2); - reg_->put (o2, q1); - reg_->put (o1, Q13()); // the empty query - - ps.clear(); - for (int i=0; i<100; ++i) - { - P px (pFac()); - Q23 qx (garbage_query()); - ps[qx] = px; - reg_->put (px, qx); - px->instanceID = qx; - } - } - - - void - check_query () - { - Iter13 i (reg_->candidates(Q13 ("irrelevant query"))); - CHECK ( i.hasNext()); - CHECK ( *i++ == o1); // ordered according to the degree of the queries - CHECK ( *i++ == o2); - CHECK ( *i++ == o3); - CHECK ( *i++ == o3); - CHECK ( *i++ == o2); - CHECK ( *i == o1); - CHECK (!i.hasNext()); - CHECK (! *++i ); // null after end - - i = reg_->candidates(q3); - CHECK ( *i++ == o3); // found by direct match - CHECK ( *i++ == o1); // followed by the ordered enumeration - CHECK ( *i++ == o2); - CHECK ( *i++ == o3); - CHECK ( *i++ == o3); - CHECK ( *i++ == o2); - CHECK ( *i++ == o1); - CHECK (!i.hasNext()); - - i = reg_->candidates(Q13()); - CHECK ( *i++ == o1); // found by direct match to the empty query - CHECK ( *i++ == o1); - CHECK ( *i++ == o2); - CHECK ( *i++ == o3); - CHECK ( *i++ == o3); - CHECK ( *i++ == o2); - CHECK ( *i++ == o1); - CHECK (!i.hasNext()); - - uint d=0; - uint d_prev=0; - Iter23 j = reg_->candidates(Q23 ("some crap")); - for ( ; *j ; ++j ) - { - CHECK ( *j ); - Q23 qx ((*j)->instanceID); - CHECK ( ps[qx] == (*j)); - d = lumiera::query::countPred (qx); - CHECK ( d_prev <= d ); - d_prev = d; - } - CHECK (!j.hasNext()); - - // calling with an arbitrary (registered) query - // yields the corresponding object at start of the enumeration - j = reg_->candidates(ps.begin()->first); - CHECK ( *j == ps.begin()->second); - - } - - - void - check_remove () - { - reg_->forget (o2); - - Iter13 i (reg_->candidates(q4)); - CHECK ( i.hasNext()); - CHECK ( *i++ == o1); // ordered according to the degree of the queries - // but the o2 entries are missing - CHECK ( *i++ == o3); - CHECK ( *i++ == o3); - // missing - CHECK ( *i == o1); - CHECK (!i.hasNext()); - - o3.reset(); // killing the only reference.... - // expires the weak ref in the registry - - i = reg_->candidates(Q13 ("something")); - CHECK ( i.hasNext()); - CHECK ( *i++ == o1); // ordered according to the degree of the queries - // but now also the o3 entries are missing... - CHECK ( *i == o1); - CHECK (!i.hasNext()); - - CHECK ( reg_->put (o1, q5)); // trying to register the same object at the same place - // doesn't change anything (but counts as "success") - i = reg_->candidates(q5); - CHECK ( *i++ == o1); // direct match - CHECK ( *i++ == o1); - CHECK ( *i++ == o1); - CHECK (!i.hasNext()); - - CHECK (!reg_->put (o2, q5)); // trying to (re)register o2 with a existing query - // counts as failure (nothing changes) - i = reg_->candidates(q5); - CHECK ( *i++ == o1); // direct match - CHECK ( *i++ == o1); - CHECK ( *i++ == o1); - CHECK (!i.hasNext()); - - CHECK ( reg_->put (o2, q2)); // trying to (re)register o2 with another query succeeds - i = reg_->candidates(q2); - CHECK ( *i++ == o2); // direct match - CHECK ( *i++ == o1); - CHECK ( *i++ == o2); // inserted here in the dataset - CHECK ( *i++ == o1); - CHECK (!i.hasNext()); - - CHECK ( reg_->forget (o1)); - CHECK (!reg_->forget (o1)); // failure, because it's already removed - CHECK ( reg_->forget (o2)); - - o3 = oFac(); // another object is another object (it's irrelevant...) - - i = reg_->candidates(q2); - CHECK (! (*i)); // empty - } - - }; - - - /** Register this test class... */ - LAUNCHER (DefsRegistryImpl_test, "function session"); - - - - } // namespace test - - } // namespace mobject - -} // namespace mobject diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am index f6930f20b..fd9c76ac4 100644 --- a/tests/lib/Makefile.am +++ b/tests/lib/Makefile.am @@ -43,7 +43,7 @@ test_lib_SOURCES = \ $(testlib_srcdir)/advice/advice-index-test.cpp \ $(testlib_srcdir)/advice/advice-multiplicity-test.cpp \ $(testlib_srcdir)/advice/advice-situations-test.cpp \ - $(testlib_srcdir)/allocationclustertest.cpp \ + $(testlib_srcdir)/allocation-cluster-test.cpp \ $(testlib_srcdir)/appconfigtest.cpp \ $(testlib_srcdir)/bool-checkable-test.cpp \ $(testlib_srcdir)/custom-shared-ptr-test.cpp \ @@ -87,7 +87,7 @@ test_lib_SOURCES = \ $(testlib_srcdir)/scoped-holder-transfer-test.cpp \ $(testlib_srcdir)/singleton-subclass-test.cpp \ $(testlib_srcdir)/singleton-test.cpp \ - $(testlib_srcdir)/singletontestmocktest.cpp \ + $(testlib_srcdir)/singleton-testmock-test.cpp \ $(testlib_srcdir)/streamtypebasicstest.cpp \ $(testlib_srcdir)/streamtypelifecycletest.cpp \ $(testlib_srcdir)/sub-id-test.cpp \ diff --git a/tests/lib/allocation-cluster-test.cpp b/tests/lib/allocation-cluster-test.cpp new file mode 100644 index 000000000..cf8897bf5 --- /dev/null +++ b/tests/lib/allocation-cluster-test.cpp @@ -0,0 +1,234 @@ +/* + AllocationCluster(Test) - verify bulk (de)allocating a family of 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. + +* *****************************************************/ + + + +#include "lib/test/run.hpp" +#include "lib/test/test-helper.hpp" +#include "lib/util.hpp" +#include "lib/util-foreach.hpp" + +#include "lib/allocation-cluster.hpp" +#include "lib/scoped-holder.hpp" + +#include +#include +#include + +using boost::lexical_cast; +using lib::test::showSizeof; +using util::for_each; +using util::isnil; +using ::Test; + +using std::numeric_limits; +using std::vector; + + + +namespace lib { +namespace test { + + namespace { // a family of test dummy classes + + uint NUM_CLUSTERS = 5; + uint NUM_OBJECTS = 500; + uint NUM_FAMILIES = 5; + + long checksum = 0; // validate proper pairing of ctor/dtor calls + bool randomFailures = false; + + template + class Dummy + { + char content[i]; + + public: + Dummy (char id=1) + { + content[0] = id; + checksum += id; + } + Dummy (char i1, char i2, char i3=0) + { + char id = i1 + i2 + i3; + content[0] = id; + checksum += id; + if (randomFailures && 0 == (rand() % 20)) + throw id; + } + + ~Dummy() + { + checksum -= content[0]; + } + + char getID() { return content[0]; } + }; + + typedef ScopedHolder PCluster; + typedef vector ClusterList; + + inline char + truncChar (uint x) + { + return x % numeric_limits::max(); + } + + template + void + place_object (AllocationCluster& clu, uint id) + { + clu.create > (id); + } + + typedef void (Invoker)(AllocationCluster&, uint); + + Invoker* invoke[20] = { &place_object<1> + , &place_object<2> + , &place_object<3> + , &place_object<5> + , &place_object<10> + , &place_object<13> + , &place_object<14> + , &place_object<15> + , &place_object<16> + , &place_object<17> + , &place_object<18> + , &place_object<19> + , &place_object<20> + , &place_object<25> + , &place_object<30> + , &place_object<35> + , &place_object<40> + , &place_object<50> + , &place_object<100> + , &place_object<200> + }; + + void + fillIt (PCluster& clu) + { + clu.create(); + + if (20 (arg[0]); + if (1 < arg.size()) NUM_OBJECTS = lexical_cast (arg[1]); + if (2 < arg.size()) NUM_FAMILIES = lexical_cast (arg[2]); + + simpleUsage(); + checkAllocation(); + checkErrorHandling(); + } + + + void + simpleUsage() + { + AllocationCluster clu; + + char c1(123), c2(56), c3(3), c4(4), c5(5); + Dummy<44>& ref1 = clu.create > (); + Dummy<37>& ref2 = clu.create > (c1); + Dummy<37>& ref3 = clu.create > (c2); + Dummy<1234>& rX = clu.create > (c3,c4,c5); + + CHECK (&ref1); + CHECK (&ref2); + CHECK (&ref3); + CHECK (&rX); + TRACE (test, "%s", showSizeof(rX).c_str()); + + CHECK (123==ref2.getID()); + CHECK (3+4+5==rX.getID()); + // shows that the returned references actually + // point at the objects we created. Just use them + // and let them go. When clu goes out of scope, + // all created object's dtors will be invoked. + } + + + void + checkAllocation() + { + CHECK (0==checksum); + { + ClusterList clusters (NUM_CLUSTERS); + for_each (clusters, fillIt); + CHECK (0!=checksum); + } + CHECK (0==checksum); + } + + + void + checkErrorHandling() + { + CHECK (0==checksum); + { + randomFailures = true; + + AllocationCluster clu; + for (uint i=0; i > (i1,i2); + } + catch (char id) + { + checksum -= id; // exception thrown from within constructor, + } // thus dtor won't be called. Repair the checksum! + } + randomFailures = false; + CHECK (0==checksum); + } + }; + + LAUNCHER (AllocationCluster_test, "unit common"); + + +}} // namespace lib::test diff --git a/tests/lib/allocationclustertest.cpp b/tests/lib/allocationclustertest.cpp deleted file mode 100644 index 6e2d38e65..000000000 --- a/tests/lib/allocationclustertest.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - AllocationCluster(Test) - verify bulk (de)allocating a family of 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. - -* *****************************************************/ - - - -#include "lib/test/run.hpp" -#include "lib/test/test-helper.hpp" -#include "lib/util.hpp" -#include "lib/util-foreach.hpp" - -#include "lib/allocationcluster.hpp" -#include "lib/scoped-holder.hpp" - -#include -#include -#include - -using boost::lexical_cast; -using lib::test::showSizeof; -using util::for_each; -using util::isnil; -using ::Test; - -using std::numeric_limits; -using std::vector; - - - -namespace lib { - namespace test { - - namespace { // a family of test dummy classes - - uint NUM_CLUSTERS = 5; - uint NUM_OBJECTS = 500; - uint NUM_FAMILIES = 5; - - long checksum = 0; // validate proper pairing of ctor/dtor calls - bool randomFailures = false; - - template - class Dummy - { - char content[i]; - - public: - Dummy (char id=1) - { - content[0] = id; - checksum += id; - } - Dummy (char i1, char i2, char i3=0) - { - char id = i1 + i2 + i3; - content[0] = id; - checksum += id; - if (randomFailures && 0 == (rand() % 20)) - throw id; - } - - ~Dummy() - { - checksum -= content[0]; - } - - char getID() { return content[0]; } - }; - - typedef ScopedHolder PCluster; - typedef vector ClusterList; - - inline char - truncChar (uint x) - { - return x % numeric_limits::max(); - } - - template - void - place_object (AllocationCluster& clu, uint id) - { - clu.create > (id); - } - - typedef void (Invoker)(AllocationCluster&, uint); - - Invoker* invoke[20] = { &place_object<1> - , &place_object<2> - , &place_object<3> - , &place_object<5> - , &place_object<10> - , &place_object<13> - , &place_object<14> - , &place_object<15> - , &place_object<16> - , &place_object<17> - , &place_object<18> - , &place_object<19> - , &place_object<20> - , &place_object<25> - , &place_object<30> - , &place_object<35> - , &place_object<40> - , &place_object<50> - , &place_object<100> - , &place_object<200> - }; - - void - fillIt (PCluster& clu) - { - clu.create(); - - if (20 (arg[0]); - if (1 < arg.size()) NUM_OBJECTS = lexical_cast (arg[1]); - if (2 < arg.size()) NUM_FAMILIES = lexical_cast (arg[2]); - - simpleUsage(); - checkAllocation(); - checkErrorHandling(); - } - - - void - simpleUsage() - { - AllocationCluster clu; - - char c1(123), c2(56), c3(3), c4(4), c5(5); - Dummy<44>& ref1 = clu.create > (); - Dummy<37>& ref2 = clu.create > (c1); - Dummy<37>& ref3 = clu.create > (c2); - Dummy<1234>& rX = clu.create > (c3,c4,c5); - - CHECK (&ref1); - CHECK (&ref2); - CHECK (&ref3); - CHECK (&rX); - TRACE (test, "%s", showSizeof(rX).c_str()); - - CHECK (123==ref2.getID()); - CHECK (3+4+5==rX.getID()); - // shows that the returned references actually - // point at the objects we created. Just use them - // and let them go. When clu goes out of scope, - // all created object's dtors will be invoked. - } - - - void - checkAllocation() - { - CHECK (0==checksum); - { - ClusterList clusters (NUM_CLUSTERS); - for_each (clusters, fillIt); - CHECK (0!=checksum); - } - CHECK (0==checksum); - } - - - void - checkErrorHandling() - { - CHECK (0==checksum); - { - randomFailures = true; - - AllocationCluster clu; - for (uint i=0; i > (i1,i2); - } - catch (char id) - { - checksum -= id; // exception thrown from within constructor, - } // thus dtor won't be called. Repair the checksum! - } - randomFailures = false; - CHECK (0==checksum); - } - }; - - LAUNCHER (AllocationCluster_test, "unit common"); - - - }// namespace test - -} // namespace lib diff --git a/tests/lib/scoped-holder-transfer-test.cpp b/tests/lib/scoped-holder-transfer-test.cpp index a01609ddf..0c3773095 100644 --- a/tests/lib/scoped-holder-transfer-test.cpp +++ b/tests/lib/scoped-holder-transfer-test.cpp @@ -34,205 +34,204 @@ namespace lib { - namespace test { - - using ::Test; - using util::isnil; - - using std::vector; - using std::cout; - - namespace { // extending the Dummy for our special purpose.... - - bool throw_in_transfer = false; - - class FixedDummy - : public Dummy - { - public: - FixedDummy() - { - TRACE (test, "CTOR FixedDummy() --> this=%p val=%d", this, getVal()); - } - - ~FixedDummy() - { - TRACE (test, "DTOR ~FixedDummy() this=%p val=%d", this, getVal()); - } - - friend void - transfer_control (FixedDummy& from, FixedDummy& to) - { - TRACE (test, "TRANSFER target=%p <-- source=%p (%d,%d)", &to,&from, to.getVal(),from.getVal()); - - if (throw_in_transfer) - throw to.getVal(); - - swap (from,to); - from.setVal(0); // remove the old Dummy from accounting (checksum) - } - - }; - - - typedef ScopedHolder HolderD; - typedef ScopedPtrHolder PtrHolderD; - - template - struct Table - { - typedef Allocator_TransferNoncopyable Allo; - typedef typename std::vector Type; - - }; - } - - - - - /********************************************************************************** - * @test growing a vector containing noncopyable objects wrapped into ScopedHolder - * instances. This requires the use of a custom allocator, invoking a - * \c transfer_control() function to be provided for the concrete - * noncopyable class type, being invoked when the vector - * needs to reallocate. - */ - class ScopedHolderTransfer_test : public Test +namespace test { + + using ::Test; + using util::isnil; + + using std::vector; + using std::cout; + + namespace { // extending the Dummy for our special purpose.... + + bool throw_in_transfer = false; + + class FixedDummy + : public Dummy { - - virtual void - run (Arg) + public: + FixedDummy() { - - cout << "checking ScopedHolder...\n"; - buildVector(); - growVector(); - checkErrorHandling(); - - cout << "checking ScopedPtrHolder...\n"; - buildVector(); - growVector(); - checkErrorHandling(); + TRACE (test, "CTOR FixedDummy() --> this=%p val=%d", this, getVal()); } - - void create_contained_object (HolderD& holder) { holder.create(); } - void create_contained_object (PtrHolderD& holder) { holder.reset(new FixedDummy()); } - - - template - void - buildVector() + + ~FixedDummy() { - CHECK (0==checksum); - { - typedef typename Table::Type Vect; - - Vect table(50); - CHECK (0==checksum); - - for (uint i=0; i<10; ++i) - create_contained_object (table[i]); - - CHECK (0 < checksum); - CHECK ( table[9]); - CHECK (!table[10]); - - Dummy *rawP = table[5].get(); - CHECK (rawP); - CHECK (table[5]); - CHECK (rawP == &(*table[5])); - CHECK (rawP->add(-555) == table[5]->add(-555)); - } - CHECK (0==checksum); + TRACE (test, "DTOR ~FixedDummy() this=%p val=%d", this, getVal()); } - - - template - void - growVector() - { - CHECK (0==checksum); - { - typedef typename Table::Type Vect; - - Vect table; - table.reserve(2); - CHECK (0==checksum); - - cout << ".\n..install one element at index[0]\n"; - table.push_back(HO()); - CHECK (0==checksum); - - create_contained_object (table[0]); // switches into "managed" state - CHECK (0 < checksum); - int theSum = checksum; - - cout << ".\n..*** resize table to 16 elements\n"; - for (uint i=0; i<15; ++i) - table.push_back(HO()); - - CHECK (theSum==checksum); - } - CHECK (0==checksum); - } - - - template - void - checkErrorHandling() - { - CHECK (0==checksum); - { - typedef typename Table::Type Vect; - - Vect table(5); - table.reserve(5); - CHECK (0==checksum); - - create_contained_object (table[2]); - create_contained_object (table[4]); - CHECK (0 < checksum); - int theSum = checksum; - - cout << ".\n.throw some exceptions...\n"; - throw_in_ctor = true; - try - { - create_contained_object (table[3]); - NOTREACHED (); - } - catch (int val) - { - CHECK (theSum < checksum); - checksum -= val; - CHECK (theSum==checksum); - } - CHECK ( table[2]); - CHECK (!table[3]); // not created because of exception - CHECK ( table[4]); - - throw_in_ctor = false; - throw_in_transfer=true; // can do this only when using ScopedHolder - try - { - table.resize(10); - } - catch (int val) - { - CHECK ( table.size() < 10); - } - CHECK (theSum == checksum); - throw_in_transfer=false; - } - CHECK (0==checksum); - } - + + friend void + transfer_control (FixedDummy& from, FixedDummy& to) + { + TRACE (test, "TRANSFER target=%p <-- source=%p (%d,%d)", &to,&from, to.getVal(),from.getVal()); + + if (throw_in_transfer) + throw to.getVal(); + + swap (from,to); + from.setVal(0); // remove the old Dummy from accounting (checksum) + } + }; - - LAUNCHER (ScopedHolderTransfer_test, "unit common"); - - - }// namespace test - -} // namespace lib - + + + typedef ScopedHolder HolderD; + typedef ScopedPtrHolder PtrHolderD; + + template + struct Table + { + typedef Allocator_TransferNoncopyable Allo; + typedef typename std::vector Type; + + }; + + }//(End) test helpers + + + + + + /********************************************************************************** + * @test growing a vector containing noncopyable objects wrapped into ScopedHolder + * instances. This requires the use of a custom allocator, invoking a + * \c transfer_control() function to be provided for the concrete + * noncopyable class type, being invoked when the vector + * needs to reallocate. + */ + class ScopedHolderTransfer_test : public Test + { + + virtual void + run (Arg) + { + + cout << "checking ScopedHolder...\n"; + buildVector(); + growVector(); + checkErrorHandling(); + + cout << "checking ScopedPtrHolder...\n"; + buildVector(); + growVector(); + checkErrorHandling(); + } + + void create_contained_object (HolderD& holder) { holder.create(); } + void create_contained_object (PtrHolderD& holder) { holder.reset(new FixedDummy()); } + + + template + void + buildVector() + { + CHECK (0==checksum); + { + typedef typename Table::Type Vect; + + Vect table(50); + CHECK (0==checksum); + + for (uint i=0; i<10; ++i) + create_contained_object (table[i]); + + CHECK (0 < checksum); + CHECK ( table[9]); + CHECK (!table[10]); + + Dummy *rawP = table[5].get(); + CHECK (rawP); + CHECK (table[5]); + CHECK (rawP == &(*table[5])); + CHECK (rawP->add(-555) == table[5]->add(-555)); + } + CHECK (0==checksum); + } + + + template + void + growVector() + { + CHECK (0==checksum); + { + typedef typename Table::Type Vect; + + Vect table; + table.reserve(2); + CHECK (0==checksum); + + cout << ".\n..install one element at index[0]\n"; + table.push_back(HO()); + CHECK (0==checksum); + + create_contained_object (table[0]); // switches into "managed" state + CHECK (0 < checksum); + int theSum = checksum; + + cout << ".\n..*** resize table to 16 elements\n"; + for (uint i=0; i<15; ++i) + table.push_back(HO()); + + CHECK (theSum==checksum); + } + CHECK (0==checksum); + } + + + template + void + checkErrorHandling() + { + CHECK (0==checksum); + { + typedef typename Table::Type Vect; + + Vect table(5); + table.reserve(5); + CHECK (0==checksum); + + create_contained_object (table[2]); + create_contained_object (table[4]); + CHECK (0 < checksum); + int theSum = checksum; + + cout << ".\n.throw some exceptions...\n"; + throw_in_ctor = true; + try + { + create_contained_object (table[3]); + NOTREACHED (); + } + catch (int val) + { + CHECK (theSum < checksum); + checksum -= val; + CHECK (theSum==checksum); + } + CHECK ( table[2]); + CHECK (!table[3]); // not created because of exception + CHECK ( table[4]); + + throw_in_ctor = false; + throw_in_transfer=true; // can do this only when using ScopedHolder + try + { + table.resize(10); + } + catch (int val) + { + CHECK ( table.size() < 10); + } + CHECK (theSum == checksum); + throw_in_transfer=false; + } + CHECK (0==checksum); + } + + }; + + LAUNCHER (ScopedHolderTransfer_test, "unit common"); + + +}} // namespace lib::test diff --git a/tests/lib/singletontestmocktest.cpp b/tests/lib/singleton-testmock-test.cpp similarity index 100% rename from tests/lib/singletontestmocktest.cpp rename to tests/lib/singleton-testmock-test.cpp diff --git a/tests/lib/typed-allocation-manager-test.cpp b/tests/lib/typed-allocation-manager-test.cpp index f72d6bdbd..bd1b2261f 100644 --- a/tests/lib/typed-allocation-manager-test.cpp +++ b/tests/lib/typed-allocation-manager-test.cpp @@ -78,7 +78,7 @@ namespace test{ * * @see CommandRegistry * @see command-registry-test.cpp - * @see allocationclustertest.cpp + * @see allocation-cluster-test.cpp */ class TypedAllocationManager_test : public Test { diff --git a/tests/lib/vector-transfer-test.cpp b/tests/lib/vector-transfer-test.cpp index 2ffd27622..98f8f4021 100644 --- a/tests/lib/vector-transfer-test.cpp +++ b/tests/lib/vector-transfer-test.cpp @@ -32,132 +32,130 @@ namespace lib { - namespace test { - - using ::Test; - using std::vector; - using std::cout; - - namespace { // extending the Dummy for our special purpose.... - - class TransDummy - : public Dummy - { - public: - TransDummy() - { - TRACE (test, "CTOR TransDummy() --> this=%p", this); - setVal(0); // we use val_==0 to mark the "empty" state - } - - ~TransDummy() - { - TRACE (test, "DTOR ~TransDummy() this=%p", this); - } - - /* to make Dummy usable within vector, we need to provide - * \em special copy operations, an operator bool() and - * a transfer_control friend function to be used by - * our special allocator. - */ - - TransDummy (const TransDummy& o) - : Dummy() - { - TRACE (test, "COPY-ctor TransDummy( ref=%p ) --> this=%p", &o,this); - CHECK (!o, "protocol violation: real copy operations inhibited"); - } - - TransDummy& - operator= (TransDummy const& ref) - { - TRACE (test, "COPY target=%p <-- source=%p", this,&ref); - CHECK (!(*this)); - CHECK (!ref, "protocol violation: real copy operations inhibited"); - return *this; - } - - void - setup (int x=0) - { - setVal (x? x : (rand() % 10000)); - TRACE (test, "CREATE val=%d ---> this=%p", getVal(),this); - } - - - // define implicit conversion to "bool" the naive way... - operator bool() const - { - return 0!=getVal(); - } - - - friend void transfer_control (TransDummy& from, TransDummy& to); - - }; - - - void - transfer_control (TransDummy& from, TransDummy& to) +namespace test { + + using ::Test; + using std::vector; + using std::cout; + + namespace { // extending the Dummy for our special purpose.... + + class TransDummy + : public Dummy { - TRACE (test, "TRANSFER target=%p <-- source=%p", &to,&from); - CHECK (!to, "protocol violation: target already manages another object"); - to.setVal (from.getVal()); - from.setVal(0); - } - - typedef Allocator_TransferNoncopyable Allo; - typedef vector TransDummyVector; - } - - - - - /********************************************************************************** - * @test growing (re-allocating) a vector with noncopyable objects, with the - * help of a special Allocator and a custom \c transfer_control operation - * provided by the contained objects. The idea is to allow some special - * copy-operations for the purpose of re-allocations within the vector, - * without requiring the object to be really copyable. - */ - class VectorTransfer_test : public Test - { - - virtual void - run (Arg) + public: + TransDummy() { - cout << "\n..setup table space for 2 elements\n"; - TransDummyVector table; - table.reserve(2); - CHECK (0==checksum); - - cout << "\n..install one element at index[0]\n"; - table.push_back(TransDummy()); - CHECK (0==checksum); - - table[0].setup(); // switches into "managed" state - CHECK (0 < checksum); - int theSum = checksum; - - cout << "\n..*** resize table to 5 elements\n"; - table.resize(5); - CHECK (theSum==checksum); - - cout << "\n..install another element\n"; - table[3].setup(375); - CHECK (theSum+375==checksum); - - cout << "\n..kill all elements....\n"; - table.clear(); - CHECK (0==checksum); + TRACE (test, "CTOR TransDummy() --> this=%p", this); + setVal(0); // we use val_==0 to mark the "empty" state } - + + ~TransDummy() + { + TRACE (test, "DTOR ~TransDummy() this=%p", this); + } + + /* to make Dummy usable within vector, we need to provide + * \em special copy operations, an operator bool() and + * a transfer_control friend function to be used by + * our special allocator. + */ + + TransDummy (const TransDummy& o) + : Dummy() + { + TRACE (test, "COPY-ctor TransDummy( ref=%p ) --> this=%p", &o,this); + CHECK (!o, "protocol violation: real copy operations inhibited"); + } + + TransDummy& + operator= (TransDummy const& ref) + { + TRACE (test, "COPY target=%p <-- source=%p", this,&ref); + CHECK (!(*this)); + CHECK (!ref, "protocol violation: real copy operations inhibited"); + return *this; + } + + void + setup (int x=0) + { + setVal (x? x : (rand() % 10000)); + TRACE (test, "CREATE val=%d ---> this=%p", getVal(),this); + } + + + // define implicit conversion to "bool" the naive way... + operator bool() const + { + return 0!=getVal(); + } + + + friend void transfer_control (TransDummy& from, TransDummy& to); + }; - - LAUNCHER (VectorTransfer_test, "unit common"); - - - }// namespace test - -} // namespace lib - + + + + void + transfer_control (TransDummy& from, TransDummy& to) + { + TRACE (test, "TRANSFER target=%p <-- source=%p", &to,&from); + CHECK (!to, "protocol violation: target already manages another object"); + to.setVal (from.getVal()); + from.setVal(0); + } + + typedef Allocator_TransferNoncopyable Allo; + typedef vector TransDummyVector; + } + + + + + /********************************************************************************** + * @test growing (re-allocating) a vector with noncopyable objects, with the + * help of a special Allocator and a custom \c transfer_control operation + * provided by the contained objects. The idea is to allow some special + * copy-operations for the purpose of re-allocations within the vector, + * without requiring the object to be really copyable. + */ + class VectorTransfer_test : public Test + { + + virtual void + run (Arg) + { + cout << "\n..setup table space for 2 elements\n"; + TransDummyVector table; + table.reserve(2); + CHECK (0==checksum); + + cout << "\n..install one element at index[0]\n"; + table.push_back(TransDummy()); + CHECK (0==checksum); + + table[0].setup(); // switches into "managed" state + CHECK (0 < checksum); + int theSum = checksum; + + cout << "\n..*** resize table to 5 elements\n"; + table.resize(5); + CHECK (theSum==checksum); + + cout << "\n..install another element\n"; + table[3].setup(375); + CHECK (theSum+375==checksum); + + cout << "\n..kill all elements....\n"; + table.clear(); + CHECK (0==checksum); + } + + }; + + LAUNCHER (VectorTransfer_test, "unit common"); + + +}} // namespace lib::test