[Orxonox-commit 5921] r10580 - in code/branches/core7/src: libraries/core libraries/core/module orxonox

landauf at orxonox.net landauf at orxonox.net
Sat Sep 12 16:10:03 CEST 2015


Author: landauf
Date: 2015-09-12 16:10:02 +0200 (Sat, 12 Sep 2015)
New Revision: 10580

Added:
   code/branches/core7/src/libraries/core/module/PluginReference.cc
   code/branches/core7/src/libraries/core/module/PluginReference.h
Modified:
   code/branches/core7/src/libraries/core/CorePrereqs.h
   code/branches/core7/src/libraries/core/module/CMakeLists.txt
   code/branches/core7/src/libraries/core/module/PluginManager.cc
   code/branches/core7/src/libraries/core/module/PluginManager.h
   code/branches/core7/src/orxonox/Level.cc
   code/branches/core7/src/orxonox/Level.h
Log:
it's now possible to define required plugins in the level definition (in XML)

Modified: code/branches/core7/src/libraries/core/CorePrereqs.h
===================================================================
--- code/branches/core7/src/libraries/core/CorePrereqs.h	2015-09-09 14:14:14 UTC (rev 10579)
+++ code/branches/core7/src/libraries/core/CorePrereqs.h	2015-09-12 14:10:02 UTC (rev 10580)
@@ -211,6 +211,7 @@
     class OrxonoxInterface;
     class Plugin;
     class PluginManager;
+    class PluginReference;
     struct ResourceInfo;
     template <ScopeID::Value>
     class Scope;

Modified: code/branches/core7/src/libraries/core/module/CMakeLists.txt
===================================================================
--- code/branches/core7/src/libraries/core/module/CMakeLists.txt	2015-09-09 14:14:14 UTC (rev 10579)
+++ code/branches/core7/src/libraries/core/module/CMakeLists.txt	2015-09-12 14:10:02 UTC (rev 10580)
@@ -4,6 +4,7 @@
   ModuleInstance.cc
   Plugin.cc
   PluginManager.cc
+  PluginReference.cc
   StaticallyInitializedInstance.cc
   StaticInitializationHandlerIncludes.cc
   StaticInitializationManager.cc

Modified: code/branches/core7/src/libraries/core/module/PluginManager.cc
===================================================================
--- code/branches/core7/src/libraries/core/module/PluginManager.cc	2015-09-09 14:14:14 UTC (rev 10579)
+++ code/branches/core7/src/libraries/core/module/PluginManager.cc	2015-09-12 14:10:02 UTC (rev 10580)
@@ -32,22 +32,34 @@
 
 #include "SpecialConfig.h"
 #include "Plugin.h"
+#include "PluginReference.h"
 #include "core/ApplicationPaths.h"
 #include "core/command/ConsoleCommandIncludes.h"
+#include "core/object/Context.h"
 
 namespace orxonox
 {
-    SetConsoleCommand("PluginManager", "load", &PluginManager::loadPlugin);
-    SetConsoleCommand("PluginManager", "unload", &PluginManager::unloadPlugin);
+    static const std::string __CC_PluginManager_load_name  = "load";
+    static const std::string __CC_PluginManager_unload_name  = "unload";
 
+    SetConsoleCommand("PluginManager", __CC_PluginManager_load_name, &PluginManager::loadPlugin);
+    SetConsoleCommand("PluginManager", __CC_PluginManager_unload_name, &PluginManager::unloadPlugin);
+
     PluginManager* PluginManager::singletonPtr_s  = 0;
 
     PluginManager::PluginManager()
     {
+        ModifyConsoleCommand("PluginManager", __CC_PluginManager_load_name).setObject(this);
+        ModifyConsoleCommand("PluginManager", __CC_PluginManager_unload_name).setObject(this);
     }
 
     PluginManager::~PluginManager()
     {
+        ModifyConsoleCommand("PluginManager", __CC_PluginManager_load_name).setObject(NULL);
+        ModifyConsoleCommand("PluginManager", __CC_PluginManager_unload_name).setObject(NULL);
+
+        for (std::map<std::string, PluginReference*>::iterator it = this->references_.begin(); it != this->references_.end(); ++it)
+            delete it->second;
         for (std::map<std::string, Plugin*>::iterator it = this->plugins_.begin(); it != this->plugins_.end(); ++it)
             delete it->second;
     }
@@ -73,21 +85,50 @@
         }
     }
 
