Changeset 7474 for code/trunk/src/modules/objects
- Timestamp:
- Sep 21, 2010, 11:15:44 PM (14 years ago)
- Location:
- code/trunk/src/modules/objects
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk/src/modules/objects/Script.cc
r7463 r7474 35 35 #include "core/LuaState.h" 36 36 #include "core/XMLPort.h" 37 #include "network/Host.h" 38 #include "network/NetworkFunction.h" 39 40 #include "PlayerManager.h" 41 #include "infos/PlayerInfo.h" 42 #include "interfaces/PlayerTrigger.h" 43 #include "worldentities/pawns/Pawn.h" 37 44 38 45 namespace orxonox 39 46 { 40 47 CreateFactory(Script); 48 49 registerMemberNetworkFunction(Script, execute); 41 50 42 51 // Initializing constants. … … 51 60 The creator of this object. 52 61 */ 53 Script::Script(BaseObject* creator) : BaseObject(creator) 62 Script::Script(BaseObject* creator) : BaseObject(creator), Synchronisable(creator) 54 63 { 55 64 RegisterObject(Script); … … 63 72 this->needsGraphics_ = false; 64 73 74 this->counter_ = 0.0f; 75 76 this->registerVariables(); 65 77 } 66 78 … … 92 104 XMLPortParam(Script, "times", setTimes, getTimes, xmlelement, mode).defaultValues(Script::INF); 93 105 XMLPortParam(Script, "needsGraphics", setNeedsGraphics, getNeedsGraphics, xmlelement, mode).defaultValues(false); 106 XMLPortParam(Script, "forAll", setForAll, isForAll, xmlelement, mode).defaultValues(false); 94 107 95 108 XMLPortEventSink(Script, BaseObject, "trigger", trigger, xmlelement, mode); 96 109 97 if(this->isOnLoad()) // If the object is onLoad the code is executed at once .98 this->execute( );110 if(this->isOnLoad()) // If the object is onLoad the code is executed at once for all clients. 111 this->execute(0); 99 112 } 100 113 … … 116 129 /** 117 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 } 165 } 166 167 /** 168 @brief 118 169 Is called when an event comes in trough the event port. 119 170 @param triggered 120 171 Whether the event is triggering or un-triggering. 121 */ 122 void Script::trigger(bool triggered) 123 { 124 if(triggered) // If the event is triggering (instead of un-triggering) the code of this Script is executed. 125 this->execute(); 126 } 127 128 /** 129 @brief 130 Executes the Scripts code, depending on the mode. 131 */ 132 void Script::execute() 133 { 134 if(this->times_ != Script::INF && this->remainingExecutions_ == 0) 135 return; 136 137 // If the code needs graphics to be executed but the GameMode doesn't show graphics the code isn't executed. 138 if(this->needsGraphics_ && !GameMode::showsGraphics()) 139 return; 140 141 if(this->mode_ == ScriptMode::normal) // If the mode is 'normal'. 142 CommandExecutor::execute(this->code_); 143 else if(this->mode_ == ScriptMode::lua) // If it's 'lua'. 144 { 145 assert(this->luaState_); 146 this->luaState_->doString(this->code_); 147 } 148 149 if(this->times_ != Script::INF) 150 this->remainingExecutions_--; 172 @param trigger 173 The object that caused the event to be fired. 174 @return 175 Returns true if successful. 176 */ 177 bool Script::trigger(bool triggered, BaseObject* trigger) 178 { 179 if(!triggered || !this->isActive()) // If the Script is inactive it cannot be executed. 180 return false; 181 182 COUT(4) << "Script (&" << this << ") triggered." << std::endl; 183 184 PlayerTrigger* pTrigger = orxonox_cast<PlayerTrigger*>(trigger); 185 Pawn* pawn = NULL; 186 187 // If the trigger is a PlayerTrigger. 188 if(pTrigger != NULL) 189 { 190 if(!pTrigger->isForPlayer()) // The PlayerTrigger is not exclusively for Pawns which means we cannot extract one. 191 return false; 192 else 193 pawn = pTrigger->getTriggeringPlayer(); 194 } 195 else 196 return false; 197 198 if(pawn == NULL) //TODO: Will this ever happen? If not, change in NotificationDispatcher as well. 199 { 200 COUT(4) << "The Script was triggered by an entity other than a Pawn. (" << trigger->getIdentifier()->getName() << ")" << std::endl; 201 return false; 202 } 203 204 // Extract the PlayerInfo from the Pawn. 205 PlayerInfo* player = pawn->getPlayer(); 206 207 if(player == NULL) 208 { 209 COUT(3) << "The PlayerInfo* is NULL." << std::endl; 210 return false; 211 } 212 213 this->execute(player->getClientID()); 214 return true; 215 } 216 217 /** 218 @brief 219 Executes the Scripts code for the input client, depending on the mode. 220 @param clientId 221 The Id of the client the Script should be executed for. 222 @param fromCallback 223 Whether this method is executed in response to the connectedCallback(). 224 */ 225 void Script::execute(unsigned int clientId, bool fromCallback) 226 { 227 if(GameMode::isServer()) 228 { 229 // If the number of executions have been used up. 230 if(this->times_ != Script::INF && this->remainingExecutions_ == 0) 231 return; 232 233 // Decrement the number of remaining executions. 234 if(this->times_ != Script::INF) 235 this->remainingExecutions_--; 236 } 237 238 if(GameMode::isStandalone() || Host::getPlayerID() == clientId) 239 { 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 } 253 if(!GameMode::isStandalone() && GameMode::isServer() && Host::getPlayerID() != clientId) 254 { 255 if(!fromCallback && this->isForAll()) 256 { 257 const std::map<unsigned int, PlayerInfo*> clients = PlayerManager::getInstance().getClients(); 258 for(std::map<unsigned int, PlayerInfo*>::const_iterator it = clients.begin(); it != clients.end(); it++) 259 { 260 callMemberNetworkFunction(Script, execute, this->getObjectID(), it->first, it->first, false); 261 } 262 } 263 else 264 { 265 callMemberNetworkFunction(Script, execute, this->getObjectID(), clientId, clientId, false); 266 } 267 } 268 } 269 270 void Script::clientConnected(unsigned int clientId) 271 { 272 if(!GameMode::isStandalone() && GameMode::isServer() && this->isOnLoad()) 273 { 274 if(clientId != 0) 275 //TODO: Do better. This is only a temporary fix. 276 this->clientCallbacks_.push_back(clientId); 277 } 151 278 } 152 279 … … 160 287 { 161 288 if(mode == Script::NORMAL) 289 { 162 290 this->setMode(ScriptMode::normal); 291 this->modeStr_ = Script::NORMAL; 292 } 163 293 else if(mode == Script::LUA) 164 294 { 165 295 this->setMode(ScriptMode::lua); 296 this->modeStr_ = Script::LUA; 166 297 // Creates a new LuaState. 167 298 if(this->luaState_ == NULL) … … 170 301 else 171 302 { 172 COUT(2) << "Invalid mode '" << mode << "' in Script object. " << std::endl;303 COUT(2) << "Invalid mode '" << mode << "' in Script object. Setting to 'normal'." << std::endl; 173 304 this->setMode(ScriptMode::normal); 305 this->modeStr_ = Script::NORMAL; 174 306 } 175 307 } … … 210 342 else 211 343 { 212 COUT(2) << "Invalid times '" << times << "' in Script. " << std::endl;344 COUT(2) << "Invalid times '" << times << "' in Script. Setting to infinity." << std::endl; 213 345 this->times_ = Script::INF; 346 this->remainingExecutions_ = Script::INF; 214 347 } 215 348 } -
code/trunk/src/modules/objects/Script.h
r7463 r7474 33 33 34 34 #include <string> 35 #include <vector> 36 35 37 #include "core/BaseObject.h" 38 #include "tools/interfaces/Tickable.h" 39 #include "network/synchronisable/Synchronisable.h" 40 #include "network/ClientConnectionListener.h" 36 41 37 42 namespace orxonox … … 54 59 'code': The code that should be executed. 55 60 'mode': The mode, specifying whether the set code should be executed the normal way ('normal') or in lua ('lua'). Default is 'normal'. 56 'onLoad': Whether the code is executed upon loading (creation) of this object. Default is true.61 'onLoad': Whether the code is executed upon loading (creation) of this object. If this is set the code is executed ofr all players, regardless of the value of parameter 'forAll'. Default is true. 57 62 'needsGraphics': Whether the code needs graphics to be executed or not. Default is false. 63 'forAll': Whether the code is executed for all players each time the Script is triggered or jut for the player triggering the Script. If forAll is false, which is default, the event that triggers the Script must come from a PlayerTrigger. 58 64 59 65 Here are two examples illustrating the usage: … … 77 83 Damian 'Mozork' Frick 78 84 */ 79 class _ObjectsExport Script : public BaseObject 85 class _ObjectsExport Script : public BaseObject, public Synchronisable, public ClientConnectionListener, public Tickable 80 86 { 81 87 public: … … 86 92 virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode); //!< Creates a port that can be used to channel events and react to them. 87 93 88 void trigger(bool triggered); //!< Is called when an event comes in trough the event port. 89 void execute(); //!< Executes the Scripts code, depending on the mode. 94 virtual void tick(float dt); 95 96 bool trigger(bool triggered, BaseObject* trigger); //!< Is called when an event comes in trough the event port. 97 void execute(unsigned int clientId, bool fromCallback = false); //!< Executes the Scripts code for the input client, depending on the mode. 90 98 91 99 /** … … 139 147 { return this->needsGraphics_; } 140 148 149 /** 150 @brief Set whether the code is executed for all players or just for the player triggering the Script. 151 @param forAll If true the code is executed for all players. 152 */ 153 void setForAll(bool forAll) 154 { this->forAll_ = forAll; } 155 /** 156 @brief Get whether the Script executes its code for all players or just for the player triggering the Script. 157 @return Returns true if the code is executed for all players, false if not. 158 */ 159 bool isForAll(void) 160 { return this->forAll_; } 161 162 virtual void clientConnected(unsigned int clientId); 163 virtual void clientDisconnected(unsigned int clientid) {} 164 141 165 private: 142 166 //! Static variables to avoid magic strings. … … 150 174 int times_; //!< The number of times the Scripts code is executed at the most. -1 denotes infinity. 151 175 bool needsGraphics_; //!< Whether the code to be executed needs graphics. 176 bool forAll_; //!< Whether the code is executed for all players (in a multiplayer setup) or just for the one triggering the Script. 177 178 std::string modeStr_; 179 180 std::vector<unsigned int> clientCallbacks_; 181 float counter_; 152 182 153 183 LuaState* luaState_; //!< The LuaState to execute the code in lua. 154 184 int remainingExecutions_; //!< The number of remainign executions. -1 denotes infinity. 185 186 void registerVariables(void); 187 void modeChanged(); 155 188 156 189 /**
Note: See TracChangeset
for help on using the changeset viewer.