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.

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