/* * ORXONOX - the hottest 3D action shooter ever to exist * > www.orxonox.net < * * * License notice: * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Author: * Oliver Scheuss , (C) 2010 * Co-authors: * ... * */ #include "FunctionCall.h" #include #include "util/MultiType.h" #include "NetworkFunction.h" namespace orxonox { FunctionCall::FunctionCall() : nrOfArguments_(-1), objectID_(OBJECTID_UNKNOWN), size_(0) { } FunctionCall::~FunctionCall() { } bool FunctionCall::execute(){ if( this->bIsStatic_ ) { NetworkFunctionStatic *fct = NetworkFunctionStatic::getFunction( this->functionID_ ); assert( this->nrOfArguments_==this->arguments_.size() ); switch(this->nrOfArguments_) { case 0: fct->call(); break; case 1: fct->call(this->arguments_[0]); break; case 2: fct->call(this->arguments_[0], this->arguments_[1]); break; case 3: fct->call(this->arguments_[0], this->arguments_[1], this->arguments_[2]); break; case 4: fct->call(this->arguments_[0], this->arguments_[1], this->arguments_[2], this->arguments_[3]); break; case 5: fct->call(this->arguments_[0], this->arguments_[1], this->arguments_[2], this->arguments_[3], this->arguments_[4]); break; default: assert(0); } } else // not a static function, so also handle with the objectID { NetworkMemberFunctionBase *fct = NetworkMemberFunctionBase::getFunction( this->functionID_ ); switch(this->nrOfArguments_) { case 0: if( !fct->call(this->objectID_) ) return false; break; case 1: if( !fct->call(this->objectID_, this->arguments_[0]) ) return false; break; case 2: if( !fct->call(this->objectID_, this->arguments_[0], this->arguments_[1]) ) return false; break; case 3: if( !fct->call(this->objectID_, this->arguments_[0], this->arguments_[1], this->arguments_[2]) ) return false; break; case 4: if( !fct->call(this->objectID_, this->arguments_[0], this->arguments_[1], this->arguments_[2], this->arguments_[3]) ) return false; break; case 5: if( !fct->call(this->objectID_, this->arguments_[0], this->arguments_[1], this->arguments_[2], this->arguments_[3], this->arguments_[4]) ) return false; break; default: assert(0); } } return true; } void FunctionCall::setCallStatic( uint32_t networkID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){ // first determine the size that has to be reserved for this call uint32_t callsize = 2*sizeof(uint32_t)+sizeof(uint8_t); //size for network-function-id and nrOfArguments and for bool isStatic uint32_t nrOfArguments = 0; if(mt1) { nrOfArguments++; callsize += mt1->getNetworkSize(); this->arguments_.push_back(*mt1); if(mt2) { nrOfArguments++; callsize += mt2->getNetworkSize(); this->arguments_.push_back(*mt2); if(mt3) { nrOfArguments++; callsize += mt3->getNetworkSize(); this->arguments_.push_back(*mt3); if(mt4) { nrOfArguments++; callsize += mt4->getNetworkSize(); this->arguments_.push_back(*mt4); if(mt5) { nrOfArguments++; callsize += mt5->getNetworkSize(); this->arguments_.push_back(*mt5); } } } } } this->nrOfArguments_ = nrOfArguments; this->size_ = callsize; this->bIsStatic_ = true; this->functionID_ = networkID; } void FunctionCall::setCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){ // first determine the size that has to be reserved for this call uint32_t callsize = 3*sizeof(uint32_t)+sizeof(uint8_t); //size for network-function-id and nrOfArguments and the objectID and bIsStatic uint32_t nrOfArguments = 0; if(mt1) { nrOfArguments++; callsize += mt1->getNetworkSize(); this->arguments_.push_back(*mt1); if(mt2) { nrOfArguments++; callsize += mt2->getNetworkSize(); this->arguments_.push_back(*mt2); if(mt3) { nrOfArguments++; callsize += mt3->getNetworkSize(); this->arguments_.push_back(*mt3); if(mt4) { nrOfArguments++; callsize += mt4->getNetworkSize(); this->arguments_.push_back(*mt4); if(mt5) { nrOfArguments++; callsize += mt5->getNetworkSize(); this->arguments_.push_back(*mt5); } } } } } this->nrOfArguments_ = nrOfArguments; this->bIsStatic_ = false; this->functionID_ = networkID; this->size_ = callsize; this->objectID_ = objectID; } void FunctionCall::loadData(uint8_t*& mem) { this->functionID_ = *(uint32_t*)mem; this->bIsStatic_ = *(uint8_t*)(mem+sizeof(uint32_t)); this->nrOfArguments_ = *(uint32_t*)(mem+sizeof(uint32_t)+sizeof(uint8_t)); if( this->bIsStatic_ ) { mem += 2*sizeof(uint32_t)+sizeof(uint8_t); } else { this->objectID_ = *(uint32_t*)(mem+2*sizeof(uint32_t)+sizeof(uint8_t)); mem += 3*sizeof(uint32_t)+sizeof(uint8_t); } for( unsigned int i=0; inrOfArguments_; ++i ) { this->arguments_.push_back(MultiType()); this->arguments_.back().importData(mem); } } void FunctionCall::saveData(uint8_t*& mem) { // now serialise the mt values and copy the function id and isStatic *(uint32_t*)mem = this->functionID_; *(uint8_t*)(mem+sizeof(uint32_t)) = this->bIsStatic_; *(uint32_t*)(mem+sizeof(uint32_t)+sizeof(uint8_t)) = this->nrOfArguments_; if( this->bIsStatic_ ) { mem += 2*sizeof(uint32_t)+sizeof(uint8_t); } else { *(uint32_t*)(mem+2*sizeof(uint32_t)+sizeof(uint8_t)) = this->objectID_; mem += 3*sizeof(uint32_t)+sizeof(uint8_t); } for( std::vector::iterator it = this->arguments_.begin(); it!=this->arguments_.end(); ++it ) { it->exportData( mem ); } } } //namespace orxonox