Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 2087 for code/trunk/src/core


Ignore:
Timestamp:
Nov 1, 2008, 7:04:09 PM (16 years ago)
Author:
landauf
Message:

merged objecthierarchy branch back to trunk

Location:
code/trunk
Files:
3 deleted
36 edited
10 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/core/ArgumentCompletionFunctions.cc

    r1505 r2087  
    3030#include <map>
    3131
    32 #include "boost/filesystem.hpp"
     32#include <boost/filesystem.hpp>
    3333
    3434#include "ArgumentCompletionFunctions.h"
  • code/trunk/src/core/BaseObject.cc

    r1625 r2087  
    3535#include "tinyxml/tinyxml.h"
    3636#include "CoreIncludes.h"
     37#include "EventIncludes.h"
    3738#include "XMLPort.h"
    38 #include "Level.h"
     39#include "XMLFile.h"
     40#include "XMLNameListener.h"
     41#include "Template.h"
     42#include "util/String.h"
    3943
    4044namespace orxonox
     
    4549        @brief Constructor: Registers the object in the BaseObject-list.
    4650    */
    47     BaseObject::BaseObject() : bInitialized_(false)
     51    BaseObject::BaseObject(BaseObject* creator) : bInitialized_(false)
    4852    {
    4953        RegisterRootObject(BaseObject);
     
    5357        this->bActive_ = true;
    5458        this->bVisible_ = true;
    55 
    56         this->level_ = 0;
    57         this->namespace_ = 0;
     59        this->oldGametype_ = 0;
     60
     61        this->setCreator(creator);
     62        if (this->creator_)
     63        {
     64            this->setFile(this->creator_->getFile());
     65            this->setNamespace(this->creator_->getNamespace());
     66            this->setScene(this->creator_->getScene());
     67            this->setGametype(this->creator_->getGametype());
     68        }
     69        else
     70        {
     71            this->file_ = 0;
     72            this->namespace_ = 0;
     73            this->scene_ = 0;
     74            this->gametype_ = 0;
     75        }
    5876    }
    5977
     
    6381    BaseObject::~BaseObject()
    6482    {
     83        for (std::list<BaseObject*>::const_iterator it = this->events_.begin(); it != this->events_.end(); ++it)
     84            (*it)->unregisterEventListener(this);
     85
     86        for (std::map<BaseObject*, std::string>::const_iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
     87            it->first->removeEvent(this);
    6588    }
    6689
     
    7396    void BaseObject::XMLPort(Element& xmlelement, XMLPort::Mode mode)
    7497    {
    75         XMLPortParam(BaseObject, "name", setName, getName, xmlelement, mode);
     98        XMLPortParam(BaseObject, "name", setXMLName, getName, xmlelement, mode);
    7699        XMLPortParam(BaseObject, "visible", setVisible, isVisible, xmlelement, mode);
    77100        XMLPortParam(BaseObject, "active", setActive, isActive, xmlelement, mode);
     101
     102        XMLPortObjectTemplate(BaseObject, Template, "templates", addTemplate, getTemplate, xmlelement, mode, Template*);
     103
     104        Element* events = xmlelement.FirstChildElement("events", false);
     105
     106        if (events)
     107        {
     108            std::list<std::string> eventnames;
     109
     110            if (mode == XMLPort::LoadObject)
     111            {
     112                for (ticpp::Iterator<ticpp::Element> child = events->FirstChildElement(false); child != child.end(); child++)
     113                    eventnames.push_back(child->Value());
     114            }
     115            else if (mode == XMLPort::SaveObject)
     116            {
     117                for (std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->getIdentifier()->getXMLPortEventMapBegin(); it != this->getIdentifier()->getXMLPortEventMapEnd(); ++it)
     118                    eventnames.push_back(it->first);
     119            }
     120
     121            for (std::list<std::string>::iterator it = eventnames.begin(); it != eventnames.end(); ++it)
     122            {
     123                std::string sectionname = (*it);
     124                ExecutorMember<BaseObject>* loadexecutor = createExecutor(createFunctor(&BaseObject::addEvent), std::string( "BaseObject" ) + "::" + "addEvent");
     125                ExecutorMember<BaseObject>* saveexecutor = createExecutor(createFunctor(&BaseObject::getEvent), std::string( "BaseObject" ) + "::" + "getEvent");
     126                loadexecutor->setDefaultValue(1, sectionname);
     127
     128                XMLPortClassObjectContainer<BaseObject, BaseObject>* container = 0;
     129                container = (XMLPortClassObjectContainer<BaseObject, BaseObject>*)(this->getIdentifier()->getXMLPortEventContainer(sectionname));
     130                if (!container)
     131                {
     132                    container = new XMLPortClassObjectContainer<BaseObject, BaseObject>(sectionname, this->getIdentifier(), loadexecutor, saveexecutor, false, true);
     133                    this->getIdentifier()->addXMLPortEventContainer(sectionname, container);
     134                }
     135                container->port(this, *events, mode);
     136            }
     137        }
     138    }
     139
     140    /**
     141        @brief Loads the name of the object through XML and calls all XMLNameListener.
     142        @param name The name of the object
     143    */
     144    void BaseObject::setXMLName(const std::string& name)
     145    {
     146        this->setName(name);
     147
     148        for (ObjectList<XMLNameListener>::iterator it = ObjectList<XMLNameListener>::begin(); it != ObjectList<XMLNameListener>::end(); ++it)
     149            it->loadedNewXMLName(this);
    78150    }
    79151
     
    82154        @return The levelfile
    83155    */
    84     const std::string& BaseObject::getLevelfile() const
    85     {
    86         return this->level_->getFile();
     156    const std::string& BaseObject::getFilename() const
     157    {
     158        if (this->file_)
     159            return this->file_->getFilename();
     160        else
     161            return BLANKSTRING;
     162    }
     163
     164    /**
     165        @brief Adds a Template to the object.
     166        @param name The name of the Template
     167    */
     168    void BaseObject::addTemplate(const std::string& name)
     169    {
     170        Template* temp = Template::getTemplate(name);
     171        if (temp)
     172            this->addTemplate(temp);
     173        else
     174            COUT(1) << "Error: \"" << name << "\" is not a valid Template name (in class: " << this->getIdentifier()->getName() << ", name: " << this->getName() << ")." << std::endl;
     175    }
     176
     177    /**
     178        @brief Adds a Template to the object.
     179        @param temp The Template
     180    */
     181    void BaseObject::addTemplate(Template* temp)
     182    {
     183        this->templates_.insert(temp);
     184        temp->applyOn(this);
     185    }
     186
     187    /**
     188        @brief Returns the Template with the given index.
     189        @param index The index
     190    */
     191    Template* BaseObject::getTemplate(unsigned int index) const
     192    {
     193        unsigned int i = 0;
     194        for (std::set<Template*>::const_iterator it = this->templates_.begin(); it != this->templates_.end(); ++it)
     195        {
     196            if (i == index)
     197                return (*it);
     198            i++;
     199        }
     200        return 0;
     201    }
     202
     203    void BaseObject::addEvent(BaseObject* event, const std::string& sectionname)
     204    {
     205        event->registerEventListener(this, sectionname);
     206        this->events_.push_back(event);
     207    }
     208
     209    void BaseObject::removeEvent(BaseObject* event)
     210    {
     211        this->events_.remove(event);
     212    }
     213
     214    BaseObject* BaseObject::getEvent(unsigned int index) const
     215    {
     216        unsigned int i = 0;
     217        for (std::list<BaseObject*>::const_iterator it = this->events_.begin(); it != this->events_.end(); ++it)
     218        {
     219            if (i == index)
     220                return (*it);
     221            ++i;
     222        }
     223        return 0;
     224    }
     225
     226    void BaseObject::addEventContainer(const std::string& sectionname, EventContainer* container)
     227    {
     228        std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.find(sectionname);
     229        if (it != this->eventContainers_.end())
     230        {
     231            COUT(2) << "Warning: Overwriting EventContainer in class " << this->getIdentifier()->getName() << "." << std::endl;
     232            delete (it->second);
     233        }
     234
     235        this->eventContainers_[sectionname] = container;
     236    }
     237
     238    EventContainer* BaseObject::getEventContainer(const std::string& sectionname) const
     239    {
     240        std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.find(sectionname);
     241        if (it != this->eventContainers_.end())
     242            return ((*it).second);
     243        else
     244            return 0;
     245    }
     246
     247    void BaseObject::fireEvent()
     248    {
     249        this->fireEvent(true);
     250        this->fireEvent(false);
     251    }
     252
     253    void BaseObject::fireEvent(bool activate)
     254    {
     255        this->fireEvent(activate, this);
     256    }
     257
     258    void BaseObject::fireEvent(bool activate, BaseObject* originator)
     259    {
     260        Event event(activate, originator);
     261
     262        for (std::map<BaseObject*, std::string>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
     263        {
     264            event.sectionname_ = it->second;
     265            it->first->processEvent(event);
     266        }
     267    }
     268
     269    void BaseObject::fireEvent(Event& event)
     270    {
     271        for (std::map<BaseObject*, std::string>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
     272            it->first->processEvent(event);
     273    }
     274
     275    void BaseObject::processEvent(Event& event)
     276    {
     277        SetEvent(BaseObject, "activity", setActive, event);
     278        SetEvent(BaseObject, "visibility", setVisible, event);
    87279    }
    88280}
  • code/trunk/src/core/BaseObject.h

    r1841 r2087  
    3737#define _BaseObject_H__
    3838
     39#include <map>
     40
    3941#include "CorePrereqs.h"
    4042
     
    4244#include "OrxonoxClass.h"
    4345#include "XMLIncludes.h"
     46#include "Event.h"
    4447
    4548namespace orxonox
    4649{
     50    class Scene;
     51    class Gametype;
     52
    4753    //! The BaseObject is the parent of all classes representing an instance in the game.
    4854    class _CoreExport BaseObject : virtual public OrxonoxClass
    4955    {
    50         friend class WorldEntity;
    51 
    5256        public:
    53             BaseObject();
     57            BaseObject(BaseObject* creator);
    5458            virtual ~BaseObject();
    5559            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
     
    5963
    6064            /** @brief Sets the name of the object. @param name The name */
    61             inline void setName(const std::string& name) { this->name_ = name; this->changedName(); }
    62             /** @brief Returns the name of the object. @return The name */
     65            inline void setName(const std::string& name) { this->oldName_ = this->name_; this->name_ = name; this->changedName(); }
     66            /** @brief Returns the name of the object. */
    6367            inline const std::string& getName() const { return this->name_; }
     68            /** @brief Returns the old name of the object. */
     69            inline const std::string& getOldName() const { return this->oldName_; }
    6470            /** @brief This function gets called if the name of the object changes. */
    6571            virtual void changedName() {}
     
    7985            virtual void changedVisibility() {}
    8086
    81             /** @brief Sets a pointer to the level that loaded this object. @param level The pointer to the level */
    82             inline void setLevel(const Level* level) { this->level_ = level; }
    83             /** @brief Returns a pointer to the level that loaded this object. @return The level */
    84             inline const Level* getLevel() const { return this->level_; }
    85             const std::string& getLevelfile() const;
     87            /** @brief Sets a pointer to the xml file that loaded this object. @param file The pointer to the XMLFile */
     88            inline void setFile(const XMLFile* file) { this->file_ = file; }
     89            /** @brief Returns a pointer to the XMLFile that loaded this object. @return The XMLFile */
     90            inline const XMLFile* getFile() const { return this->file_; }
     91            const std::string& getFilename() const;
     92
     93            void addTemplate(const std::string& name);
     94            void addTemplate(Template* temp);
     95            /** @brief Returns the set of all aplied templates. */
     96            inline const std::set<Template*>& getTemplates() const
     97                { return this->templates_; }
    8698
    8799            virtual inline void setNamespace(Namespace* ns) { this->namespace_ = ns; }
    88100            inline Namespace* getNamespace() const { return this->namespace_; }
     101
     102            inline void setCreator(BaseObject* creator) { this->creator_ = creator; }
     103            inline BaseObject* getCreator() const { return this->creator_; }
     104
     105            inline void setScene(Scene* scene) { this->scene_ = scene; }
     106            inline Scene* getScene() const { return this->scene_; }
     107
     108            inline void setGametype(Gametype* gametype) { this->oldGametype_ = this->gametype_; this->gametype_ = gametype; this->changedGametype(); }
     109            inline Gametype* getGametype() const { return this->gametype_; }
     110            inline Gametype* getOldGametype() const { return this->oldGametype_; }
     111            virtual inline void changedGametype() {}
     112
     113            void fireEvent();
     114            void fireEvent(bool activate);
     115            void fireEvent(bool activate, BaseObject* originator);
     116            void fireEvent(Event& event);
     117
     118            virtual void processEvent(Event& event);
     119
     120            inline void registerEventListener(BaseObject* object, const std::string& sectionname)
     121                { this->eventListeners_[object] = sectionname; }
     122            inline void unregisterEventListener(BaseObject* object)
     123                { this->eventListeners_.erase(object); }
     124
     125            void addEvent(BaseObject* event, const std::string& sectionname);
     126            void removeEvent(BaseObject* event);
     127            BaseObject* getEvent(unsigned int index) const;
     128
     129            void addEventContainer(const std::string& sectionname, EventContainer* container);
     130            EventContainer* getEventContainer(const std::string& sectionname) const;
    89131
    90132            /** @brief Sets the indentation of the debug output in the Loader. @param indentation The indentation */
     
    93135            inline const std::string& getLoaderIndentation() const { return this->loaderIndentation_; }
    94136
    95         private:
     137        protected:
    96138            std::string name_;                          //!< The name of the object
    97             bool bInitialized_;                         //!< True if the object was initialized (passed the object registration)
     139            std::string oldName_;                       //!< The old name of the object
    98140            bool bActive_;                              //!< True = the object is active
    99141            bool bVisible_;                             //!< True = the object is visible
    100             const Level* level_;                        //!< The level that loaded this object
    101             std::string loaderIndentation_;             //!< Indentation of the debug output in the Loader
    102             Namespace* namespace_;
     142
     143        private:
     144            void setXMLName(const std::string& name);
     145            Template* getTemplate(unsigned int index) const;
     146
     147            bool                  bInitialized_;         //!< True if the object was initialized (passed the object registration)
     148            const XMLFile*        file_;                 //!< The XMLFile that loaded this object
     149            std::string           loaderIndentation_;    //!< Indentation of the debug output in the Loader
     150            Namespace*            namespace_;
     151            BaseObject*           creator_;
     152            Scene*                scene_;
     153            Gametype*             gametype_;
     154            Gametype*             oldGametype_;
     155            std::set<Template*>   templates_;
     156            std::map<BaseObject*, std::string> eventListeners_;
     157            std::list<BaseObject*> events_;
     158            std::map<std::string, EventContainer*> eventContainers_;
    103159    };
    104160
     
    106162    SUPER_FUNCTION(2, BaseObject, changedActivity, false);
    107163    SUPER_FUNCTION(3, BaseObject, changedVisibility, false);
     164    SUPER_FUNCTION(4, BaseObject, processEvent, false);
    108165}
    109166
  • code/trunk/src/core/CMakeLists.txt

    r1887 r2087  
    44  ConfigValueContainer.cc
    55  Core.cc
     6  Event.cc
    67  GameState.cc
    78  Language.cc
     9  LuaBind.cc
    810  ObjectListBase.cc
    911  OrxonoxClass.cc
    1012  RootGameState.cc
    11   Script.cc
    1213
    1314  # command
     
    3132  Namespace.cc
    3233  NamespaceNode.cc
     34  Template.cc
    3335  XMLPort.cc
     36  XMLNameListener.cc
    3437
    3538  # shell
     
    6265    tolua_orxonox
    6366    tolua/tolua.pkg
    64     Script.h
     67    LuaBind.h
    6568    CommandExecutor.h
    6669  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/lib
  • code/trunk/src/core/ClassFactory.h

    r1747 r2087  
    5555    {
    5656        public:
    57             static bool create(const std::string& name);
    58             BaseObject* fabricate();
     57            static bool create(const std::string& name, bool bLoadable = true);
     58            BaseObject* fabricate(BaseObject* creator);
    5959
    6060        private:
     
    6363            virtual ~ClassFactory() {}                      // Don't delete
    6464
    65             static T* createNewObject();
     65            static T* createNewObject(BaseObject* creator);
    6666    };
    6767
    6868    /**
    6969        @brief Adds the ClassFactory to the Identifier of the same type and the Identifier to the Factory.
     70        @param name The name of the class
     71        @param bLoadable True if the class can be loaded through XML
    7072        @return Always true (this is needed because the compiler only allows assignments before main())
    7173    */
    7274    template <class T>
    73     bool ClassFactory<T>::create(const std::string& name)
     75    bool ClassFactory<T>::create(const std::string& name, bool bLoadable)
    7476    {
    7577        COUT(4) << "*** ClassFactory: Create entry for " << name << " in Factory." << std::endl;
    7678        ClassIdentifier<T>::getIdentifier(name)->addFactory(new ClassFactory<T>);
     79        ClassIdentifier<T>::getIdentifier()->setLoadable(bLoadable);
    7780        Factory::add(name, ClassIdentifier<T>::getIdentifier());
    7881
     
    8588    */
    8689    template <class T>
    87     BaseObject* ClassFactory<T>::fabricate()
     90    BaseObject* ClassFactory<T>::fabricate(BaseObject* creator)
    8891    {
    89         return ClassFactory<T>::createNewObject();
     92        return ClassFactory<T>::createNewObject(creator);
    9093    }
    9194
     
    9598    */
    9699    template <class T>
    97     T* ClassFactory<T>::createNewObject()
     100    T* ClassFactory<T>::createNewObject(BaseObject* creator)
    98101    {
    99         return new T;
     102        return new T(creator);
    100103    }
    101104}
  • code/trunk/src/core/CommandEvaluation.cc

    r1879 r2087  
    7878        if (this->bEvaluatedParams_ && this->function_)
    7979        {
    80             COUT(5) << "CE_execute (evaluation): " << this->function_->getName() << " " << this->param_[0] << " " << this->param_[1] << " " << this->param_[2] << " " << this->param_[3] << " " << this->param_[4] << std::endl;
     80            COUT(6) << "CE_execute (evaluation): " << this->function_->getName() << " " << this->param_[0] << " " << this->param_[1] << " " << this->param_[2] << " " << this->param_[3] << " " << this->param_[4] << std::endl;
    8181            (*this->function_)(this->param_[0], this->param_[1], this->param_[2], this->param_[3], this->param_[4]);
    8282            return true;
  • code/trunk/src/core/CommandLine.cc

    r1755 r2087  
    3535    /**
    3636    @brief
     37        Parses a value string for a command line argument.
     38        It simply uses convertValue(Output, Input) to do that.
     39        Bools are treated specially. That is necessary
     40        so that you can have simple command line switches.
     41    */
     42    void CommandLineArgument::parse(const std::string& value)
     43    {
     44        if (value_.getType() == MT_bool)
     45        {
     46            // simulate command line switch
     47            bool temp;
     48            if (convertValue(&temp, value))
     49            {
     50                this->bHasDefaultValue_ = false;
     51                this->value_ = temp;
     52            }
     53            else if (value == "")
     54            {
     55                this->bHasDefaultValue_ = false;
     56                this->value_ = true;
     57            }
     58            else
     59            {
     60                ThrowException(Argument, "Could not read command line argument '" + getName() + "'.");
     61            }
     62        }
     63        else
     64        {
     65            if (!value_.setValue(value))
     66            {
     67                value_.setValue(defaultValue_);
     68                ThrowException(Argument, "Could not read command line argument '" + getName() + "'.");
     69            }
     70            else
     71                this->bHasDefaultValue_ = false;
     72        }
     73    }
     74
     75
     76    /**
     77    @brief
    3778        Destructor destroys all CommandLineArguments with it.
    3879    */
    3980    CommandLine::~CommandLine()
    4081    {
    41         for (std::map<std::string, BaseCommandLineArgument*>::const_iterator it = cmdLineArgs_.begin();
     82        for (std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.begin();
    4283            it != cmdLineArgs_.end(); ++it)
    4384        {
     
    73114        {
    74115            // first shove all the shortcuts in a map
    75             for (std::map<std::string, BaseCommandLineArgument*>::const_iterator it = cmdLineArgs_.begin();
     116            for (std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.begin();
    76117                it != cmdLineArgs_.end(); ++it)
    77118            {
     
    178219    void CommandLine::checkFullArgument(const std::string& name, const std::string& value)
    179220    {
    180         std::map<std::string, BaseCommandLineArgument*>::const_iterator it = cmdLineArgs_.find(name);
     221        std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.find(name);
    181222        if (it == cmdLineArgs_.end())
    182223            ThrowException(Argument, "Command line argument '" + name + "' does not exist.");
     
    195236    void CommandLine::checkShortcut(const std::string& shortcut, const std::string& value)
    196237    {
    197         std::map<std::string, BaseCommandLineArgument*>::const_iterator it = cmdLineArgsShortcut_.find(shortcut);
     238        std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgsShortcut_.find(shortcut);
    198239        if (it == cmdLineArgsShortcut_.end())
    199240            ThrowException(Argument, "Command line shortcut '" + shortcut + "' does not exist.");
     
    206247        CommandLine* inst = &_getInstance();
    207248        std::string infoStr;
    208         for (std::map<std::string, BaseCommandLineArgument*>::const_iterator it = inst->cmdLineArgs_.begin();
     249        for (std::map<std::string, CommandLineArgument*>::const_iterator it = inst->cmdLineArgs_.begin();
    209250            it != inst->cmdLineArgs_.end(); ++it)
    210251        {
     
    214255    }
    215256
     257    /**
     258    @brief
     259        Retrieves a CommandLineArgument.
     260        The method throws an exception if 'name' was not found or the value could not be converted.
     261    @note
     262        You shold of course not call this method before the command line has been parsed.
     263    */
     264    const CommandLineArgument* CommandLine::getArgument(const std::string& name)
     265    {
     266        std::map<std::string, CommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
     267        if (it == _getInstance().cmdLineArgs_.end())
     268        {
     269            ThrowException(Argument, "Could find command line argument '" + name + "'.");
     270        }
     271        else
     272        {
     273            return it->second;
     274        }
     275    }
    216276}
  • code/trunk/src/core/CommandLine.h

    r1764 r2087  
    3535#include "util/Debug.h"
    3636#include "util/Exception.h"
     37#include "util/MultiType.h"
    3738
    3839#define SetCommandLineArgument(name, defaultValue) \
    39     BaseCommandLineArgument& CmdArgumentDummyBoolVar##name \
     40    CommandLineArgument& CmdArgumentDummyBoolVar##name \
    4041    = orxonox::CommandLine::addArgument(#name, defaultValue)
    4142#define SetCommandLineSwitch(name) \
    42     BaseCommandLineArgument& CmdArgumentDummyBoolVar##name \
     43    CommandLineArgument& CmdArgumentDummyBoolVar##name \
    4344    = orxonox::CommandLine::addArgument(#name, false)
    4445
     
    4849    /**
    4950    @brief
    50         Template struct which creates a distinct type for every integer constant.
    51     @note
    52         This allows to select a different function depending on a boolean value
    53         when creating a new CommandLineArgument.
    54         From 'Modern C++ Design' (Alexandrescu 2001).
     51        Container class for a command line argument of any type supported by MultiType.
     52
     53        Whenever you want to have an option specified by a command line switch,
     54        you need to first define it with SetCommandLineArgument(name, defaultValue).
     55        It is then added to a map and possibly changed when the command line is being parsed.
     56        If the option was not given, you can detect this by asking hasDefaultValue().
     57
     58        There is a possibility to define a short cut so you can write "-p 20" instead of "--port 20".
     59        Note the difference between "-" and "--"!
     60        Also, there is no restriction to the number of strings you add after --name.
     61        So "--startVector (2, 4, 5)" is perfectly legal.
     62
     63        Retrieving an argument is possible with the getCommandLineArgument function of the
     64        CommandLine class. It is a Singleton, but the public interface is static.
    5565    */
    56     template <int v>
    57     struct Int2Type
    58     {
    59         enum { value = v };
    60     };
    61 
    62     /**
    63     @brief
    64         Base class for CommandLineArguments.
    65     */
    66     class _CoreExport BaseCommandLineArgument
     66    class _CoreExport CommandLineArgument
    6767    {
    6868        friend class CommandLine;
     
    7878        const std::string& getShortcut() const { return shortcut_; }
    7979        //! Sets the shortcut for the argument
    80         BaseCommandLineArgument& setShortcut(const std::string& shortcut)
     80        CommandLineArgument& shortcut(const std::string& shortcut)
    8181        { this->shortcut_ = shortcut; return *this; }
    8282
     
    8484        const std::string& getInformation() const { return this->usageInformation_; }
    8585        //! Sets the option information when displaying orxonox usage.
    86         BaseCommandLineArgument& setInformation(const std::string& usage)
     86        CommandLineArgument& information(const std::string& usage)
    8787        { this->usageInformation_ = usage; return *this; }
    8888
    89     protected:
    90         BaseCommandLineArgument(const std::string& name)
     89        //! Returns the actual value of the argument. Can be equal to default value.
     90        MultiType getValue() const { return value_; }
     91        //! Returns the given default value as type T.
     92        MultiType getDefaultValue() const { return defaultValue_; }
     93
     94    private:
     95        //! Constructor initialises both value_ and defaultValue_ with defaultValue.
     96        CommandLineArgument(const std::string& name, const MultiType& defaultValue)
    9197            : bHasDefaultValue_(true)
    9298            , name_(name)
     99            , value_(defaultValue)
     100            , defaultValue_(defaultValue)
    93101        { }
    94102
    95103        //! Undefined copy constructor
    96         BaseCommandLineArgument(const BaseCommandLineArgument& instance);
    97         virtual ~BaseCommandLineArgument() { }
     104        CommandLineArgument(const CommandLineArgument& instance);
     105        ~CommandLineArgument() { }
    98106
    99107        //! Parses the value string of a command line argument.
    100         virtual void parse(const std::string& value) = 0;
     108        void parse(const std::string& value);
    101109
    102110        //! Tells whether the value has been changed by the command line.
     
    107115        std::string shortcut_;         //!< Shortcut of the argument. @see getShortcut().
    108116        std::string usageInformation_; //!< Tells about the usage of this parameter
     117
     118        MultiType value_;            //!< The actual value
     119        MultiType defaultValue_;     //!< Default value. Should not be changed.
    109120    };
    110 
    111 
    112     /**
    113     @brief
    114         Container class for a command line argument of type T.
    115        
    116         Whenever you want to have an option specified by a command line switch,
    117         you need to first define it with SetCommandLineArgument(name, defaultValue).
    118         It is then added to a map and possibly changed when the command line is being parsed.
    119         If the option was not given, you can detect this by asking hasDefaultValue().
    120        
    121         There is a possibility to define a short cut so you can write "-p 20" instead of "--port 20".
    122         Note the difference between "-" and "--"!
    123         Also, there is no restriction to the number of strings you add after --name.
    124         So "--startVector (2, 4, 5)" is perfectly legal.
    125 
    126         Retrieving an argument is possible with the getCommandLineArgument function of the
    127         CommandLine class. It is a Singleton, but the public interface is static.
    128     */
    129     template <class T>
    130     class CommandLineArgument : public BaseCommandLineArgument
    131     {
    132         // Only let CommandLine change the value.
    133         friend class CommandLine;
    134 
    135     public:
    136         //! Returns the actual value of the argument. Can be equal to default value.
    137         T getValue() const { return value_; }
    138         //! Returns the given default value as type T.
    139         T getDefaultValue() const { return defaultValue_; }
    140 
    141     private:
    142         //! Constructor initialises both value_ and defaultValue_ with defaultValue.
    143         CommandLineArgument(const std::string& name, const T& defaultValue)
    144             : BaseCommandLineArgument(name)
    145             , value_(defaultValue)
    146             , defaultValue_(defaultValue)
    147         { }
    148 
    149         virtual void parse(const std::string& value);
    150 
    151         T value_;            //!< The actual value
    152         T defaultValue_;     //!< Default value. Should not be changed.
    153     };
    154 
    155     /**
    156     @brief
    157         Parses a value string for a command line argument.
    158         It simply uses convertValue(Output, Input) to do that.
    159     */
    160     template <class T>
    161     void CommandLineArgument<T>::parse(const std::string& value)
    162     {
    163         if (convertValue(&this->value_, value))
    164         {
    165             this->bHasDefaultValue_ = false;
    166         }
    167         else
    168         {
    169             ThrowException(Argument, "Could not read command line argument '" + getName() + "'.");
    170         }
    171     }
    172 
    173     /**
    174     @brief
    175         Parses a value string for a command line argument.
    176         It simply uses convertValue(Output, Input) to do that.
    177         This is a template specialisation for bool type. That is necessary
    178         so that you can have simple command line switches.
    179     */
    180     template <>
    181     inline void CommandLineArgument<bool>::parse(const std::string& value)
    182     {
    183         if (convertValue(&this->value_, value))
    184         {
    185             this->bHasDefaultValue_ = false;
    186         }
    187         else if (value == "")
    188         {
    189             this->bHasDefaultValue_ = false;
    190             this->value_ = true;
    191         }
    192         else
    193         {
    194             ThrowException(Argument, "Could not read command line argument '" + getName() + "'.");
    195         }
    196     }
    197121
    198122
     
    215139        static std::string getUsageInformation();
    216140
    217         template <class T>
    218         static const CommandLineArgument<T>* getArgument(const std::string& name);
     141        static const CommandLineArgument* getArgument(const std::string& name);
    219142        //! Writes the argument value in the given parameter.
    220143        template <class T>
    221144        static void getValue(const std::string& name, T* value)
    222         { *value = getArgument<T>(name)->getValue(); }
     145        { *value = (T)(getArgument(name)->getValue()); }
     146        static MultiType getValue(const std::string& name)
     147        { return getArgument(name)->getValue(); }
    223148        template <class T>
    224         static BaseCommandLineArgument& addArgument(const std::string& name, T defaultValue);
     149        static CommandLineArgument& addArgument(const std::string& name, T defaultValue);
     150
     151        static bool existsArgument(const std::string& name)
     152        {
     153            std::map<std::string, CommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
     154            return !(it == _getInstance().cmdLineArgs_.end());
     155        }
     156
    225157
    226158    private:
     
    237169        void checkShortcut(const std::string& shortcut, const std::string& value);
    238170
    239         template <class T>
    240         BaseCommandLineArgument* createArg(const std::string& name, T defaultValue, Int2Type<0> isString);
    241         template <class T>
    242         BaseCommandLineArgument* createArg(const std::string& name, T defaultValue, Int2Type<1> isString);
    243 
    244171        /**
    245             Tells whether we parse the first expression. The CommmandLineArguments are added before main().
     172            Tells whether we parsed for the first time. The CommmandLineArguments are added before main().
    246173            So when we call parse() the first time, we need to create a map with all shortcuts since these
    247174            get added after addCommandLineArgument().
     
    250177
    251178        //! Holds all pointers to the arguments and serves as a search map by name.
    252         std::map<std::string, BaseCommandLineArgument*> cmdLineArgs_;
     179        std::map<std::string, CommandLineArgument*> cmdLineArgs_;
    253180        //! Search map by chortcut for the arguments.
    254         std::map<std::string, BaseCommandLineArgument*> cmdLineArgsShortcut_;
     181        std::map<std::string, CommandLineArgument*> cmdLineArgsShortcut_;
    255182    };
    256183
    257 
    258     /**
    259     @brief
    260         Retrieves a CommandLineArgument.
    261         The method throws an exception if 'name' was not found or the value could not be converted.
    262     @note
    263         You shold of course not call this method before the command line has been parsed.
    264     */
    265     template <class T>
    266     const CommandLineArgument<T>* CommandLine::getArgument(const std::string& name)
    267     {
    268         std::map<std::string, BaseCommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
    269         if (it == _getInstance().cmdLineArgs_.end())
    270         {
    271             ThrowException(Argument, "Could find command line argument '" + name + "'.");
    272         }
    273         else
    274         {
    275             CommandLineArgument<T>* arg = dynamic_cast<CommandLineArgument<T>* >(it->second);
    276             if (arg == 0)
    277             {
    278                 ThrowException(Argument, "Could not convert command line argument value to requested type. " \
    279                     "You should use exactly the same type as predefined.");
    280             }
    281             else
    282             {
    283                 return arg;
    284             }
    285         }
     184    template <>
     185    inline void CommandLine::getValue<std::string>(const std::string& name, std::string* value)
     186    {
     187        *value = (std::string)(getArgument(name)->getValue().getString());
    286188    }
    287189
     
    294196    @param defaultValue
    295197        Default value that is used when argument was not given.
    296     @note
    297         In order to store char* strings as std::string too, there's
    298         little bit of template programming involved:
    299         StaticConversions::exists determines whether T converts to std::string.
    300         Int2Type<int> is then used to call the right function. One returns
    301         a CommandLineArgument<T> and the other CommandLineArgument<std::string>.
    302198    */
    303199    template <class T>
    304     BaseCommandLineArgument& CommandLine::addArgument(const std::string& name, T defaultValue)
    305     {
    306         std::map<std::string, BaseCommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
    307         OrxAssert(it == _getInstance().cmdLineArgs_.end(),
     200    CommandLineArgument& CommandLine::addArgument(const std::string& name, T defaultValue)
     201    {
     202        OrxAssert(!_getInstance().existsArgument(name),
    308203            "Cannot add a command line argument with name '" + name + "' twice.");
    309204
    310         return *(_getInstance().cmdLineArgs_[name] =
    311             _getInstance().createArg(name, defaultValue, Int2Type<StaticConversion<T, std::string>::exists>()));
    312     }
    313 
    314     /**
    315         Returns a new CommandLineArgument<T>.
    316     */
    317     template <class T>
    318     BaseCommandLineArgument* CommandLine::createArg(const std::string& name, T defaultValue, Int2Type<0> isPrime)
    319     {
    320         return new CommandLineArgument<T>(name, defaultValue);
    321     }
    322 
    323     /**
    324         Returns a new CommandLineArgument<std::string>.
    325     */
    326     template <class T>
    327     BaseCommandLineArgument* CommandLine::createArg(const std::string& name, T defaultValue, Int2Type<1> isPrime)
    328     {
    329         return new CommandLineArgument<std::string>(name, defaultValue);
     205        return *(_getInstance().cmdLineArgs_[name] = new CommandLineArgument(name, defaultValue));
    330206    }
    331207}
  • code/trunk/src/core/ConfigValueContainer.h

    r1887 r2087  
    5252#include "util/MultiType.h"
    5353#include "ConfigFileManager.h"
     54#include "Identifier.h"
    5455
    5556namespace orxonox
     
    6970            inline virtual ~ConfigValueCallback() {}
    7071            inline virtual void call(void* object)
    71                 { (((T*)object)->*this->function_)(); }
     72                { if (!Identifier::isCreatingHierarchy()) { (((T*)object)->*this->function_)(); } }
    7273
    7374        private:
  • code/trunk/src/core/ConsoleCommand.cc

    r1755 r2087  
    4141
    4242        this->keybindMode_ = KeybindMode::OnPress;
    43         this->axisParamIndex_ = -1;
    44         this->bAxisRelative_ = false;
     43        this->inputConfiguredParam_ = -1;
    4544    }
    4645
  • code/trunk/src/core/ConsoleCommand.h

    r1755 r2087  
    122122                { return this->argumentList_.end(); }
    123123
     124            inline ConsoleCommand& setAsInputCommand()
     125            {
     126                this->keybindMode(KeybindMode::OnHold);
     127                this->defaultValue(0, Vector2(0.0f, 0.0f));
     128                this->inputConfiguredParam(0);
     129                return *this;
     130            }
     131
    124132            inline ConsoleCommand& keybindMode(KeybindMode::Enum mode)
    125133                { this->keybindMode_ = mode; return *this; }
     
    127135                { return this->keybindMode_; }
    128136
    129             inline ConsoleCommand& axisParamIndex(int index)
    130                 { this->axisParamIndex_ = index; return *this; }
    131             inline int getAxisParamIndex() const
    132                 { return this->axisParamIndex_; }
    133 
    134             inline ConsoleCommand& isAxisRelative(bool val)
    135                 { this->bAxisRelative_ = val; return *this; }
    136             inline int getIsAxisRelative() const
    137                 { return this->bAxisRelative_; }
     137            inline ConsoleCommand& inputConfiguredParam(int index)
     138                { this->inputConfiguredParam_ = index; return *this; }
     139            inline int getInputConfiguredParam_() const
     140                { return this->inputConfiguredParam_; }
    138141
    139142        private:
     
    143146
    144147            KeybindMode::Enum keybindMode_;
    145             int axisParamIndex_;
    146             bool bAxisRelative_;
     148            int inputConfiguredParam_;
    147149    };
    148150
  • code/trunk/src/core/Core.cc

    r1762 r2087  
    3737#include "CoreIncludes.h"
    3838#include "ConfigValueIncludes.h"
    39 //#include "input/InputManager.h"
    40 //#include "TclThreadManager.h"
    4139
    4240namespace orxonox
    4341{
     42    bool Core::bShowsGraphics_s = false;
     43    bool Core::bHasServer_s     = false;
     44    bool Core::bIsClient_s      = false;
     45    bool Core::bIsStandalone_s  = false;
     46    bool Core::bIsMaster_s      = false;
     47
    4448    /**
    4549        @brief Constructor: Registers the object and sets the config-values.
     
    205209        ResetConfigValue(language_);
    206210    }
    207 
    208     ///**
    209     //    @brief Ticks every core class in a specified sequence. Has to be called
    210     //           every Orxonox tick!
    211     //    @param dt Delta Time
    212     //*/
    213     //void Core::tick(float dt)
    214     //{
    215     //    TclThreadManager::getInstance().tick(dt);
    216     //    InputManager::getInstance().tick(dt);
    217     //}
    218211}
  • code/trunk/src/core/Core.h

    r1755 r2087  
    6060            static void resetLanguage();
    6161
    62             //static void tick(float dt);
     62            // fast access global variables.
     63            static bool showsGraphics() { return bShowsGraphics_s; }
     64            static bool hasServer()     { return bHasServer_s; }
     65            static bool isClient()      { return bIsClient_s; }
     66            static bool isStandalone()  { return bIsStandalone_s; }
     67            static bool isMaster()      { return bIsMaster_s; }
     68            static void setShowsGraphics(bool val) { bShowsGraphics_s = val; updateIsMaster(); }
     69            static void setHasServer    (bool val) { bHasServer_s     = val; updateIsMaster(); }
     70            static void setIsClient     (bool val) { bIsClient_s      = val; updateIsMaster(); }
     71            static void setIsStandalone (bool val) { bIsStandalone_s  = val; updateIsMaster(); }
     72            static void updateIsMaster  ()         { bIsMaster_s      = (bHasServer_s || bIsStandalone_s); }
    6373
    6474        private:
     
    7484            int softDebugLevelShell_;                       //!< The debug level for the ingame shell
    7585            std::string language_;                          //!< The language
     86
     87            static bool bShowsGraphics_s;                   //!< global variable that tells whether to show graphics
     88            static bool bHasServer_s;                       //!< global variable that tells whether this is a server
     89            static bool bIsClient_s;
     90            static bool bIsStandalone_s;
     91            static bool bIsMaster_s;
    7692    };
    7793}
  • code/trunk/src/core/CoreIncludes.h

    r1856 r2087  
    4646#include "Factory.h"
    4747#include "ClassFactory.h"
     48#include "Functor.h"
    4849#include "util/Debug.h"
    4950
     
    9899*/
    99100#define CreateFactory(ClassName) \
    100     bool bCreated##ClassName##Factory = orxonox::ClassFactory<ClassName>::create(#ClassName)
     101    bool bCreated##ClassName##Factory = orxonox::ClassFactory<ClassName>::create(#ClassName, true)
     102
     103/**
     104    @brief Creates the entry in the Factory for classes which should not be loaded through XML.
     105    @param ClassName The name of the class
     106*/
     107#define CreateUnloadableFactory(ClassName) \
     108    bool bCreated##ClassName##Factory = orxonox::ClassFactory<ClassName>::create(#ClassName, false)
    101109
    102110/**
     
    105113*/
    106114#define Class(ClassName) \
    107     ClassIdentifier<ClassName>::getIdentifier()
     115    orxonox::ClassIdentifier<ClassName>::getIdentifier()
    108116
    109117/**
     
    111119    @param String The name of the class
    112120*/
    113 #define ClassByName(String) \
     121#define ClassByString(String) \
    114122    orxonox::Factory::getIdentifier(String)
    115123
     
    121129    orxonox::Factory::getIdentifier(networkID)
    122130
     131/**
     132    @brief Registers a member function as callback when an object of 'type' is created.
     133    @param
     134*/
     135#define RegisterConstructionCallback(ThisClassName, TargetClassName, FunctionName) \
     136    orxonox::ClassIdentifier<TargetClassName>::getIdentifier()->addConstructionCallback( \
     137        createFunctor(&ThisClassName::FunctionName)->setObject(this))
     138
    123139#endif /* _CoreIncludes_H__ */
  • code/trunk/src/core/CorePrereqs.h

    r1757 r2087  
    103103  class CommandExecutor;
    104104  class CommandLine;
    105   class BaseCommandLineArgument;
    106   template <class T>
    107105  class CommandLineArgument;
    108106  class ConfigFile;
     
    115113  class ConsoleCommand;
    116114  class Core;
     115  struct Event;
     116  class EventContainer;
    117117  class Executor;
    118118  template <class T>
     
    131131  class Language;
    132132  class LanguageEntry;
    133   class Level;
    134133  class Loader;
    135134  class MetaObjectList;
     
    153152  struct TclInterpreterBundle;
    154153  class TclThreadManager;
     154  class Template;
    155155  class Tickable;
     156  class XMLFile;
     157  class XMLNameListener;
    156158  template <class T, class O>
    157159  class XMLPortClassObjectContainer;
  • code/trunk/src/core/Factory.cc

    r1856 r2087  
    4646    Identifier* Factory::getIdentifier(const std::string& name)
    4747    {
    48         return getFactoryPointer()->identifierStringMap_[name];
     48        std::map<std::string, Identifier*>::const_iterator it = getFactoryPointer()->identifierStringMap_.find(name);
     49        if (it != getFactoryPointer()->identifierStringMap_.end())
     50            return it->second;
     51        else
     52            return 0;
    4953    }
    5054
     
    5660    Identifier* Factory::getIdentifier(const unsigned int id)
    5761    {
    58         return getFactoryPointer()->identifierNetworkIDMap_[id];
     62        std::map<unsigned int, Identifier*>::const_iterator it = getFactoryPointer()->identifierNetworkIDMap_.find(id);
     63        if (it != getFactoryPointer()->identifierNetworkIDMap_.end())
     64            return it->second;
     65        else
     66            return 0;
    5967    }
    6068
     
    6876        getFactoryPointer()->identifierStringMap_[name] = identifier;
    6977        getFactoryPointer()->identifierNetworkIDMap_[identifier->getNetworkID()] = identifier;
     78//std::cout << identifier->getName() << ": " << identifier->getNetworkID() << std::endl;
    7079    }
    7180
     
    8089        getFactoryPointer()->identifierNetworkIDMap_.erase(oldID);
    8190        getFactoryPointer()->identifierNetworkIDMap_[newID] = identifier;
     91//std::cout << identifier->getName() << ": " << oldID << " -> " << newID << std::endl;
    8292    }
    8393
     
    94104        {
    95105            // To create the new branch of the class-hierarchy, we create a new object and delete it afterwards.
    96             BaseObject* temp = (*it).second->fabricate();
     106            BaseObject* temp = (*it).second->fabricate(0);
    97107            delete temp;
    98108        }
  • code/trunk/src/core/Factory.h

    r1856 r2087  
    9393    {
    9494        public:
    95             virtual BaseObject* fabricate() = 0;
     95            virtual BaseObject* fabricate(BaseObject* creator) = 0;
    9696            virtual ~BaseFactory() {};
    9797    };
  • code/trunk/src/core/Functor.h

    r1889 r2087  
    106106            inline const MultiType& getReturnvalue() const { return this->returnedValue_; }
    107107
    108             const std::string& getTypenameParam(unsigned int param) const { return (param < 5) ? this->typeParam_[param] : blankString; }
     108            const std::string& getTypenameParam(unsigned int param) const { return (param < 5) ? this->typeParam_[param] : BLANKSTRING; }
    109109            const std::string& getTypenameReturnvalue() const { return this->typeReturnvalue_; }
    110110
     
    167167            }
    168168
    169             void setObject(T* object)
     169            FunctorMember* setObject(T* object)
    170170            {
    171171                this->bConstObject_ = false;
    172172                this->object_ = object;
     173                return this;
    173174            }
    174175
    175             void setObject(const T* object)
     176            FunctorMember* setObject(const T* object)
    176177            {
    177178                this->bConstObject_ = true;
    178179                this->constObject_ = object;
     180                return this;
    179181            }
    180182
  • code/trunk/src/core/Identifier.cc

    r1856 r2087  
    5959        this->bSetName_ = false;
    6060        this->factory_ = 0;
     61        this->bLoadable_ = true;
    6162
    6263        this->bHasConfigValues_ = false;
    6364        this->bHasConsoleCommands_ = false;
     65        this->bHasConstructionCallback_ = false;
    6466
    6567        this->children_ = new std::set<const Identifier*>();
     
    213215        @return The new object
    214216    */
    215     BaseObject* Identifier::fabricate()
     217    BaseObject* Identifier::fabricate(BaseObject* creator)
    216218    {
    217219        if (this->factory_)
    218220        {
    219             return this->factory_->fabricate(); // We have to return a BaseObject, because we don't know the exact type.
     221            return this->factory_->fabricate(creator); // We have to return a BaseObject, because we don't know the exact type.
    220222        }
    221223        else
     
    420422    XMLPortParamContainer* Identifier::getXMLPortParamContainer(const std::string& paramname)
    421423    {
    422         std::map<std::string, XMLPortParamContainer*>::const_iterator it = xmlportParamContainers_.find(paramname);
    423         if (it != xmlportParamContainers_.end())
     424        std::map<std::string, XMLPortParamContainer*>::const_iterator it = this->xmlportParamContainers_.find(paramname);
     425        if (it != this->xmlportParamContainers_.end())
    424426            return ((*it).second);
    425427        else
     
    434436    void Identifier::addXMLPortParamContainer(const std::string& paramname, XMLPortParamContainer* container)
    435437    {
     438        std::map<std::string, XMLPortParamContainer*>::const_iterator it = this->xmlportParamContainers_.find(paramname);
     439        if (it != this->xmlportParamContainers_.end())
     440        {
     441            COUT(2) << "Warning: Overwriting XMLPortParamContainer in class " << this->getName() << "." << std::endl;
     442            delete (it->second);
     443        }
     444
    436445        this->xmlportParamContainers_[paramname] = container;
    437446    }
     
    444453    XMLPortObjectContainer* Identifier::getXMLPortObjectContainer(const std::string& sectionname)
    445454    {
    446         std::map<std::string, XMLPortObjectContainer*>::const_iterator it = xmlportObjectContainers_.find(sectionname);
    447         if (it != xmlportObjectContainers_.end())
     455        std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportObjectContainers_.find(sectionname);
     456        if (it != this->xmlportObjectContainers_.end())
    448457            return ((*it).second);
    449458        else
     
    458467    void Identifier::addXMLPortObjectContainer(const std::string& sectionname, XMLPortObjectContainer* container)
    459468    {
     469        std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportObjectContainers_.find(sectionname);
     470        if (it != this->xmlportObjectContainers_.end())
     471        {
     472            COUT(2) << "Warning: Overwriting XMLPortObjectContainer in class " << this->getName() << "." << std::endl;
     473            delete (it->second);
     474        }
     475
    460476        this->xmlportObjectContainers_[sectionname] = container;
     477    }
     478
     479    /**
     480        @brief Returns a XMLPortEventContainer that attaches an event to this class.
     481        @param sectionname The name of the section that contains the event
     482        @return The container
     483    */
     484    XMLPortObjectContainer* Identifier::getXMLPortEventContainer(const std::string& eventname)
     485    {
     486        std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportEventContainers_.find(eventname);
     487        if (it != this->xmlportEventContainers_.end())
     488            return ((*it).second);
     489        else
     490            return 0;
     491    }
     492
     493    /**
     494        @brief Adds a new XMLPortEventContainer that attaches an event to this class.
     495        @param sectionname The name of the section that contains the event
     496        @param container The container
     497    */
     498    void Identifier::addXMLPortEventContainer(const std::string& eventname, XMLPortObjectContainer* container)
     499    {
     500        std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportEventContainers_.find(eventname);
     501        if (it != this->xmlportEventContainers_.end())
     502        {
     503            COUT(2) << "Warning: Overwriting XMLPortEventContainer in class " << this->getName() << "." << std::endl;
     504            delete (it->second);
     505        }
     506
     507        this->xmlportEventContainers_[eventname] = container;
     508    }
     509
     510    /**
     511        @brief Adds a construction callback functor that gets called every time an object is created.
     512        @param functor Functor pointer to any function with no argument.
     513    */
     514    void Identifier::addConstructionCallback(Functor* functor)
     515    {
     516        for (unsigned int i = 0; i < this->constructionCallbacks_.size(); ++i)
     517        {
     518            if (this->constructionCallbacks_[i] == functor)
     519                return;
     520        }
     521        this->constructionCallbacks_.push_back(functor);
     522        this->bHasConstructionCallback_ = true;
     523    }
     524
     525    /**
     526        @brief Removes a construction callback functor that gets called every time an object is created.
     527        @param functor Functor pointer to any function with no argument.
     528    */
     529    void Identifier::removeConstructionCallback(Functor* functor)
     530    {
     531        for (unsigned int i = 0; i < this->constructionCallbacks_.size(); ++i)
     532        {
     533            if (this->constructionCallbacks_[i] == functor)
     534            {
     535                this->constructionCallbacks_.erase(this->constructionCallbacks_.begin() + i);
     536            }
     537        }
     538        if (constructionCallbacks_.empty())
     539            this->bHasConstructionCallback_ = false;
    461540    }
    462541
  • code/trunk/src/core/Identifier.h

    r1856 r2087  
    5757#include <set>
    5858#include <map>
     59#include <vector>
    5960#include <string>
    6061#include <utility>
    6162#include <typeinfo>
    6263#include <stdlib.h>
     64#include <cassert>
    6365
    6466#include "MetaObjectList.h"
    6567#include "Iterator.h"
    6668#include "Super.h"
     69#include "Functor.h"
    6770#include "util/Debug.h"
    6871#include "util/String.h"
     
    99102            inline void addFactory(BaseFactory* factory) { this->factory_ = factory; }
    100103
    101             BaseObject* fabricate();
     104            BaseObject* fabricate(BaseObject* creator);
    102105            bool isA(const Identifier* identifier) const;
    103106            bool isExactlyA(const Identifier* identifier) const;
     
    107110            bool isDirectParentOf(const Identifier* identifier) const;
    108111
     112            /** @brief Returns true if the class can be loaded through XML. */
     113            inline bool isLoadable() const { return this->bLoadable_; }
     114            /** @brief Set the class to be loadable through XML or not. */
     115            inline void setLoadable(bool bLoadable) { this->bLoadable_ = bLoadable; }
     116
    109117            /** @brief Returns the list of all existing objects of this class. @return The list */
    110118            inline ObjectListBase* getObjects() const
     
    204212            inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortObjectMapEnd() const { return this->xmlportObjectContainers_.end(); }
    205213
     214            /** @brief Returns the map that stores all XMLPort events. @return The const_iterator */
     215            inline const std::map<std::string, XMLPortObjectContainer*>& getXMLPortEventMap() const { return this->xmlportEventContainers_; }
     216            /** @brief Returns a const_iterator to the beginning of the map that stores all XMLPort events. @return The const_iterator */
     217            inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortEventMapBegin() const { return this->xmlportEventContainers_.begin(); }
     218            /** @brief Returns a const_iterator to the end of the map that stores all XMLPort events. @return The const_iterator */
     219            inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortEventMapEnd() const { return this->xmlportEventContainers_.end(); }
     220
    206221            /** @brief Returns true if this class has at least one config value. @return True if this class has at least one config value */
    207222            inline bool hasConfigValues() const { return this->bHasConfigValues_; }
    208223            /** @brief Returns true if this class has at least one console command. @return True if this class has at least one console command */
    209224            inline bool hasConsoleCommands() const { return this->bHasConsoleCommands_; }
     225            /** @brief Returns true if this class has at least one construction callback Functor registered. */
     226            inline bool hasConstructionCallback() const { return this->bHasConstructionCallback_; }
    210227
    211228            /** @brief Returns true, if a branch of the class-hierarchy is being created, causing all new objects to store their parents. @return The status of the class-hierarchy creation */
     
    228245            XMLPortObjectContainer* getXMLPortObjectContainer(const std::string& sectionname);
    229246
     247            void addXMLPortEventContainer(const std::string& eventname, XMLPortObjectContainer* container);
     248            XMLPortObjectContainer* getXMLPortEventContainer(const std::string& eventname);
     249
    230250            ConsoleCommand& addConsoleCommand(ConsoleCommand* command, bool bCreateShortcut);
    231251            ConsoleCommand* getConsoleCommand(const std::string& name) const;
    232252            ConsoleCommand* getLowercaseConsoleCommand(const std::string& name) const;
     253
     254            void addConstructionCallback(Functor* functor);
     255            void removeConstructionCallback(Functor* functor);
    233256
    234257            void initializeClassHierarchy(std::set<const Identifier*>* parents, bool bRootClass);
     
    252275            inline std::set<const Identifier*>& getDirectChildrenIntern() const { return (*this->directChildren_); }
    253276
     277            bool bHasConstructionCallback_;                                //!< True if at least one Functor is registered to get informed when an object of type T is created.
     278            std::vector<Functor*> constructionCallbacks_;                  //!< All construction callback Functors of this class.
     279
    254280            ObjectListBase* objects_;                                      //!< The list of all objects of this class
    255281
     
    285311            bool bCreatedOneObject_;                                       //!< True if at least one object of the given type was created (used to determine the need of storing the parents)
    286312            bool bSetName_;                                                //!< True if the name is set
     313            bool bLoadable_;                                               //!< False = it's not permitted to load the object through XML
    287314            std::string name_;                                             //!< The name of the class the Identifier belongs to
    288315            BaseFactory* factory_;                                         //!< The Factory, able to create new objects of the given class (if available)
     
    300327            std::map<std::string, XMLPortParamContainer*> xmlportParamContainers_;     //!< All loadable parameters
    301328            std::map<std::string, XMLPortObjectContainer*> xmlportObjectContainers_;   //!< All attachable objects
     329            std::map<std::string, XMLPortObjectContainer*> xmlportEventContainers_;    //!< All events
    302330    };
    303331
     
    423451        COUT(5) << "*** ClassIdentifier: Added object to " << this->getName() << "-list." << std::endl;
    424452        object->getMetaList().add(this->objects_, this->objects_->add(new ObjectListElement<T>(object)));
     453        if (this->bHasConstructionCallback_)
     454        {
     455            // Call all registered callbacks that a new object of type T has been created.
     456            // Do NOT deliver a T* pointer here because it's way too risky (object not yet fully created).
     457            for (unsigned int i = 0; i < this->constructionCallbacks_.size(); ++i)
     458                (*constructionCallbacks_[i])();
     459        }
    425460    }
    426461
     
    480515            SubclassIdentifier<T>& operator=(Identifier* identifier)
    481516            {
    482                 if (!identifier->isA(ClassIdentifier<T>::getIdentifier()))
     517                if (!identifier || !identifier->isA(ClassIdentifier<T>::getIdentifier()))
    483518                {
    484519                    COUT(1) << "An error occurred in SubclassIdentifier (Identifier.h):" << std::endl;
    485                     COUT(1) << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<T>::getIdentifier()->getName() << "!" << std::endl;
    486                     COUT(1) << "Error: SubclassIdentifier<" << ClassIdentifier<T>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden." << std::endl;
    487                     COUT(1) << "Aborting..." << std::endl;
    488                     abort();
     520                    if (identifier)
     521                    {
     522                        COUT(1) << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<T>::getIdentifier()->getName() << "!" << std::endl;
     523                        COUT(1) << "Error: SubclassIdentifier<" << ClassIdentifier<T>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden." << std::endl;
     524                    }
     525                    else
     526                    {
     527                        COUT(1) << "Error: Can't assign NULL identifier" << std::endl;
     528                    }
    489529                }
    490                 this->identifier_ = identifier;
     530                else
     531                {
     532                    this->identifier_ = identifier;
     533                }
    491534                return *this;
    492535            }
     
    495538                @brief Overloading of the * operator: returns the assigned identifier.
    496539            */
    497             inline Identifier* operator*()
     540            inline Identifier* operator*() const
    498541            {
    499542                return this->identifier_;
     
    520563                @return The new object
    521564            */
    522             T* fabricate()
    523             {
    524                 BaseObject* newObject = this->identifier_->fabricate();
     565            T* fabricate(BaseObject* creator) const
     566            {
     567                BaseObject* newObject = this->identifier_->fabricate(creator);
    525568
    526569                // Check if the creation was successful
     
    546589                    }
    547590
    548                     abort();
     591                    assert(false);
     592                    return 0;
    549593                }
    550594            }
  • code/trunk/src/core/Loader.cc

    r1755 r2087  
    2828
    2929#include "Loader.h"
    30 #include "Level.h"
     30#include "XMLFile.h"
    3131#include "BaseObject.h"
    3232#include "Identifier.h"
     
    3434#include "ObjectList.h"
    3535#include "CoreIncludes.h"
    36 #include "Script.h"
     36#include "LuaBind.h"
    3737#include "Namespace.h"
    3838#include "util/Debug.h"
     
    4242namespace orxonox
    4343{
    44     std::vector<std::pair<const Level*, ClassTreeMask> > Loader::levels_s;
     44    std::vector<std::pair<const XMLFile*, ClassTreeMask> > Loader::files_s;
    4545    ClassTreeMask Loader::currentMask_s;
    4646
    47     bool Loader::open(const Level* level, const ClassTreeMask& mask)
     47    bool Loader::open(const XMLFile* file, const ClassTreeMask& mask)
    4848    {
    49         Loader::add(level, mask);
    50         return Loader::load(level, mask);
     49        Loader::add(file, mask);
     50        return Loader::load(file, mask);
    5151    }
    5252
     
    5454    {
    5555        Loader::unload();
    56         Loader::levels_s.clear();
     56        Loader::files_s.clear();
    5757    }
    5858
    59     void Loader::close(const Level* level)
     59    void Loader::close(const XMLFile* file)
    6060    {
    61         Loader::unload(level);
    62         Loader::remove(level);
     61        Loader::unload(file);
     62        Loader::remove(file);
    6363    }
    6464
    65     void Loader::add(const Level* level, const ClassTreeMask& mask)
     65    void Loader::add(const XMLFile* file, const ClassTreeMask& mask)
    6666    {
    67         if (!level)
     67        if (!file)
    6868            return;
    69         Loader::levels_s.insert(Loader::levels_s.end(), std::pair<const Level*, ClassTreeMask>(level, mask));
     69        Loader::files_s.insert(Loader::files_s.end(), std::pair<const XMLFile*, ClassTreeMask>(file, mask));
    7070    }
    7171
    72     void Loader::remove(const Level* level)
     72    void Loader::remove(const XMLFile* file)
    7373    {
    74         if (!level)
     74        if (!file)
    7575            return;
    76         for (std::vector<std::pair<const Level*, ClassTreeMask> >::iterator it = Loader::levels_s.begin(); it != Loader::levels_s.end(); ++it)
     76        for (std::vector<std::pair<const XMLFile*, ClassTreeMask> >::iterator it = Loader::files_s.begin(); it != Loader::files_s.end(); ++it)
    7777        {
    78             if ((*it).first == level)
     78            if ((*it).first == file)
    7979            {
    80                 Loader::levels_s.erase(it);
     80                Loader::files_s.erase(it);
    8181                break;
    8282            }
     
    8787    {
    8888        bool success = true;
    89         for (std::vector<std::pair<const Level*, ClassTreeMask> >::iterator it = Loader::levels_s.begin(); it != Loader::levels_s.end(); ++it)
     89        for (std::vector<std::pair<const XMLFile*, ClassTreeMask> >::iterator it = Loader::files_s.begin(); it != Loader::files_s.end(); ++it)
    9090            if (!Loader::load((*it).first, (*it).second * mask))
    9191                success = false;
     
    111111    }
    112112
    113     bool Loader::load(const Level* level, const ClassTreeMask& mask)
     113    bool Loader::load(const XMLFile* file, const ClassTreeMask& mask)
    114114    {
    115         if (!level)
     115        if (!file)
    116116            return false;
    117117
    118         Loader::currentMask_s = level->getMask() * mask;
     118        Loader::currentMask_s = file->getMask() * mask;
    119119
    120120        // let Lua work this out:
    121         //Script* lua;
    122         /*Script::loadFile(level->getFile(), true);
    123         Script::init(Script::getLuaState());
    124         Script::run();*/
    125         Script* lua = Script::getInstance();
     121        LuaBind* lua = LuaBind::getInstance();
    126122        lua->clearLuaOutput();
    127         lua->loadFile(level->getFile(), true);
     123        lua->loadFile(file->getFilename(), true);
    128124        lua->run();
    129125
    130126        try
    131127        {
    132             COUT(0) << "Start loading " << level->getFile() << "..." << std::endl;
     128            COUT(0) << "Start loading " << file->getFilename() << "..." << std::endl;
    133129            COUT(3) << "Mask: " << Loader::currentMask_s << std::endl;
    134130
    135             //ticpp::Document xmlfile(level->getFile());
     131            //ticpp::Document xmlfile(file->getFilename());
    136132            //xmlfile.LoadFile();
    137133            //ticpp::Element myelement(*Script::getFileString());
     
    148144
    149145            COUT(4) << "  creating root-namespace..." << std::endl;
    150             Namespace* rootNamespace = new Namespace();
     146            Namespace* rootNamespace = new Namespace(0);
    151147            rootNamespace->setLoaderIndentation("    ");
    152             rootNamespace->setLevel(level);
     148            rootNamespace->setFile(file);
    153149            rootNamespace->setNamespace(rootNamespace);
    154150            rootNamespace->setRoot(true);
    155151            rootNamespace->XMLPort(rootElement, XMLPort::LoadObject);
    156152
    157             COUT(0) << "Finished loading " << level->getFile() << "." << std::endl;
     153            COUT(0) << "Finished loading " << file->getFilename() << "." << std::endl;
    158154
    159155            COUT(4) << "Namespace-tree:" << std::endl << rootNamespace->toString("  ") << std::endl;
     
    164160        {
    165161            COUT(1) << std::endl;
    166             COUT(1) << "An error occurred in Loader.cc while loading " << level->getFile() << ":" << std::endl;
     162            COUT(1) << "An error occurred in Loader.cc while loading " << file->getFilename() << ":" << std::endl;
    167163            COUT(1) << ex.what() << std::endl;
    168164            COUT(1) << "Loading aborted." << std::endl;
     
    171167    }
    172168
    173     void Loader::unload(const Level* level, const ClassTreeMask& mask)
     169    void Loader::unload(const XMLFile* file, const ClassTreeMask& mask)
    174170    {
    175         if (!level)
     171        if (!file)
    176172            return;
    177173        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it; )
    178174        {
    179             if ((it->getLevel() == level) && mask.isIncluded(it->getIdentifier()))
     175            if ((it->getFile() == file) && mask.isIncluded(it->getIdentifier()))
    180176                delete (*(it++));
    181177            else
     
    184180    }
    185181
    186     bool Loader::reload(const Level* level, const ClassTreeMask& mask)
     182    bool Loader::reload(const XMLFile* file, const ClassTreeMask& mask)
    187183    {
    188         Loader::unload(level, mask);
    189         return Loader::load(level, mask);
     184        Loader::unload(file, mask);
     185        return Loader::load(file, mask);
    190186    }
    191187}
  • code/trunk/src/core/Loader.h

    r1505 r2087  
    3535
    3636#include "ClassTreeMask.h"
    37 #include "Level.h"
    3837
    3938namespace orxonox
     
    4241    {
    4342        public:
    44             static bool open(const Level* level, const ClassTreeMask& mask = ClassTreeMask());
     43            static bool open(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
    4544            static void close();
    46             static void close(const Level* level);
     45            static void close(const XMLFile* file);
    4746
    48             static void add(const Level* level, const ClassTreeMask& mask = ClassTreeMask());
    49             static void remove(const Level* level);
     47            static void add(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
     48            static void remove(const XMLFile* file);
    5049
    5150            static bool load(const ClassTreeMask& mask = ClassTreeMask());
     
    5352            static bool reload(const ClassTreeMask& mask = ClassTreeMask());
    5453
    55             static bool load(const Level* level, const ClassTreeMask& mask = ClassTreeMask());
    56             static void unload(const Level* level, const ClassTreeMask& mask = ClassTreeMask());
    57             static bool reload(const Level* level, const ClassTreeMask& mask = ClassTreeMask());
     54            static bool load(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
     55            static void unload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
     56            static bool reload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
    5857
    5958            static ClassTreeMask currentMask_s;
    6059
    6160        private:
    62             static std::vector<std::pair<const Level*, ClassTreeMask> > levels_s;
     61            static std::vector<std::pair<const XMLFile*, ClassTreeMask> > files_s;
    6362    };
    6463}
  • code/trunk/src/core/Namespace.cc

    r1889 r2087  
    3737    CreateFactory(Namespace);
    3838
    39     Namespace::Namespace() :
     39    Namespace::Namespace(BaseObject* creator) : BaseObject(creator),
    4040      bAutogeneratedFileRootNamespace_(false),
    4141      bRoot_(false),
  • code/trunk/src/core/Namespace.h

    r1841 r2087  
    4242    {
    4343        public:
    44             Namespace();
     44            Namespace(BaseObject* creator);
    4545            virtual ~Namespace();
    4646
  • code/trunk/src/core/RootGameState.cc

    r1824 r2087  
    3939namespace orxonox
    4040{
    41     SetCommandLineArgument(state, "gui").setShortcut("s");
     41    SetCommandLineArgument(state, "gui").shortcut("s");
    4242
    4343    RootGameState::RootGameState(const std::string& name)
     
    147147
    148148            // get initial state from command line
    149             std::string initialState;
    150             CommandLine::getValue<std::string>("state", &initialState);
    151             gotoState(initialState);
     149            gotoState(CommandLine::getValue("state"));
    152150
    153151            while (this->activeChild_)
  • code/trunk/src/core/Super.h

    r1841 r2087  
    7373#include "util/Debug.h"
    7474#include "XMLIncludes.h"
     75#include "Event.h"
    7576
    7677///////////////////////
     
    229230    #define SUPER_changedVisibility(classname, functionname, ...) \
    230231        SUPER_NOARGS(classname, functionname)
     232
     233    #define SUPER_processEvent(classname, functionname, ...) \
     234        SUPER_ARGS(classname, functionname, __VA_ARGS__)
    231235    // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
    232236
     
    433437            ()
    434438        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
     439
     440        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(4, processEvent, true, Event& event)
     441            (event)
     442        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
    435443        // (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
    436444
     
    479487    SUPER_INTRUSIVE_DECLARATION(changedActivity);
    480488    SUPER_INTRUSIVE_DECLARATION(changedVisibility);
     489    SUPER_INTRUSIVE_DECLARATION(processEvent);
    481490    // (3/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
    482491
  • code/trunk/src/core/XMLIncludes.h

    • Property svn:mergeinfo changed (with no actual effect on merging)
  • code/trunk/src/core/XMLPort.h

    r1889 r2087  
    7070*/
    7171#define XMLPortParam(classname, paramname, loadfunction, savefunction, xmlelement, mode) \
    72     XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, classname, this, paramname, orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction), orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction), xmlelement, mode)
     72    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
     73    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
     74    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, classname, this, paramname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode)
    7375/**
    7476    @brief This is the same as XMLPortParam, but you can set the template arguments needed to store the loadfunction.
     
    8385*/
    8486#define XMLPortParamTemplate(classname, paramname, loadfunction, savefunction, xmlelement, mode, ...) \
    85     XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, classname, this, paramname, orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction), orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction), xmlelement, mode)
     87    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
     88    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
     89    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, classname, this, paramname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode)
    8690
    8791// --------------------
     
    100104*/
    101105#define XMLPortParamLoadOnly(classname, paramname, loadfunction, xmlelement, mode) \
    102     XMLPortParamGeneric(xmlcontainer##loadfunction##0, classname, classname, this, paramname, orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction), 0, xmlelement, mode)
     106    static ExecutorMember<classname>* xmlcontainer##loadfunction##0##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
     107    XMLPortParamGeneric(xmlcontainer##loadfunction##0, classname, classname, this, paramname, xmlcontainer##loadfunction##0##loadexecutor, 0, xmlelement, mode)
    103108/**
    104109    @brief This is the same as XMLPortParamTemplate, but for load-only attributes (see XMLPortParamLoadOnly).
    105110*/
    106111#define XMLPortParamLoadOnlyTemplate(classname, paramname, loadfunction, xmlelement, mode, ...) \
    107     XMLPortParamGeneric(xmlcontainer##loadfunction##0, classname, classname, this, paramname, orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction), 0, xmlelement, mode)
     112    static ExecutorMember<classname>* xmlcontainer##loadfunction##0##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
     113    XMLPortParamGeneric(xmlcontainer##loadfunction##0, classname, classname, this, paramname, xmlcontainer##loadfunction##0##loadexecutor, 0, xmlelement, mode)
    108114
    109115// ------------------
     
    130136*/
    131137#define XMLPortParamExtern(classname, externclass, object, paramname, loadfunction, savefunction, xmlelement, mode) \
    132     XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, externclass, object, paramname, orxonox::createExecutor(orxonox::createFunctor(&externclass::loadfunction), std::string( #externclass ) + "::" + #loadfunction), orxonox::createExecutor(orxonox::createFunctor(&externclass::savefunction), std::string( #externclass ) + "::" + #savefunction), xmlelement, mode);
     138    static ExecutorMember<externclass>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&externclass::loadfunction), std::string( #externclass ) + "::" + #loadfunction); \
     139    static ExecutorMember<externclass>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&externclass::savefunction), std::string( #externclass ) + "::" + #savefunction); \
     140    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, externclass, object, paramname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode);
    133141/**
    134142    @brief This is the same as XMLPortParamTemplate, but for extern attributes (see XMLPortParamExtern).
    135143*/
    136144#define XMLPortParamExternTemplate(classname, externclass, object, paramname, loadfunction, savefunction, xmlelement, mode, ...) \
    137     XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, externclass, object, paramname, orxonox::createExecutor(orxonox::createFunctor<externclass, __VA_ARGS__ >(&externclass::loadfunction), std::string( #externclass ) + "::" + #loadfunction), orxonox::createExecutor(orxonox::createFunctor(&externclass::savefunction), std::string( #externclass ) + "::" + #savefunction), xmlelement, mode);
     145    static ExecutorMember<externclass>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<externclass, __VA_ARGS__ >(&externclass::loadfunction), std::string( #externclass ) + "::" + #loadfunction); \
     146    static ExecutorMember<externclass>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&externclass::savefunction), std::string( #externclass ) + "::" + #savefunction); \
     147    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, externclass, object, paramname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode);
    138148
    139149// -------------------
     
    214224*/
    215225#define XMLPortObjectExtended(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode, bApplyLoaderMask, bLoadBefore) \
    216     XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction), orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction), xmlelement, mode, bApplyLoaderMask, bLoadBefore)
     226    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
     227    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
     228    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode, bApplyLoaderMask, bLoadBefore)
    217229/**
    218230    @brief This is the same as XMLPortObjectExtended, but you can specify the loadfunction by adding the param types. See XMLPortParamTemplate for more details about the types.
    219231*/
    220232#define XMLPortObjectExtendedTemplate(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode, bApplyLoaderMask, bLoadBefore, ...) \
    221     XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, orxonox::createExecutor(orxonox::createFunctor< __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction), orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction), xmlelement, mode, bApplyLoaderMask, bLoadBefore)
     233    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
     234    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
     235    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode, bApplyLoaderMask, bLoadBefore)
    222236
    223237// -------------
     
    228242*/
    229243#define XMLPortObject(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode) \
    230     XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction), orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction), xmlelement, mode, false, true)
     244    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
     245    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
     246    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode, false, true)
    231247/**
    232248    @brief This is the same as XMLPortObject, but you can specify the loadfunction by adding the param types. See XMLPortParamTemplate for more details about the types.
    233249*/
    234250#define XMLPortObjectTemplate(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode, ...) \
    235     XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, orxonox::createExecutor(orxonox::createFunctor< __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction), orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction), xmlelement, mode, false, true)
     251    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
     252    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
     253    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode, false, true)
    236254
    237255// --------------------
     
    336354                    {
    337355                        COUT(1) << std::endl;
    338                         COUT(1) << "An error occurred in XMLPort.h while loading attribute '" << this->paramname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << this->owner_->getName() << ") in " << this->owner_->getLevelfile() << ":" << std::endl;
     356                        COUT(1) << "An error occurred in XMLPort.h while loading attribute '" << this->paramname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << this->owner_->getName() << ") in " << this->owner_->getFilename() << ":" << std::endl;
    339357                        COUT(1) << ex.what() << std::endl;
    340358                    }
     
    468486                            for (ticpp::Iterator<ticpp::Element> child = xmlsubelement->FirstChildElement(false); child != child.end(); child++)
    469487                            {
    470                                 Identifier* identifier = ClassByName(child->Value());
     488                                Identifier* identifier = ClassByString(child->Value());
    471489                                if (identifier)
    472490                                {
    473491                                    if (identifier->isA(Class(O)))
    474492                                    {
    475                                         if (this->identifierIsIncludedInLoaderMask(identifier))
     493                                        if (identifier->isLoadable())
    476494                                        {
    477                                             COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl;
    478 
    479                                             BaseObject* newObject = identifier->fabricate();
    480                                             newObject->setLoaderIndentation(((BaseObject*)object)->getLoaderIndentation() + "  ");
    481                                             newObject->setLevel(((BaseObject*)object)->getLevel());
    482                                             newObject->setNamespace(((BaseObject*)object)->getNamespace());
    483 
    484                                             if (this->bLoadBefore_)
     495                                            if (this->identifierIsIncludedInLoaderMask(identifier))
    485496                                            {
    486                                                 newObject->XMLPort(*child, XMLPort::LoadObject);
    487                                                 COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;
     497                                                COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl;
     498
     499                                                BaseObject* newObject = identifier->fabricate((BaseObject*)object);
     500                                                assert(newObject);
     501                                                newObject->setLoaderIndentation(((BaseObject*)object)->getLoaderIndentation() + "  ");
     502
     503                                                O* castedObject = dynamic_cast<O*>(newObject);
     504                                                assert(castedObject);
     505
     506                                                if (this->bLoadBefore_)
     507                                                {
     508                                                    newObject->XMLPort(*child, XMLPort::LoadObject);
     509                                                    COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;
     510                                                }
     511                                                else
     512                                                {
     513                                                    COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;
     514                                                }
     515
     516                                                COUT(5) << ((BaseObject*)object)->getLoaderIndentation();
     517                                                (*this->loadexecutor_)(object, castedObject);
     518
     519                                                if (!this->bLoadBefore_)
     520                                                    newObject->XMLPort(*child, XMLPort::LoadObject);
     521
     522                                                COUT(5) << ((BaseObject*)object)->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl;
    488523                                            }
    489                                             else
    490                                             {
    491                                                 COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;
    492                                             }
    493 
    494                                             COUT(5) << ((BaseObject*)object)->getLoaderIndentation();
    495                                             (*this->loadexecutor_)(object, newObject);
    496 
    497                                             if (!this->bLoadBefore_)
    498                                                 newObject->XMLPort(*child, XMLPort::LoadObject);
    499 
    500                                             COUT(5) << ((BaseObject*)object)->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl;
     524                                        }
     525                                        else
     526                                        {
     527                                            COUT(2) << ((BaseObject*)object)->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not loadable." << std::endl;
    501528                                        }
    502529                                    }
     
    508535                                else
    509536                                {
    510                                     COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a valid classname." << std::endl;
     537                                    if (this->sectionname_ != "")
     538                                    {
     539                                        COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a valid classname." << std::endl;
     540                                    }
     541                                    else
     542                                    {
     543                                        // It's probably just another subsection
     544                                    }
    511545                                }
    512546                            }
     
    516550                    {
    517551                        COUT(1) << std::endl;
    518                         COUT(1) << "An error occurred in XMLPort.h while loading a '" << Class(O)->getName() << "' in '" << this->sectionname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << ((BaseObject*)object)->getName() << ") in " << object->getLevelfile() << ":" << std::endl;
     552                        COUT(1) << "An error occurred in XMLPort.h while loading a '" << Class(O)->getName() << "' in '" << this->sectionname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << ((BaseObject*)object)->getName() << ") in " << object->getFilename() << ":" << std::endl;
    519553                        COUT(1) << ex.what() << std::endl;
    520554                    }
  • code/trunk/src/core/input/Button.cc

    r1887 r2087  
    175175
    176176                // check for param command
    177                 int paramIndex = eval.getConsoleCommand()->getAxisParamIndex();
     177                int paramIndex = eval.getConsoleCommand()->getInputConfiguredParam_();
    178178                if (paramIndex >= 0)
    179179                {
    180180                    // parameter supported command
    181181                    ParamCommand* cmd = new ParamCommand();
    182                     cmd->paramModifier_ = paramModifier;
    183                     cmd->bRelative_ = eval.getConsoleCommand()->getIsAxisRelative();
     182                    cmd->scale_ = paramModifier;
    184183
    185184                    // add command to the buffer if not yet existing
    186185                    for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer_->size(); iParamCmd++)
    187186                    {
    188                         if (getLowercase((*paramCommandBuffer_)[iParamCmd]->evaluation_.getOriginalCommand())
    189                             == getLowercase(commandStr))
     187                        if ((*paramCommandBuffer_)[iParamCmd]->evaluation_.getConsoleCommand()
     188                            == eval.getConsoleCommand())
    190189                        {
    191190                            // already in list
  • code/trunk/src/core/input/HalfAxis.h

    r1887 r2087  
    5050            , paramCommands_(0)
    5151            , nParamCommands_(0)
    52             , wasDown_(false)
     52            , pressed_(false)
    5353            , hasChanged_(false)
    5454        { }
     
    6565
    6666        // button related
    67         bool wasDown_;
     67        bool pressed_;
    6868        bool hasChanged_;
    6969    };
  • code/trunk/src/core/input/InputCommands.cc

    r1887 r2087  
    3434
    3535#include "InputCommands.h"
     36#include "util/Math.h"
    3637#include "core/CommandExecutor.h"
    3738
     
    5152    bool BufferedParamCommand::execute()
    5253    {
    53         if (nValuesAdded_)
     54        if (this->abs_ != 0.0f || this->rel_ != 0.0f)
    5455        {
    55             BufferedParamCommand& cmd = *this;
    56             cmd.evaluation_.setEvaluatedParameter(cmd.paramIndex_, cmd.value_);
     56            evaluation_.setEvaluatedParameter(paramIndex_, Vector2(abs_, rel_));
    5757            // reset
    58             cmd.nValuesAdded_ = 0;
    59             cmd.value_ = 0;
    60             return cmd.evaluation_.execute();
     58            rel_ = 0.0;
     59            abs_ = 0.0;
     60            return evaluation_.execute();
    6161        }
    6262        else
     
    7979        BufferedParamCommand& cmd = *paramCommand_;
    8080        // command has an additional parameter
    81         if (bRelative_)
     81        if (rel != 0.0f)
    8282        {
    83             if (rel != 0.0f)
    84             {
    85                 // we have to calculate a relative movement.
    86                 // paramModifier_ says how much one keystroke is
    87                 cmd.value_ += paramModifier_ * rel;
    88             }
     83            // calculate relative movement.
     84            // scale_ says how much one keystroke is
     85            cmd.rel_ += scale_ * rel;
    8986        }
    90         else if (abs != 0.0f)
     87
     88        if (abs != 0.0f)
    9189        {
    92             // Usually, joy sticks create 'noise' (they return values if they're in 0 position)
    93             // and normally this is caught in tickInput(), but that threshold cannot be to high
    94             // in order to preserve accuracy. Instead, we have to catch the problem here. An example:
    95             // Someone only uses buttons with an active joystick. The joy stick value could then
    96             // be 0.05 for instance and the the key value 1. Without handling the problem, the final
    97             // value would be computed to (1+0.05)/2=0.5025 which is not what the user expects.
    98             float absQ = abs * abs;
    99             float valueQ = cmd.value_ * cmd.value_;
    100             if (absQ > 50.0f * valueQ) // ease up comparison by using quadratics
    101             {
    102                 cmd.value_ = abs * paramModifier_;
    103                 cmd.nValuesAdded_ = 1;
    104             }
    105             else if (absQ * 50.0f < valueQ)
    106             {
    107                 // abs is too small, we just don't do anything
    108             }
    109             else
    110             {
    111                 // we have to calculate the absolute position of the axis.
    112                 // Since there might be another axis that is affected, we have to wait and
    113                 // store the result in a temporary place
    114                 cmd.value_ = (cmd.value_ * cmd.nValuesAdded_ + paramModifier_ * abs) / ++cmd.nValuesAdded_;
    115             }
     90            cmd.abs_ += scale_ * abs;
     91            if (cmd.abs_ > 1.0)
     92                cmd.abs_ = 1.0;
     93            if (cmd.abs_ < -1.0)
     94                cmd.abs_ = -1.0;
    11695        }
    11796        return true;
  • code/trunk/src/core/input/InputCommands.h

    r1887 r2087  
    4444    {
    4545    public:
    46         BufferedParamCommand() : value_(0.0f), nValuesAdded_(0), paramIndex_(-1) { }
     46        BufferedParamCommand() : abs_(0.0f), rel_(0.0), paramIndex_(-1) { }
    4747        bool execute();
    4848
    49         float value_;
    50         unsigned int nValuesAdded_;
     49        float abs_;
     50        float rel_;
    5151        int paramIndex_;
    5252        CommandEvaluation evaluation_;
     
    8282    {
    8383    public:
    84         ParamCommand() : bRelative_(false), paramModifier_(1.0f), paramCommand_(0) { }
     84        ParamCommand() : scale_(1.0f), paramCommand_(0) { }
    8585        bool execute(float abs = 1.0f, float rel = 1.0f);
    8686
    87         bool bRelative_;
    88         float paramModifier_;
     87        float scale_;
    8988        BufferedParamCommand* paramCommand_;
    9089    };
  • code/trunk/src/core/input/KeyBinder.cc

    r1887 r2087  
    137137        SetConfigValue(analogThreshold_, 0.05f)
    138138            .description("Threshold for analog axes until which the state is 0.");
     139        SetConfigValue(bFilterAnalogNoise_, false)
     140            .description("Specifies whether to filter small analog values like joy stick fluctuations.");
    139141        SetConfigValue(mouseSensitivity_, 1.0f)
    140142            .description("Mouse sensitivity.");
     
    145147        SetConfigValue(mouseSensitivityDerived_, 1.0f)
    146148            .description("Mouse sensitivity if mouse input is derived.");
    147         SetConfigValue(mouseWheelStepSize_, 120.0f)
     149        SetConfigValue(mouseWheelStepSize_, 120)
    148150            .description("Equals one step of the mousewheel.");
    149151        SetConfigValue(buttonThreshold_, 0.80f)
     
    323325    void KeyBinder::tickMouse(float dt)
    324326    {
    325         tickDevices(mouseAxes_, mouseAxes_ + MouseAxisCode::numberOfAxes * 2);
    326 
    327327        if (bDeriveMouseInput_)
    328328        {
     329            // only update when derive dt has passed
    329330            if (deriveTime_ > derivePeriod_)
    330331            {
     
    357358                deriveTime_ += dt;
    358359        }
    359     }
    360 
    361     void KeyBinder::tickDevices(HalfAxis* begin, HalfAxis* end)
    362     {
    363         for (HalfAxis* current = begin; current < end; ++current) // pointer arithmetic
    364         {
    365             // button mode
    366             // TODO: optimize out all the half axes that don't act as a button at the moment
    367             if (current->hasChanged_)
    368             {
    369                 if (!current->wasDown_ && current->absVal_ > current->buttonThreshold_)
    370                 {
    371                     current->wasDown_ = true;
    372                     if (current->nCommands_[KeybindMode::OnPress])
    373                         current->execute(KeybindMode::OnPress);
    374                 }
    375                 else if (current->wasDown_ && current->absVal_ < current->buttonThreshold_)
    376                 {
    377                     current->wasDown_ = false;
    378                     if (current->nCommands_[KeybindMode::OnRelease])
    379                         current->execute(KeybindMode::OnRelease);
    380                 }
    381                 current->hasChanged_ = false;
    382             }
    383 
    384             if (current->wasDown_)
    385             {
    386                 if (current->nCommands_[KeybindMode::OnHold])
    387                     current->execute(KeybindMode::OnHold);
    388             }
    389 
    390             // these are the actually useful axis bindings for analog input
    391             if (current->relVal_ > analogThreshold_ || current->absVal_ > analogThreshold_)
    392             {
    393                 current->execute();
    394             }
     360
     361        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
     362        {
     363            // Why dividing relative value by dt? The reason lies in the simple fact, that when you
     364            // press a button that has relative movement, that value has to be multiplied by dt to be
     365            // frame rate independant. This can easily (and only) be done in tickInput(float).
     366            // Hence we need to divide by dt here for the mouse to compensate, because the relative
     367            // move movements have nothing to do with dt.
     368            if (dt != 0.0f)
     369            {
     370                // just ignore if dt == 0.0 because we have multiplied by 0.0 anyway..
     371                mouseAxes_[i].relVal_ /= dt;
     372            }
     373
     374            tickHalfAxis(mouseAxes_[i]);
     375        }
     376    }
     377
     378    void KeyBinder::tickJoyStick(float dt, unsigned int joyStick)
     379    {
     380        for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
     381        {
     382            tickHalfAxis(joyStickAxes_[joyStick][i]);
     383        }
     384    }
     385
     386    void KeyBinder::tickHalfAxis(HalfAxis& halfAxis)
     387    {
     388        // button mode
     389        // TODO: optimize out all the half axes that don't act as a button at the moment
     390        if (halfAxis.hasChanged_)
     391        {
     392            if (!halfAxis.pressed_ && halfAxis.absVal_ > halfAxis.buttonThreshold_)
     393            {
     394                // key pressed event
     395                halfAxis.pressed_ = true;
     396                if (halfAxis.nCommands_[KeybindMode::OnPress])
     397                    halfAxis.execute(KeybindMode::OnPress);
     398            }
     399            else if (halfAxis.pressed_ && halfAxis.absVal_ < halfAxis.buttonThreshold_)
     400            {
     401                // key released event
     402                halfAxis.pressed_ = false;
     403                if (halfAxis.nCommands_[KeybindMode::OnRelease])
     404                    halfAxis.execute(KeybindMode::OnRelease);
     405            }
     406            halfAxis.hasChanged_ = false;
     407        }
     408
     409        if (halfAxis.pressed_)
     410        {
     411            // key held event
     412            if (halfAxis.nCommands_[KeybindMode::OnHold])
     413                halfAxis.execute(KeybindMode::OnHold);
     414        }
     415
     416        // these are the actually useful axis bindings for analog input
     417        if (!bFilterAnalogNoise_ || halfAxis.relVal_ > analogThreshold_ || halfAxis.absVal_ > analogThreshold_)
     418        {
     419            halfAxis.execute();
    395420        }
    396421    }
     
    407432        int rel[] = { rel_.x, -rel_.y };
    408433
    409         if (!bDeriveMouseInput_)
     434        if (bDeriveMouseInput_)
     435        {
     436            mouseRelative_[0] += rel[0];
     437            mouseRelative_[1] += rel[1];
     438        }
     439        else
    410440        {
    411441            for (int i = 0; i < 2; i++)
     
    437467            }
    438468        }
    439         else
    440         {
    441             mouseRelative_[0] += rel[0];
    442             mouseRelative_[1] += rel[1];
    443         }
    444469
    445470        // relative
  • code/trunk/src/core/input/KeyBinder.h

    r1888 r2087  
    7171        void tickJoyStick(float dt, unsigned int joyStick);
    7272        // internal
    73         void tickDevices(HalfAxis* begin, HalfAxis* end);
     73        void tickHalfAxis(HalfAxis& halfAxis);
    7474
    7575        void buttonThresholdChanged();
     
    149149        //! Filename of default keybindings.
    150150        std::string defaultKeybindings_;
     151        //! Whether to filter small value analog input
     152        bool bFilterAnalogNoise_;
    151153        //! Threshold for analog triggers until which the state is 0.
    152154        float analogThreshold_;
     
    162164        float mouseSensitivityDerived_;
    163165        //! Equals one step of the mousewheel
    164         float mouseWheelStepSize_;
     166        int mouseWheelStepSize_;
    165167
    166168        //##### Constant config variables #####
     
    198200    { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnHold); }
    199201
    200     inline void KeyBinder::tickJoyStick(float dt, unsigned int joyStick)
    201     {
    202         tickDevices(&joyStickAxes_[joyStick][0], &joyStickAxes_[joyStick][JoyStickAxisCode::numberOfAxes * 2]);
    203     }
    204 
    205202    inline void KeyBinder::tickInput(float dt)
    206203    {
    207204        // execute all buffered bindings (additional parameter)
    208205        for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
     206        {
     207            paramCommandBuffer_[i]->rel_ *= dt;
    209208            paramCommandBuffer_[i]->execute();
     209        }
    210210
    211211        // always reset the relative movement of the mouse
  • code/trunk/src/core/tolua/tolua.pkg

    r1755 r2087  
    1 $cfile "../../src/core/Script.h"
     1$cfile "../../src/core/LuaBind.h"
    22$cfile "../../src/core/CommandExecutor.h"
Note: See TracChangeset for help on using the changeset viewer.