Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 10580


Ignore:
Timestamp:
Sep 12, 2015, 4:10:02 PM (4 years ago)
Author:
landauf
Message:

it's now possible to define required plugins in the level definition (in XML)

Location:
code/branches/core7/src
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • code/branches/core7/src/libraries/core/CorePrereqs.h

    r10555 r10580  
    212212    class Plugin;
    213213    class PluginManager;
     214    class PluginReference;
    214215    struct ResourceInfo;
    215216    template <ScopeID::Value>
  • code/branches/core7/src/libraries/core/module/CMakeLists.txt

    r10552 r10580  
    55  Plugin.cc
    66  PluginManager.cc
     7  PluginReference.cc
    78  StaticallyInitializedInstance.cc
    89  StaticInitializationHandlerIncludes.cc
  • code/branches/core7/src/libraries/core/module/PluginManager.cc

    r10552 r10580  
    3333#include "SpecialConfig.h"
    3434#include "Plugin.h"
     35#include "PluginReference.h"
    3536#include "core/ApplicationPaths.h"
    3637#include "core/command/ConsoleCommandIncludes.h"
     38#include "core/object/Context.h"
    3739
    3840namespace orxonox
    3941{
    40     SetConsoleCommand("PluginManager", "load", &PluginManager::loadPlugin);
    41     SetConsoleCommand("PluginManager", "unload", &PluginManager::unloadPlugin);
     42    static const std::string __CC_PluginManager_load_name  = "load";
     43    static const std::string __CC_PluginManager_unload_name  = "unload";
     44
     45    SetConsoleCommand("PluginManager", __CC_PluginManager_load_name, &PluginManager::loadPlugin);
     46    SetConsoleCommand("PluginManager", __CC_PluginManager_unload_name, &PluginManager::unloadPlugin);
    4247
    4348    PluginManager* PluginManager::singletonPtr_s  = 0;
     
    4550    PluginManager::PluginManager()
    4651    {
     52        ModifyConsoleCommand("PluginManager", __CC_PluginManager_load_name).setObject(this);
     53        ModifyConsoleCommand("PluginManager", __CC_PluginManager_unload_name).setObject(this);
    4754    }
    4855
    4956    PluginManager::~PluginManager()
    5057    {
     58        ModifyConsoleCommand("PluginManager", __CC_PluginManager_load_name).setObject(NULL);
     59        ModifyConsoleCommand("PluginManager", __CC_PluginManager_unload_name).setObject(NULL);
     60
     61        for (std::map<std::string, PluginReference*>::iterator it = this->references_.begin(); it != this->references_.end(); ++it)
     62            delete it->second;
    5163        for (std::map<std::string, Plugin*>::iterator it = this->plugins_.begin(); it != this->plugins_.end(); ++it)
    5264            delete it->second;
     
    7486    }
    7587
    76     /*static*/ void PluginManager::loadPlugin(const std::string& name)
     88    void PluginManager::referencePlugin(const std::string& name)
    7789    {
    78         Plugin* plugin = PluginManager::getInstance().plugins_[name];
     90        Plugin* plugin = this->plugins_[name];
    7991        if (plugin != NULL)
    8092            plugin->load();
     
    8395    }
    8496
    85     /*static*/ void PluginManager::unloadPlugin(const std::string& name)
     97    void PluginManager::dereferencePlugin(const std::string& name)
    8698    {
    87         Plugin* plugin = PluginManager::getInstance().plugins_[name];
     99        Plugin* plugin = this->plugins_[name];
    88100        if (plugin != NULL)
    89101            plugin->unload();
     
    91103            orxout(internal_warning) << "Cannot find plugin with name " << name << endl;
    92104    }
     105
     106    /**
     107     * @brief Console command to manually load a plugin. The plugin stays loaded until @ref unloadPlugin is called.
     108     */
     109    void PluginManager::loadPlugin(const std::string& name)
     110    {
     111        if (this->references_[name] == NULL)
     112        {
     113            this->references_[name] = new PluginReference(name);
     114        }
     115        else
     116            orxout(internal_warning) << "Plugin " << name << " is already loaded" << endl;
     117    }
     118
     119    /**
     120     * @brief Console command to unload a plugin if it was previously loaded manually by calling @ref loadPlugin.
     121     * Does not unload the plugin immediately if it is still used by another @ref PluginReference (e.g. by a @ref Level).
     122     */
     123    void PluginManager::unloadPlugin(const std::string& name)
     124    {
     125        PluginReference* reference = this->references_[name];
     126        if (reference != NULL)
     127        {
     128            this->references_[name] = NULL;
     129            delete reference;
     130        }
     131        else
     132            orxout(internal_warning) << "Plugin " << name << " is already unloaded" << endl;
     133    }
    93134}
  • code/branches/core7/src/libraries/core/module/PluginManager.h

    r10552 r10580  
    4848            void findPlugins();
    4949
    50             static void loadPlugin(const std::string& name);
    51             static void unloadPlugin(const std::string& name);
     50            void referencePlugin(const std::string& name);
     51            void dereferencePlugin(const std::string& name);
     52
     53            // console commands
     54            void loadPlugin(const std::string& name);
     55            void unloadPlugin(const std::string& name);
    5256
    5357        private:
    5458            std::map<std::string, Plugin*> plugins_;
     59            std::map<std::string, PluginReference*> references_; // references that were created by console command
    5560
    5661            static PluginManager* singletonPtr_s;
  • code/branches/core7/src/orxonox/Level.cc

    r10579 r10580  
    3535#include "core/XMLFile.h"
    3636#include "core/XMLPort.h"
     37#include "core/module/PluginReference.h"
    3738
    3839#include "infos/PlayerInfo.h"
     
    6566            if (this->xmlfile_)
    6667                Loader::getInstance().unload(this->xmlfile_);
     68
     69            this->unloadPlugins();
    6770        }
    6871    }
     
    7275        SUPER(Level, XMLPort, xmlelement, mode);
    7376
     77        XMLPortParam(Level, "plugins",  setPluginsString,  getPluginsString,  xmlelement, mode);
    7478        XMLPortParam(Level, "gametype", setGametypeString, getGametypeString, xmlelement, mode).defaultValues("Gametype");
    7579
     
    106110            Template::getTemplate(*it)->applyOn(this);
    107111        }
     112    }
     113
     114    void Level::setPluginsString(const std::string& pluginsString)
     115    {
     116        // unload old plugins
     117        this->unloadPlugins();
     118
     119        // load new plugins
     120        this->pluginsString_ = pluginsString;
     121        SubString tokens(pluginsString, ",");
     122        for (size_t i = 0; i < tokens.size(); ++i)
     123            this->plugins_.push_back(new PluginReference(tokens[i]));
     124    }
     125
     126    void Level::unloadPlugins()
     127    {
     128        // use destroyLater() - this ensures that plugins are not unloaded too early.
     129        // Note: When a level gets unloaded, the Level object is usually the last object that gets destroyed. This is because all other
     130        //       objects inside a level have a StrongPtr (in BaseObject) that references the Level object. This means that the Level
     131        //       object is only destroyed, when all StrongPtrs that pointed to it were destroyed. But at the time when the last StrongPtr
     132        //       is destroyed, the other object is not yet fully destroyed because the StrongPtr is destroyed in ~BaseObject (and this
     133        //       means that e.g. ~Identifiable was not yet called for this object). This means that technically there are still other
     134        //       objects alive when ~Level is called. This is the reason why we cannot directly destroy() the Plugins - instead we need
     135        //       to call destroyLater() to ensure that no instances from this plugin exist anymore.
     136        for (std::list<PluginReference*>::iterator it = this->plugins_.begin(); it != this->plugins_.end(); ++it)
     137            (*it)->destroyLater();
     138        this->plugins_.clear();
    108139    }
    109140
  • code/branches/core7/src/orxonox/Level.h

    r9667 r10580  
    6565//            MeshLodInformation* getLodInfo(unsigned int index) const;
    6666
     67            void setPluginsString(const std::string& pluginsString);
     68            inline const std::string& getPluginsString() const
     69                { return this->pluginsString_; }
     70
     71            void unloadPlugins();
     72
    6773            void setGametypeString(const std::string& gametype);
    6874            inline const std::string& getGametypeString() const
     
    7076
    7177            void networkcallback_applyXMLFile();
     78
     79            std::string                    pluginsString_;
     80            std::list<PluginReference*>    plugins_;
    7281
    7382            std::string                    gametype_;
Note: See TracChangeset for help on using the changeset viewer.