/* -*- c++ -*- This file is part of libkdepim. Copyright (c) 2002,2004 Marc Mutz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __KPIM_SHARED_PLUGINLOADER_H__ #define __KPIM_SHARED_PLUGINLOADER_H__ #include namespace KPIM { /** * @short A generic plugin loader for when KPart::Plugin is overkill * @author Marc Mutz based on KABC's FormatFactory * * This is a generic plugin loader / factory for small plugins that * don't want to be QObjects. * * @section Usage * * A PluginLoader takes two template arguments, T and * T_config: * *
*
T
The type of object to return
*
T_config::mainfunc
The suffix of the factory function to call * in the library to obtain a new object of type T. * The string passed to KLibrary::symbol() is * libName_mainfunc.
*
T_config::path
The search pattern for .desktop files * containing the plugin descriptions. This is the string passed as * the @p filter argument to * KStandardDirs::findAllResources.
*
* * The last two parameters being strings, they are passed via an * encapsulating class, of which mainfunc and * path are public static members: * *
   * struct MyObjectPluginLoaderConfig {
   *   static const char * const mainfunc;
   *   static const char * const path;
   * };
   * const char * const MyObjectPluginLoaderConfig::mainfunc = "myapp_create_myobject";
   * const char * const MyObjectPluginLoaderConfig::path = "myapp/plugins/ *.desktop";
   * 
* * You would then use a typedef to create a less unwieldy * name for your plugin loader: * *
   * typedef KPIM::PluginLoader< MyObject, MyObjectPluginLoaderConfig > MyObjectPluginLoader;
   * 
* * All of this is what the * KPIM_DEFINE_PLUGIN_LOADER(pluginloadername,type,mainfunc,path) macro * achieves. * **/ template< typename T, typename T_config > class KDE_EXPORT PluginLoader : public PluginLoaderBase { protected: PluginLoader() : PluginLoaderBase() {} private: static PluginLoader * mSelf; public: virtual ~PluginLoader() { mSelf = 0; } /** Returns the single instance of this loader. */ static PluginLoader * instance() { if ( !mSelf ) { mSelf = new PluginLoader(); mSelf->scan(); } return mSelf; } /** Rescans the plugin directory to find any newly installed plugins. **/ virtual void scan() { doScan( T_config::path ); } /** Returns a pointer to a plugin object (of type @p T) or a null pointer if the type wasn't found. You can extend this method for when you want to handle builtin types */ virtual T * createForName( const QString & type ) const { void * main_func = mainFunc( type, T_config::mainfunc ); if ( !main_func ) return 0; // cast to a pointer to a function returning T*, call it and // return the result; don't you love C? ;-) return ((T* (*)())( main_func ))(); } }; template< typename T, typename T_config > PluginLoader * PluginLoader::mSelf = 0; } #define KPIM_DEFINE_PLUGIN_LOADER( pl, t, mf, p ) \ namespace { /* don't pollute namespaces */ \ struct KDE_EXPORT pl##Config { \ static const char * const mainfunc; \ static const char * const path; \ }; \ const char * const pl##Config::mainfunc = mf; \ const char * const pl##Config::path = p; \ } \ typedef KPIM::PluginLoader< t, pl##Config > pl; \ #endif // __KPIM_SHARED_PLUGINLOADER_H__