LayerManagerService: updated PluginManager to load IPlugins
authorTimo Lotterbach <timo.lotterbach@bmw-carit.de>
Wed, 28 Nov 2012 10:24:51 +0000 (02:24 -0800)
committerTimo Lotterbach <timo.lotterbach@bmw-carit.de>
Mon, 14 Jan 2013 08:34:16 +0000 (00:34 -0800)
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 <timo.lotterbach@bmw-carit.de>
LayerManagerService/include/FileList.h [new file with mode: 0644]
LayerManagerService/include/PluginList.h [new file with mode: 0644]
LayerManagerService/include/PluginManager.h
LayerManagerService/src/Layermanager.cpp
LayerManagerService/src/PluginManager.cpp

diff --git a/LayerManagerService/include/FileList.h b/LayerManagerService/include/FileList.h
new file mode 100644 (file)
index 0000000..d6bba08
--- /dev/null
@@ -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 <list>
+#include <string>
+
+typedef std::list<std::string> FileList;
+typedef std::list<std::string>::iterator FileListIterator;
+typedef std::list<std::string>::const_iterator FileListConstIterator;
+
+#endif // __FILELIST_H__
diff --git a/LayerManagerService/include/PluginList.h b/LayerManagerService/include/PluginList.h
new file mode 100644 (file)
index 0000000..89fc361
--- /dev/null
@@ -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 <list>
+#include "IPlugin.h"
+
+typedef std::list<IPlugin*> PluginList;
+typedef std::list<IPlugin*>::iterator PluginListIterator;
+typedef std::list<IPlugin*>::const_iterator PluginListConstIterator;
+
+#endif // __PLUGINLIST_H__
index 93df875..6d7102d 100644 (file)
  * 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<StaticPluginCreateFunc> 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
index 3e31d6c..9bcc3f7 100644 (file)
@@ -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;
index bed8654..4f651bc 100644 (file)
  ****************************************************************************/
 
 #include "PluginManager.h"
-#include "ICommandExecutor.h"
 #include "Configuration.h"
-#include "Scene.h"
+#include "Log.h"
+#include "IPlugin.h"
+#include <IScene.h>
 
-#include <iostream>
-#include <sys/types.h>
 #include <dirent.h>
 #include <errno.h>
 #include <dlfcn.h>
-#include "Log.h"
-#include <libgen.h> // basename
-#include <sys/stat.h>
-
-#include <list>
-using std::list;
+#include <stdlib.h>
 
-#include <string.h>
-using std::string;
 
-typedef list<string> tFileList;
-typedef list<string>::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<class T>
-T* getCreateFunction(string libname)
+PluginManager::PluginManager(ICommandExecutor& executor, Configuration& config)
+: mExecutor(executor)
+, mConfiguration(config)
 {
-    // cut off directories
-    char* fileWithPath = const_cast<char*>(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<T*>(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<IRenderer*>(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<IHealthMonitor*>(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<IHealthMonitor*(ICommandExecutor* executor)>(*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<ISceneProvider*>(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<ISceneProvider*(ICommandExecutor*)>(*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<ICommunicator*>(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<ICommunicator*(ICommandExecutor*)>(*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<IRenderer*(IScene*)>(*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