/** * @file Common/iregistry.h * @brief Common registry for interfaces * @author Enar Vaikene * * Copyright (c) 2011 Enar Vaikene * * This file is part of the eVaf C++ cross-platform application development framework. * * This file can be used under the terms of the GNU General Public License * version 3.0 as published by the Free Software Foundation and appearing in * the file LICENSE included in the packaging of this file. Please review the * the following information to ensure the GNU General Public License version * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. * * Alternatively, this file may be used in accordance with the Commercial License * Agreement provided with the Software. */ #ifndef __COMMON_IREGISTRY_H #define __COMMON_IREGISTRY_H #include "libcommon.h" #include #include namespace eVaf { namespace Common { /** * Common registry for interfaces. * @code#include @endcode * * Registry is a central collection of all the eVaf interfaces and iRegistry the interface for it. * Modules use the iRegistry interface to register new interfaces and query existing ones. * * Existing interfaces are queried with the queryInterface() function. The returned pointer to QObject * shall be type casted to the requested interface class using qobject_cast<>(): * @code * iEnv * env = qobject_cast(iRegistry::instance()->queryInterface("iEnv")); * @endcode * * Or use the evafQueryInterface<>() function: * @code * iEnv * env = evafQueryInterface("iEnv"); * @endcode * * Registering new interfaces is done with the registerInterface() function as shown in the following example: * @code * iRegistry::instance()->registerInterface("iSample", this); * @endcode * * In general, every interface should have a unique name. If an interface is registered with a name that already * exists, then the new interface overwrites the old interface with the same name. To reimplement an interface, * query for the old implementation, store it and then register a new interface with the same name. * * Any class implementing an interface shall have QObject as their top-most parent. * * iRegistry and instance() functions * * Most of the interfaces have the instance() function that returns the current instance of the interface. * The main difference is that by using the instance() function, modules shall link against the module * that implements the interface's instance() function. The iRegistry interface can be used to get the same * interface without knowing the module that implements it. */ class COMMON_EXPORT iRegistry : public QObject { Q_OBJECT public: /// Interface constructor iRegistry() : QObject() {} /// Empty virtual destructor virtual ~iRegistry() {} /** * Returns the iRegistry interface instance * @return The iRegistry interface * * This function returns the global iRegistry interface instance. All eVaf modules and applications * are expected to be linked against the common library and this is the only method of obtaining * the iRegistry interface. */ static iRegistry * instance(); /** * Registers an interface * @param name Name of the interface * @param obj Object implementing the interface * @return True if ok; false if registering failed * * This function registers a new interface in the global registry of interfaces. * * If an interface with this name already exists, then the new interface implementation overwrites the old * implementation. */ virtual bool registerInterface(QString const & name, QObject * obj) = 0; /** * Returns the interface by its name * @param name Name of the interface * @return Interface implementation or NULL if not found. * * This function queries the global registry for the interface by its name. It returns a pointer * to the implementation of the interface or NULL if no such interface is found. * * Use the qobject_cast<>() function to type cast the returned pointer to the required interface class. * Always check for NULL in case there is a mismatch in interface versions or no such interface is found. */ virtual QObject * queryInterface(QString const & name) const = 0; }; } // namespace eVaf::Common } // namespace eVaf /** * Helper function for querying interfaces * @param name Name of the requested interface * @return The requested interface or NULL if not found * * This function can be used to query interfaces from the global registry. It returns a properly * type-casted interface or NULL if the interface cannot be found or is of an invalid type. * * Example: * @code * iEnv * env = evafQueryInterface("iEnv"); * if (env) { * // Use the interface * } * @endcode */ template inline T * evafQueryInterface(QString const & name) { return qobject_cast(eVaf::Common::iRegistry::instance()->queryInterface(name)); } #endif // iregistry.h