/*----------------------------------------------------------------- LOG GEM - Graphics Environment for Multimedia - template implementation for PluginFactory Copyright (c) 2010-2011 IOhannes m zmölnig. forum::für::umläute. IEM. zmoelnig@iem.at For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution. -----------------------------------------------------------------*/ #ifndef _INCLUDE__GEM_PLUGINS_PLUGINFACTORY_H_ # error you must not include PluginFactory Implementation directly! include PluginFactory.h instead #endif #if 0 /* set to 1 to enable some debugging printout */ # define GEM_PLUGFAC_DEBUG 1 #else # define GEM_PLUGFAC_DEBUG 0 #endif /* on W32 (regardless of whether we use MinGW or M$VC) we must _not_ * define the template-implementation in the plugins, if we want to * use the same implementation in both host and plugin * (if we do, the host and the plugin will see different factories!) * * on linux/gcc we have to provide the implementation * (on osx/gcc as well, it seems) */ #if defined _WIN32 && !defined GEM_INTERNAL # define OMIT_PLUGINFACTORY_TEMPLATE_IMPLEMENATION #endif #ifndef OMIT_PLUGINFACTORY_TEMPLATE_IMPLEMENATION /* Implementation of templated PluginFactory */ /* actually this should be done in a cpp file rather than a header-file, * but since virtually no compiler can handle this it is done here... */ /* ********************************************************************* */ /* Implementation of PluginFactory */ template PluginFactory* PluginFactory::s_factory=NULL; template PluginFactory* PluginFactory::getPluginFactory(void) { if(NULL==s_factory) { s_factory=new PluginFactory; } #if GEM_PLUGFAC_DEBUG std::cerr << "factory @ " << (void*)s_factory << " --> " << typeid( s_factory).name() << std::endl; #endif /* GEM_PLUGFAC_DEBUG */ return s_factory; } template void PluginFactory::doRegisterClass(std::string id, ctor_t*c) { set(id, (void*)c); } template Class*PluginFactory::doGetInstance(std::string id) { ctor_t*ctor=(ctor_t*)get(id); if(ctor) { return ctor(); } else { return NULL; } } template void PluginFactory::registerClass(std::string id, ctor_t*c) { PluginFactory*fac=getPluginFactory(); if(NULL==fac) { std::cerr << "unable to get a factory!" << std::endl; } #if GEM_PLUGFAC_DEBUG std::cerr << "register " << typeid(Class).name() << " @ factory: " << (void*)fac << std::endl; #endif /* GEM_PLUGFAC_DEBUG */ fac->doRegisterClass(id, c); } template Class*PluginFactory::getInstance(std::string id) { PluginFactory*fac=getPluginFactory(); #if GEM_PLUGFAC_DEBUG std::cerr << "getting " << typeid(Class).name() << " instance '" << id << "' from factory: " << (void*)fac << std::endl; #endif /* GEM_PLUGFAC_DEBUG */ if(NULL==fac) { return NULL; } return(fac->doGetInstance(id)); } template int PluginFactory::loadPlugins(std::string basename, std::string path) { PluginFactory*fac=getPluginFactory(); #if GEM_PLUGFAC_DEBUG std::cerr << "loading " << typeid(Class).name() << " plugins from factory: " << (void*)fac << std::endl; #endif /* GEM_PLUGFAC_DEBUG */ if(NULL==fac) { return 0; } return fac->doLoadPlugins(basename, path); } template std::vectorPluginFactory::doGetIDs() { return get(); } template std::vectorPluginFactory::getIDs() { std::vectorresult; PluginFactory*fac=getPluginFactory(); if(fac) { return fac->doGetIDs(); } return result; } #endif /* !OMIT_PLUGINFACTORY_TEMPLATE_IMPLEMENATION */ /* ********************************************************************* */ /* Implementation of PluginFactoryRegistrar */ namespace PluginFactoryRegistrar { template BaseClass* allocator() { ChildClass* res0 = new ChildClass(); BaseClass* res1 = dynamic_cast(res0); if(NULL==res1) { /* if ChildClass is derived from BaseClass and we successfully allocated an object, * this code cannot never be reached; * the compiler can check this during template expansion, be we don't */ /* coverity[dead_error_line] FIXXME stackoverflow:23489764 */ delete res0; } return res1; } template registrar :: registrar(std::string id) { PluginFactory::registerClass(id, allocator); } template dummy :: dummy() { std::string id; // default ID PluginFactory::registerClass(id, NULL); } };