From: stephan b. <sg...@us...> - 2004-12-25 01:46:14
|
Update of /cvsroot/pclasses/pclasses2/include/pclasses/Plugin In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3409/include/pclasses/Plugin Modified Files: Plugin.h Log Message: Added an experimental FactoryInstanceHook partial specialization which adds DLL-lookup support to the default Factory::instance()es. Index: Plugin.h =================================================================== RCS file: /cvsroot/pclasses/pclasses2/include/pclasses/Plugin/Plugin.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- Plugin.h 25 Dec 2004 01:08:58 -0000 1.4 +++ Plugin.h 25 Dec 2004 01:46:04 -0000 1.5 @@ -14,7 +14,8 @@ #define CERR std::cerr << __FILE__ << ":" << std::dec << __LINE__ << " : " #endif -namespace P { namespace Plugin { +namespace P { +namespace Plugin { /** @@ -65,7 +66,7 @@ provide a platform-neutral Plugin interface. Note that it inherits a "context type" from NamedTypeFactory, - and shares factory maps with Factory<InterfaceT,string,ContextT>. + and shares factory maps with Factory<InterfaceT,ContextT,string>. The main implication of this is that one a PluginManager loads a plugin it may enable lower-level Factory objects to load types the plugin just loaded. @@ -108,6 +109,41 @@ // and cleans up it's container() now... } + + /** + Reimplemented to do DLL lookups. + + If a factory for feature is found then it is called + and the result is returned. If one is not found, we + look for a plugin via findPlugin( feature ). If + that finds a plugin, we open it and look again for + a factory for feature. If found, it is called, + otherwise we give up. + + The caller owns the returned object, which may be 0. + */ + virtual + InterfaceType * create( const std::string & feature ) + { + InterfaceType * ret = ParentType::create( feature ); + if( ret ) return ret; + std::string dll = this->findPlugin( feature ); + if( dll.empty() ) + { + return 0; + } + try + { + this->addPlugin( dll ); + ret = ParentType::create( feature ); + } + catch(...) + { + return 0; + } + return ret; + } + /** Adds dir to the lib search path. @@ -218,9 +254,6 @@ private: -// PluginManager( const ThisType & ); // not impl. -// ThisType & operator=( const ThisType & ); // not impl. - void init() { this->m_path.addPath( "." ); @@ -268,7 +301,44 @@ } -} } // namespace P:: Plugin +} // namespace Plugin + + +namespace Hook +{ + /** + This hook will cause calls to Factory::instance() to return + a PluginManager instance in disguise. Doing so enables DLL + lookups in the core without it knowing so. :) + */ + template < typename InterfaceT > + struct FactoryInstanceHook< ::P::Factory< InterfaceT, ::P::Sharing::FactoryContext, std::string > > + { + typedef ::P::Factory< InterfaceT, ::P::Sharing::FactoryContext, std::string > FactoryType; + typedef ::P::Plugin::PluginManager< InterfaceT > RealFactoryType; + typedef FactoryInstanceHook<FactoryType> ThisType; + + /** + */ + void operator()( FactoryType & ) throw() + { + CERR << "Initializing a PluginManager instance() we hacked in via FactoryInstanceHook!\n"; + } + + /** + The default implementation returns a shared Factory object. + THIS type's operator() will be called on the factory immediately + after creating the factory. + */ + static FactoryType & instance() + { + typedef ::P::Phoenix<RealFactoryType, ::P::Sharing::FactoryContext, ThisType > PHX; + return PHX::instance(); + } + }; + +} // ns Hook +} // namespace P #endif // p_PLUGIN_HPP_INCLUDED |