diff --git a/src/lib/multifact.hpp b/src/lib/multifact.hpp index c24648bd7..557e52375 100644 --- a/src/lib/multifact.hpp +++ b/src/lib/multifact.hpp @@ -46,7 +46,6 @@ namespace lib { namespace factory { - using util::contains; /** * Dummy "wrapper", @@ -60,9 +59,11 @@ namespace lib { PType wrap (TAR& object) { return object; } }; + /** - * Repository of registered production lines. - * @todo write type comment + * Table of registered production functions for MultiFact. + * Each stored function can be accessed by ID and is able + * to fabricate a specific object, which is assignable to TY */ template struct Fab @@ -74,7 +75,7 @@ namespace lib { FactoryFunc& select (ID id) { - if (!contains (producerTable_,id)) + if (!contains (id)) throw lumiera::error::Invalid("unknown factory product requested."); return producerTable_[id]; @@ -86,6 +87,12 @@ namespace lib { producerTable_[id] = fun; } + + /* === diagnostics === */ + + bool empty () const { return producerTable_.empty(); } + bool contains (ID id) const { return util::contains (producerTable_,id); } + private: std::map producerTable_; }; @@ -93,7 +100,14 @@ namespace lib { /** - * @todo write type comment + * Factory for creating a family of objects by ID. + * The actual factory functions are to be installed + * from the usage site through calls to #defineProduction . + * Each generated object will be treated by the Wrapper template, + * allowing for the generation of smart-ptrs. The embedded class + * Singleton allows to build a family of singleton objects; it is + * to be instantiated at the call site and acts as singleton factory, + * accessible through a MultiFact instance as frontend. */ template< typename TY , typename ID @@ -108,6 +122,7 @@ namespace lib { _Fab funcTable_; + public: Product operator() (ID id) @@ -116,6 +131,7 @@ namespace lib { return wrap (func()); } + /** to set up a production line, * associated with a specific ID */ @@ -126,17 +142,17 @@ namespace lib { funcTable_.defineProduction (id, fun); } + /** * Convenience shortcut for automatically setting up * a production line, fabricating a singleton instance * of the given target type (TAR) */ - template + template class Singleton - : lib::Singleton + : lib::Singleton { - typedef lib::Singleton SingFac; -// typedef std::tr1::function AccessSingleton_Func; + typedef lib::Singleton SingFac; Creator createSingleton_accessFunction() @@ -151,13 +167,30 @@ namespace lib { factory.defineProduction(id, createSingleton_accessFunction()); } }; + + + /* === diagnostics === */ + + bool empty () const { return funcTable_.empty(); } + bool contains (ID id) const { return funcTable_.contains (id); } }; } // namespace factory -//using factory::Factory; + + + /** + * Standard configuration of the family-of-object factory + * @todo this is rather guesswork... find out what the best and most used configuration could be.... + */ + template< typename TY + , typename ID + > + class MultiFact + : public factory::MultiFact + { }; } // namespace lib diff --git a/src/proc/control/handling-patterns.hpp b/src/proc/control/handling-patterns.hpp index 8a5a87c2c..0bf03035b 100644 --- a/src/proc/control/handling-patterns.hpp +++ b/src/proc/control/handling-patterns.hpp @@ -44,7 +44,7 @@ //#include "pre.hpp" #include "lib/error.hpp" -#include "lib/singleton-subclass.hpp" +#include "lib/multifact.hpp" #include "proc/control/handling-pattern.hpp" #include "proc/control/command-impl.hpp" #include "include/lifecycle.h" @@ -156,39 +156,27 @@ namespace control { /* ======== Handling Pattern Table ========== */ - typedef lib::SingletonSub SingletonFac; + typedef lib::MultiFact HandlingPatternFactory; /** Table of available command handling patterns */ - vector patternTable; + HandlingPatternFactory patternTable; + + HandlingPatternFactory::Singleton holder1 (patternTable, HandlingPattern::SYNC); + HandlingPatternFactory::Singleton holder2 (patternTable, HandlingPattern::SYNC_THROW); + HandlingPatternFactory::Singleton holder3 (patternTable, HandlingPattern::ASYNC); /** access the singleton instance for a given ID */ inline HandlingPattern const& - getPatternInstance (size_t id) + getPatternInstance (HandlingPattern::ID id) { - REQUIRE (id < patternTable.size()); - return patternTable[id] (); - } - - - /** populate the handling pattern table. - * This init-function will be invoked each time - * a new session is created or loaded. - */ - void - prepareCommandHandlingPatterns() - { - using lib::singleton::UseSubclass; + REQUIRE (patternTable.contains(id)); - patternTable[HandlingPattern::SYNC ] = SingletonFac(UseSubclass()); -// patternTable[HandlingPattern::SYNC_THROW] = SingletonFac(UseSubclass()); -// patternTable[HandlingPattern::ASYNC ] = SingletonFac(UseSubclass()); + return patternTable (id); } - - lumiera::LifecycleHook _schedule (lumiera::ON_GLOBAL_INIT, &prepareCommandHandlingPatterns); - } // (END) definition of concrete handling patterns + } // (END) definition of concrete handling patterns diff --git a/tests/lib/multifact-test.cpp b/tests/lib/multifact-test.cpp index 8669b188d..d2df7c886 100644 --- a/tests/lib/multifact-test.cpp +++ b/tests/lib/multifact-test.cpp @@ -37,8 +37,8 @@ namespace test{ using boost::lexical_cast; using lib::test::showSizeof; - //using util::isnil; using util::isSameObject; + using util::isnil; using std::ostream; using std::string; using std::cout; @@ -46,6 +46,7 @@ namespace test{ using lumiera::error::LUMIERA_ERROR_INVALID; + namespace { // hierarchy of test dummy objects struct Interface @@ -80,8 +81,10 @@ namespace test{ static theID getTypeID() { return ii; } }; + /** Factory instance for the tests... */ TestFactory theFact; + // Configure the products to be fabricated.... TestFactory::Singleton > holder1 (theFact,ONE); TestFactory::Singleton > holder2 (theFact,TWO); TestFactory::Singleton > holder3 (theFact,THR); @@ -116,6 +119,7 @@ namespace test{ ASSERT (isSameObject(o1,o2)); TestFactory anotherFact; + ASSERT (isnil (anotherFact)); VERIFY_ERROR (INVALID, anotherFact(ONE) ); TestFactory::Singleton > anotherSingletonHolder (anotherFact,ONE);