Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Sep 23, 2010, 11:12:22 AM (14 years ago)
Author:
dafrick
Message:

Fixed Script class. Works now without having to rely on guessing how long it is going to take for the object to be synchronized.

Location:
code/trunk/src/modules/objects
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/modules/objects/Script.cc

    r7474 r7482  
     1
    12/*
    23 *   ORXONOX - the hottest 3D action shooter ever to exist
     
    4748    CreateFactory(Script);
    4849
    49     registerMemberNetworkFunction(Script, execute);
     50    registerStaticNetworkFunction(Script::executeHelper);
    5051
    5152    // Initializing constants.
     
    5455    /*static*/ const int Script::INF = -1;
    5556
     57    /*static*/ LuaState* Script::LUA_STATE = NULL;
     58
    5659    /**
    5760    @brief
     
    6568
    6669        // Initialize variables.
    67         this->luaState_ = NULL;
    6870        this->remainingExecutions_ = Script::INF;
    6971        this->mode_ = ScriptMode::normal;
     
    7173        this->times_ = Script::INF;
    7274        this->needsGraphics_ = false;
    73 
    74         this->counter_ = 0.0f;
    75 
    76         this->registerVariables();
    7775    }
    7876
     
    8381    Script::~Script()
    8482    {
    85         if(this->isInitialized() && this->luaState_ != NULL)
    86             delete this->luaState_;
     83        //if(this->isInitialized() && this->luaState_ != NULL)
     84        //    delete this->luaState_;
    8785    }
    8886
     
    108106        XMLPortEventSink(Script, BaseObject, "trigger", trigger, xmlelement, mode);
    109107
    110         if(this->isOnLoad()) // If the object is onLoad the code is executed at once for all clients.
     108        if(this->isOnLoad()) // If the object is onLoad the code is executed at once for the server.
    111109            this->execute(0);
    112110    }
     
    125123
    126124        XMLPortEventState(Script, BaseObject, "trigger", trigger, xmlelement, mode);
    127     }
    128 
    129     /**
    130     @brief
    131         Register the variables that need to be synchronized.
    132     */
    133     void Script::registerVariables(void)
    134     {
    135         registerVariable(code_, VariableDirection::ToClient);
    136         registerVariable(needsGraphics_, VariableDirection::ToClient);
    137         registerVariable(modeStr_, VariableDirection::ToClient, new NetworkCallback<Script>(this, &Script::modeChanged));
    138     }
    139 
    140     void Script::modeChanged(void)
    141     {
    142         this->setMode(this->modeStr_);
    143     }
    144 
    145     void Script::tick(float dt)
    146     {
    147         SUPER(Script, tick, dt);
    148 
    149         if(!this->clientCallbacks_.empty())
    150         {
    151             if(this->counter_ < 2.0f)
    152             {
    153                 this->counter_ += dt;
    154             }
    155             else
    156             {
    157                 for(std::vector<unsigned int>::iterator it = this->clientCallbacks_.begin(); it != this->clientCallbacks_.end(); it++)
    158                 {
    159                     this->execute(*it, true);
    160                 }
    161                 this->clientCallbacks_.clear();
    162                 this->counter_ = 0.0f;
    163             }
    164         }
    165125    }
    166126
     
    225185    void Script::execute(unsigned int clientId, bool fromCallback)
    226186    {
    227         if(GameMode::isServer())
     187        COUT(0) << "EXECUTE: " << Host::getPlayerID() << " | " << clientId << std::endl; //TODO: Remove.
     188        // If this is the server or we're in standalone mode we check whether we still want to execute the code and if so decrease the number of remaining executions.
     189        if(GameMode::isServer() || GameMode::isStandalone())
    228190        {
    229191            // If the number of executions have been used up.
     
    232194
    233195            // Decrement the number of remaining executions.
     196            //TODO: Mode such that this is consistent in any case.
    234197            if(this->times_ != Script::INF)
    235198                this->remainingExecutions_--;
    236199        }
    237200
     201        // If this is either the standalone mode or we're on the client we want to be.
    238202        if(GameMode::isStandalone() || Host::getPlayerID() == clientId)
    239203        {
    240             // If the code needs graphics to be executed but the GameMode doesn't show graphics the code isn't executed.
    241             if(this->needsGraphics_ && !GameMode::showsGraphics())
    242                 return;
    243 
    244             if(this->mode_ == ScriptMode::normal) // If the mode is 'normal'.
    245                 CommandExecutor::execute(this->code_);
    246             else if(this->mode_ == ScriptMode::lua) // If it's 'lua'.
    247             {
    248                 if(this->luaState_ == NULL)
    249                     this->luaState_ = new LuaState();
    250                 this->luaState_->doString(this->code_);
    251             }
    252         }
     204           this->executeHelper(this->getCode(), this->getMode(), this->getNeedsGraphics());
     205        }
     206
     207        // If this is the server and we're not on the client we want to be.
    253208        if(!GameMode::isStandalone() && GameMode::isServer() && Host::getPlayerID() != clientId)
    254209        {
     210            COUT(0) << "1" << std::endl; //TODO: Remove.
     211            // If this is not the result of a clientConnected callback and we want to execute the code for all clients.
     212            //TODO: In this case does the server get executed as well?
    255213            if(!fromCallback && this->isForAll())
    256214            {
     
    258216                for(std::map<unsigned int, PlayerInfo*>::const_iterator it = clients.begin(); it != clients.end(); it++)
    259217                {
    260                     callMemberNetworkFunction(Script, execute, this->getObjectID(), it->first, it->first, false);
     218                    callStaticNetworkFunction(Script::executeHelper, it->first, this->getCode(), this->getMode(), this->getNeedsGraphics());
    261219                }
    262220            }
     221            // Else we execute the code just for the specified client.
    263222            else
    264223            {
    265                 callMemberNetworkFunction(Script, execute, this->getObjectID(), clientId, clientId, false);
     224                COUT(0) << "2" << std::endl; //TODO: Remove.
     225                callStaticNetworkFunction(Script::executeHelper, clientId, this->getCode(), this->getMode(), this->getNeedsGraphics());
    266226            }
    267227        }
    268228    }
    269229
     230    /**
     231    @brief
     232        Helper method that is used to reach this Script object on other clients.
     233    */
     234    /*static*/ void Script::executeHelper(const std::string& code, const std::string& mode, bool needsGraphics)
     235    {
     236        COUT(0) << "HELPER: " << code << " | " << mode << " | " << needsGraphics << std::endl; //TODO: Remove.
     237
     238        // If the code needs graphics to be executed but the GameMode doesn't show graphics the code isn't executed.
     239        if(needsGraphics && !GameMode::showsGraphics())
     240            return;
     241
     242        if(mode == Script::NORMAL) // If the mode is 'normal'.
     243            CommandExecutor::execute(code);
     244        else if(mode == Script::LUA) // If it's 'lua'.
     245        {
     246            if(Script::LUA_STATE == NULL)
     247                Script::LUA_STATE = new LuaState();
     248            Script::LUA_STATE->doString(code);
     249        }
     250    }
     251
     252    /**
     253    @brief
     254        Callback that is called when a new client has connected.
     255    @param clientId
     256        The clientId of the new client that has connected.
     257    */
    270258    void Script::clientConnected(unsigned int clientId)
    271259    {
     260        // If this is the server and the Script is specified as being 'onLoad'.
    272261        if(!GameMode::isStandalone() && GameMode::isServer() && this->isOnLoad())
    273262        {
    274             if(clientId != 0)
    275                 //TODO: Do better. This is only a temporary fix.
    276                 this->clientCallbacks_.push_back(clientId);
     263            if(clientId != 0) //TODO: Remove if not needed.
     264                this->execute(clientId, true);
    277265        }
    278266    }
     
    295283            this->setMode(ScriptMode::lua);
    296284            this->modeStr_ = Script::LUA;
    297             // Creates a new LuaState.
    298             if(this->luaState_ == NULL)
    299                 this->luaState_ = new LuaState();
    300285        }
    301286        else
     
    305290            this->modeStr_ = Script::NORMAL;
    306291        }
     292    }
     293
     294    /**
     295    @brief
     296        Sets the mode to the mode specified in this->modeStr_.
     297        This is used internally for networking purposes.
     298    */
     299    void Script::modeChanged(void)
     300    {
     301        this->setMode(this->modeStr_);
    307302    }
    308303
  • code/trunk/src/modules/objects/Script.h

    r7474 r7482  
     1
    12/*
    23 *   ORXONOX - the hottest 3D action shooter ever to exist
     
    3637
    3738#include "core/BaseObject.h"
    38 #include "tools/interfaces/Tickable.h"
    3939#include "network/synchronisable/Synchronisable.h"
    4040#include "network/ClientConnectionListener.h"
     
    8383        Damian 'Mozork' Frick
    8484    */
    85     class _ObjectsExport Script : public BaseObject, public Synchronisable, public ClientConnectionListener, public Tickable
     85    class _ObjectsExport Script : public BaseObject, public Synchronisable, public ClientConnectionListener
    8686    {
    8787        public:
     
    9292            virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode); //!< Creates a port that can be used to channel events and react to them.
    9393
    94             virtual void tick(float dt);
    95 
    9694            bool trigger(bool triggered, BaseObject* trigger); //!< Is called when an event comes in trough the event port.
    9795            void execute(unsigned int clientId, bool fromCallback = false); //!< Executes the Scripts code for the input client, depending on the mode.
     96            static void executeHelper(const std::string& code, const std::string& mode, bool needsGraphics); //!< Helper method that is used to reach this Script object on other clients.
    9897
    9998            /**
     
    160159                { return this->forAll_; }
    161160
    162             virtual void clientConnected(unsigned int clientId);
     161            virtual void clientConnected(unsigned int clientId); //!< Callback that is called when a new client has connected.
    163162            virtual void clientDisconnected(unsigned int clientid) {}
    164163
     
    171170            std::string code_; //!< The code that is executed by this Script.
    172171            ScriptMode::Value mode_; //!< The mode the Script is in. Determines whether the code is executed the normal way or in lua.
     172            std::string modeStr_; //!< The mode the Script is in, as a string. Is used for networking purposes.
    173173            bool onLoad_; //!< Whether the Scripts code is executed upon loading (creation) of this Script.
    174174            int times_; //!< The number of times the Scripts code is executed at the most. -1 denotes infinity.
     
    176176            bool forAll_; //!< Whether the code is executed for all players (in a multiplayer setup) or just for the one triggering the Script.
    177177
    178             std::string modeStr_;
    179 
    180             std::vector<unsigned int> clientCallbacks_;
    181             float counter_;
    182 
    183             LuaState* luaState_; //!< The LuaState to execute the code in lua.
     178            static LuaState* LUA_STATE; //!< The LuaState to execute the code in lua.
    184179            int remainingExecutions_; //!< The number of remainign executions. -1 denotes infinity.
    185180
    186             void registerVariables(void);
    187             void modeChanged();
     181            void modeChanged(); //!< Sets the mode to the mode specified in this->modeStr_.
    188182
    189183            /**
Note: See TracChangeset for help on using the changeset viewer.