From: Prochnow, C. <pro...@se...> - 2005-05-18 14:27:57
|
Hi List, i've rewritten the Factory and PluginManager! The old one had some problems which could not be solved with the old implementation: 1) The first problem was that using Phoenix<> inside of a template leads to different instances used by client- and library-code. We should keep that in mind - never use Phoenix<> inline or inside of a template !! 2) The second problem was the FactoryInstanceHook code. I wondered why Factory::create() could not create a type which should be dynamically loaded by the PluginManager. After figuring out how the old code worked, i realized that one had to use PuginManager::create() instead of Factory::create() to make use of the "dynamically loadable types" feature, which was not feasible. I remember, the goal was that Factory can create types that are dynamically registered by shared libraries, without even knowing about shared libraries. Ok, now the solution: 1) Instances of Factory are now kept by the FactoryBase class, which is implemented in the library itself. Instances of Factory are retrieved and created by a call to FactoryBase::instance(). FactoryBase::instance() uses a callback to create an instance of the requested Factory (Factory::createHook()). 2) FactoryBase holds a list of registered type-loader callbacks, which can be registered via FactoryBase::registerLoader(). The type-loader callbacks are called by Factory::create() whenever a type should be created, which is not known to the Factory. This enables the PluginManager to register a type-loader which tries to dynamically load types from shared libraries. The PluginManager's type-loader is statically registered upon application init. Some notes: FactoryBase and PluginManager must distinguish between different Interface- and Context-types, since these classes are non-templates, they use type-strings obtained by a call to the RTTI typeid() function. A draw-back is that the new Factory implementation does not support a variable key-type, since it is not possible for the non-templated FactoryBase to have variable key-types. Maybe we can re-introduce this feature, if it's really needed, by using key-string's generated by LexT<>. The Factory-class is now thread-safe. I added the CoreMutex class to get rid of the dependency on the System-module in the AtomicTraits class, which should be only used by classes in the core-module. Example: suppose we have a shared-library named "FileLogTarget.so" which implements the LogTarget interface. The class inside the library is also named "FileLogTarget". // add directory where plugins are located PluginManager::instance().addPluginDir<LogTarget>("./plugins"); // create an instance of FileLogTarget LogTarget* target = Factory<LogTarget>::instance().create("FileLogTarget"); We now have an instance of the FileLogTarget class which got dynamically registered by the shared-library, cool .. isnt it ? With the old Factory and PluginManager code clients had to be aware that FileLogTarget did come from a plugin and therefore had to use PluginManager<LogTarget>::create() instead of Factory<LogTarget>::create(). Regards, Christian |