-    /*static*/ void PluginManager::loadPlugin(const std::string& name)
+    void PluginManager::referencePlugin(const std::string& name)
     {
-        Plugin* plugin = PluginManager::getInstance().plugins_[name];
+        Plugin* plugin = this->plugins_[name];
         if (plugin != NULL)
             plugin->load();
         else
             orxout(internal_warning) << "Cannot find plugin with name " << name << endl;
     }
 
-    /*static*/ void PluginManager::unloadPlugin(const std::string& name)
+    void PluginManager::dereferencePlugin(const std::string& name)
     {
-        Plugin* plugin = PluginManager::getInstance().plugins_[name];
+        Plugin* plugin = this->plugins_[name];
         if (plugin != NULL)
             plugin->unload();
         else
             orxout(internal_warning) << "Cannot find plugin with name " << name << endl;
     }
+
+    /**
+     * @brief Console command to manually load a plugin. The plugin stays loaded until @ref unloadPlugin is called.
+     */
+    void PluginManager::loadPlugin(const std::string& name)
+    {
+        if (this->references_[name] == NULL)
+        {
+            this->references_[name] = new PluginReference(name);
+        }
+        else
+            orxout(internal_warning) << "Plugin " << name << " is already loaded" << endl;
+    }
+
+    /**
+     * @brief Console command to unload a plugin if it was previously loaded manually by calling @ref loadPlugin.
+     * Does not unload the plugin immediately if it is still used by another @ref PluginReference (e.g. by a @ref Level).
+     */
+    void PluginManager::unloadPlugin(const std::string& name)
+    {
+        PluginReference* reference = this->references_[name];
+        if (reference != NULL)
+        {
+            this->references_[name] = NULL;
+            delete reference;
+        }
+        else
+            orxout(internal_warning) << "Plugin " << name << " is already unloaded" << endl;
+    }
 }

Modified: code/branches/core7/src/libraries/core/module/PluginManager.h
===================================================================
--- code/branches/core7/src/libraries/core/module/PluginManager.h	2015-09-09 14:14:14 UTC (rev 10579)
+++ code/branches/core7/src/libraries/core/module/PluginManager.h	2015-09-12 14:10:02 UTC (rev 10580)
@@ -47,11 +47,16 @@
 
             void findPlugins();
 
-            static void loadPlugin(const std::string& name);
-            static void unloadPlugin(const std::string& name);
+            void referencePlugin(const std::string& name);
+            void dereferencePlugin(const std::string& name);
 
+            // console commands
+            void loadPlugin(const std::string& name);
+            void unloadPlugin(const std::string& name);
+
         private:
             std::map<std::string, Plugin*> plugins_;
+            std::map<std::string, PluginReference*> references_; // references that were created by console command
 
             static PluginManager* singletonPtr_s;
     };

Added: code/branches/core7/src/libraries/core/module/PluginReference.cc
===================================================================
--- code/branches/core7/src/libraries/core/module/PluginReference.cc	                        (rev 0)
+++ code/branches/core7/src/libraries/core/module/PluginReference.cc	2015-09-12 14:10:02 UTC (rev 10580)
@@ -0,0 +1,46 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program 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 General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "PluginReference.h"
+
+#include "PluginManager.h"
+
+namespace orxonox
+{
+    PluginReference::PluginReference(const std::string& name) : name_(name)
+    {
+        // load plugin
+        PluginManager::getInstance().referencePlugin(this->name_);
+    }
+
+    PluginReference::~PluginReference()
+    {
+        // unload plugin
+        PluginManager::getInstance().dereferencePlugin(this->name_);
+    }
+}


Property changes on: code/branches/core7/src/libraries/core/module/PluginReference.cc
___________________________________________________________________
Added: svn:eol-style
   + native

Added: code/branches/core7/src/libraries/core/module/PluginReference.h
===================================================================
--- code/branches/core7/src/libraries/core/module/PluginReference.h	                        (rev 0)
+++ code/branches/core7/src/libraries/core/module/PluginReference.h	2015-09-12 14:10:02 UTC (rev 10580)
@@ -0,0 +1,49 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program 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 General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PluginReference_H__
+#define _PluginReference_H__
+
+#include "core/CorePrereqs.h"
+
+#include "core/object/Destroyable.h"
+
+namespace orxonox
+{
+    class _CoreExport PluginReference : public Destroyable
+    {
+        public:
+            PluginReference(const std::string& name);
+            ~PluginReference();
+
+        private:
+            std::string name_;
+    };
+}
+
+#endif /* _PluginReference_H__ */


