Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Aug 25, 2010, 1:04:55 PM (14 years ago)
Author:
landauf
Message:

progress on the new console command interface.
enhanced possibilities to compare Functors and to manipulate Executors

Location:
code/branches/consolecommands3/src/libraries/core/command
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • code/branches/consolecommands3/src/libraries/core/command/ConsoleCommand.cc

    r7203 r7214  
    3030#include <cassert>
    3131
     32#include "util/Convert.h"
    3233#include "core/Language.h"
    3334
     
    124125    _ConsoleCommand::_ConsoleCommandManipulator test(_ModifyConsoleCommand("BaseObject", "setName").setFunction(&BaseObject::setActive));
    125126
    126     _ConsoleCommand::_ConsoleCommand(const std::string& group, const std::string& name, const FunctorPtr& functor, bool bInitialized) : Executor(functor, name), functionHeader_(functor->getHeaderIdentifier())
     127    _ConsoleCommand::_ConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized)
    127128    {
    128129        this->bActive_ = true;
    129         this->bInitialized_ = bInitialized;
     130        this->baseName_ = name;
     131        this->baseExecutor_ = executor;
     132
     133        if (bInitialized)
     134            this->executor_ = executor;
     135
    130136        _ConsoleCommand::registerCommand(group, name, this);
    131137    }
    132138
     139    _ConsoleCommand::~_ConsoleCommand()
     140    {
     141        _ConsoleCommand::unregisterCommand(this);
     142    }
     143
    133144    _ConsoleCommand& _ConsoleCommand::addShortcut()
    134145    {
    135         _ConsoleCommand::registerCommand("", this->getName(), this);
     146        _ConsoleCommand::registerCommand("", this->baseName_, this);
    136147        return *this;
    137148    }
     
    145156    _ConsoleCommand& _ConsoleCommand::addGroup(const std::string& group)
    146157    {
    147         _ConsoleCommand::registerCommand(group, this->getName(), this);
     158        _ConsoleCommand::registerCommand(group, this->baseName_, this);
    148159        return *this;
    149160    }
     
    155166    }
    156167
    157     bool _ConsoleCommand::setFunctor(const FunctorPtr& functor, bool bForce)
    158     {
    159         if (!functor)
    160         {
    161             this->bInitialized_ = false;
    162             return true;
    163         }
    164 
    165         if (!bForce && !this->functionHeaderMatches(functor))
    166         {
    167             COUT(1) << "Error: Couldn't assign new function to console command with name \"" << this->getName() << "\", headers don't match." << std::endl;
     168    bool _ConsoleCommand::isActive() const
     169    {
     170        return (this->bActive_ && this->executor_ && this->executor_->getFunctor());
     171    }
     172
     173    bool _ConsoleCommand::headersMatch(const FunctorPtr& functor)
     174    {
     175        unsigned int minparams = std::min(this->baseExecutor_->getParamCount(), functor->getParamCount());
     176
     177        if (this->baseExecutor_->getFunctor()->getHeaderIdentifier(minparams) != functor->getHeaderIdentifier(minparams))
    168178            return false;
    169         }
    170 
    171         this->functor_ = functor;
    172         this->bInitialized_ = true;
    173         return true;
    174     }
    175 
    176     void _ConsoleCommand::pushFunctor(const FunctorPtr& functor, bool bForce)
    177     {
    178         const FunctorPtr& oldfunctor = this->getFunctor();
    179 
    180         if (this->setFunctor(functor, bForce));
    181             this->functorStack_.push(oldfunctor);
    182     }
    183 
    184     void _ConsoleCommand::popFunctor()
    185     {
    186         FunctorPtr newfunctor;
    187         if (!this->functorStack_.empty())
    188         {
    189             newfunctor = this->functorStack_.top();
    190             this->functorStack_.pop();
    191         }
    192         this->setFunctor(newfunctor);
     179        else if (functor->getParamCount() <= this->baseExecutor_->getParamCount())
     180            return true;
     181        else if (!this->executor_)
     182            return false;
     183        else
     184        {
     185            for (unsigned int i = this->baseExecutor_->getParamCount(); i < functor->getParamCount(); ++i)
     186                if (!this->executor_->defaultValueSet(i))
     187                    return false;
     188
     189            return true;
     190        }
     191    }
     192
     193    bool _ConsoleCommand::headersMatch(const ExecutorPtr& executor)
     194    {
     195        unsigned int minparams = std::min(this->baseExecutor_->getParamCount(), executor->getParamCount());
     196
     197        if (this->baseExecutor_->getFunctor()->getHeaderIdentifier(minparams) != executor->getFunctor()->getHeaderIdentifier(minparams))
     198            return false;
     199        else if (executor->getParamCount() <= this->baseExecutor_->getParamCount())
     200            return true;
     201        else
     202        {
     203            for (unsigned int i = this->baseExecutor_->getParamCount(); i < executor->getParamCount(); ++i)
     204                if (!executor->defaultValueSet(i))
     205                    return false;
     206
     207            return true;
     208        }
     209    }
     210
     211    bool _ConsoleCommand::setFunction(const ExecutorPtr& executor, bool bForce)
     212    {
     213        if (!executor || !executor->getFunctor() || bForce || this->headersMatch(executor))
     214        {
     215            this->executor_ = executor;
     216            return true;
     217        }
     218        else
     219        {
     220            COUT(1) << "Error: Couldn't assign new executor to console command \"" << this->baseName_ << "\", headers don't match." << std::endl;
     221            return false;
     222        }
     223    }
     224
     225    bool _ConsoleCommand::setFunction(const FunctorPtr& functor, bool bForce)
     226    {
     227        if (!functor || bForce || this->headersMatch(functor))
     228        {
     229            if (this->executor_)
     230                this->executor_->setFunctor(functor);
     231            else
     232                this->executor_ = createExecutor(functor);
     233
     234            return true;
     235        }
     236        else
     237        {
     238            COUT(1) << "Error: Couldn't assign new functor to console command \"" << this->baseName_ << "\", headers don't match." << std::endl;
     239            return false;
     240        }
     241    }
     242
     243    void _ConsoleCommand::pushFunction(const ExecutorPtr& executor, bool bForce)
     244    {
     245        Command command;
     246        command.executor_ = this->getExecutor();
     247        if (command.executor_)
     248            command.functor_ = this->getFunctor();
     249
     250        if (this->setFunction(executor, bForce))
     251            this->commandStack_.push(command);
     252    }
     253
     254    void _ConsoleCommand::pushFunction(const FunctorPtr& functor, bool bForce)
     255    {
     256        Command command;
     257        command.executor_ = this->getExecutor();
     258        if (command.executor_)
     259            command.functor_ = this->getFunctor();
     260
     261        if (this->setFunction(functor, bForce))
     262            this->commandStack_.push(command);
     263    }
     264
     265    void _ConsoleCommand::pushFunction()
     266    {
     267        if (this->executor_)
     268            this->pushFunction(new Executor(*this->executor_.get()));
     269        else
     270            COUT(1) << "Error: Couldn't push copy of executor in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     271    }
     272
     273    void _ConsoleCommand::popFunction()
     274    {
     275        Command command;
     276        if (!this->commandStack_.empty())
     277        {
     278            command = this->commandStack_.top();
     279            this->commandStack_.pop();
     280        }
     281
     282        this->executor_ = command.executor_;
     283        if (command.executor_)
     284            this->executor_->setFunctor(command.functor_);
     285    }
     286
     287    const ExecutorPtr& _ConsoleCommand::getExecutor() const
     288    {
     289        return this->executor_;
    193290    }
    194291
    195292    const FunctorPtr& _ConsoleCommand::getFunctor() const
    196293    {
    197 //        if (this->bInitialized_) // FIXME
    198             return this->functor_;
    199 //        else
    200 //            return 0;
    201     }
    202 
    203     bool _ConsoleCommand::functionHeaderMatches(const FunctorPtr& functor) const
    204     {
    205         if (!this->functor_)
    206         {
    207             assert(false);
    208             return true;
    209         }
    210         return (functor->getHeaderIdentifier() == this->functionHeader_);
    211     }
    212 
    213     void _ConsoleCommand::setObject(void* object)
    214     {
    215         if (this->functor_)
    216             this->functor_->setRawObjectPointer(object);
     294        return this->executor_->getFunctor();
     295    }
     296
     297    bool _ConsoleCommand::setObject(void* object)
     298    {
     299        if (this->executor_)
     300        {
     301            if (this->executor_->getFunctor())
     302            {
     303                this->executor_->getFunctor()->setRawObjectPointer(object);
     304                return true;
     305            }
     306            else if (object)
     307                COUT(1) << "Error: Can't assign object to console command \"" << this->baseName_ << "\", no functor set." << std::endl;
     308        }
    217309        else if (object)
    218             COUT(1) << "Error: Can't set object in console command \"" << this->getName() << "\", no functor set." << std::endl;
     310            COUT(1) << "Error: Can't assign object to console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     311
     312        return false;
    219313    }
    220314
    221315    void _ConsoleCommand::pushObject(void* object)
    222316    {
    223         if (this->functor_)
    224         {
    225             this->objectStack_.push(this->getObject());
    226             this->setObject(object);
    227         }
    228         else
    229             COUT(1) << "Error: Can't set object in console command \"" << this->getName() << "\", no functor set." << std::endl;
     317        void* oldobject = this->getObject();
     318        if (this->setObject(object))
     319            this->objectStack_.push(oldobject);
    230320    }
    231321
     
    243333    void* _ConsoleCommand::getObject() const
    244334    {
    245         if (this->functor_)
    246             return this->functor_->getRawObjectPointer();
     335        if (this->executor_ && this->executor_->getFunctor())
     336            return this->executor_->getFunctor()->getRawObjectPointer();
    247337        else
    248338            return 0;
     
    284374        {
    285375            if (group == "")
    286                 COUT(2) << "Warning: A console command with shortcut name \"" << name << "\" already exists." << std::endl;
     376                COUT(2) << "Warning: A console command with shortcut \"" << name << "\" already exists." << std::endl;
    287377            else
    288                 COUT(2) << "Warning: A console command with group \"" << group << "\" and name \"" << name << "\" already exists." << std::endl;
     378                COUT(2) << "Warning: A console command with name \"" << name << "\" already exists in group \"" << group << "\"." << std::endl;
    289379        }
    290380        else
     
    293383        }
    294384    }
     385
     386    /* static */ void _ConsoleCommand::unregisterCommand(_ConsoleCommand* command)
     387    {
     388        for (std::map<std::string, std::map<std::string, _ConsoleCommand*> >::iterator it_group = _ConsoleCommand::getCommandMap().begin(); it_group != _ConsoleCommand::getCommandMap().end(); )
     389        {
     390            for (std::map<std::string, _ConsoleCommand*>::iterator it_name = it_group->second.begin(); it_name != it_group->second.end(); )
     391            {
     392                if (it_name->second == command)
     393                    it_group->second.erase(it_name++);
     394                else
     395                    ++it_name;
     396            }
     397
     398            if (it_group->second.empty())
     399                _ConsoleCommand::getCommandMap().erase(it_group++);
     400            else
     401                ++it_group;
     402        }
     403    }
    295404}
  • code/branches/consolecommands3/src/libraries/core/command/ConsoleCommand.h

    r7203 r7214  
    176176
    177177#define _SetConsoleCommandGeneric(group, name, functor) \
    178     orxonox::_ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::_createConsoleCommand(group, name, functor))
     178    orxonox::_ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::_createConsoleCommand(group, name, orxonox::createExecutor(functor)))
    179179
    180180
     
    182182    BOOST_PP_CAT(_DeclareConsoleCommand, ORXONOX_VA_NARGS(__VA_ARGS__))(__VA_ARGS__)
    183183#define _DeclareConsoleCommand2(name, functionpointer) \
    184     _DeclareConsoleCommandGeneric("", name, functionpointer)
     184    _DeclareConsoleCommandGeneric("", name, orxonox::createFunctor(functionpointer))
    185185#define _DeclareConsoleCommand3(group, name, functionpointer) \
    186     _DeclareConsoleCommandGeneric(group, name, functionpointer)
    187 
    188 #define _DeclareConsoleCommandGeneric(group, name, functionpointer) \
    189     orxonox::_ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::_createConsoleCommand(group, name, orxonox::createFunctor(functionpointer), false))
     186    _DeclareConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer))
     187#define _DeclareConsoleCommand4(group, name, functionpointer, object) \
     188    _DeclareConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer, object))
     189
     190#define _DeclareConsoleCommandGeneric(group, name, functor) \
     191    orxonox::_ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = orxonox::_createConsoleCommand(group, name, orxonox::createExecutor(functor), false)
    190192
    191193
     
    196198namespace orxonox
    197199{
    198     class _CoreExport _ConsoleCommand : protected Executor
     200    class _CoreExport _ConsoleCommand
    199201    {
    200202        friend struct _ConsoleCommandManipulator;
     203
     204        struct Command
     205        {
     206            ExecutorPtr executor_;
     207            FunctorPtr functor_;
     208        };
    201209
    202210        public:
     
    208216                    template <class F>
    209217                    inline _ConsoleCommandManipulator& setFunction(F function, bool bForce = false)
    210                         { if (this->command_) { this->command_->setFunctor(createFunctor(function), bForce); } return *this; }
     218                        {
     219                            if (this->command_)
     220                            {
     221                                if (this->command_->getExecutor() && this->command_->getFunctor() && this->command_->getFunctor()->getFullIdentifier() == typeid(F))
     222                                {
     223                                    FunctorPointer<F>* functor = static_cast<FunctorPointer<F>*>(this->command_->getFunctor().get());
     224                                    functor->setFunction(function);
     225                                    return *this;
     226                                }
     227                                this->command_->setFunction(createFunctor(function), bForce);
     228                            }
     229                            return *this;
     230                        }
    211231                    template <class F, class O>
    212232                    inline _ConsoleCommandManipulator& setFunction(F function, O* object, bool bForce = false)
    213                         { if (this->command_) { this->command_->setFunctor(createFunctor(function, object), bForce); } return *this; }
     233                        {
     234                            if (this->command_)
     235                            {
     236                                if (this->command_->getExecutor() && this->command_->getFunctor() && this->command_->getFunctor()->getFullIdentifier() == typeid(F))
     237                                {
     238                                    FunctorPointer<F, O>* functor = static_cast<FunctorPointer<F, O>*>(this->command_->getFunctor().get());
     239                                    functor->setFunction(function);
     240                                    functor->setObject(object);
     241                                    return *this;
     242                                }
     243                                this->command_->setFunction(createFunctor(function, object), bForce);
     244                            }
     245                            return *this;
     246                        }
    214247                    inline _ConsoleCommandManipulator& setFunction(const FunctorPtr& functor, bool bForce = false)
    215                         { if (this->command_) { this->command_->setFunctor(functor, bForce); } return *this; }
     248                        { if (this->command_) { this->command_->setFunction(functor, bForce); } return *this; }
     249                    inline _ConsoleCommandManipulator& setFunction(const ExecutorPtr& executor, bool bForce = false)
     250                        { if (this->command_) { this->command_->setFunction(executor, bForce); } return *this; }
    216251
    217252                    template <class F>
    218253                    inline _ConsoleCommandManipulator& pushFunction(F function, bool bForce = false)
    219                         { if (this->command_) { this->command_->pushFunctor(createFunctor(function), bForce); } return *this; }
     254                        { if (this->command_) { this->command_->pushFunction(createFunctor(function), bForce); } return *this; }
    220255                    template <class F, class O>
    221256                    inline _ConsoleCommandManipulator& pushFunction(F function, O* object, bool bForce = false)
    222                         { if (this->command_) { this->command_->pushFunctor(createFunctor(function, object), bForce); } return *this; }
     257                        { if (this->command_) { this->command_->pushFunction(createFunctor(function, object), bForce); } return *this; }
    223258                    inline _ConsoleCommandManipulator& pushFunction(const FunctorPtr& functor, bool bForce = false)
    224                         { if (this->command_) { this->command_->pushFunctor(functor, bForce); } return *this; }
     259                        { if (this->command_) { this->command_->pushFunction(functor, bForce); } return *this; }
     260                    inline _ConsoleCommandManipulator& pushFunction(const ExecutorPtr& executor, bool bForce = false)
     261                        { if (this->command_) { this->command_->pushFunction(executor, bForce); } return *this; }
    225262
    226263                    inline _ConsoleCommandManipulator& popFunction()
    227                         { if (this->command_) { this->command_->popFunctor(); } return *this; }
     264                        { if (this->command_) { this->command_->popFunction(); } return *this; }
    228265
    229266                    inline _ConsoleCommandManipulator& setObject(void* object)
     
    239276                    inline _ConsoleCommandManipulator& setActive(bool bActive)
    240277                        { if (this->command_) { this->command_->setActive(bActive); } return *this; }
     278                    inline _ConsoleCommandManipulator& activate()
     279                        { return this->setActive(true); }
     280                    inline _ConsoleCommandManipulator& deactivate()
     281                        { return this->setActive(false); }
     282
     283                    inline bool isActive() const
     284                        { return this->command_ ? this->command_->isActive() : false; }
     285                    inline bool exists() const
     286                        { return (this->command_ != 0); }
    241287
    242288                private:
     
    245291
    246292        public:
    247             _ConsoleCommand(const std::string& group, const std::string& name, const FunctorPtr& functor, bool bInitialized = true);
     293            _ConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized = true);
     294            ~_ConsoleCommand();
    248295
    249296            _ConsoleCommand& addShortcut();
     
    254301            inline void setActive(bool bActive)
    255302                { this->bActive_ = bActive; }
    256             inline bool isActive() const
    257                 { return (this->bActive_ && this->bInitialized_); }
     303            inline void activate()
     304                { this->setActive(true); }
     305            inline void deactivate()
     306                { this->setActive(false); }
     307            bool isActive() const;
    258308
    259309            inline _ConsoleCommandManipulator getManipulator() const
     
    270320            static std::map<std::string, std::map<std::string, _ConsoleCommand*> >& getCommandMap();
    271321            static void registerCommand(const std::string& group, const std::string& name, _ConsoleCommand* command);
    272 
    273             bool setFunctor(const FunctorPtr& functor, bool bForce = false);
    274             void pushFunctor(const FunctorPtr& functor, bool bForce = false);
    275             void popFunctor();
     322            static void unregisterCommand(_ConsoleCommand* command);
     323
     324            bool headersMatch(const FunctorPtr& functor);
     325            bool headersMatch(const ExecutorPtr& executor);
     326
     327            bool setFunction(const ExecutorPtr& executor, bool bForce = false);
     328            bool setFunction(const FunctorPtr& functor, bool bForce = false);
     329            void pushFunction(const ExecutorPtr& executor, bool bForce = false);
     330            void pushFunction(const FunctorPtr& functor, bool bForce = false);
     331            void pushFunction();
     332            void popFunction();
     333            const ExecutorPtr& getExecutor() const;
    276334            const FunctorPtr& getFunctor() const;
    277335
    278             bool functionHeaderMatches(const FunctorPtr& functor) const;
    279 
    280             void setObject(void* object);
     336            bool setObject(void* object);
    281337            void pushObject(void* object);
    282338            void popObject();
     
    284340
    285341            bool bActive_;
    286             bool bInitialized_;
    287             const std::type_info& functionHeader_;
    288             std::stack<FunctorPtr> functorStack_;
     342//            const std::type_info& functionHeader_;
     343            std::string baseName_;
     344            ExecutorPtr baseExecutor_;
     345
     346            ExecutorPtr executor_;
     347            std::stack<Command> commandStack_;
    289348            std::stack<void*> objectStack_;
    290349    };
    291350
    292     inline _ConsoleCommand* _createConsoleCommand(const std::string& name, const FunctorPtr& functor, bool bInitialized = true)
    293     {
    294         return new _ConsoleCommand("", name, functor, bInitialized);
     351    inline _ConsoleCommand* _createConsoleCommand(const std::string& name, const ExecutorPtr& executor, bool bInitialized = true)
     352    {
     353        return new _ConsoleCommand("", name, executor, bInitialized);
    295354    }
    296355
    297     inline _ConsoleCommand* _createConsoleCommand(const std::string& group, const std::string& name, const FunctorPtr& functor, bool bInitialized = true)
    298     {
    299         return new _ConsoleCommand(group, name, functor, bInitialized);
     356    inline _ConsoleCommand* _createConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized = true)
     357    {
     358        return new _ConsoleCommand(group, name, executor, bInitialized);
    300359    }
    301360}
  • code/branches/consolecommands3/src/libraries/core/command/Executor.h

    r7212 r7214  
    6363            bool evaluate(const std::string& params, MultiType param[5], const std::string& delimiter = " ") const;
    6464
     65            inline void setFunctor(const FunctorPtr& functor)
     66                { this->functor_ = functor; }
    6567            inline const FunctorPtr& getFunctor() const
    6668                { return this->functor_; }
     69
     70            inline void setName(const std::string& name)
     71                { this->name_ = name; }
     72            inline const std::string& getName() const
     73                { return this->name_; }
     74
    6775            inline unsigned int getParamCount() const
    6876                { return this->functor_->getParamCount(); }
     
    7583            inline std::string getTypenameReturnvalue() const
    7684                { return this->functor_->getTypenameReturnvalue(); }
    77 
    78             inline void setName(const std::string& name)
    79                 { this->name_ = name; }
    80             inline const std::string& getName() const
    81                 { return this->name_; }
    8285
    8386            void setDefaultValues(const MultiType& param1);
  • code/branches/consolecommands3/src/libraries/core/command/Functor.h

    r7213 r7214  
    111111            virtual const std::type_info& getFullIdentifier() const = 0;
    112112            virtual const std::type_info& getHeaderIdentifier() const = 0;
     113            virtual const std::type_info& getHeaderIdentifier(unsigned int params) const = 0;
    113114    };
    114115
     
    294295                switch (param)
    295296                {
    296                     case 0: return typeToString<P1>();
    297                     case 1: return typeToString<P2>();
    298                     case 2: return typeToString<P3>();
    299                     case 3: return typeToString<P4>();
    300                     case 4: return typeToString<P5>();
     297                    case 0:  return typeToString<P1>();
     298                    case 1:  return typeToString<P2>();
     299                    case 2:  return typeToString<P3>();
     300                    case 3:  return typeToString<P4>();
     301                    case 4:  return typeToString<P5>();
    301302                    default: return "";
    302303                }
     
    311312            {
    312313                return typeid(detail::FunctorHeaderIdentifier<R, P1, P2, P3, P4, P5>);
     314            }
     315
     316            const std::type_info& getHeaderIdentifier(unsigned int params) const
     317            {
     318                switch (params)
     319                {
     320                    case 0:  return typeid(detail::FunctorHeaderIdentifier<R, void, void, void, void, void>);
     321                    case 1:  return typeid(detail::FunctorHeaderIdentifier<R, P1, void, void, void, void>);
     322                    case 2:  return typeid(detail::FunctorHeaderIdentifier<R, P1, P2, void, void, void>);
     323                    case 3:  return typeid(detail::FunctorHeaderIdentifier<R, P1, P2, P3, void, void>);
     324                    case 4:  return typeid(detail::FunctorHeaderIdentifier<R, P1, P2, P3, P4, void>);
     325                    default: return typeid(detail::FunctorHeaderIdentifier<R, P1, P2, P3, P4, P5>);
     326                }
    313327            }
    314328    };
Note: See TracChangeset for help on using the changeset viewer.