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

File:
1 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}
Note: See TracChangeset for help on using the changeset viewer.