Property changes on: code/branches/core7/src/libraries/core/module/PluginReference.h
___________________________________________________________________
Added: svn:eol-style
   + native

Modified: code/branches/core7/src/orxonox/Level.cc
===================================================================
--- code/branches/core7/src/orxonox/Level.cc	2015-09-09 14:14:14 UTC (rev 10579)
+++ code/branches/core7/src/orxonox/Level.cc	2015-09-12 14:10:02 UTC (rev 10580)
@@ -34,6 +34,7 @@
 #include "core/Template.h"
 #include "core/XMLFile.h"
 #include "core/XMLPort.h"
+#include "core/module/PluginReference.h"
 
 #include "infos/PlayerInfo.h"
 #include "gametypes/Gametype.h"
@@ -64,6 +65,8 @@
 
             if (this->xmlfile_)
                 Loader::getInstance().unload(this->xmlfile_);
+
+            this->unloadPlugins();
         }
     }
 
@@ -71,6 +74,7 @@
     {
         SUPER(Level, XMLPort, xmlelement, mode);
 
+        XMLPortParam(Level, "plugins",  setPluginsString,  getPluginsString,  xmlelement, mode);
         XMLPortParam(Level, "gametype", setGametypeString, getGametypeString, xmlelement, mode).defaultValues("Gametype");
 
         XMLPortObject(Level, MeshLodInformation, "lodinformation", addLodInfo, getLodInfo, xmlelement, mode);
@@ -107,6 +111,33 @@
         }
     }
 
+    void Level::setPluginsString(const std::string& pluginsString)
+    {
+        // unload old plugins
+        this->unloadPlugins();
+
+        // load new plugins
+        this->pluginsString_ = pluginsString;
+        SubString tokens(pluginsString, ",");
+        for (size_t i = 0; i < tokens.size(); ++i)
+            this->plugins_.push_back(new PluginReference(tokens[i]));
+    }
+
+    void Level::unloadPlugins()
+    {
+        // use destroyLater() - this ensures that plugins are not unloaded too early.
+        // Note: When a level gets unloaded, the Level object is usually the last object that gets destroyed. This is because all other
+        //       objects inside a level have a StrongPtr (in BaseObject) that references the Level object. This means that the Level
+        //       object is only destroyed, when all StrongPtrs that pointed to it were destroyed. But at the time when the last StrongPtr
+        //       is destroyed, the other object is not yet fully destroyed because the StrongPtr is destroyed in ~BaseObject (and this
+        //       means that e.g. ~Identifiable was not yet called for this object). This means that technically there are still other
+        //       objects alive when ~Level is called. This is the reason why we cannot directly destroy() the Plugins - instead we need
+        //       to call destroyLater() to ensure that no instances from this plugin exist anymore.
+        for (std::list<PluginReference*>::iterator it = this->plugins_.begin(); it != this->plugins_.end(); ++it)
+            (*it)->destroyLater();
+        this->plugins_.clear();
+    }
+
     void Level::setGametypeString(const std::string& gametype)
     {
         Identifier* identifier = ClassByString(gametype);

Modified: code/branches/core7/src/orxonox/Level.h
===================================================================
--- code/branches/core7/src/orxonox/Level.h	2015-09-09 14:14:14 UTC (rev 10579)
+++ code/branches/core7/src/orxonox/Level.h	2015-09-12 14:10:02 UTC (rev 10580)
@@ -64,12 +64,21 @@
 //            const MeshLodInformation* getLodInfo(std::string meshName) const;
 //            MeshLodInformation* getLodInfo(unsigned int index) const;
 
+            void setPluginsString(const std::string& pluginsString);
+            inline const std::string& getPluginsString() const
+                { return this->pluginsString_; }
+
+            void unloadPlugins();
+
             void setGametypeString(const std::string& gametype);
             inline const std::string& getGametypeString() const
                 { return this->gametype_; }
 
             void networkcallback_applyXMLFile();
 
+            std::string                    pluginsString_;
+            std::list<PluginReference*>    plugins_;
+
             std::string                    gametype_;
             std::string                    xmlfilename_;
             XMLFile*                       xmlfile_;




More information about the Orxonox-commit mailing list