[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