From: Timo Lotterbach Date: Wed, 28 Nov 2012 10:24:51 +0000 (-0800) Subject: LayerManagerService: updated PluginManager to load IPlugins X-Git-Tag: 1_0_rc~102 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=df1386047b08d89c1c349eba0236a65804447847;p=profile%2Fivi%2Flayer-management.git LayerManagerService: updated PluginManager to load IPlugins the plugin discovery was updated to recursively scan the whole plugin directory. Every file in this directory is tested, if it is a valid LayerManagement plugin. If a plugin is valid, it is instantiated. The type and API version of the plugin can be validated afterwards. Signed-off-by: Timo Lotterbach --- diff --git a/LayerManagerService/include/FileList.h b/LayerManagerService/include/FileList.h new file mode 100644 index 0000000..d6bba08 --- /dev/null +++ b/LayerManagerService/include/FileList.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * + * Copyright 2012 BMW Car IT GmbH + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ +#ifndef __FILELIST_H__ +#define __FILELIST_H__ + +#include +#include + +typedef std::list FileList; +typedef std::list::iterator FileListIterator; +typedef std::list::const_iterator FileListConstIterator; + +#endif // __FILELIST_H__ diff --git a/LayerManagerService/include/PluginList.h b/LayerManagerService/include/PluginList.h new file mode 100644 index 0000000..89fc361 --- /dev/null +++ b/LayerManagerService/include/PluginList.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * + * Copyright 2012 BMW Car IT GmbH + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ +#ifndef __PLUGINLIST_H__ +#define __PLUGINLIST_H__ + +#include +#include "IPlugin.h" + +typedef std::list PluginList; +typedef std::list::iterator PluginListIterator; +typedef std::list::const_iterator PluginListConstIterator; + +#endif // __PLUGINLIST_H__ diff --git a/LayerManagerService/include/PluginManager.h b/LayerManagerService/include/PluginManager.h index 93df875..6d7102d 100644 --- a/LayerManagerService/include/PluginManager.h +++ b/LayerManagerService/include/PluginManager.h @@ -16,40 +16,49 @@ * limitations under the License. * ****************************************************************************/ + #ifndef __PLUGINMANAGER_H__ #define __PLUGINMANAGER_H__ -#include "ilm_types.h" +#include "PluginList.h" #include "RendererList.h" +#include "HealthMonitorList.h" #include "CommunicatorList.h" #include "SceneProviderList.h" -#include "HealthMonitorList.h" +#include "FileList.h" class ICommandExecutor; class Configuration; +typedef IPlugin*(*StaticPluginCreateFunc)(ICommandExecutor&, Configuration&); +typedef std::list StaticPluginCreateFuncList; + + class PluginManager { public: PluginManager(ICommandExecutor& executor, Configuration& config); ~PluginManager(); - RendererList* getRendererList(); - CommunicatorList* getCommunicatorList(); - SceneProviderList* getSceneProviderList(); - HealthMonitorList* getHealthMonitorList(); - + void getRendererList(RendererList& list); + void getHealthMonitorList(HealthMonitorList& list); + void getSceneProviderList(SceneProviderList& list); + void getCommunicatorList(CommunicatorList& list); + + static bool registerStaticPluginCreateFunction(StaticPluginCreateFunc func); + private: - void createAndStartAllPlugins(); - void stopAndDestroyAllPlugins(); + void createStaticallyLinkedPlugins(); + void getAllFilesInPluginPath(std::string path); + void createDynamicallyLinkedPlugins(); + IPlugin* createDynamicallyLinkedPlugin(std::string path); private: ICommandExecutor& mExecutor; Configuration& mConfiguration; - RendererList mRendererList; - CommunicatorList mCommunicatorList; - SceneProviderList mSceneProviderList; - HealthMonitorList mHealthMonitorList; + FileList mFileList; + PluginList mPluginList; + static StaticPluginCreateFuncList mStaticPluginCreateFuncList; }; -#endif // __PLUGINMANAGER_H__ +#endif // __PLUGINMANAGER_H__ \ No newline at end of file diff --git a/LayerManagerService/src/Layermanager.cpp b/LayerManagerService/src/Layermanager.cpp index 3e31d6c..9bcc3f7 100644 --- a/LayerManagerService/src/Layermanager.cpp +++ b/LayerManagerService/src/Layermanager.cpp @@ -44,15 +44,41 @@ Layermanager::Layermanager(Configuration& config) m_pPluginManager = new PluginManager(*this, mConfiguration); m_pApplicationReferenceMap = new ApplicationReferenceMap(); - m_pRendererList = m_pPluginManager->getRendererList(); - m_pCommunicatorList = m_pPluginManager->getCommunicatorList(); - m_pSceneProviderList = m_pPluginManager->getSceneProviderList(); - m_pHealthMonitorList = m_pPluginManager->getHealthMonitorList(); + m_pRendererList = new RendererList(); + m_pCommunicatorList = new CommunicatorList(); + m_pSceneProviderList = new SceneProviderList(); + m_pHealthMonitorList = new HealthMonitorList(); + + m_pPluginManager->getRendererList(*m_pRendererList); + m_pPluginManager->getCommunicatorList(*m_pCommunicatorList); + m_pPluginManager->getSceneProviderList(*m_pSceneProviderList); + m_pPluginManager->getHealthMonitorList(*m_pHealthMonitorList); + mHealthState = true; } Layermanager::~Layermanager() { + if (m_pRendererList) + { + delete m_pRendererList; + } + + if (m_pCommunicatorList) + { + delete m_pCommunicatorList; + } + + if (m_pSceneProviderList) + { + delete m_pSceneProviderList; + } + + if (m_pHealthMonitorList) + { + delete m_pHealthMonitorList; + } + if (m_pApplicationReferenceMap) { delete m_pApplicationReferenceMap; diff --git a/LayerManagerService/src/PluginManager.cpp b/LayerManagerService/src/PluginManager.cpp index bed8654..4f651bc 100644 --- a/LayerManagerService/src/PluginManager.cpp +++ b/LayerManagerService/src/PluginManager.cpp @@ -18,441 +18,253 @@ ****************************************************************************/ #include "PluginManager.h" -#include "ICommandExecutor.h" #include "Configuration.h" -#include "Scene.h" +#include "Log.h" +#include "IPlugin.h" +#include -#include -#include #include #include #include -#include "Log.h" -#include // basename -#include - -#include -using std::list; +#include -#include -using std::string; -typedef list tFileList; -typedef list::iterator tFileListIterator; +StaticPluginCreateFuncList PluginManager::mStaticPluginCreateFuncList; //=========================================================================== -// plugin configuration +// register statically linked plugins (configured by build system) //=========================================================================== -const char* gPluginLookupPath = NULL; - -const char* gRendererPluginDirectories[] = { "/renderer" }; - -uint gRendererPluginDirectoriesCount = sizeof(gRendererPluginDirectories) / sizeof(gRendererPluginDirectories[0]); - -const char* gCommunicatorPluginDirectories[] = { "/communicator" }; - -uint gCommunicatorPluginDirectoriesCount = sizeof(gCommunicatorPluginDirectories) / sizeof(gCommunicatorPluginDirectories[0]); - -const char* gScenePluginDirectories[] = { "/sceneprovider" }; - -uint gScenePluginDirectoriesCount = sizeof(gScenePluginDirectories) / sizeof(gScenePluginDirectories[0]); - -const char* gHealthPluginDirectories[] = { "/health" }; - -uint gHealthPluginDirectoriesCount = sizeof(gHealthPluginDirectories) / sizeof(gHealthPluginDirectories[0]); +STATIC_PLUGIN_REGISTRATION //=========================================================================== -// global functions for loading plugins +// class implementation //=========================================================================== -template -T* getCreateFunction(string libname) +PluginManager::PluginManager(ICommandExecutor& executor, Configuration& config) +: mExecutor(executor) +, mConfiguration(config) { - // cut off directories - char* fileWithPath = const_cast(libname.c_str()); - string libFileName = basename(fileWithPath); - LOG_DEBUG("LayerManagerService", "lib name without directory: " << libFileName); + LOG_DEBUG("PluginManager", "loading plugins from " << mConfiguration.getPluginPath()); - // cut off "lib" in front and cut off .so end" - string createFunctionName = "create" + libFileName.substr(3, libFileName.length() - 6); - LOG_DEBUG("LayerManagerService", "lib entry point name: " << createFunctionName); + // create static plugins + createStaticallyLinkedPlugins(); - // open library - void *libraryHandle; - dlerror(); // Clear any existing error - libraryHandle = dlopen(libname.c_str(), RTLD_NOW | RTLD_GLOBAL /*LAZY*/); - const char* dlopen_error = dlerror(); - if (!libraryHandle || dlopen_error) - { - LOG_ERROR("LayerManagerService", "dlopen failed: " << dlopen_error); - dlclose(libraryHandle); - return 0; - } + // create dynamic plugins + getAllFilesInPluginPath(mConfiguration.getPluginPath()); + createDynamicallyLinkedPlugins(); - // get entry point from shared lib - dlerror(); // Clear any existing error - LOG_DEBUG("LayerManagerService", "loading external function with name: " << createFunctionName); - - union - { - void* voidPointer; - T* typedPointer; - } functionPointer; - - // Note: direct cast is not allowed by ISO C++. e.g. - // T* createFunction = reinterpret_cast(dlsym(libraryHandle, createFunctionName.c_str())); - // compiler warning: "forbids casting between pointer-to-function and pointer-to-object" - - functionPointer.voidPointer = dlsym(libraryHandle, createFunctionName.c_str()); - T* createFunction = functionPointer.typedPointer; + LOG_INFO("PluginManager", "created " << mPluginList.size() << " plugins"); +} + +PluginManager::~PluginManager() +{ + PluginList::iterator iter = mPluginList.begin(); + PluginList::iterator iterEnd = mPluginList.end(); - const char* dlsym_error = dlerror(); - if (!createFunction || dlsym_error) + for (; iter != iterEnd; ++iter) { - LOG_ERROR("LayerManagerService", "Failed to load shared lib entry point: " << dlsym_error); + IPlugin* plugin = *iter; + if (plugin) + { + LOG_INFO("PluginManager", "plugin " << plugin->pluginGetName() << " destroyed"); + delete plugin; + } } - - // Note: free these resources on shutdown - //dlclose(libraryHandle); - - return createFunction; + mPluginList.clear(); } -void getSharedLibrariesFromDirectory(tFileList& fileList, string dirName) +void PluginManager::getRendererList(RendererList& list) { - // open directory - DIR *directory = opendir(dirName.c_str()); - if (!directory) + PluginList::const_iterator iter = mPluginList.begin(); + PluginList::const_iterator iterEnd = mPluginList.end(); + + for (; iter != iterEnd; ++iter) { - LOG_ERROR("LayerManagerService", "Error(" << errno << ") opening " << dirName); - return; + IPlugin* plugin = *iter; + ilmPluginApi api = plugin->pluginGetApi(); + if (PLUGIN_IS_RENDERER(api)) + { + IRenderer* renderer = dynamic_cast(plugin); + list.push_back(renderer); + } } +} + +void PluginManager::getHealthMonitorList(HealthMonitorList& list) +{ + PluginList::const_iterator iter = mPluginList.begin(); + PluginList::const_iterator iterEnd = mPluginList.end(); - // iterate content of directory - struct dirent *itemInDirectory = 0; - while ((itemInDirectory = readdir(directory))) + for (; iter != iterEnd; ++iter) { - unsigned char entryType = itemInDirectory->d_type; - string entryName = itemInDirectory->d_name; - - bool regularFile; - bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1)); - - if ((entryType == DT_LNK) || (entryType == DT_UNKNOWN)) + IPlugin* plugin = *iter; + ilmPluginApi api = plugin->pluginGetApi(); + if (PLUGIN_IS_HEALTHMONITOR(api)) { - struct stat st; - string fpath = dirName + "/" + itemInDirectory->d_name; - - if (!stat(fpath.c_str(), &st)) - regularFile = S_ISREG(st.st_mode); - else + IHealthMonitor* monitor = dynamic_cast(plugin); + if (monitor) { - regularFile = false; - LOG_WARNING("LayerManagerService", "Could not stat() file " << fpath << ": " << errno); + list.push_back(monitor); } } - else - { - regularFile = (entryType == DT_REG); - } - - - if (regularFile && sharedLibExtension) - { - LOG_DEBUG("LayerManagerService", "adding file " << entryName); - fileList.push_back(dirName + "/" + entryName); - } - else - { - LOG_DEBUG("LayerManagerService", "ignoring file " << entryName);; - } } - - closedir(directory); } -void loadHealthPlugins(HealthMonitorList& healthMonitorList, ICommandExecutor* executor) +void PluginManager::getSceneProviderList(SceneProviderList& list) { - tFileList sharedLibraryNameList; - - // search sceneprovider plugins in configured directories - for (uint dirIndex = 0; dirIndex < gScenePluginDirectoriesCount; ++dirIndex) - { - char directoryName[1024]; - strncpy(directoryName, gPluginLookupPath, sizeof(directoryName) - 1); - strncat(directoryName, gHealthPluginDirectories[dirIndex], sizeof(directoryName) - 1 - strlen(directoryName)); - LOG_DEBUG("LayerManagerService", "Searching for HealthMonitors in: " << directoryName); - getSharedLibrariesFromDirectory(sharedLibraryNameList, directoryName); - } - - LOG_DEBUG("LayerManagerService", sharedLibraryNameList.size() << " HealthMonitor plugins found"); - - // iterate all communicator plugins and start them - tFileListIterator iter = sharedLibraryNameList.begin(); - tFileListIterator iterEnd = sharedLibraryNameList.end(); + PluginList::const_iterator iter = mPluginList.begin(); + PluginList::const_iterator iterEnd = mPluginList.end(); for (; iter != iterEnd; ++iter) { - LOG_INFO("LayerManagerService", "Loading HealthMonitor plugin " << *iter); - - IHealthMonitor* (*createFunc)(ICommandExecutor* executor); - createFunc = getCreateFunction(*iter); - - if (!createFunc) + IPlugin* plugin = *iter; + ilmPluginApi api = plugin->pluginGetApi(); + if (PLUGIN_IS_SCENEPROVIDER(api)) { - LOG_DEBUG("LayerManagerService", "Entry point of HealthMonitor not found"); - continue; - } - - LOG_DEBUG("LayerManagerService", "Creating HealthMonitor instance"); - IHealthMonitor* newHealthMonitor = createFunc(executor); - - if (!newHealthMonitor) - { - LOG_ERROR("LayerManagerService","HealthMonitor initialization failed. Entry Function not callable"); - continue; + ISceneProvider* sceneprovider = dynamic_cast(plugin); + list.push_back(sceneprovider); } - - healthMonitorList.push_back(newHealthMonitor); } } - -void loadScenePlugins(SceneProviderList& sceneProviderList, ICommandExecutor* executor) +void PluginManager::getCommunicatorList(CommunicatorList& list) { - tFileList sharedLibraryNameList; - - // search sceneprovider plugins in configured directories - for (uint dirIndex = 0; dirIndex < gScenePluginDirectoriesCount; ++dirIndex) - { - char directoryName[1024]; - strncpy(directoryName, gPluginLookupPath, sizeof(directoryName) - 1); - strncat(directoryName, gScenePluginDirectories[dirIndex], sizeof(directoryName) - 1 - strlen(directoryName)); - LOG_DEBUG("LayerManagerService", "Searching for SceneProviders in: " << directoryName); - getSharedLibrariesFromDirectory(sharedLibraryNameList, directoryName); - } - - LOG_DEBUG("LayerManagerService", sharedLibraryNameList.size() << " SceneProvider plugins found"); - - // iterate all communicator plugins and start them - tFileListIterator iter = sharedLibraryNameList.begin(); - tFileListIterator iterEnd = sharedLibraryNameList.end(); + PluginList::const_iterator iter = mPluginList.begin(); + PluginList::const_iterator iterEnd = mPluginList.end(); for (; iter != iterEnd; ++iter) { - LOG_INFO("LayerManagerService", "Loading SceneProvider plugin " << *iter); - - ISceneProvider* (*createFunc)(ICommandExecutor*); - createFunc = getCreateFunction(*iter); - - if (!createFunc) + IPlugin* plugin = *iter; + ilmPluginApi api = plugin->pluginGetApi(); + if (PLUGIN_IS_COMMUNICATOR(api)) { - LOG_DEBUG("LayerManagerService", "Entry point of SceneProvider not found"); - continue; + ICommunicator* comm = dynamic_cast(plugin); + list.push_back(comm); } - - LOG_DEBUG("LayerManagerService", "Creating SceneProvider instance"); - ISceneProvider* newSceneProvider = createFunc(executor); - - if (!newSceneProvider) - { - LOG_ERROR("LayerManagerService","SceneProvider initialization failed. Entry Function not callable"); - continue; - } - - sceneProviderList.push_back(newSceneProvider); } } -void loadCommunicatorPlugins(CommunicatorList& communicatorList, ICommandExecutor* executor) +bool PluginManager::registerStaticPluginCreateFunction(StaticPluginCreateFunc func) { - tFileList sharedLibraryNameList; - - // search communicator plugins in configured directories - for (uint dirIndex = 0; dirIndex < gCommunicatorPluginDirectoriesCount; ++dirIndex) + bool result = false; + if (func) { - char directoryName[1024]; - strncpy(directoryName, gPluginLookupPath, sizeof(directoryName) - strlen(directoryName)); - strncat(directoryName, gCommunicatorPluginDirectories[dirIndex], sizeof(directoryName) -strlen(directoryName)); - LOG_DEBUG("LayerManagerService", "Searching for communicator in: " << directoryName); - getSharedLibrariesFromDirectory(sharedLibraryNameList, directoryName); + mStaticPluginCreateFuncList.push_back(func); + result = true; } - - LOG_DEBUG("LayerManagerService", sharedLibraryNameList.size() << " Communicator plugins found"); - - // iterate all communicator plugins and start them - tFileListIterator iter = sharedLibraryNameList.begin(); - tFileListIterator iterEnd = sharedLibraryNameList.end(); + return result; +} + +void PluginManager::createStaticallyLinkedPlugins() +{ + StaticPluginCreateFuncList::iterator iter = mStaticPluginCreateFuncList.begin(); + StaticPluginCreateFuncList::iterator iterEnd = mStaticPluginCreateFuncList.end(); for (; iter != iterEnd; ++iter) { - LOG_INFO("LayerManagerService", "Loading Communicator plugin " << *iter); - - ICommunicator* (*createFunc)(ICommandExecutor*); - createFunc = getCreateFunction(*iter); + StaticPluginCreateFunc func = *iter; + IPlugin* plugin = (*func)(mExecutor, mConfiguration); + LOG_INFO("PluginManager", "creating plugin " << plugin->pluginGetName() << " (static linking)"); + mPluginList.push_back(plugin); + } +} + +void PluginManager::getAllFilesInPluginPath(std::string path) +{ + DIR *directory = opendir(path.c_str()); + struct dirent *itemInDirectory = 0; + + while (directory && (itemInDirectory = readdir(directory))) + { + unsigned char entryType = itemInDirectory->d_type; + std::string entryName = itemInDirectory->d_name; + std::string fullPath = path + "/" + entryName; - if (!createFunc) + if (entryName.at(0) == '.') { - LOG_DEBUG("LayerManagerService", "Entry point of Communicator not found"); continue; } - LOG_DEBUG("LayerManagerService", "Creating Communicator instance"); - ICommunicator* newCommunicator = createFunc(executor); - - if (!newCommunicator) + switch (entryType) { - LOG_ERROR("LayerManagerService","Communicator initialization failed. Entry Function not callable"); - continue; + case DT_REG: + case DT_LNK: + case DT_UNKNOWN: + mFileList.push_back(fullPath); + LOG_DEBUG("PluginManager", "considering File " << fullPath); + break; + + case DT_DIR: + getAllFilesInPluginPath(fullPath); + break; + + default: + LOG_DEBUG("PluginManager", "ignored file " << fullPath); + break; } - - communicatorList.push_back(newCommunicator); } + + closedir(directory); } -void loadRendererPlugins(RendererList& rendererList, IScene* pScene) +void PluginManager::createDynamicallyLinkedPlugins() { - tFileList sharedLibraryNameList; - - // search communicator plugins in configured directories - for (uint dirIndex = 0; dirIndex < gRendererPluginDirectoriesCount; ++dirIndex) - { - char directoryName[1024]; - strncpy(directoryName, gPluginLookupPath, sizeof(directoryName) - 1); - strncat(directoryName, gRendererPluginDirectories[dirIndex], sizeof(directoryName) - 1 - strlen(directoryName)); - LOG_DEBUG("LayerManagerService", "Searching for renderer in: " << directoryName); - getSharedLibrariesFromDirectory(sharedLibraryNameList, directoryName); - } - - LOG_DEBUG("LayerManagerService", sharedLibraryNameList.size() << " Renderer plugins found"); - - // currently the use of only one renderer is enforced - if (sharedLibraryNameList.size() > 1) - { - LOG_WARNING("LayerManagerService", "more than 1 Renderer plugin found. using only " << sharedLibraryNameList.front()); - while (sharedLibraryNameList.size() > 1) - { - sharedLibraryNameList.pop_back(); - } - } - - // iterate all renderer plugins and start them - tFileListIterator iter = sharedLibraryNameList.begin(); - tFileListIterator iterEnd = sharedLibraryNameList.end(); + FileList::const_iterator iter = mFileList.begin(); + FileList::const_iterator iterEnd = mFileList.end(); for (; iter != iterEnd; ++iter) { - LOG_INFO("LayerManagerService", "Loading Renderer plugin " << *iter); - IRenderer* (*createFunc)(IScene*); - createFunc = getCreateFunction(*iter); - if (!createFunc) - { - LOG_DEBUG("LayerManagerService", "Entry point of Renderer not found"); - continue; - } - - LOG_DEBUG("LayerManagerService", "Creating Renderer instance"); - IRenderer* newRenderer = createFunc(pScene); - if (!newRenderer) + IPlugin* plugin = createDynamicallyLinkedPlugin(*iter); + if (plugin) { - LOG_ERROR("LayerManagerService","Renderer initialization failed. Entry Function not callable"); - continue; + mPluginList.push_back(plugin); } - - rendererList.push_back(newRenderer); } } - -//=========================================================================== -// class implementation -//=========================================================================== -PluginManager::PluginManager(ICommandExecutor& executor, Configuration& config) -: mExecutor(executor) -, mConfiguration(config) -{ - createAndStartAllPlugins(); -} - -PluginManager::~PluginManager() -{ - stopAndDestroyAllPlugins(); -} - -RendererList* PluginManager::getRendererList() -{ - return &mRendererList; -} - -CommunicatorList* PluginManager::getCommunicatorList() -{ - return &mCommunicatorList; -} - -SceneProviderList* PluginManager::getSceneProviderList() -{ - return &mSceneProviderList; -} - -HealthMonitorList* PluginManager::getHealthMonitorList() +IPlugin* PluginManager::createDynamicallyLinkedPlugin(std::string path) { - return &mHealthMonitorList; -} - -void PluginManager::createAndStartAllPlugins() -{ - gPluginLookupPath = mConfiguration.getPluginPath().c_str(); + IPlugin* returnValue = NULL; + + // open library + void *libraryHandle; + dlerror(); // Clear any existing error + libraryHandle = dlopen(path.c_str(), RTLD_NOW | RTLD_GLOBAL); + const char* dlopen_error = dlerror(); + if (dlopen_error) + { + LOG_DEBUG("PluginManager", "not a shared library: " << dlopen_error); + return NULL; + } - LOG_INFO("LayerManagerService", "Used plugin directory is " << gPluginLookupPath); + // load entry point + union + { + void* data; + IPlugin* (*createFunc)(ICommandExecutor&, Configuration&); + } convertUnion; - LOG_DEBUG("LayerManagerService", "Loading renderer plugins."); - loadRendererPlugins(mRendererList, mExecutor.getScene()); + int cutBegin = path.find_last_of('/') + 4; // remove '*/lib' from name + int cutEnd = path.find_first_of('.', cutBegin); // remove '.extension' from name - LOG_DEBUG("LayerManagerService", "Loading communicator plugins."); - loadCommunicatorPlugins(mCommunicatorList, &mExecutor); + std::string createFunctionName = "create"; + createFunctionName += path.substr(cutBegin, cutEnd - cutBegin); - LOG_DEBUG("LayerManagerService", "Loading scene provider plugins."); - loadScenePlugins(mSceneProviderList, &mExecutor); - - LOG_DEBUG("LayerManagerService", "Loading health monitor plugins."); - loadHealthPlugins(mHealthMonitorList, &mExecutor); -} - -void PluginManager::stopAndDestroyAllPlugins() -{ - LOG_DEBUG("LayerManagerService", "Removing all scene provider plugins.") - { - SceneProviderListIterator iter = mSceneProviderList.begin(); - SceneProviderListIterator iterEnd = mSceneProviderList.end(); - for (; iter != iterEnd; ++iter) - { - ISceneProvider* sceneProvider = *iter; - delete sceneProvider; - } - mSceneProviderList.clear(); - } + convertUnion.data = dlsym(libraryHandle, createFunctionName.c_str()); - LOG_DEBUG("LayerManagerService", "Removing all communicator plugins.") + // create plugin instance from entry point + const char* dlsym_error = dlerror(); + if (convertUnion.data && !dlsym_error) { - CommunicatorListIterator iter = mCommunicatorList.begin(); - CommunicatorListIterator iterEnd = mCommunicatorList.end(); - for (; iter != iterEnd; ++iter) - { - ICommunicator* comm = *iter; - delete comm; - } - mCommunicatorList.clear(); + returnValue = convertUnion.createFunc(mExecutor, mConfiguration); + LOG_INFO("PluginManager", "creating plugin " << returnValue->pluginGetName() << " (dynamic linking)"); } - - LOG_DEBUG("LayerManagerService", "Removing all renderer plugins.") + else { - RendererListIterator iter = mRendererList.begin(); - RendererListIterator iterEnd = mRendererList.end(); - for (; iter != iterEnd; ++iter) - { - IRenderer* renderer = *iter; - delete renderer; - } - mRendererList.clear(); + LOG_DEBUG("PluginManager", "not a valid Plugin: " << path << ": " << dlsym_error); + dlclose(libraryHandle); + returnValue = NULL; } -} + + return returnValue; +} \ No newline at end of file