Changeset 2171
- Timestamp:
- Nov 10, 2008, 12:05:03 AM (16 years ago)
- Location:
- code/trunk
- Files:
-
- 2 deleted
- 201 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
/code/branches/objecthierarchy merged: 2111-2115,2123,2132-2134,2143-2144,2153-2158,2160-2169
- Property svn:mergeinfo changed
-
code/trunk/TODO
r2087 r2171 1 1 todo: 2 3 test network functionality with paketloss/delay: http://www.linuxfoundation.org/en/Net:Netem#Packet_loss 2 4 3 5 bidirectional -
code/trunk/bin/run-script
r1735 r2171 8 8 fi 9 9 10 if [[ -ne orge.cfg ]] ; then10 if [[ ! -f ogre.cfg ]] ; then 11 11 cp ogre.cfg-init ogre.cfg 12 12 fi -
code/trunk/src/audio/AudioBuffer.cc
r2103 r2171 29 29 #include "AudioBuffer.h" 30 30 31 namespace audio31 namespace orxonox 32 32 { 33 33 AudioBuffer::AudioBuffer(std::string filename) -
code/trunk/src/audio/AudioBuffer.h
r2103 r2171 35 35 #include <AL/al.h> 36 36 37 namespace audio37 namespace orxonox 38 38 { 39 39 class _AudioExport AudioBuffer -
code/trunk/src/audio/AudioManager.cc
r1784 r2171 37 37 #include "AudioStream.h" 38 38 39 namespace audio39 namespace orxonox 40 40 { 41 41 AudioManager::AudioManager() -
code/trunk/src/audio/AudioManager.h
r1784 r2171 35 35 #include <string> 36 36 37 namespace audio37 namespace orxonox 38 38 { 39 39 class _AudioExport AudioManager -
code/trunk/src/audio/AudioPrereqs.h
r1505 r2171 60 60 // Forward declarations 61 61 //----------------------------------------------------------------------- 62 namespace audio62 namespace orxonox 63 63 { 64 64 class AudioBuffer; -
code/trunk/src/audio/AudioSource.cc
r1784 r2171 29 29 #include "AudioSource.h" 30 30 31 namespace audio31 namespace orxonox 32 32 { 33 33 AudioSource::AudioSource() -
code/trunk/src/audio/AudioSource.h
r1784 r2171 32 32 #include "AudioPrereqs.h" 33 33 34 namespace audio34 namespace orxonox 35 35 { 36 36 class _AudioExport AudioSource -
code/trunk/src/audio/AudioStream.cc
r1784 r2171 30 30 #include "util/Debug.h" 31 31 32 namespace audio32 namespace orxonox 33 33 { 34 34 AudioStream::AudioStream(std::string path) -
code/trunk/src/audio/AudioStream.h
r1784 r2171 39 39 40 40 41 namespace audio41 namespace orxonox 42 42 { 43 43 const int BUFFER_SIZE = 4096 * 4; -
code/trunk/src/core/BaseObject.cc
r2087 r2171 41 41 #include "Template.h" 42 42 #include "util/String.h" 43 #include "util/mbool.h" 43 44 44 45 namespace orxonox -
code/trunk/src/core/BaseObject.h
r2087 r2171 28 28 29 29 /** 30 @file BaseObject.h30 @file 31 31 @brief Definition of the BaseObject class. 32 32 … … 45 45 #include "XMLIncludes.h" 46 46 #include "Event.h" 47 #include "util/mbool.h" 47 48 48 49 namespace orxonox … … 72 73 73 74 /** @brief Sets the state of the objects activity. @param bActive True = active */ 74 inline void setActive(bool bActive) { this->bActive_ = bActive; this->changedActivity(); } 75 inline void setActive(bool bActive) 76 { 77 if (this->bActive_ != bActive) 78 { 79 this->bActive_ = bActive; 80 this->changedActivity(); 81 } 82 } 75 83 /** @brief Returns the state of the objects activity. @return The state of the activity */ 76 inline boolisActive() const { return this->bActive_; }84 inline const mbool& isActive() const { return this->bActive_; } 77 85 /** @brief This function gets called if the activity of the object changes. */ 78 86 virtual void changedActivity() {} 79 87 80 88 /** @brief Sets the state of the objects visibility. @param bVisible True = visible */ 81 inline void setVisible(bool bVisible) { this->bVisible_ = bVisible; this->changedVisibility(); } 89 inline void setVisible(bool bVisible) 90 { 91 if (this->bVisible_ != bVisible) 92 { 93 this->bVisible_ = bVisible; 94 this->changedVisibility(); 95 } 96 } 82 97 /** @brief Returns the state of the objects visibility. @return The state of the visibility */ 83 inline boolisVisible() const { return this->bVisible_; }98 inline const mbool& isVisible() const { return this->bVisible_; } 84 99 /** @brief This function gets called if the visibility of the object changes. */ 85 100 virtual void changedVisibility() {} … … 138 153 std::string name_; //!< The name of the object 139 154 std::string oldName_; //!< The old name of the object 140 bool bActive_;//!< True = the object is active141 bool bVisible_;//!< True = the object is visible155 mbool bActive_; //!< True = the object is active 156 mbool bVisible_; //!< True = the object is visible 142 157 143 158 private: -
code/trunk/src/core/ClassFactory.h
r2087 r2171 28 28 29 29 /** 30 @file ClassFactory.h30 @file 31 31 @brief Definition and implementation of the ClassFactory class 32 32 -
code/trunk/src/core/ClassTreeMask.cc
r1757 r2171 28 28 29 29 /** 30 @file ClassTreeMask.cc30 @file 31 31 @brief Implementation of the ClassTreeMask, ClassTreeMaskNode and ClassTreeMaskIterator classes. 32 32 */ -
code/trunk/src/core/ClassTreeMask.h
r1759 r2171 28 28 29 29 /** 30 @file ClassTreeMask.h30 @file 31 31 @brief Definition of the ClassTreeMask, ClassTreeMaskNode and ClassTreeMaskIterator classes. 32 32 -
code/trunk/src/core/Clock.h
r1755 r2171 28 28 29 29 /** 30 @file Core.h30 @file 31 31 @brief Declaration of the Core class. 32 32 -
code/trunk/src/core/ConfigValueContainer.cc
r1887 r2171 28 28 29 29 /** 30 @file ConfigValueContainer.cc30 @file 31 31 @brief Implementation of the ConfigValueContainer class. 32 32 */ -
code/trunk/src/core/ConfigValueContainer.h
r2087 r2171 28 28 29 29 /** 30 @file ConfigValueContainer.h30 @file 31 31 @brief Definition of the ConfigValueContainer class. 32 32 -
code/trunk/src/core/ConfigValueIncludes.h
r2103 r2171 28 28 29 29 /** 30 @file ConfigValueIncludes.h30 @file 31 31 @brief Definition of macros for config-values. 32 32 */ -
code/trunk/src/core/Core.cc
r2087 r2171 28 28 29 29 /** 30 @file Core.cc30 @file 31 31 @brief Implementation of the Core class. 32 32 */ -
code/trunk/src/core/Core.h
r2087 r2171 28 28 29 29 /** 30 @file Core.h30 @file 31 31 @brief Declaration of the Core class. 32 32 -
code/trunk/src/core/CoreIncludes.h
r2103 r2171 28 28 29 29 /** 30 @file CoreIncludes.h30 @file 31 31 @brief Definition of macros for Identifier and Factory. 32 32 -
code/trunk/src/core/Factory.cc
r2087 r2171 28 28 29 29 /** 30 @file Factory.cc30 @file 31 31 @brief Implementation of the Factory class. 32 32 */ -
code/trunk/src/core/Factory.h
r2087 r2171 28 28 29 29 /** 30 @file Factory.h30 @file 31 31 @brief Definition of the Factory and the BaseFactory class. 32 32 -
code/trunk/src/core/Identifier.cc
r2087 r2171 28 28 29 29 /** 30 @file Identifier.cc30 @file 31 31 @brief Implementation of the Identifier class. 32 32 */ -
code/trunk/src/core/Identifier.h
r2103 r2171 28 28 29 29 /** 30 @file Identifier.h30 @file 31 31 @brief Definition of the Identifier, ClassIdentifier and SubclassIdentifier classes, implementation of the ClassIdentifier and SubclassIdentifier classes. 32 32 -
code/trunk/src/core/Iterator.h
r1854 r2171 28 28 29 29 /** 30 @file Iterator.h30 @file 31 31 @brief Definition and implementation of the Iterator class. 32 32 -
code/trunk/src/core/Language.cc
r2103 r2171 28 28 29 29 /** 30 @file Language.cc30 @file 31 31 @brief Implementation of the Language and the LanguageEntry classes. 32 32 */ -
code/trunk/src/core/Language.h
r2103 r2171 28 28 29 29 /** 30 @file Language.h30 @file 31 31 @brief Definition of the Language and the LanguageEntry class. 32 32 -
code/trunk/src/core/Loader.cc
r2087 r2171 37 37 #include "Namespace.h" 38 38 #include "util/Debug.h" 39 #include "util/Exception.h" 39 40 40 41 #include "tinyxml/ticpp.h" … … 157 158 return true; 158 159 } 159 catch(ticpp::Exception& ex) 160 catch (ticpp::Exception& ex) 161 { 162 COUT(1) << std::endl; 163 COUT(1) << "An XML-error occurred in Loader.cc while loading " << file->getFilename() << ":" << std::endl; 164 COUT(1) << ex.what() << std::endl; 165 COUT(1) << "Loading aborted." << std::endl; 166 return false; 167 } 168 catch (Exception& ex) 169 { 170 COUT(1) << std::endl; 171 COUT(1) << "A loading-error occurred in Loader.cc while loading " << file->getFilename() << ":" << std::endl; 172 COUT(1) << ex.what() << std::endl; 173 COUT(1) << "Loading aborted." << std::endl; 174 return false; 175 } 176 catch (std::exception& ex) 160 177 { 161 178 COUT(1) << std::endl; 162 179 COUT(1) << "An error occurred in Loader.cc while loading " << file->getFilename() << ":" << std::endl; 163 180 COUT(1) << ex.what() << std::endl; 181 COUT(1) << "Loading aborted." << std::endl; 182 return false; 183 } 184 catch (...) 185 { 186 COUT(1) << std::endl; 187 COUT(1) << "An unknown error occurred in Loader.cc while loading " << file->getFilename() << ":" << std::endl; 164 188 COUT(1) << "Loading aborted." << std::endl; 165 189 return false; -
code/trunk/src/core/MetaObjectList.cc
r1747 r2171 28 28 29 29 /** 30 @file MetaObjectList.cc30 @file 31 31 @brief Implementation of the MetaObjectList class. 32 32 */ -
code/trunk/src/core/MetaObjectList.h
r1747 r2171 28 28 29 29 /** 30 @file MetaObjectList.h30 @file 31 31 @brief Definition of the MetaObjectList class. 32 32 -
code/trunk/src/core/ObjectList.h
r1747 r2171 28 28 29 29 /** 30 @file ObjectList.h30 @file 31 31 @brief Definition and implementation of the ObjectList class. 32 32 -
code/trunk/src/core/ObjectListBase.cc
r1747 r2171 28 28 29 29 /** 30 @file ObjectListBase.cc30 @file 31 31 @brief Implementation of the ObjectListBase class. 32 32 -
code/trunk/src/core/ObjectListBase.h
r1854 r2171 28 28 29 29 /** 30 @file ObjectListBase.h30 @file 31 31 @brief Definition of the ObjectListBase class. 32 32 -
code/trunk/src/core/OrxonoxClass.cc
r1747 r2171 28 28 29 29 /** 30 @file OrxonoxClass.cc30 @file 31 31 @brief Implementation of the OrxonoxClass Class. 32 32 */ -
code/trunk/src/core/OrxonoxClass.h
r1755 r2171 28 28 29 29 /** 30 @file OrxonoxClass.h30 @file 31 31 @brief Declaration of the OrxonoxClass Class. 32 32 -
code/trunk/src/core/Super.h
r2087 r2171 28 28 29 29 /** 30 @file Super.h30 @file 31 31 @brief Definition of all super-function related macros. 32 32 -
code/trunk/src/core/Template.cc
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/core/Template.h
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/core/XMLFile.h
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/core/XMLIncludes.h
- Property svn:mergeinfo changed
/code/branches/objecthierarchy/src/core/XMLIncludes.h merged: 2114
r2103 r2171 28 28 29 29 /** 30 @file XMLIncludes.h30 @file 31 31 @brief Forward declarations of some XML classes. 32 32 */ - Property svn:mergeinfo changed
-
code/trunk/src/core/XMLPort.h
r2087 r2171 28 28 29 29 /** 30 @file XMLPort.h30 @file 31 31 @brief Declaration of the XMLPort helper classes and macros. 32 32 … … 44 44 45 45 #include "util/Debug.h" 46 #include "util/Exception.h" 46 47 #include "util/MultiType.h" 47 48 #include "tinyxml/ticpp.h" … … 495 496 if (this->identifierIsIncludedInLoaderMask(identifier)) 496 497 { 497 COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl; 498 499 BaseObject* newObject = identifier->fabricate((BaseObject*)object); 500 assert(newObject); 501 newObject->setLoaderIndentation(((BaseObject*)object)->getLoaderIndentation() + " "); 502 503 O* castedObject = dynamic_cast<O*>(newObject); 504 assert(castedObject); 505 506 if (this->bLoadBefore_) 498 try 507 499 { 508 newObject->XMLPort(*child, XMLPort::LoadObject); 509 COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl; 500 COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl; 501 502 BaseObject* newObject = identifier->fabricate((BaseObject*)object); 503 assert(newObject); 504 newObject->setLoaderIndentation(((BaseObject*)object)->getLoaderIndentation() + " "); 505 506 O* castedObject = dynamic_cast<O*>(newObject); 507 assert(castedObject); 508 509 if (this->bLoadBefore_) 510 { 511 newObject->XMLPort(*child, XMLPort::LoadObject); 512 COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl; 513 } 514 else 515 { 516 COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl; 517 } 518 519 COUT(5) << ((BaseObject*)object)->getLoaderIndentation(); 520 (*this->loadexecutor_)(object, castedObject); 521 522 if (!this->bLoadBefore_) 523 newObject->XMLPort(*child, XMLPort::LoadObject); 524 525 COUT(5) << ((BaseObject*)object)->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl; 510 526 } 511 else527 catch (AbortLoadingException& ex) 512 528 { 513 COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl; 529 COUT(1) << "An error occurred while loading object, abort loading..." << std::endl; 530 throw ex; 514 531 } 515 516 COUT(5) << ((BaseObject*)object)->getLoaderIndentation(); 517 (*this->loadexecutor_)(object, castedObject); 518 519 if (!this->bLoadBefore_) 520 newObject->XMLPort(*child, XMLPort::LoadObject); 521 522 COUT(5) << ((BaseObject*)object)->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl; 532 catch (std::exception& ex) 533 { 534 COUT(1) << "An error occurred while loading object:" << std::endl; 535 COUT(1) << ex.what() << std::endl; 536 } 537 catch (...) 538 { 539 COUT(1) << "An unknown error occurred while loading object." << std::endl; 540 } 523 541 } 524 542 } -
code/trunk/src/network/ChatListener.cc
r2087 r2171 32 32 #include "core/Core.h" 33 33 34 namespace network34 namespace orxonox 35 35 { 36 36 ChatListener::ChatListener() -
code/trunk/src/network/ChatListener.h
r2087 r2171 35 35 #include "core/OrxonoxClass.h" 36 36 37 namespace network37 namespace orxonox 38 38 { 39 class _NetworkExport ChatListener : virtual public orxonox::OrxonoxClass39 class _NetworkExport ChatListener : virtual public OrxonoxClass 40 40 { 41 41 public: -
code/trunk/src/network/Client.cc
r2087 r2171 49 49 // #include "packet/Acknowledgement.h" 50 50 51 namespace network51 namespace orxonox 52 52 { 53 53 // SetConsoleCommandShortcut(Client, chat); -
code/trunk/src/network/Client.h
r2087 r2171 54 54 55 55 56 namespace network56 namespace orxonox 57 57 { 58 58 /** 59 network::Client *client;59 Client *client; 60 60 * The network/Client class 61 61 * This class implements all necessary function for the network communication -
code/trunk/src/network/ClientConnection.cc
r2087 r2171 48 48 #include "util/Debug.h" 49 49 50 namespace network50 namespace orxonox 51 51 { 52 52 //static boost::thread_group network_threads; -
code/trunk/src/network/ClientConnection.h
r2087 r2171 50 50 namespace boost { class thread; } 51 51 52 namespace network52 namespace orxonox 53 53 { 54 54 -
code/trunk/src/network/ClientConnectionListener.cc
r2087 r2171 3 3 #include "core/Core.h" 4 4 5 namespace network{5 namespace orxonox{ 6 6 7 7 ClientConnectionListener::ClientConnectionListener() … … 11 11 12 12 void ClientConnectionListener::getConnectedClients(){ 13 if( orxonox::Core::showsGraphics())13 if(Core::showsGraphics()) 14 14 this->clientConnected(0); //server client id 15 15 ClientInformation *client = ClientInformation::getBegin(); -
code/trunk/src/network/ClientConnectionListener.h
r2087 r2171 6 6 #include "core/OrxonoxClass.h" 7 7 8 namespace network{8 namespace orxonox{ 9 9 10 class _NetworkExport ClientConnectionListener : virtual public orxonox::OrxonoxClass10 class _NetworkExport ClientConnectionListener : virtual public OrxonoxClass 11 11 { 12 12 friend class Server; -
code/trunk/src/network/ClientInformation.cc
r2087 r2171 43 43 #include <iostream> //debug 44 44 45 namespace network45 namespace orxonox 46 46 { 47 47 -
code/trunk/src/network/ClientInformation.h
r2087 r2171 48 48 // WATCH OUT: THE CLIENTINFORMATION LIST IS NOT THREADSAFE ANYMORE 49 49 50 namespace network50 namespace orxonox 51 51 { 52 52 static const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1; -
code/trunk/src/network/ConnectionManager.cc
r2087 r2171 65 65 } 66 66 67 namespace network67 namespace orxonox 68 68 { 69 69 //boost::thread_group network_threads; … … 138 138 139 139 bool ConnectionManager::addPacket(ENetPacket *packet, ENetPeer *peer) { 140 boost::recursive_mutex::scoped_lock lock( instance_->enet_mutex);140 boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex); 141 141 if(enet_peer_send(peer, NETWORK_DEFAULT_CHANNEL, packet)!=0) 142 142 return false; … … 156 156 if(!instance_) 157 157 return false; 158 boost::recursive_mutex::scoped_lock lock( instance_->enet_mutex);158 boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex); 159 159 for(ClientInformation *i=ClientInformation::getBegin()->next(); i!=0; i=i->next()){ 160 160 COUT(3) << "adding broadcast packet for client: " << i->getID() << std::endl; … … 169 169 if(server==NULL || !instance_) 170 170 return false; 171 boost::recursive_mutex::scoped_lock lock( enet_mutex);171 boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex); 172 172 enet_host_flush(server); 173 173 lock.unlock(); … … 180 180 atexit(enet_deinitialize); 181 181 { //scope of the mutex 182 boost::recursive_mutex::scoped_lock lock( enet_mutex);182 boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex); 183 183 enet_initialize(); 184 184 server = enet_host_create(&bindAddress, NETWORK_MAX_CONNECTIONS, 0, 0); … … 194 194 while(!quit){ 195 195 { //mutex scope 196 boost::recursive_mutex::scoped_lock lock( enet_mutex);196 boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex); 197 197 if(enet_host_service(server, event, NETWORK_WAIT_TIMEOUT)<0){ 198 198 // we should never reach this point … … 236 236 // if we're finishied, destroy server 237 237 { 238 boost::recursive_mutex::scoped_lock lock( enet_mutex);238 boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex); 239 239 enet_host_destroy(server); 240 240 lock.unlock(); … … 250 250 while(temp!=0){ 251 251 { 252 boost::recursive_mutex::scoped_lock lock( enet_mutex);252 boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex); 253 253 enet_peer_disconnect(temp->getPeer(), 0); 254 254 lock.unlock(); … … 258 258 //bugfix: might be the reason why server crashes when clients disconnects 259 259 temp = ClientInformation::getBegin()->next(); 260 boost::recursive_mutex::scoped_lock lock( enet_mutex);260 boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex); 261 261 while( temp!=0 && enet_host_service(server, &event, NETWORK_WAIT_TIMEOUT) >= 0){ 262 262 switch (event.type) … … 306 306 unsigned int network_id=0, failures=0; 307 307 std::string classname; 308 orxonox::Identifier *id;309 std::map<std::string, orxonox::Identifier*>::const_iterator it = orxonox::Factory::getFactoryMapBegin();310 while(it != orxonox::Factory::getFactoryMapEnd()){308 Identifier *id; 309 std::map<std::string, Identifier*>::const_iterator it = Factory::getFactoryMapBegin(); 310 while(it != Factory::getFactoryMapEnd()){ 311 311 id = (*it).second; 312 312 if(id == NULL) … … 332 332 void ConnectionManager::disconnectClient(ClientInformation *client){ 333 333 { 334 boost::recursive_mutex::scoped_lock lock( enet_mutex);334 boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex); 335 335 enet_peer_disconnect(client->getPeer(), 0); 336 336 lock.unlock(); -
code/trunk/src/network/ConnectionManager.h
r2087 r2171 59 59 } 60 60 61 namespace network61 namespace orxonox 62 62 { 63 63 const int NETWORK_PORT = 55556; -
code/trunk/src/network/GamestateClient.cc
r2087 r2171 39 39 40 40 41 namespace network41 namespace orxonox 42 42 { 43 43 struct _NetworkExport GameStateItem{ … … 94 94 * @return iterator pointing to the next object in the list 95 95 */ 96 void GamestateClient::removeObject( orxonox::ObjectList<Synchronisable>::iterator &it) {97 orxonox::ObjectList<Synchronisable>::iterator temp=it;96 void GamestateClient::removeObject(ObjectList<Synchronisable>::iterator &it) { 97 ObjectList<Synchronisable>::iterator temp=it; 98 98 ++it; 99 99 delete *temp; -
code/trunk/src/network/GamestateClient.h
r2087 r2171 50 50 const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1; 51 51 52 namespace network52 namespace orxonox 53 53 { 54 54 class _NetworkExport GamestateClient: public GamestateHandler … … 66 66 private: 67 67 packet::Gamestate *processGamestate(packet::Gamestate *gs); 68 void removeObject( orxonox::ObjectListIterator<Synchronisable> &it);68 void removeObject(ObjectListIterator<Synchronisable> &it); 69 69 void printGamestateMap(); 70 70 bool sendAck(unsigned int gamestateID); -
code/trunk/src/network/GamestateHandler.cc
r1763 r2171 4 4 #include "packet/Packet.h" 5 5 6 namespace network{6 namespace orxonox { 7 7 8 8 GamestateHandler *GamestateHandler::instance_=0; … … 22 22 23 23 24 }//namespace network24 }//namespace orxonox -
code/trunk/src/network/GamestateHandler.h
r2087 r2171 34 34 #include "packet/Chat.h" 35 35 36 namespace network{36 namespace orxonox { 37 37 38 38 /** -
code/trunk/src/network/GamestateManager.cc
r2087 r2171 51 51 #include "Synchronisable.h" 52 52 53 namespace network53 namespace orxonox 54 54 { 55 55 GamestateManager::GamestateManager() { -
code/trunk/src/network/GamestateManager.h
r2087 r2171 47 47 #include "packet/Gamestate.h" 48 48 49 namespace network49 namespace orxonox 50 50 { 51 51 -
code/trunk/src/network/Host.cc
r2087 r2171 34 34 #include "ChatListener.h" 35 35 36 namespace network{36 namespace orxonox { 37 37 38 38 SetConsoleCommandShortcut(Host, Chat); … … 80 80 // } 81 81 82 // bool Host::receiveChat( network::packet::Chat *message, unsigned int clientID){82 // bool Host::receiveChat(packet::Chat *message, unsigned int clientID){ 83 83 // if(instance_) 84 84 // return instance_->processChat(message, clientID); … … 110 110 111 111 bool Host::incomingChat(const std::string& message, unsigned int playerID){ 112 for ( orxonox::ObjectList<ChatListener>::iterator it = orxonox::ObjectList<ChatListener>::begin(); it != orxonox::ObjectList<ChatListener>::end(); ++it)112 for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it) 113 113 it->incomingChat(message, playerID); 114 114 … … 116 116 } 117 117 118 }//namespace network118 }//namespace orxonox -
code/trunk/src/network/Host.h
r2087 r2171 34 34 #include "packet/Chat.h" 35 35 36 namespace network{36 namespace orxonox { 37 37 38 38 /** -
code/trunk/src/network/NetworkCallback.h
r2087 r2171 4 4 #include "NetworkPrereqs.h" 5 5 6 namespace network{6 namespace orxonox{ 7 7 class _NetworkExport NetworkCallbackBase 8 8 { -
code/trunk/src/network/NetworkPrereqs.h
r2087 r2171 59 59 // Forward declarations 60 60 //----------------------------------------------------------------------- 61 namespace network61 namespace orxonox 62 62 { 63 63 class Client; -
code/trunk/src/network/PacketBuffer.cc
r1505 r2171 39 39 #include <boost/thread/mutex.hpp> 40 40 41 namespace network41 namespace orxonox 42 42 { 43 43 boost::recursive_mutex PacketBuffer::mutex_; … … 147 147 } 148 148 149 } // namespace network149 } // namespace orxonox -
code/trunk/src/network/PacketBuffer.h
r2087 r2171 47 47 #include <boost/thread/recursive_mutex.hpp> 48 48 49 namespace network49 namespace orxonox 50 50 { 51 51 struct _NetworkExport PacketEnvelope{ -
code/trunk/src/network/Server.cc
r2087 r2171 60 60 #include "ChatListener.h" 61 61 62 namespace network62 namespace orxonox 63 63 { 64 64 const unsigned int MAX_FAILURES = 20; … … 317 317 318 318 // inform all the listeners 319 orxonox::ObjectList<ClientConnectionListener>::iterator listener = orxonox::ObjectList<ClientConnectionListener>::begin();319 ObjectList<ClientConnectionListener>::iterator listener = ObjectList<ClientConnectionListener>::begin(); 320 320 while(listener){ 321 321 listener->clientConnected(newid); … … 366 366 367 367 // inform all the listeners 368 orxonox::ObjectList<ClientConnectionListener>::iterator listener = orxonox::ObjectList<ClientConnectionListener>::begin();368 ObjectList<ClientConnectionListener>::iterator listener = ObjectList<ClientConnectionListener>::begin(); 369 369 while(listener){ 370 370 listener->clientDisconnected(client->getID()); … … 404 404 } 405 405 // COUT(1) << "Player " << Host::getPlayerID() << ": " << message << std::endl; 406 for ( orxonox::ObjectList<ChatListener>::iterator it = orxonox::ObjectList<ChatListener>::begin(); it != orxonox::ObjectList<ChatListener>::end(); ++it)406 for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it) 407 407 it->incomingChat(message, clientID); 408 408 -
code/trunk/src/network/Server.h
r2087 r2171 49 49 #include "GamestateManager.h" 50 50 51 namespace network51 namespace orxonox 52 52 { 53 53 const int CLIENTID_SERVER = 0; -
code/trunk/src/network/Synchronisable.cc
r2087 r2171 50 50 // #include "core/Identifier.h" 51 51 52 namespace network 52 #include "Host.h" 53 namespace orxonox 53 54 { 54 55 … … 57 58 std::queue<unsigned int> Synchronisable::deletedObjects_; 58 59 59 int Synchronisable::state_=0x1; // detemines wheter we are server (default) or client60 uint8_t Synchronisable::state_=0x1; // detemines wheter we are server (default) or client 60 61 61 62 /** … … 63 64 * Initializes all Variables and sets the right objectID 64 65 */ 65 Synchronisable::Synchronisable( orxonox::BaseObject* creator){66 Synchronisable::Synchronisable(BaseObject* creator){ 66 67 RegisterRootObject(Synchronisable); 67 68 static uint32_t idCounter=0; 68 69 objectFrequency_=1; 69 70 objectMode_=0x1; // by default do not send data to server 70 objectID=idCounter++; 71 if ( !Host::running() || ( Host::running() && Host::isServer() ) ) 72 { 73 this->objectID = idCounter++; //this is only needed when running a server 74 //add synchronisable to the objectMap 75 objectMap_[this->objectID] = this; 76 } 77 else 78 objectID=OBJECTID_UNKNOWN; 71 79 classID = (unsigned int)-1; 72 80 syncList = new std::list<synchronisableVariable *>; 81 82 83 #ifndef NDEBUG 84 ObjectList<Synchronisable>::iterator it; 85 for(it = ObjectList<Synchronisable>::begin(); it!=ObjectList<Synchronisable>::end(); ++it){ 86 if( it->getObjectID()==this->objectID ) 87 assert(*it==this || (it->objectID==OBJECTID_UNKNOWN && it->objectMode_==0x0)); 88 } 89 #endif 73 90 74 91 this->creatorID = OBJECTID_UNKNOWN; … … 96 113 Synchronisable::~Synchronisable(){ 97 114 // delete callback function objects 98 if(! orxonox::Identifier::isCreatingHierarchy()){115 if(!Identifier::isCreatingHierarchy()){ 99 116 for(std::list<synchronisableVariable *>::iterator it = syncList->begin(); it!=syncList->end(); it++) 100 117 delete (*it)->callback; 101 if (this->objectMode_ != 0x0 )118 if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer())) 102 119 deletedObjects_.push(objectID); 103 120 // COUT(3) << "destruct synchronisable +++" << objectID << " | " << classID << std::endl; … … 106 123 // objectMap_.erase(objectID); 107 124 } 125 std::map<unsigned int, Synchronisable*>::iterator it; 126 it = objectMap_.find(objectID); 127 if (it != objectMap_.end()) 128 objectMap_.erase(it); 108 129 } 109 130 … … 143 164 * @return pointer to the newly created synchronisable 144 165 */ 145 Synchronisable *Synchronisable::fabricate(uint8_t*& mem, int mode)166 Synchronisable *Synchronisable::fabricate(uint8_t*& mem, uint8_t mode) 146 167 { 147 168 synchronisableHeader *header = (synchronisableHeader *)mem; … … 152 173 return 0; 153 174 } 154 175 155 176 COUT(4) << "fabricating object with id: " << header->objectID << std::endl; 156 177 157 orxonox::Identifier* id = ClassByID(header->classID);178 Identifier* id = ClassByID(header->classID); 158 179 assert(id); 159 orxonox::BaseObject* creator = 0;180 BaseObject* creator = 0; 160 181 if (header->creatorID != OBJECTID_UNKNOWN) 161 182 { … … 167 188 } 168 189 else 169 creator = dynamic_cast<orxonox::BaseObject*>(synchronisable_creator); 170 } 171 orxonox::BaseObject *bo = id->fabricate(creator); 190 creator = dynamic_cast<BaseObject*>(synchronisable_creator); 191 } 192 assert(getSynchronisable(header->objectID)==0); //make sure no object with this id exists 193 BaseObject *bo = id->fabricate(creator); 172 194 assert(bo); 173 195 Synchronisable *no = dynamic_cast<Synchronisable *>(bo); … … 214 236 */ 215 237 Synchronisable* Synchronisable::getSynchronisable(unsigned int objectID){ 216 orxonox::ObjectList<Synchronisable>::iterator it; 217 for(it = orxonox::ObjectList<Synchronisable>::begin(); it; ++it){ 218 if( it->getObjectID()==objectID ) 219 return *it; 238 std::map<unsigned int, Synchronisable*>::iterator it1; 239 it1 = objectMap_.find(objectID); 240 if (it1 != objectMap_.end()) 241 return it1->second; 242 243 ObjectList<Synchronisable>::iterator it; 244 for(it = ObjectList<Synchronisable>::begin(); it; ++it){ 245 if( it->getObjectID()==objectID ){ 246 objectMap_[objectID] = *it; 247 return *it; 248 } 220 249 } 221 250 return NULL; 222 223 // std::map<unsigned int, Synchronisable *>::iterator i = objectMap_.find(objectID);224 // if(i==objectMap_.end())225 // return NULL;226 // assert(i->second->objectID==objectID);227 // return (*i).second;228 251 } 229 252 … … 234 257 * @param var pointer to the variable 235 258 * @param size size of the datatype the variable consists of 236 * @param t the type of the variable ( network::DATA or network::STRING259 * @param t the type of the variable (DATA or STRING 237 260 * @param mode same as in getData 238 261 * @param cb callback object that should get called, if the value of the variable changes 239 262 */ 240 void Synchronisable::registerVar (void *var, int size, variableType t, int mode, NetworkCallbackBase *cb){263 void Synchronisable::registerVariable(void *var, int size, variableType t, uint8_t mode, NetworkCallbackBase *cb){ 241 264 assert( mode==direction::toclient || mode==direction::toserver || mode==direction::serverMaster || mode==direction::clientMaster); 242 265 // create temporary synch.Var struct … … 249 272 if( ( mode & direction::bidirectional ) ) 250 273 { 251 temp->varBuffer = new uint8_t[size]; 252 memcpy(temp->varBuffer, temp->var, size); //now fill the buffer for the first time 274 if(t!=STRING) 275 { 276 temp->varBuffer = new uint8_t[size]; 277 memcpy(temp->varBuffer, temp->var, size); //now fill the buffer for the first time 278 } 279 else 280 { 281 temp->varBuffer=new std::string( *static_cast<std::string*>(var) ); 282 } 253 283 temp->varReference = 0; 254 284 } … … 265 295 #endif 266 296 } 297 298 void Synchronisable::unregisterVariable(void *var){ 299 std::list<synchronisableVariable *>::iterator it = syncList->begin(); 300 while(it!=syncList->end()){ 301 if( (*it)->var == var ){ 302 delete *it; 303 syncList->erase(it); 304 return; 305 } 306 else 307 it++; 308 } 309 bool unregistered_nonexistent_variable = false; 310 assert(unregistered_nonexistent_variable); //if we reach this point something went wrong: 311 // the variable has not been registered before 312 } 313 267 314 268 315 /** … … 280 327 * @return true: if !doSync or if everything was successfully saved 281 328 */ 282 bool Synchronisable::getData(uint8_t*& mem, unsigned int id, int mode){ 329 bool Synchronisable::getData(uint8_t*& mem, unsigned int id, uint8_t mode){ 330 if(mode==0x0) 331 mode=state_; 283 332 //if this tick is we dont synchronise, then abort now 284 if(!doSync(id ))333 if(!doSync(id, mode)) 285 334 return true; 286 335 //std::cout << "inside getData" << std::endl; 287 336 unsigned int tempsize = 0; 288 if(mode==0x0)289 mode=state_;290 337 if(classID==0) 291 338 COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl; … … 307 354 header->classID = this->classID; 308 355 header->dataAvailable = true; 309 tempsize +=sizeof(synchronisableHeader);310 mem +=sizeof(synchronisableHeader);356 tempsize += sizeof(synchronisableHeader); 357 mem += sizeof(synchronisableHeader); 311 358 // end copy header 312 359 … … 319 366 continue; // this variable should only be received 320 367 } 368 369 // =========== start bidirectional stuff ============= 321 370 // if the variable gets synchronised bidirectional, then add the reference to the bytestream 322 371 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 323 372 { 373 if( ( ((*i)->mode == direction::serverMaster) && (mode == 0x1) ) || \ 374 ( ((*i)->mode == direction::clientMaster) && (mode == 0x2) ) ) 375 { 376 // MASTER 377 if((*i)->type==DATA){ 378 if( memcmp((*i)->var,(*i)->varBuffer,(*i)->size) != 0 ) //check whether the variable changed during the last tick 379 { 380 ((*i)->varReference)++; //the variable changed so increase the refnr 381 memcpy((*i)->varBuffer, (*i)->var, (*i)->size); //set the buffer to the new value 382 } 383 } 384 else //STRING 385 { 386 if( *static_cast<std::string*>((*i)->var) != *static_cast<std::string*>((*i)->varBuffer) ) //the string changed 387 { 388 ((*i)->varReference)++; //the variable changed 389 *static_cast<std::string*>((*i)->varBuffer) = *static_cast<std::string*>((*i)->var); //now set the buffer to the new value 390 } 391 } 392 } 393 // copy the reference number to the stream 324 394 *(uint8_t*)mem = (*i)->varReference; 325 395 mem += sizeof( (*i)->varReference ); 326 396 tempsize += sizeof( (*i)->varReference ); 327 397 } 398 // ================== end bidirectional stuff 399 328 400 switch((*i)->type){ 329 401 case DATA: 330 402 memcpy( (void *)(mem), (void*)((*i)->var), (*i)->size); 331 mem +=(*i)->size;332 tempsize +=(*i)->size;403 mem += (*i)->size; 404 tempsize += (*i)->size; 333 405 break; 334 406 case STRING: 335 407 memcpy( (void *)(mem), (void *)&((*i)->size), sizeof(size_t) ); 336 mem +=sizeof(size_t);408 mem += sizeof(size_t); 337 409 const char *data = ( ( *(std::string *) (*i)->var).c_str()); 338 410 memcpy( mem, (void*)data, (*i)->size); 339 411 COUT(5) << "synchronisable: char: " << (const char *)(mem) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl; 340 mem +=(*i)->size;341 tempsize +=(*i)->size + sizeof(size_t);412 mem += (*i)->size; 413 tempsize += (*i)->size + sizeof(size_t); 342 414 break; 343 415 } … … 354 426 * @return true/false 355 427 */ 356 bool Synchronisable::updateData(uint8_t*& mem, int mode, bool forceCallback){428 bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback){ 357 429 if(mode==0x0) 358 430 mode=state_; 359 431 std::list<synchronisableVariable *>::iterator i; 432 //assert(objectMode_!=0x0); 433 //assert( (mode ^ objectMode_) != 0); 360 434 if(syncList->empty()){ 361 435 COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl; … … 367 441 synchronisableHeader *syncHeader = (synchronisableHeader *)mem; 368 442 assert(syncHeader->objectID==this->objectID); 369 // assert(syncHeader->creatorID==this->creatorID); 443 assert(syncHeader->creatorID==this->creatorID); 444 assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ? 370 445 if(syncHeader->dataAvailable==false){ 371 mem +=syncHeader->size;446 mem += syncHeader->size; 372 447 return true; 373 448 } 374 449 375 mem +=sizeof(synchronisableHeader);450 mem += sizeof(synchronisableHeader); 376 451 // stop extract header 377 assert(this->objectID==syncHeader->objectID);378 // assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ?379 452 380 453 COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl; … … 382 455 if( ((*i)->mode ^ mode) == 0 ){ 383 456 COUT(5) << "synchronisable: not updating variable " << std::endl; 457 // if we have a forcecallback then do the callback 384 458 continue; // this variable should only be set 385 459 } 386 460 COUT(5) << "Synchronisable: element size: " << (*i)->size << " type: " << (*i)->type << std::endl; 387 461 bool callback=false; 462 bool master=false; 463 464 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 465 { 466 uint8_t refNr = *(uint8_t *)mem; 467 if( ( ((*i)->mode == direction::serverMaster) && (mode == 0x1) ) || \ 468 ( ((*i)->mode == direction::clientMaster) && (mode == 0x2) ) ) 469 { // MASTER 470 master=true; 471 if( refNr != (*i)->varReference || ( memcmp((*i)->var, (*i)->varBuffer, (*i)->size) != 0 ) ) 472 { // DISCARD data 473 if( (*i)->type == DATA ) 474 { 475 mem += sizeof((*i)->varReference) + (*i)->size; 476 } 477 else //STRING 478 { 479 mem += sizeof(size_t) + *(size_t *)mem; 480 } 481 if( forceCallback && (*i)->callback) 482 (*i)->callback->call(); 483 continue; 484 }//otherwise everything is ok and we update the value 485 } 486 else // SLAVE 487 { 488 if( (*i)->varReference == refNr ){ 489 //discard data because it's outdated or not different to what we've got 490 if( (*i)->type == DATA ) 491 { 492 mem += sizeof((*i)->varReference) + (*i)->size; 493 } 494 else //STRING 495 { 496 mem += sizeof(size_t) + *(size_t *)mem; 497 } 498 if( forceCallback && (*i)->callback) 499 (*i)->callback->call(); 500 continue; 501 } 502 else 503 (*i)->varReference = refNr; //copy the reference value for this variable 504 } 505 mem += sizeof((*i)->varReference); 506 } 507 388 508 switch((*i)->type){ 389 509 case DATA: 390 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional)510 if((*i)->callback) // check whether this variable changed (but only if callback was set) 391 511 { 392 if( ( mode == 0x1 && (*i)->mode == direction::serverMaster ) || \ 393 ( mode == 0x2 && (*i)->mode == direction::clientMaster ) ) // if true we are master on this variable 394 { 395 uint8_t refNr = *(uint8_t *)mem; 396 if( refNr != (*i)->varReference ) 397 { 398 mem += sizeof((*i)->varReference) + (*i)->size; // the reference for this variable is not recent, discard data 399 break; 400 } 401 } 402 else //we are slave for this variable 403 { 404 (*i)->varReference = *(uint8_t *)mem; //copy the reference value for this variable 405 } 406 mem += sizeof((*i)->varReference); 512 if(memcmp((*i)->var, mem, (*i)->size) != 0) 513 callback=true; 407 514 } 408 if((*i)->callback) // check whether this variable changed (but only if callback was set) 409 if(strncmp((char *)(*i)->var, (char *)mem, (*i)->size)!=0) 410 callback=true; 411 memcpy((void*)(*i)->var, mem, (*i)->size); 412 mem+=(*i)->size; 515 if( master ) 516 { 517 if( callback || memcmp((*i)->var, mem, (*i)->size) != 0 ) 518 //value changed, so set the buffer to the new value 519 memcpy((*i)->varBuffer, mem, (*i)->size); 520 } 521 memcpy((*i)->var, mem, (*i)->size); 522 mem += (*i)->size; 413 523 break; 414 524 case STRING: 415 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 525 (*i)->size = *(size_t *)mem; 526 mem += sizeof(size_t); 527 528 if( (*i)->callback) // check whether this string changed 529 if( *static_cast<std::string*>((*i)->var) != std::string((char *)mem) ) 530 callback=true; 531 if( master ) 416 532 { 417 if( ( mode == 0x1 && (*i)->mode == direction::serverMaster ) || \ 418 ( mode == 0x2 && (*i)->mode == direction::clientMaster ) ) // if true we are master for this variable 419 { 420 uint8_t refNr = *(uint8_t *)mem; 421 mem += sizeof( (*i)->varReference ); 422 if( refNr != (*i)->varReference ){ 423 mem += sizeof(size_t) + *(size_t *)mem; // the reference for this variable is not recent, discard data 424 break; 425 } 426 } 427 else //we are slave for this variable 428 { 429 (*i)->varReference = *(uint8_t *)mem; //copy the reference value for this variable 430 } 431 mem += sizeof( (*i)->varReference ); 533 if( callback || *static_cast<std::string*>((*i)->var) != std::string((char *)mem) ) 534 //string changed. set the buffer to the new one 535 *static_cast<std::string*>((*i)->varBuffer)=*static_cast<std::string*>( (void*)(mem+sizeof(size_t)) ); 432 536 } 433 (*i)->size = *(size_t *)mem; 434 COUT(5) << "string size: " << (*i)->size << std::endl; 435 mem += sizeof(size_t); 436 if((*i)->callback) // check whether this string changed 437 if( *(std::string *)((*i)->var) != std::string((char *)mem) ) 438 callback=true; 537 439 538 *((std::string *)((*i)->var)) = std::string((const char*)mem); 440 539 COUT(5) << "synchronisable: char: " << (const char*)mem << " string: " << std::string((const char*)mem) << std::endl; … … 446 545 (*i)->callback->call(); 447 546 } 547 assert(mem == data+syncHeader->size); 448 548 return true; 449 549 } … … 455 555 * @return amount of bytes 456 556 */ 457 uint32_t Synchronisable::getSize(unsigned int id, int mode){ 458 if(!doSync(id)) 459 return 0; 557 uint32_t Synchronisable::getSize(unsigned int id, uint8_t mode){ 460 558 int tsize=sizeof(synchronisableHeader); 461 559 if(mode==0x0) 462 560 mode=state_; 561 if(!doSync(id, mode)) 562 return 0; 463 563 std::list<synchronisableVariable *>::iterator i; 464 564 for(i=syncList->begin(); i!=syncList->end(); i++){ … … 489 589 * @return true/false 490 590 */ 491 bool Synchronisable::doSync(unsigned int id){ 492 return ( (objectMode_&state_)!=0 && (!syncList->empty() ) ); 591 bool Synchronisable::doSync(unsigned int id, uint8_t mode){ 592 if(mode==0x0) 593 mode=state_; 594 return ( (objectMode_&mode)!=0 && (!syncList->empty() ) ); 493 595 } 494 596 495 597 bool Synchronisable::doSelection(unsigned int id){ 496 return ( id==0 || id%objectFrequency_==objectID%objectFrequency_ ) && ((objectMode_&state_)!=0); 598 return true; //TODO: change this 599 //return ( id==0 || id%objectFrequency_==objectID%objectFrequency_ ) && ((objectMode_&state_)!=0); 497 600 } 498 601 … … 510 613 /** 511 614 * This function sets the synchronisation mode of the object 615 * If set to 0x0 variables will not be synchronised at all 512 616 * If set to 0x1 variables will only be synchronised to the client 513 617 * If set to 0x2 variables will only be synchronised to the server … … 515 619 * @param mode same as in registerVar 516 620 */ 517 void Synchronisable::setObjectMode( int mode){621 void Synchronisable::setObjectMode(uint8_t mode){ 518 622 assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3); 519 623 objectMode_=mode; -
code/trunk/src/network/Synchronisable.h
r2087 r2171 42 42 43 43 #define REGISTERDATA(varname, ...) \ 44 registerVar ((void*)&varname, sizeof(varname), network::DATA, __VA_ARGS__)44 registerVariable((void*)&varname, sizeof(varname), DATA, __VA_ARGS__) 45 45 #define REGISTERSTRING(stringname, ...) \ 46 registerVar (&stringname, stringname.length()+1, network::STRING, __VA_ARGS__)46 registerVariable(&stringname, stringname.length()+1, STRING, __VA_ARGS__) 47 47 48 namespace network48 namespace orxonox 49 49 { 50 50 static const unsigned int OBJECTID_UNKNOWN = (unsigned int)-1; … … 62 62 namespace syncmode{ 63 63 enum mode{ 64 on e=0,64 once=0, 65 65 always=1 66 66 }; … … 81 81 82 82 struct _NetworkExport synchronisableVariable{ 83 unsigned int size;84 int mode; // this determines in which direction the variable gets synchronised83 size_t size; 84 uint8_t mode; // this determines in which direction the variable gets synchronised 85 85 void *var; 86 86 variableType type; … … 95 95 * @author Oliver Scheuss 96 96 */ 97 class _NetworkExport Synchronisable : virtual public orxonox::OrxonoxClass{97 class _NetworkExport Synchronisable : virtual public OrxonoxClass{ 98 98 public: 99 99 friend class packet::Gamestate; 100 friend class GamestateClient; 101 friend class Server; 100 // friend class Server; 102 101 virtual ~Synchronisable(); 103 102 … … 106 105 static void setClient(bool b); 107 106 108 static Synchronisable *fabricate(uint8_t*& mem, int mode=0x0);107 static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0); 109 108 static bool deleteObject(unsigned int objectID); 110 109 static Synchronisable *getSynchronisable(unsigned int objectID); … … 115 114 inline unsigned int getClassID(){return classID;} 116 115 protected: 117 Synchronisable(orxonox::BaseObject* creator); 118 void registerVar(void *var, int size, variableType t, int mode=1, NetworkCallbackBase *cb=0); 119 void setObjectMode(int mode); 116 Synchronisable(BaseObject* creator); 117 void registerVariable(void *var, int size, variableType t, uint8_t mode=0x1, NetworkCallbackBase *cb=0); 118 void unregisterVariable(void *var); 119 void setObjectMode(uint8_t mode); 120 120 void setObjectFrequency(unsigned int freq){ objectFrequency_ = freq; } 121 121 122 122 123 123 private: 124 bool getData(uint8_t*& men, unsigned int id, int mode=0x0);125 uint32_t getSize(unsigned int id, int mode=0x0);126 bool updateData(uint8_t*& mem, int mode=0x0, bool forceCallback=false);124 bool getData(uint8_t*& men, unsigned int id, uint8_t mode=0x0); 125 uint32_t getSize(unsigned int id, uint8_t mode=0x0); 126 bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false); 127 127 bool isMyData(uint8_t* mem); 128 128 bool doSelection(unsigned int id); 129 bool doSync(unsigned int id );129 bool doSync(unsigned int id, uint8_t mode=0x0); 130 130 131 131 unsigned int objectID; … … 134 134 135 135 std::list<synchronisableVariable *> *syncList; 136 static int state_; // detemines wheter we are server (default) or client136 static uint8_t state_; // detemines wheter we are server (default) or client 137 137 bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server) 138 138 unsigned int objectFrequency_; -
code/trunk/src/network/packet/Acknowledgement.cc
r1907 r2171 33 33 #include "core/CoreIncludes.h" 34 34 35 namespace network{35 namespace orxonox { 36 36 namespace packet { 37 37 38 38 #define PACKET_FLAGS_ACK 0 39 39 #define _PACKETID 0 40 #define _ACKID _PACKETID + sizeof( network::packet::ENUM::Type)40 #define _ACKID _PACKETID + sizeof(packet::ENUM::Type) 41 41 42 42 Acknowledgement::Acknowledgement( unsigned int id, unsigned int clientID ) … … 74 74 75 75 } //namespace packet 76 } //namespace network76 } //namespace orxonox -
code/trunk/src/network/packet/Acknowledgement.h
r2087 r2171 33 33 34 34 35 namespace network{35 namespace orxonox { 36 36 namespace packet { 37 37 /** … … 53 53 54 54 } //namespace packet 55 } //namespace network55 } //namespace orxonox 56 56 57 57 #endif -
code/trunk/src/network/packet/Chat.cc
r1907 r2171 31 31 #include "network/Host.h" 32 32 33 namespace network{33 namespace orxonox { 34 34 namespace packet { 35 35 … … 77 77 78 78 } //namespace packet 79 } //namespace network79 } //namespace orxonox -
code/trunk/src/network/packet/Chat.h
r2087 r2171 10 10 #include "Packet.h" 11 11 12 namespace network{12 namespace orxonox { 13 13 namespace packet { 14 14 /** … … 33 33 34 34 } //namespace packet 35 } //namespace network35 } //namespace orxonox 36 36 37 37 #endif -
code/trunk/src/network/packet/ClassID.cc
r1907 r2171 34 34 #include <assert.h> 35 35 36 namespace network{36 namespace orxonox { 37 37 namespace packet { 38 38 … … 68 68 69 69 unsigned int ClassID::getSize() const{ 70 return sizeof( network::packet::ENUM::Type) + 2*sizeof(uint32_t) + classNameLength_;70 return sizeof(packet::ENUM::Type) + 2*sizeof(uint32_t) + classNameLength_; 71 71 } 72 72 73 73 bool ClassID::process(){ 74 74 COUT(3) << "processing classid: " << getClassID() << " name: " << (const char*)(data_+_CLASSNAME) << std::endl; 75 orxonox::Identifier *id=ClassByID( std::string((const char*)(data_+_CLASSNAME) ));75 Identifier *id=ClassByID( std::string((const char*)(data_+_CLASSNAME) )); 76 76 if(id==NULL) 77 77 return false; … … 86 86 87 87 } //namespace packet 88 }//namespace network88 }//namespace orxonox -
code/trunk/src/network/packet/ClassID.h
r2087 r2171 35 35 #include "Packet.h" 36 36 37 namespace network{37 namespace orxonox { 38 38 namespace packet { 39 39 … … 59 59 60 60 } //namespace packet 61 } //namespace network61 } //namespace orxonox 62 62 63 63 #endif -
code/trunk/src/network/packet/DeleteObjects.cc
r1907 r2171 34 34 #include <assert.h> 35 35 36 namespace network{36 namespace orxonox { 37 37 namespace packet { 38 38 … … 95 95 96 96 } //namespace packet 97 } //namespace network97 } //namespace orxonox -
code/trunk/src/network/packet/DeleteObjects.h
r2087 r2171 34 34 35 35 36 namespace network{36 namespace orxonox { 37 37 namespace packet { 38 38 /** … … 55 55 56 56 } //namespace packet 57 } //namespace network57 } //namespace orxonox 58 58 59 59 #endif -
code/trunk/src/network/packet/Gamestate.cc
r2087 r2171 38 38 39 39 40 namespace network{40 namespace orxonox { 41 41 42 42 namespace packet { … … 71 71 } 72 72 73 bool Gamestate::collectData(int id, int mode)74 { 75 int tempsize=0, currentsize=0;73 bool Gamestate::collectData(int id, uint8_t mode) 74 { 75 unsigned int tempsize=0, currentsize=0; 76 76 assert(data_==0); 77 int size = calcGamestateSize(id, mode);77 unsigned int size = calcGamestateSize(id, mode); 78 78 79 79 COUT(4) << "G.ST.Man: producing gamestate with id: " << id << std::endl; … … 86 86 } 87 87 88 #ifndef NDEBUG89 std::list<Synchronisable*> slist;90 std::list<Synchronisable*>::iterator iit;91 #endif92 88 //start collect data synchronisable by synchronisable 93 89 uint8_t *mem=data_; 94 90 mem+=sizeof(GamestateHeader); 95 orxonox::ObjectList<Synchronisable>::iterator it;96 for(it = orxonox::ObjectList<Synchronisable>::begin(); it; ++it){91 ObjectList<Synchronisable>::iterator it; 92 for(it = ObjectList<Synchronisable>::begin(); it; ++it){ 97 93 tempsize=it->getSize(id, mode); 98 94 99 95 if(currentsize+tempsize > size){ 96 assert(0); // if we don't use multithreading this part shouldn't be neccessary 100 97 // start allocate additional memory 101 98 COUT(3) << "G.St.Man: need additional memory" << std::endl; 102 orxonox::ObjectList<Synchronisable>::iterator temp = it;99 ObjectList<Synchronisable>::iterator temp = it; 103 100 int addsize=tempsize; 104 101 while(++temp) … … 110 107 }// stop allocate additional memory 111 108 112 #ifndef NDEBUG113 for(iit=slist.begin(); iit!=slist.end(); iit++)114 assert((*iit)!=*it);115 slist.push_back(*it);116 #endif117 109 118 110 //if(it->doSelection(id)) … … 127 119 //start write gamestate header 128 120 HEADER->packetType = ENUM::Gamestate; 129 assert( *(ENUM::Type *)(data_) == ENUM::Gamestate);130 121 HEADER->datasize = currentsize; 131 122 HEADER->id = id; … … 140 131 } 141 132 142 bool Gamestate::spreadData( int mode)133 bool Gamestate::spreadData(uint8_t mode) 143 134 { 144 135 assert(data_); … … 147 138 uint8_t *mem=data_+sizeof(GamestateHeader); 148 139 // get the start of the Synchronisable list 149 // orxonox::ObjectList<Synchronisable>::iterator it=orxonox::ObjectList<Synchronisable>::begin();140 //ObjectList<Synchronisable>::iterator it=ObjectList<Synchronisable>::begin(); 150 141 Synchronisable *s; 151 142 … … 163 154 bool b = s->updateData(mem, mode); 164 155 assert(b); 165 //if(!s->updateData(mem, mode))166 //return false;167 156 } 168 157 } … … 367 356 assert(it->second->objectID==oldobjectheader->objectID); 368 357 *newobjectheader = *oldobjectheader; 369 objectOffset=sizeof( uint8_t)+sizeof(bool); //skip the size and the availableData variables in the objectheader358 objectOffset=sizeof(synchronisableHeader); //skip the size and the availableData variables in the objectheader 370 359 if(it->second->doSelection(HEADER->id)){ 371 newobjectheader->dataAvailable=true; //TODO: probably not neccessary 372 while(objectOffset<objectsize){ 373 *(newdata + objectOffset)=*(origdata + objectOffset); // copy the data 374 objectOffset++; 375 } 360 assert(newobjectheader->dataAvailable==true); 361 memcpy(newdata+objectOffset, origdata+objectOffset, objectsize-objectOffset); 376 362 }else{ 377 363 newobjectheader->dataAvailable=false; 378 while(objectOffset<objectsize){ 379 *(newdata+objectOffset)=0; // set to 0 380 objectOffset++; 381 } 364 memset(newdata+objectOffset, 0, objectsize-objectOffset); 382 365 assert(objectOffset==objectsize); 383 366 } … … 565 548 566 549 567 unsigned int Gamestate::calcGamestateSize(unsigned int id, int mode)568 { 569 int size=0;550 unsigned int Gamestate::calcGamestateSize(unsigned int id, uint8_t mode) 551 { 552 unsigned int size=0; 570 553 // get the start of the Synchronisable list 571 orxonox::ObjectList<Synchronisable>::iterator it;554 ObjectList<Synchronisable>::iterator it; 572 555 // get total size of gamestate 573 for(it = orxonox::ObjectList<Synchronisable>::begin(); it; ++it)556 for(it = ObjectList<Synchronisable>::begin(); it; ++it) 574 557 size+=it->getSize(id, mode); // size of the actual data of the synchronisable 575 558 // size+=sizeof(GamestateHeader); … … 582 565 * @return iterator pointing to the next object in the list 583 566 */ 584 void Gamestate::removeObject( orxonox::ObjectList<Synchronisable>::iterator &it) {585 orxonox::ObjectList<Synchronisable>::iterator temp=it;567 void Gamestate::removeObject(ObjectList<Synchronisable>::iterator &it) { 568 ObjectList<Synchronisable>::iterator temp=it; 586 569 ++it; 587 570 delete *temp; -
code/trunk/src/network/packet/Gamestate.h
r2087 r2171 40 40 #endif 41 41 42 namespace network{42 namespace orxonox { 43 43 44 44 namespace packet { … … 69 69 ~Gamestate(); 70 70 71 bool collectData(int id, int mode=0x0);72 bool spreadData( int mode=0x0);71 bool collectData(int id, uint8_t mode=0x0); 72 bool spreadData( uint8_t mode=0x0); 73 73 int getID(); 74 74 bool isDiffed(); … … 90 90 bool operator ==(packet::Gamestate gs); 91 91 private: 92 unsigned int calcGamestateSize(unsigned int id, int mode=0x0);93 void removeObject( orxonox::ObjectListIterator<Synchronisable> &it);92 unsigned int calcGamestateSize(unsigned int id, uint8_t mode=0x0); 93 void removeObject(ObjectListIterator<Synchronisable> &it); 94 94 std::map<unsigned int, Synchronisable*> dataMap_; 95 95 }; -
code/trunk/src/network/packet/Packet.cc
r2087 r2171 46 46 #include "core/CoreIncludes.h" 47 47 48 namespace network{48 namespace orxonox{ 49 49 50 50 namespace packet{ … … 53 53 #define _PACKETID 0 54 54 55 std::map<ENetPacket *, Packet *> Packet::packetMap_; 55 std::map<size_t, Packet *> Packet::packetMap_; 56 boost::recursive_mutex Packet::packetMap_mutex; 56 57 57 58 Packet::Packet(){ … … 128 129 return false; 129 130 } 131 // Assures we don't create a packet and destroy it right after in another thread 132 // without having a reference in the packetMap_ 133 boost::recursive_mutex::scoped_lock lock(Packet::packetMap_mutex); 130 134 // We deliver ENet the data address so that it doesn't memcpy everything again. 131 135 // --> We have to delete data_ ourselves! … … 134 138 // Add the packet to a global list so we can access it again once enet calls our 135 139 // deletePacket method. We can of course only give a one argument function to the ENet C library. 136 packetMap_[ enetPacket_] = this;140 packetMap_[(size_t)(void*)enetPacket_] = this; 137 141 } 138 142 #ifndef NDEBUG … … 153 157 // ENetPacket *temp = enetPacket_; 154 158 // enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet 155 network::Host::addPacket( enetPacket_, clientID_);159 Host::addPacket( enetPacket_, clientID_); 156 160 return true; 157 161 } … … 207 211 */ 208 212 void Packet::deletePacket(ENetPacket *enetPacket){ 213 boost::recursive_mutex::scoped_lock lock(Packet::packetMap_mutex); 209 214 // Get our Packet from a gloabal map with all Packets created in the send() method of Packet. 210 std::map< ENetPacket*, Packet*>::iterator it = packetMap_.find(enetPacket);215 std::map<size_t, Packet*>::iterator it = packetMap_.find((size_t)enetPacket); 211 216 assert(it != packetMap_.end()); 212 217 // Make sure we don't delete it again in the destructor 213 218 it->second->enetPacket_ = 0; 214 219 delete it->second; 215 //packetMap_.erase(it);220 packetMap_.erase(it); 216 221 COUT(4) << "PacketMap size: " << packetMap_.size() << std::endl; 217 222 } … … 219 224 } // namespace packet 220 225 221 } // namespace network222 226 } // namespace orxonox 227 -
code/trunk/src/network/packet/Packet.h
r2087 r2171 29 29 #define NETWORKPACKET_H 30 30 31 #include " ../NetworkPrereqs.h"31 #include "network/NetworkPrereqs.h" 32 32 33 33 #include <map> 34 34 #include <enet/enet.h> 35 #include <boost/thread/recursive_mutex.hpp> 35 36 36 37 #include "util/Integers.h" 37 38 38 namespace network{39 namespace orxonox { 39 40 40 41 namespace packet{ … … 92 93 bool bDataENetAllocated_; 93 94 private: 94 static std::map<ENetPacket *, Packet *> packetMap_; 95 static std::map<size_t, Packet *> packetMap_; 96 //! Static mutex for any packetMap_ access 97 static boost::recursive_mutex packetMap_mutex; 95 98 ENetPacket *enetPacket_; 96 99 }; … … 98 101 } //namespace packet 99 102 100 } //namespace network103 } //namespace orxonox 101 104 102 105 #endif -
code/trunk/src/network/packet/Welcome.cc
r1907 r2171 36 36 #include <assert.h> 37 37 38 namespace network{38 namespace orxonox { 39 39 namespace packet { 40 40 … … 70 70 71 71 unsigned int Welcome::getSize() const{ 72 return sizeof( network::packet::ENUM::Type) + 2*sizeof(uint32_t);72 return sizeof(packet::ENUM::Type) + 2*sizeof(uint32_t); 73 73 } 74 74 … … 87 87 88 88 } //namespace packet 89 }//namespace network89 }//namespace orxonox -
code/trunk/src/network/packet/Welcome.h
r2087 r2171 33 33 #include "Packet.h" 34 34 35 namespace network{35 namespace orxonox { 36 36 namespace packet { 37 37 … … 54 54 55 55 } //namespace packet 56 } //namespace network56 } //namespace orxonox 57 57 58 58 #endif -
code/trunk/src/orxonox/CMakeLists.txt
r2130 r2171 4 4 LevelManager.cc 5 5 Main.cc 6 PlayerManager.cc 6 7 Settings.cc 7 8 -
code/trunk/src/orxonox/CameraManager.cc
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/orxonox/CameraManager.h
- Property svn:mergeinfo changed
/code/branches/objecthierarchy/src/orxonox/CameraManager.h merged: 2114
r2103 r2171 28 28 29 29 /** 30 @file CameraManager.h30 @file 31 31 @brief Handles the instances of Camera class 32 32 @author Benjamin Knecht <beni_at_orxonox.net> - Property svn:mergeinfo changed
-
code/trunk/src/orxonox/LevelManager.cc
r2087 r2171 28 28 29 29 #include "OrxonoxStableHeaders.h" 30 31 30 #include "LevelManager.h" 32 31 33 #include "core/CoreIncludes.h" 34 35 #include "objects/infos/Level.h" 32 #include "PlayerManager.h" 33 #include "objects/Level.h" 36 34 #include "objects/infos/HumanPlayer.h" 37 35 … … 42 40 LevelManager::LevelManager() 43 41 { 44 RegisterRootObject(LevelManager);45 46 42 assert(singletonRef_s == 0); 47 43 singletonRef_s = this; 48 49 this->getConnectedClients();50 44 } 51 45 … … 95 89 { 96 90 this->levels_s.front()->setActive(true); 97 for (std::map<unsigned int, PlayerInfo*>:: iterator it = this->clients_.begin(); it != this->clients_.end(); ++it)91 for (std::map<unsigned int, PlayerInfo*>::const_iterator it = PlayerManager::getInstance().getClients().begin(); it != PlayerManager::getInstance().getClients().end(); ++it) 98 92 this->levels_s.front()->playerEntered(it->second); 99 93 } 100 94 } 101 102 103 void LevelManager::clientConnected(unsigned int clientID)104 {105 COUT(3) << "client connected" << std::endl;106 107 // create new HumanPlayer instance108 HumanPlayer* player = new HumanPlayer(0);109 player->setClientID(clientID);110 111 // add to clients-map112 assert(!this->clients_[clientID]);113 this->clients_[clientID] = player;114 115 if (this->getActiveLevel())116 this->getActiveLevel()->playerEntered(player);117 }118 119 void LevelManager::clientDisconnected(unsigned int clientID)120 {121 COUT(3) << "client disconnected" << std::endl;122 123 // remove from clients-map124 PlayerInfo* player = this->clients_[clientID];125 this->clients_.erase(clientID);126 127 if (this->getActiveLevel())128 this->getActiveLevel()->playerLeft(player);129 130 // delete PlayerInfo instance131 if (player)132 delete player;133 }134 135 136 PlayerInfo* LevelManager::getClient(unsigned int clientID) const137 {138 std::map<unsigned int, PlayerInfo*>::const_iterator it = this->clients_.find(clientID);139 if (it != this->clients_.end())140 return it->second;141 else142 return 0;143 }144 95 } -
code/trunk/src/orxonox/LevelManager.h
r2087 r2171 36 36 #include <cassert> 37 37 38 #include "network/ClientConnectionListener.h"39 40 38 namespace orxonox 41 39 { 42 class _OrxonoxExport LevelManager : public network::ClientConnectionListener40 class _OrxonoxExport LevelManager 43 41 { 44 42 public: … … 50 48 Level* getActiveLevel(); 51 49 52 PlayerInfo* getClient(unsigned int clientID) const; 53 inline const std::map<unsigned int, PlayerInfo*>& getClients() const 54 { return this->clients_; } 55 50 static LevelManager* getInstancePtr() { return singletonRef_s; } 56 51 static LevelManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; } 57 52 … … 59 54 LevelManager(const LevelManager&); 60 55 61 void clientConnected(unsigned int clientID);62 void clientDisconnected(unsigned int clientID);63 64 56 void activateNextLevel(); 65 57 66 58 std::list<Level*> levels_s; 67 std::map<unsigned int, PlayerInfo*> clients_;68 69 59 static LevelManager* singletonRef_s; 70 60 }; -
code/trunk/src/orxonox/OrxonoxPrereqs.h
r2096 r2171 82 82 class CameraManager; 83 83 class LevelManager; 84 class PlayerManager; 84 85 85 86 // objects 87 class Level; 86 88 class Scene; 87 89 … … 142 144 143 145 class Info; 144 class Level;145 146 class PlayerInfo; 146 147 class HumanPlayer; -
code/trunk/src/orxonox/Settings.h
r2087 r2171 28 28 29 29 /** 30 @file Core.h30 @file 31 31 @brief Declaration of the Settings class. 32 32 -
code/trunk/src/orxonox/gamestates/GSClient.cc
r2087 r2171 53 53 Core::setIsClient(true); 54 54 55 this->client_ = new network::Client(CommandLine::getValue("ip").getString(), CommandLine::getValue("port"));55 this->client_ = new Client(CommandLine::getValue("ip").getString(), CommandLine::getValue("port")); 56 56 57 57 if(!client_->establishConnection()) -
code/trunk/src/orxonox/gamestates/GSClient.h
r2087 r2171 49 49 void ticked(const Clock& time); 50 50 51 network::Client* client_;51 Client* client_; 52 52 }; 53 53 } -
code/trunk/src/orxonox/gamestates/GSDedicated.cc
r2087 r2171 32 32 #include "core/CommandLine.h" 33 33 #include "core/Core.h" 34 #include "core/Iterator.h" 34 35 #include "network/Server.h" 36 #include "objects/Tickable.h" 35 37 36 38 namespace orxonox … … 50 52 Core::setHasServer(true); 51 53 52 this->server_ = new network::Server(CommandLine::getValue("port"));54 this->server_ = new Server(CommandLine::getValue("port")); 53 55 COUT(0) << "Loading scene in server mode" << std::endl; 54 56 -
code/trunk/src/orxonox/gamestates/GSDedicated.h
r2087 r2171 48 48 void ticked(const Clock& time); 49 49 50 network::Server* server_;50 Server* server_; 51 51 }; 52 52 } -
code/trunk/src/orxonox/gamestates/GSGraphics.cc
r2103 r2171 56 56 #include "gui/GUIManager.h" 57 57 #include "tools/WindowEventListener.h" 58 #include "objects/Tickable.h"59 58 #include "Settings.h" 60 59 … … 242 241 this->tickChild(time); 243 242 244 /*** HACK *** HACK ***/245 // Call the Tickable objects246 for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)247 it->tick(time.getDeltaTime());248 /*** HACK *** HACK ***/249 250 243 if (this->bWindowEventListenerUpdateRequired_) 251 244 { -
code/trunk/src/orxonox/gamestates/GSRoot.cc
r2087 r2171 41 41 #include "core/TclThreadManager.h" 42 42 #include "tools/Timer.h" 43 #include "objects/Tickable.h" 43 44 #include "Settings.h" 44 45 … … 143 144 it->tick(time); 144 145 146 /*** HACK *** HACK ***/ 147 // Call the Tickable objects 148 for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it) 149 it->tick(time.getDeltaTime()); 150 /*** HACK *** HACK ***/ 151 145 152 this->tickChild(time); 146 153 } -
code/trunk/src/orxonox/gamestates/GSServer.cc
r2087 r2171 52 52 Core::setHasServer(true); 53 53 54 this->server_ = new network::Server(CommandLine::getValue("port"));54 this->server_ = new Server(CommandLine::getValue("port")); 55 55 COUT(0) << "Loading scene in server mode" << std::endl; 56 56 -
code/trunk/src/orxonox/gamestates/GSServer.h
r2087 r2171 48 48 void ticked(const Clock& time); 49 49 50 network::Server* server_;50 Server* server_; 51 51 }; 52 52 } -
code/trunk/src/orxonox/objects/CMakeLists.txt
r2131 r2171 3 3 EventDispatcher.cc 4 4 EventTarget.cc 5 Level.cc 5 6 Radar.cc 6 7 RadarListener.cc -
code/trunk/src/orxonox/objects/Scene.cc
r2087 r2171 43 43 CreateFactory(Scene); 44 44 45 Scene::Scene(BaseObject* creator) : BaseObject(creator), network::Synchronisable(creator)45 Scene::Scene(BaseObject* creator) : BaseObject(creator), Synchronisable(creator) 46 46 { 47 47 RegisterObject(Scene); … … 114 114 void Scene::registerVariables() 115 115 { 116 REGISTERSTRING(this->skybox_, network::direction::toclient, new network::NetworkCallback<Scene>(this, &Scene::networkcallback_applySkybox));117 REGISTERDATA(this->ambientLight_, network::direction::toclient, new network::NetworkCallback<Scene>(this, &Scene::networkcallback_applyAmbientLight));116 REGISTERSTRING(this->skybox_, direction::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applySkybox)); 117 REGISTERDATA(this->ambientLight_, direction::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applyAmbientLight)); 118 118 } 119 119 … … 164 164 return 0; 165 165 } 166 167 void Scene::tick(float dt) 168 { 169 if (!Core::showsGraphics()) 170 { 171 // We need to update the scene nodes if we don't render 172 this->rootSceneNode_->_update(true, false); 173 } 174 } 166 175 } -
code/trunk/src/orxonox/objects/Scene.h
r2087 r2171 35 35 #include "core/BaseObject.h" 36 36 #include "util/Math.h" 37 #include "objects/Tickable.h" 37 38 38 39 namespace orxonox 39 40 { 40 class _OrxonoxExport Scene : public BaseObject, public network::Synchronisable41 class _OrxonoxExport Scene : public BaseObject, public Synchronisable, public Tickable 41 42 { 42 43 public: … … 64 65 { return this->bShadows_; } 65 66 67 virtual void tick(float dt); 68 66 69 private: 67 70 void addObject(BaseObject* object); -
code/trunk/src/orxonox/objects/Test.cc
r2087 r2171 30 30 #include "core/CoreIncludes.h" 31 31 #include "core/ConfigValueIncludes.h" 32 #include "core/ConsoleCommand.h" 32 33 #include "Test.h" 33 34 … … 35 36 { 36 37 CreateFactory ( Test ); 38 39 SetConsoleCommand(Test, printV1, true).accessLevel(AccessLevel::User); 40 SetConsoleCommand(Test, printV2, true).accessLevel(AccessLevel::User); 41 SetConsoleCommand(Test, printV3, true).accessLevel(AccessLevel::User); 42 SetConsoleCommand(Test, printV4, true).accessLevel(AccessLevel::User); 43 44 Test* Test::instance_ = 0; 37 45 38 Test::Test(BaseObject* creator) : BaseObject(creator), network::Synchronisable(creator)46 Test::Test(BaseObject* creator) : BaseObject(creator), Synchronisable(creator) 39 47 { 48 assert(instance_==0); 49 instance_=this; 40 50 RegisterObject ( Test ); 41 42 51 setConfigValues(); 52 registerVariables(); 43 53 setObjectMode(0x3); 44 54 } … … 46 56 Test::~Test() 47 57 { 48 58 instance_=0; 49 59 } 50 60 51 61 void Test::setConfigValues() 52 62 { 53 SetConfigValue ( v1, 1 ).callback ( this, &Test::checkV1 ); 54 SetConfigValue ( v2, 2 ).callback ( this, &Test::checkV2 ); 55 SetConfigValue ( v3, 3 ).callback ( this, &Test::checkV3 ); 63 SetConfigValue ( v1, 1 )/*.callback ( this, &Test::checkV1 )*/; 64 SetConfigValue ( v2, 2 )/*.callback ( this, &Test::checkV2 )*/; 65 SetConfigValue ( v3, 3 )/*.callback ( this, &Test::checkV3 )*/; 66 SetConfigValue ( v4, 4 )/*.callback ( this, &Test::checkV4 )*/; 56 67 } 57 68 … … 59 70 void Test::registerVariables() 60 71 { 61 REGISTERDATA ( v1,network::direction::toclient, new network::NetworkCallback<Test> ( this, &Test::checkV1 ) ); 62 REGISTERDATA ( v2,network::direction::toserver, new network::NetworkCallback<Test> ( this, &Test::checkV2 ) ); 63 REGISTERDATA ( v3,network::direction::bidirectional, new network::NetworkCallback<Test> ( this, &Test::checkV3 ) ); 72 REGISTERDATA ( v1,direction::toclient, new NetworkCallback<Test> ( this, &Test::checkV1 ) ); 73 REGISTERDATA ( v2,direction::toserver, new NetworkCallback<Test> ( this, &Test::checkV2 ) ); 74 REGISTERDATA ( v3,direction::serverMaster, new NetworkCallback<Test> ( this, &Test::checkV3 ) ); 75 REGISTERDATA ( v4,direction::clientMaster, new NetworkCallback<Test> ( this, &Test::checkV4 ) ); 64 76 } 65 77 66 67 68 78 void Test::checkV1(){ 79 COUT(1) << "V1 changed: " << v1 << std::endl; 80 } 69 81 70 71 72 82 void Test::checkV2(){ 83 COUT(1) << "V2 changed: " << v2 << std::endl; 84 } 73 85 74 void Test::checkV3(){ 75 COUT(1) << "V3 changed: " << v3 << std::endl; 76 } 86 void Test::checkV3(){ 87 COUT(1) << "V3 changed: " << v3 << std::endl; 88 } 89 90 void Test::checkV4(){ 91 COUT(1) << "V4 changed: " << v4 << std::endl; 92 } 77 93 78 94 -
code/trunk/src/orxonox/objects/Test.h
r2087 r2171 36 36 namespace orxonox 37 37 { 38 class _OrxonoxExport Test: public BaseObject, public network::Synchronisable38 class _OrxonoxExport Test: public BaseObject, public Synchronisable 39 39 { 40 40 public: … … 48 48 void setV2(unsigned int value){ v2 = value; } 49 49 void setV3(unsigned int value){ v3 = value; } 50 void setV4(unsigned int value){ v4 = value; } 50 51 51 52 void checkV1(); 52 53 void checkV2(); 53 54 void checkV3(); 55 void checkV4(); 56 57 void printV1(){ instance_->checkV1(); } 58 void printV2(){ instance_->checkV2(); } 59 void printV3(){ instance_->checkV3(); } 60 void printV4(){ instance_->checkV4(); } 54 61 55 62 private: … … 57 64 unsigned int v2; 58 65 unsigned int v3; 66 unsigned int v4; 67 68 static Test* instance_; 59 69 }; 60 70 } -
code/trunk/src/orxonox/objects/Tickable.h
r1790 r2171 28 28 29 29 /*! 30 @file Tickable.h30 @file 31 31 @brief Declaration of the Tickable interface. 32 32 -
code/trunk/src/orxonox/objects/gametypes/Gametype.cc
r2087 r2171 67 67 if (!this->bStarted_) 68 68 this->checkStart(); 69 else 70 this->spawnDeadPlayersIfRequested(); 69 71 70 72 this->assignDefaultPawnsIfNeeded(); 71 this->spawnDeadPlayersIfRequested();72 73 } 73 74 … … 88 89 void Gametype::playerEntered(PlayerInfo* player) 89 90 { 90 this->players_ .insert(player);91 this->players_[player] = PlayerState::Joined; 91 92 92 93 std::string message = player->getName() + " entered the game"; 93 94 COUT(0) << message << std::endl; 94 network::Host::Broadcast(message);95 Host::Broadcast(message); 95 96 } 96 97 97 98 void Gametype::playerLeft(PlayerInfo* player) 98 99 { 99 std:: set<PlayerInfo*>::iterator it = this->players_.find(player);100 std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.find(player); 100 101 if (it != this->players_.end()) 101 102 { … … 104 105 std::string message = player->getName() + " left the game"; 105 106 COUT(0) << message << std::endl; 106 network::Host::Broadcast(message);107 Host::Broadcast(message); 107 108 } 108 109 } … … 124 125 std::string message = player->getOldName() + " changed name to " + player->getName(); 125 126 COUT(0) << message << std::endl; 126 network::Host::Broadcast(message);127 Host::Broadcast(message); 127 128 } 128 129 } … … 165 166 } 166 167 167 void Gametype::assignDefaultPawnsIfNeeded() const168 { 169 for (std:: set<PlayerInfo*>::const_iterator it = this->players_.begin(); it != this->players_.end(); ++it)170 { 171 if (! (*it)->getControllableEntity() && (!(*it)->isReadyToSpawn() || !this->bStarted_))172 { 173 SpawnPoint* spawn = this->getBestSpawnPoint( *it);168 void Gametype::assignDefaultPawnsIfNeeded() 169 { 170 for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it) 171 { 172 if (!it->first->getControllableEntity() && (!it->first->isReadyToSpawn() || !this->bStarted_)) 173 { 174 SpawnPoint* spawn = this->getBestSpawnPoint(it->first); 174 175 if (spawn) 175 176 { … … 177 178 ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn); 178 179 spawn->spawn(entity); 179 (*it)->startControl(entity); 180 it->first->startControl(entity); 181 it->second = PlayerState::Dead; 180 182 } 181 183 else … … 210 212 { 211 213 bool allplayersready = true; 212 for (std:: set<PlayerInfo*>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)214 for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it) 213 215 { 214 if (! (*it)->isReadyToSpawn())216 if (!it->first->isReadyToSpawn()) 215 217 allplayersready = false; 216 218 } … … 227 229 void Gametype::spawnPlayersIfRequested() 228 230 { 229 for (std:: set<PlayerInfo*>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)230 if ( (*it)->isReadyToSpawn() || this->bForceSpawn_)231 this->spawnPlayer( *it);231 for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it) 232 if (it->first->isReadyToSpawn() || this->bForceSpawn_) 233 this->spawnPlayer(it->first); 232 234 } 233 235 234 236 void Gametype::spawnDeadPlayersIfRequested() 235 237 { 236 for (std:: set<PlayerInfo*>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)237 if ( !(*it)->getControllableEntity())238 if ( (*it)->isReadyToSpawn() || this->bForceSpawn_)239 this->spawnPlayer( *it);238 for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it) 239 if (it->second == PlayerState::Dead) 240 if (it->first->isReadyToSpawn() || this->bForceSpawn_) 241 this->spawnPlayer(it->first); 240 242 } 241 243 … … 246 248 { 247 249 player->startControl(spawnpoint->spawn()); 250 this->players_[player] = PlayerState::Alive; 248 251 } 249 252 else -
code/trunk/src/orxonox/objects/gametypes/Gametype.h
r2087 r2171 41 41 namespace orxonox 42 42 { 43 namespace PlayerState 44 { 45 enum Enum 46 { 47 Uninitialized, 48 Joined, 49 Alive, 50 Dead 51 }; 52 } 53 43 54 class _OrxonoxExport Gametype : public BaseObject, public Tickable 44 55 { … … 70 81 virtual void pawnPostSpawn(Pawn* pawn); 71 82 72 inline const std:: set<PlayerInfo*>& getPlayers() const83 inline const std::map<PlayerInfo*, PlayerState::Enum>& getPlayers() const 73 84 { return this->players_; } 74 85 … … 87 98 void removePlayer(PlayerInfo* player); 88 99 89 void assignDefaultPawnsIfNeeded() const;100 void assignDefaultPawnsIfNeeded(); 90 101 void checkStart(); 91 102 void spawnPlayer(PlayerInfo* player); … … 102 113 bool bStartCountdownRunning_; 103 114 104 std:: set<PlayerInfo*> players_;115 std::map<PlayerInfo*, PlayerState::Enum> players_; 105 116 std::set<SpawnPoint*> spawnpoints_; 106 117 SubclassIdentifier<ControllableEntity> defaultControllableEntity_; -
code/trunk/src/orxonox/objects/infos/CMakeLists.txt
r2131 r2171 1 1 SET( SRC_FILES 2 2 Info.cc 3 Level.cc4 3 PlayerInfo.cc 5 4 HumanPlayer.cc -
code/trunk/src/orxonox/objects/infos/HumanPlayer.cc
r2087 r2171 46 46 RegisterObject(HumanPlayer); 47 47 48 this->server_ ready_ = Core::isMaster();49 this->client_ ready_ = false;48 this->server_initialized_ = Core::isMaster(); 49 this->client_initialized_ = false; 50 50 51 51 this->bHumanPlayer_ = true; … … 67 67 void HumanPlayer::registerVariables() 68 68 { 69 REGISTERSTRING(this->synchronize_nick_, network::direction::toserver, new network::NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_changednick));69 REGISTERSTRING(this->synchronize_nick_, direction::toserver, new NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_changednick)); 70 70 71 REGISTERDATA(this->clientID_, network::direction::toclient, new network::NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_clientIDchanged));72 REGISTERDATA(this->server_ ready_, network::direction::toclient, new network::NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_server_ready));73 REGISTERDATA(this->client_ ready_, network::direction::toserver, new network::NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_client_ready));71 REGISTERDATA(this->clientID_, direction::toclient, new NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_clientIDchanged)); 72 REGISTERDATA(this->server_initialized_, direction::toclient, new NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_server_initialized)); 73 REGISTERDATA(this->client_initialized_, direction::toserver, new NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_client_initialized)); 74 74 } 75 75 … … 92 92 void HumanPlayer::networkcallback_clientIDchanged() 93 93 { 94 if (this->clientID_ == network::Host::getPlayerID())94 if (this->clientID_ == Host::getPlayerID()) 95 95 { 96 96 this->bLocalPlayer_ = true; 97 97 this->synchronize_nick_ = this->nick_; 98 this->client_ ready_ = true;98 this->client_initialized_ = true; 99 99 100 100 if (!Core::isMaster()) 101 this->setObjectMode( network::direction::bidirectional);101 this->setObjectMode(direction::bidirectional); 102 102 else 103 103 this->setName(this->nick_); … … 107 107 } 108 108 109 void HumanPlayer::networkcallback_server_ ready()109 void HumanPlayer::networkcallback_server_initialized() 110 110 { 111 this->client_ ready_ = true;111 this->client_initialized_ = true; 112 112 } 113 113 114 void HumanPlayer::networkcallback_client_ ready()114 void HumanPlayer::networkcallback_client_initialized() 115 115 { 116 116 if (this->getGametype()) … … 118 118 } 119 119 120 bool HumanPlayer::is Ready() const120 bool HumanPlayer::isInitialized() const 121 121 { 122 return (this->server_ ready_ && this->client_ready_);122 return (this->server_initialized_ && this->client_initialized_); 123 123 } 124 124 125 125 float HumanPlayer::getPing() const 126 126 { 127 return network::ClientInformation::findClient(this->getClientID())->getRTT();127 return ClientInformation::findClient(this->getClientID())->getRTT(); 128 128 } 129 129 130 130 float HumanPlayer::getPacketLossRatio() const 131 131 { 132 return network::ClientInformation::findClient(this->getClientID())->getPacketLoss();132 return ClientInformation::findClient(this->getClientID())->getPacketLoss(); 133 133 } 134 134 -
code/trunk/src/orxonox/objects/infos/HumanPlayer.h
r2087 r2171 47 47 void setConfigValues(); 48 48 49 bool is Ready() const;49 bool isInitialized() const; 50 50 float getPing() const; 51 51 float getPacketLossRatio() const; … … 57 57 void networkcallback_changednick(); 58 58 void networkcallback_clientIDchanged(); 59 void networkcallback_server_ ready();60 void networkcallback_client_ ready();59 void networkcallback_server_initialized(); 60 void networkcallback_client_initialized(); 61 61 62 62 std::string nick_; 63 63 std::string synchronize_nick_; 64 bool server_ ready_;65 bool client_ ready_;64 bool server_initialized_; 65 bool client_initialized_; 66 66 }; 67 67 } -
code/trunk/src/orxonox/objects/infos/Info.cc
r2087 r2171 34 34 namespace orxonox 35 35 { 36 Info::Info(BaseObject* creator) : BaseObject(creator), network::Synchronisable(creator)36 Info::Info(BaseObject* creator) : BaseObject(creator), Synchronisable(creator) 37 37 { 38 38 RegisterObject(Info); -
code/trunk/src/orxonox/objects/infos/Info.h
r2087 r2171 37 37 namespace orxonox 38 38 { 39 class _OrxonoxExport Info : public BaseObject, public network::Synchronisable39 class _OrxonoxExport Info : public BaseObject, public Synchronisable 40 40 { 41 41 public: -
code/trunk/src/orxonox/objects/infos/PlayerInfo.cc
r2087 r2171 42 42 RegisterObject(PlayerInfo); 43 43 44 this->clientID_ = network::CLIENTID_UNKNOWN;44 this->clientID_ = CLIENTID_UNKNOWN; 45 45 this->bHumanPlayer_ = false; 46 46 this->bLocalPlayer_ = false; … … 48 48 this->controller_ = 0; 49 49 this->controllableEntity_ = 0; 50 this->controllableEntityID_ = network::CLIENTID_UNKNOWN;50 this->controllableEntityID_ = CLIENTID_UNKNOWN; 51 51 52 52 this->registerVariables(); … … 55 55 PlayerInfo::~PlayerInfo() 56 56 { 57 if (this-> isInitialized())57 if (this->BaseObject::isInitialized()) 58 58 { 59 59 this->stopControl(this->controllableEntity_); … … 69 69 void PlayerInfo::registerVariables() 70 70 { 71 REGISTERSTRING(this->name_, network::direction::toclient, new network::NetworkCallback<PlayerInfo>(this, &PlayerInfo::changedName));72 REGISTERDATA (this->controllableEntityID_, network::direction::toclient, new network::NetworkCallback<PlayerInfo>(this, &PlayerInfo::networkcallback_changedcontrollableentityID));73 REGISTERDATA (this->bReadyToSpawn_, network::direction::toserver);71 REGISTERSTRING(this->name_, direction::toclient, new NetworkCallback<PlayerInfo>(this, &PlayerInfo::changedName)); 72 REGISTERDATA (this->controllableEntityID_, direction::toclient, new NetworkCallback<PlayerInfo>(this, &PlayerInfo::networkcallback_changedcontrollableentityID)); 73 REGISTERDATA (this->bReadyToSpawn_, direction::toserver); 74 74 } 75 75 76 76 void PlayerInfo::changedName() 77 77 { 78 if (this->is Ready() && this->getGametype())78 if (this->isInitialized() && this->getGametype()) 79 79 this->getGametype()->playerChangedName(this); 80 80 } … … 82 82 void PlayerInfo::changedGametype() 83 83 { 84 if (this->is Ready())84 if (this->isInitialized()) 85 85 { 86 86 if (this->getOldGametype()) … … 126 126 else 127 127 { 128 this->controllableEntityID_ = network::OBJECTID_UNKNOWN;128 this->controllableEntityID_ = OBJECTID_UNKNOWN; 129 129 } 130 130 … … 138 138 { 139 139 this->controllableEntity_ = 0; 140 this->controllableEntityID_ = network::OBJECTID_UNKNOWN;140 this->controllableEntityID_ = OBJECTID_UNKNOWN; 141 141 142 142 if (this->controller_) … … 150 150 void PlayerInfo::networkcallback_changedcontrollableentityID() 151 151 { 152 if (this->controllableEntityID_ != network::OBJECTID_UNKNOWN)152 if (this->controllableEntityID_ != OBJECTID_UNKNOWN) 153 153 { 154 154 Synchronisable* temp = Synchronisable::getSynchronisable(this->controllableEntityID_); -
code/trunk/src/orxonox/objects/infos/PlayerInfo.h
r2087 r2171 55 55 inline unsigned int getClientID() const 56 56 { return this->clientID_; } 57 inline bool isReadyToSpawn() const58 { return this->bReadyToSpawn_; }59 57 60 virtual bool is Ready() const = 0;58 virtual bool isInitialized() const = 0; 61 59 virtual float getPing() const = 0; 62 60 virtual float getPacketLossRatio() const = 0; … … 64 62 inline void setReadyToSpawn(bool bReady) 65 63 { this->bReadyToSpawn_ = bReady; } 64 inline bool isReadyToSpawn() const 65 { return this->bReadyToSpawn_; } 66 66 67 67 void startControl(ControllableEntity* entity); -
code/trunk/src/orxonox/objects/weaponSystem/WeaponSystem.h
- Property svn:mergeinfo changed
/code/branches/objecthierarchy/src/orxonox/objects/weaponSystem/WeaponSystem.h (added) merged: 2110-2169
- Property svn:mergeinfo changed
-
code/trunk/src/orxonox/objects/worldentities/Backlight.cc
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/orxonox/objects/worldentities/Backlight.h
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/orxonox/objects/worldentities/Billboard.cc
r2087 r2171 64 64 void Billboard::registerVariables() 65 65 { 66 REGISTERSTRING(this->material_, network::direction::toclient, new network::NetworkCallback<Billboard>(this, &Billboard::changedMaterial));67 REGISTERDATA (this->colour_, network::direction::toclient, new network::NetworkCallback<Billboard>(this, &Billboard::changedColour));66 REGISTERSTRING(this->material_, direction::toclient, new NetworkCallback<Billboard>(this, &Billboard::changedMaterial)); 67 REGISTERDATA (this->colour_, direction::toclient, new NetworkCallback<Billboard>(this, &Billboard::changedColour)); 68 68 } 69 69 … … 75 75 { 76 76 this->billboard_.setBillboardSet(this->getScene()->getSceneManager(), this->material_, this->colour_, 1); 77 this->getNode()->attachObject(this->billboard_.getBillboardSet()); 77 if (this->billboard_.getBillboardSet()) 78 this->getNode()->attachObject(this->billboard_.getBillboardSet()); 78 79 this->billboard_.setVisible(this->isVisible()); 79 80 } … … 90 91 { 91 92 this->billboard_.setBillboardSet(this->getScene()->getSceneManager(), this->material_, this->colour_, 1); 92 this->getNode()->attachObject(this->billboard_.getBillboardSet()); 93 if (this->billboard_.getBillboardSet()) 94 this->getNode()->attachObject(this->billboard_.getBillboardSet()); 93 95 this->billboard_.setVisible(this->isVisible()); 94 96 } -
code/trunk/src/orxonox/objects/worldentities/BlinkingBillboard.cc
r2087 r2171 68 68 void BlinkingBillboard::registerVariables() 69 69 { 70 // REGISTERDATA(this->amplitude_, network::direction::toclient);71 // REGISTERDATA(this->frequency_, network::direction::toclient);72 // REGISTERDATA(this->phase_, network::direction::toclient);70 // REGISTERDATA(this->amplitude_, direction::toclient); 71 // REGISTERDATA(this->frequency_, direction::toclient); 72 // REGISTERDATA(this->phase_, direction::toclient); 73 73 } 74 74 -
code/trunk/src/orxonox/objects/worldentities/Camera.cc
- Property svn:mergeinfo changed
/code/branches/objecthierarchy/src/orxonox/objects/worldentities/Camera.cc merged: 2161-2162
r2103 r2171 38 38 #include <OgreViewport.h> 39 39 40 #include "util/Exception.h" 40 41 #include "core/CoreIncludes.h" 41 42 #include "core/ConfigValueIncludes.h" … … 51 52 RegisterObject(Camera); 52 53 53 assert(this->getScene());54 assert(this->getScene()->getSceneManager());54 if (!this->getScene() || !this->getScene()->getSceneManager()) 55 ThrowException(AbortLoading, "Can't create Camera, no scene or no scene manager given."); 55 56 56 57 this->camera_ = this->getScene()->getSceneManager()->createCamera(getUniqueNumberString()); - Property svn:mergeinfo changed
-
code/trunk/src/orxonox/objects/worldentities/Camera.h
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/orxonox/objects/worldentities/ControllableEntity.cc
r2087 r2171 52 52 this->client_overwrite_ = 0; 53 53 this->player_ = 0; 54 this->playerID_ = network::OBJECTID_UNKNOWN;54 this->playerID_ = OBJECTID_UNKNOWN; 55 55 this->hud_ = 0; 56 56 this->camera_ = 0; … … 165 165 this->client_overwrite_ = this->server_overwrite_; 166 166 COUT(0) << "CE: bidirectional synchronization" << std::endl; 167 this->setObjectMode( network::direction::bidirectional);167 this->setObjectMode(direction::bidirectional); 168 168 } 169 169 } … … 176 176 177 177 this->player_ = 0; 178 this->playerID_ = network::OBJECTID_UNKNOWN;178 this->playerID_ = OBJECTID_UNKNOWN; 179 179 this->bControlled_ = false; 180 this->setObjectMode( network::direction::toclient);180 this->setObjectMode(direction::toclient); 181 181 182 182 if (this->bDestroyWhenPlayerLeft_) … … 187 187 { 188 188 // just do this in case the entity wasn't yet synchronized when the corresponding PlayerInfo got our objectID 189 if (this->playerID_ != network::OBJECTID_UNKNOWN)190 { 191 this->player_ = dynamic_cast<PlayerInfo*>( network::Synchronisable::getSynchronisable(this->playerID_));189 if (this->playerID_ != OBJECTID_UNKNOWN) 190 { 191 this->player_ = dynamic_cast<PlayerInfo*>(Synchronisable::getSynchronisable(this->playerID_)); 192 192 if (this->player_ && (this->player_->getControllableEntity() != this)) 193 193 this->player_->startControl(this); … … 248 248 void ControllableEntity::registerVariables() 249 249 { 250 REGISTERSTRING(this->cameraPositionTemplate_, network::direction::toclient);251 252 REGISTERDATA(this-> server_position_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));253 REGISTERDATA(this->server_velocity_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerVelocity));254 REGISTERDATA(this->server_ orientation_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));255 256 REGISTERDATA(this->server_o verwrite_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));257 REGISTERDATA(this-> client_overwrite_, network::direction::toserver);258 259 REGISTERDATA(this->client_position_, network::direction::toserver, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));260 REGISTERDATA(this->client_velocity_, network::direction::toserver, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientVelocity));261 REGISTERDATA(this->client_orientation_, network::direction::toserver, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));262 263 264 REGISTERDATA(this->playerID_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedplayerID));250 REGISTERSTRING(this->cameraPositionTemplate_, direction::toclient); 251 252 REGISTERDATA(this->client_overwrite_, direction::toserver); 253 254 REGISTERDATA(this->server_position_, direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition)); 255 REGISTERDATA(this->server_velocity_, direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerVelocity)); 256 REGISTERDATA(this->server_orientation_, direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation)); 257 REGISTERDATA(this->server_overwrite_, direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite)); 258 259 REGISTERDATA(this->client_position_, direction::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition)); 260 REGISTERDATA(this->client_velocity_, direction::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientVelocity)); 261 REGISTERDATA(this->client_orientation_, direction::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation)); 262 263 264 REGISTERDATA(this->playerID_, direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedplayerID)); 265 265 } 266 266 -
code/trunk/src/orxonox/objects/worldentities/Light.cc
r2087 r2171 79 79 void Light::registerVariables() 80 80 { 81 REGISTERDATA(this->type_, network::direction::toclient, new network::NetworkCallback<Light>(this, &Light::changedType));82 REGISTERDATA(this->light_->getDiffuseColour(), network::direction::toclient);83 REGISTERDATA(this->light_->getSpecularColour(), network::direction::toclient);84 REGISTERDATA(this->light_->getDirection(), network::direction::toclient);81 REGISTERDATA(this->type_, direction::toclient, new NetworkCallback<Light>(this, &Light::changedType)); 82 REGISTERDATA(this->light_->getDiffuseColour(), direction::toclient); 83 REGISTERDATA(this->light_->getSpecularColour(), direction::toclient); 84 REGISTERDATA(this->light_->getDirection(), direction::toclient); 85 85 } 86 86 -
code/trunk/src/orxonox/objects/worldentities/Model.cc
r2087 r2171 61 61 void Model::registerVariables() 62 62 { 63 REGISTERSTRING(this->meshSrc_, network::direction::toclient, new network::NetworkCallback<Model>(this, &Model::changedMesh));64 REGISTERDATA(this->bCastShadows_, network::direction::toclient, new network::NetworkCallback<Model>(this, &Model::changedShadows));63 REGISTERSTRING(this->meshSrc_, direction::toclient, new NetworkCallback<Model>(this, &Model::changedMesh)); 64 REGISTERDATA(this->bCastShadows_, direction::toclient, new NetworkCallback<Model>(this, &Model::changedShadows)); 65 65 } 66 66 -
code/trunk/src/orxonox/objects/worldentities/MovableEntity.cc
r2087 r2171 84 84 void MovableEntity::registerVariables() 85 85 { 86 REGISTERDATA(this->velocity_.x, network::direction::toclient);87 REGISTERDATA(this->velocity_.y, network::direction::toclient);88 REGISTERDATA(this->velocity_.z, network::direction::toclient);86 REGISTERDATA(this->velocity_.x, direction::toclient); 87 REGISTERDATA(this->velocity_.y, direction::toclient); 88 REGISTERDATA(this->velocity_.z, direction::toclient); 89 89 90 REGISTERDATA(this->rotationAxis_.x, network::direction::toclient);91 REGISTERDATA(this->rotationAxis_.y, network::direction::toclient);92 REGISTERDATA(this->rotationAxis_.z, network::direction::toclient);90 REGISTERDATA(this->rotationAxis_.x, direction::toclient); 91 REGISTERDATA(this->rotationAxis_.y, direction::toclient); 92 REGISTERDATA(this->rotationAxis_.z, direction::toclient); 93 93 94 REGISTERDATA(this->rotationRate_, network::direction::toclient);94 REGISTERDATA(this->rotationRate_, direction::toclient); 95 95 96 REGISTERDATA(this->overwrite_position_, network::direction::toclient, new network::NetworkCallback<MovableEntity>(this, &MovableEntity::overwritePosition));97 REGISTERDATA(this->overwrite_orientation_, network::direction::toclient, new network::NetworkCallback<MovableEntity>(this, &MovableEntity::overwriteOrientation));96 REGISTERDATA(this->overwrite_position_, direction::toclient, new NetworkCallback<MovableEntity>(this, &MovableEntity::overwritePosition)); 97 REGISTERDATA(this->overwrite_orientation_, direction::toclient, new NetworkCallback<MovableEntity>(this, &MovableEntity::overwriteOrientation)); 98 98 } 99 99 -
code/trunk/src/orxonox/objects/worldentities/MovableEntity.h
r2087 r2171 38 38 namespace orxonox 39 39 { 40 class _OrxonoxExport MovableEntity : public WorldEntity, public Tickable, public network::ClientConnectionListener40 class _OrxonoxExport MovableEntity : public WorldEntity, public Tickable, public ClientConnectionListener 41 41 { 42 42 public: -
code/trunk/src/orxonox/objects/worldentities/ParticleEmitter.cc
r2087 r2171 28 28 29 29 /** 30 * @file ParticleInterface.cc30 * @file 31 31 * @brief class to control praticle effects 32 32 */ … … 37 37 38 38 #include "tools/ParticleInterface.h" 39 #include "util/Exception.h" 39 40 #include "core/CoreIncludes.h" 40 41 #include "core/XMLPort.h" … … 49 50 RegisterObject(ParticleEmitter); 50 51 51 assert(this->getScene());52 assert(this->getScene()->getSceneManager());52 if (!this->getScene() || !this->getScene()->getSceneManager()) 53 ThrowException(AbortLoading, "Can't create Camera, no scene or no scene manager given."); 53 54 54 55 this->particles_ = 0; … … 74 75 void ParticleEmitter::registerVariables() 75 76 { 76 REGISTERSTRING(this->source_, network::direction::toclient, new network::NetworkCallback<ParticleEmitter>(this, &ParticleEmitter::sourceChanged));77 REGISTERDATA (this->LOD_, network::direction::toclient, new network::NetworkCallback<ParticleEmitter>(this, &ParticleEmitter::LODchanged));77 REGISTERSTRING(this->source_, direction::toclient, new NetworkCallback<ParticleEmitter>(this, &ParticleEmitter::sourceChanged)); 78 REGISTERDATA (this->LOD_, direction::toclient, new NetworkCallback<ParticleEmitter>(this, &ParticleEmitter::LODchanged)); 78 79 } 79 80 -
code/trunk/src/orxonox/objects/worldentities/ParticleSpawner.cc
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/orxonox/objects/worldentities/ParticleSpawner.h
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/orxonox/objects/worldentities/PositionableEntity.cc
r2087 r2171 48 48 void PositionableEntity::registerVariables() 49 49 { 50 REGISTERDATA(this->getPosition().x, network::direction::toclient);51 REGISTERDATA(this->getPosition().y, network::direction::toclient);52 REGISTERDATA(this->getPosition().z, network::direction::toclient);50 REGISTERDATA(this->getPosition().x, direction::toclient); 51 REGISTERDATA(this->getPosition().y, direction::toclient); 52 REGISTERDATA(this->getPosition().z, direction::toclient); 53 53 54 REGISTERDATA(this->getOrientation().w, network::direction::toclient);55 REGISTERDATA(this->getOrientation().x, network::direction::toclient);56 REGISTERDATA(this->getOrientation().y, network::direction::toclient);57 REGISTERDATA(this->getOrientation().z, network::direction::toclient);54 REGISTERDATA(this->getOrientation().w, direction::toclient); 55 REGISTERDATA(this->getOrientation().x, direction::toclient); 56 REGISTERDATA(this->getOrientation().y, direction::toclient); 57 REGISTERDATA(this->getOrientation().z, direction::toclient); 58 58 } 59 59 } -
code/trunk/src/orxonox/objects/worldentities/WorldEntity.cc
r2087 r2171 36 36 #include "core/XMLPort.h" 37 37 #include "util/Convert.h" 38 #include "util/Exception.h" 38 39 39 40 #include "objects/Scene.h" … … 48 49 const Vector3 WorldEntity::UP = Vector3::UNIT_Y; 49 50 50 WorldEntity::WorldEntity(BaseObject* creator) : BaseObject(creator), network::Synchronisable(creator)51 WorldEntity::WorldEntity(BaseObject* creator) : BaseObject(creator), Synchronisable(creator) 51 52 { 52 53 RegisterObject(WorldEntity); 53 54 54 assert(this->getScene());55 assert(this->getScene()->getRootSceneNode());55 if (!this->getScene() || !this->getScene()->getRootSceneNode()) 56 ThrowException(AbortLoading, "Can't create WorldEntity, no scene or no root-scenenode given."); 56 57 57 58 this->node_ = this->getScene()->getRootSceneNode()->createChildSceneNode(); 58 59 59 60 this->parent_ = 0; 60 this->parentID_ = (unsigned int)-1;61 this->parentID_ = OBJECTID_UNKNOWN; 61 62 62 63 this->node_->setPosition(Vector3::ZERO); … … 95 96 void WorldEntity::registerVariables() 96 97 { 97 REGISTERDATA(this->bActive_, network::direction::toclient, new network::NetworkCallback<WorldEntity>(this, &WorldEntity::changedActivity));98 REGISTERDATA(this->bVisible_, network::direction::toclient, new network::NetworkCallback<WorldEntity>(this, &WorldEntity::changedVisibility));98 REGISTERDATA(this->bActive_, direction::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedActivity)); 99 REGISTERDATA(this->bVisible_, direction::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedVisibility)); 99 100 100 REGISTERDATA(this->getScale3D().x, network::direction::toclient);101 REGISTERDATA(this->getScale3D().y, network::direction::toclient);102 REGISTERDATA(this->getScale3D().z, network::direction::toclient);101 REGISTERDATA(this->getScale3D().x, direction::toclient); 102 REGISTERDATA(this->getScale3D().y, direction::toclient); 103 REGISTERDATA(this->getScale3D().z, direction::toclient); 103 104 104 REGISTERDATA(this->parentID_, network::direction::toclient, new network::NetworkCallback<WorldEntity>(this, &WorldEntity::updateParent));105 REGISTERDATA(this->parentID_, direction::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::updateParent)); 105 106 } 106 107 107 108 void WorldEntity::updateParent() 108 109 { 109 WorldEntity* parent = dynamic_cast<WorldEntity*>(Synchronisable::getSynchronisable(this->parentID_)); 110 if (parent) 111 this->attachToParent(parent); 110 if (this->parentID_ != OBJECTID_UNKNOWN) 111 { 112 WorldEntity* parent = dynamic_cast<WorldEntity*>(Synchronisable::getSynchronisable(this->parentID_)); 113 if (parent) 114 this->attachToParent(parent); 115 } 112 116 } 113 117 … … 134 138 this->children_.erase(object); 135 139 object->parent_ = 0; 136 object->parentID_ = (unsigned int)-1;140 object->parentID_ = OBJECTID_UNKNOWN; 137 141 138 142 // this->getScene()->getRootSceneNode()->addChild(object->node_); -
code/trunk/src/orxonox/objects/worldentities/WorldEntity.h
r2087 r2171 42 42 namespace orxonox 43 43 { 44 class _OrxonoxExport WorldEntity : public BaseObject, public network::Synchronisable44 class _OrxonoxExport WorldEntity : public BaseObject, public Synchronisable 45 45 { 46 46 public: -
code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.cc
r2106 r2171 80 80 void Pawn::registerVariables() 81 81 { 82 REGISTERDATA(this->bAlive_, network::direction::toclient);83 REGISTERDATA(this->health_, network::direction::toclient);82 REGISTERDATA(this->bAlive_, direction::toclient); 83 REGISTERDATA(this->health_, direction::toclient); 84 84 } 85 85 -
code/trunk/src/orxonox/objects/worldentities/pawns/SpaceShip.cc
r2087 r2171 82 82 void SpaceShip::registerVariables() 83 83 { 84 REGISTERDATA(this->maxSpeed_, network::direction::toclient);85 REGISTERDATA(this->maxSecondarySpeed_, network::direction::toclient);86 REGISTERDATA(this->maxRotation_, network::direction::toclient);87 REGISTERDATA(this->translationAcceleration_, network::direction::toclient);88 REGISTERDATA(this->rotationAcceleration_, network::direction::toclient);89 REGISTERDATA(this->translationDamping_, network::direction::toclient);84 REGISTERDATA(this->maxSpeed_, direction::toclient); 85 REGISTERDATA(this->maxSecondarySpeed_, direction::toclient); 86 REGISTERDATA(this->maxRotation_, direction::toclient); 87 REGISTERDATA(this->translationAcceleration_, direction::toclient); 88 REGISTERDATA(this->rotationAcceleration_, direction::toclient); 89 REGISTERDATA(this->translationDamping_, direction::toclient); 90 90 } 91 91 -
code/trunk/src/orxonox/objects/worldentities/pawns/Spectator.cc
r2087 r2171 62 62 this->greetingFlare_ = new BillboardSet(); 63 63 this->greetingFlare_->setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0, 1.0, 0.8), Vector3(0, 20, 0), 1); 64 this->getNode()->attachObject(this->greetingFlare_->getBillboardSet()); 64 if (this->greetingFlare_->getBillboardSet()) 65 this->getNode()->attachObject(this->greetingFlare_->getBillboardSet()); 65 66 this->greetingFlare_->setVisible(false); 66 67 this->bGreetingFlareVisible_ = false; … … 76 77 if (this->greetingFlare_) 77 78 { 78 this->getNode()->detachObject(this->greetingFlare_->getBillboardSet()); 79 if (this->greetingFlare_->getBillboardSet()) 80 this->getNode()->detachObject(this->greetingFlare_->getBillboardSet()); 79 81 delete this->greetingFlare_; 80 82 } … … 84 86 void Spectator::registerVariables() 85 87 { 86 REGISTERDATA(this->bGreetingFlareVisible_, network::direction::toclient, new network::NetworkCallback<Spectator>(this, &Spectator::changedFlareVisibility));87 REGISTERDATA(this->bGreeting_, network::direction::toserver, new network::NetworkCallback<Spectator>(this, &Spectator::changedGreeting));88 REGISTERDATA(this->hudmode_, network::direction::toclient);88 REGISTERDATA(this->bGreetingFlareVisible_, direction::toclient, new NetworkCallback<Spectator>(this, &Spectator::changedFlareVisibility)); 89 REGISTERDATA(this->bGreeting_, direction::toserver, new NetworkCallback<Spectator>(this, &Spectator::changedGreeting)); 90 REGISTERDATA(this->hudmode_, direction::toclient); 89 91 } 90 92 … … 129 131 ControllableEntity::setPlayer(player); 130 132 131 // this->setObjectMode( network::direction::toclient);133 // this->setObjectMode(direction::toclient); 132 134 } 133 135 … … 203 205 { 204 206 if (this->getGametype()->isStartCountdownRunning()) 205 this->hudmode_ = 2 + 10* ceil(this->getGametype()->getStartCountdown());207 this->hudmode_ = 2 + 10*(int)ceil(this->getGametype()->getStartCountdown()); 206 208 else 207 209 this->hudmode_ = 3; -
code/trunk/src/orxonox/objects/worldentities/triggers/DistanceTrigger.cc
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/orxonox/objects/worldentities/triggers/DistanceTrigger.h
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/orxonox/objects/worldentities/triggers/Trigger.cc
- Property svn:mergeinfo changed
/code/branches/objecthierarchy/src/orxonox/objects/worldentities/triggers/Trigger.cc merged: 2161
r2103 r2171 69 69 this->debugBillboard_.setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1); 70 70 this->debugBillboard_.setVisible(false); 71 } 72 73 this->getNode()->attachObject(this->debugBillboard_.getBillboardSet()); 71 72 if (this->debugBillboard_.getBillboardSet()) 73 this->getNode()->attachObject(this->debugBillboard_.getBillboardSet()); 74 } 75 74 76 this->setObjectMode(0x0); 75 77 } … … 310 312 void Trigger::setBillboardColour(const ColourValue& colour) 311 313 { 312 this->debugBillboard_. getBillboardSet()->getBillboard(0)->setColour(colour);314 this->debugBillboard_.setColour(colour); 313 315 } 314 316 - Property svn:mergeinfo changed
-
code/trunk/src/orxonox/objects/worldentities/triggers/Trigger.h
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/orxonox/overlays/OrxonoxOverlay.cc
r2087 r2171 40 40 #include <OgrePanelOverlayElement.h> 41 41 #include "util/Convert.h" 42 #include "util/Exception.h" 42 43 #include "util/String.h" 44 #include "core/Core.h" 43 45 #include "core/CoreIncludes.h" 44 46 #include "core/XMLPort.h" … … 58 60 { 59 61 RegisterObject(OrxonoxOverlay); 62 63 if (!Core::showsGraphics()) 64 ThrowException(NoGraphics, "Can't create OrxonoxOverlay, graphics engine not initialized"); 60 65 61 66 // add this overlay to the static map of OrxonoxOverlays -
code/trunk/src/orxonox/overlays/hud/ChatOverlay.cc
r2087 r2171 38 38 #include "network/ClientInformation.h" 39 39 40 #include " LevelManager.h"40 #include "PlayerManager.h" 41 41 #include "objects/infos/PlayerInfo.h" 42 42 #include "overlays/console/InGameConsole.h" … … 72 72 std::string text; 73 73 74 if (senderID != network::CLIENTID_UNKNOWN)74 if (senderID != CLIENTID_UNKNOWN) 75 75 { 76 76 std::string name = "unknown"; 77 77 78 PlayerInfo* player = LevelManager::getInstance().getClient(senderID);78 PlayerInfo* player = PlayerManager::getInstance().getClient(senderID); 79 79 if (player) 80 80 name = player->getName(); -
code/trunk/src/orxonox/overlays/hud/ChatOverlay.h
r2087 r2171 39 39 namespace orxonox 40 40 { 41 class _OrxonoxExport ChatOverlay : public OverlayText, public network::ChatListener41 class _OrxonoxExport ChatOverlay : public OverlayText, public ChatListener 42 42 { 43 43 public: -
code/trunk/src/orxonox/tools/BillboardSet.cc
r2087 r2171 36 36 #include <OgreBillboard.h> 37 37 38 #include "core/Core.h" 38 39 #include "util/Convert.h" 39 40 #include "util/String.h" … … 70 71 try 71 72 { 72 this->billboardSet_ = scenemanager->createBillboardSet("Billboard" + convertToString(BillboardSet::billboardSetCounter_s++), count); 73 this->billboardSet_->createBillboard(position); 74 this->billboardSet_->setMaterialName(file); 73 if (Core::showsGraphics()) 74 { 75 this->billboardSet_ = scenemanager->createBillboardSet("Billboard" + convertToString(BillboardSet::billboardSetCounter_s++), count); 76 this->billboardSet_->createBillboard(position); 77 this->billboardSet_->setMaterialName(file); 78 } 75 79 } 76 80 catch (...) 77 81 { 78 82 COUT(1) << "Error: Couln't load billboard \"" << file << "\"" << std::endl; 83 this->billboardSet_ = 0; 79 84 } 80 85 … … 89 94 try 90 95 { 91 this->billboardSet_ = scenemanager->createBillboardSet("Billboard" + convertToString(BillboardSet::billboardSetCounter_s++), count); 92 this->billboardSet_->createBillboard(position, colour); 93 this->billboardSet_->setMaterialName(file); 96 if (Core::showsGraphics()) 97 { 98 this->billboardSet_ = scenemanager->createBillboardSet("Billboard" + convertToString(BillboardSet::billboardSetCounter_s++), count); 99 this->billboardSet_->createBillboard(position, colour); 100 this->billboardSet_->setMaterialName(file); 101 } 94 102 } 95 103 catch (...) 96 104 { 97 105 COUT(1) << "Error: Couln't load billboard \"" << file << "\"" << std::endl; 106 this->billboardSet_ = 0; 98 107 } 99 108 … … 105 114 if (this->billboardSet_ && this->scenemanager_) 106 115 this->scenemanager_->destroyBillboardSet(this->billboardSet_); 116 this->billboardSet_ = 0; 107 117 } 108 118 -
code/trunk/src/orxonox/tools/Mesh.cc
r2087 r2171 73 73 { 74 74 COUT(1) << "Error: Couln't load mesh \"" << meshsource << "\"" << std::endl; 75 this->entity_ = 0; 75 76 } 76 77 } -
code/trunk/src/orxonox/tools/ParticleInterface.cc
r2087 r2171 28 28 29 29 /** 30 * @file ParticleInterface.cc30 * @file 31 31 * @brief class to control praticle effects 32 32 */ … … 41 41 42 42 #include "GraphicsEngine.h" 43 #include "core/Core.h" 43 44 #include "core/CoreIncludes.h" 44 45 #include "util/Convert.h" … … 57 58 this->scenemanager_ = scenemanager; 58 59 this->sceneNode_ = 0; 60 this->particleSystem_ = 0; 59 61 60 62 this->bEnabled_ = true; … … 62 64 this->bAllowedByLOD_ = true; 63 65 64 this->particleSystem_ = this->scenemanager_->createParticleSystem("particles" + getConvertedValue<unsigned int, std::string>(ParticleInterface::counter_s++), templateName); 65 this->particleSystem_->setSpeedFactor(1.0f); 66 //this->particleSystem_->setSpeedFactor(Orxonox::getInstance().getTimeFactor()); 66 if (Core::showsGraphics()) 67 { 68 try 69 { 70 this->particleSystem_ = this->scenemanager_->createParticleSystem("particles" + getConvertedValue<unsigned int, std::string>(ParticleInterface::counter_s++), templateName); 71 this->particleSystem_->setSpeedFactor(1.0f); 72 // this->particleSystem_->setSpeedFactor(Orxonox::getInstance().getTimeFactor()); 73 } 74 catch (...) 75 { 76 COUT(1) << "Error: Couln't load particle system \"" << templateName << "\"" << std::endl; 77 this->particleSystem_ = 0; 78 } 79 } 67 80 68 81 this->setDetailLevel((unsigned int)detaillevel); … … 71 84 ParticleInterface::~ParticleInterface() 72 85 { 73 this->particleSystem_->removeAllEmitters(); 74 this->detachFromSceneNode(); 75 this->scenemanager_->destroyParticleSystem(particleSystem_); 86 if (this->particleSystem_) 87 { 88 this->particleSystem_->removeAllEmitters(); 89 this->detachFromSceneNode(); 90 this->scenemanager_->destroyParticleSystem(this->particleSystem_); 91 } 76 92 } 77 93 … … 81 97 this->detachFromSceneNode(); 82 98 83 this->sceneNode_ = sceneNode; 84 this->sceneNode_->attachObject(this->particleSystem_); 99 if (this->particleSystem_) 100 { 101 this->sceneNode_ = sceneNode; 102 this->sceneNode_->attachObject(this->particleSystem_); 103 } 85 104 } 86 105 … … 89 108 if (this->sceneNode_) 90 109 { 91 this->sceneNode_->detachObject(this->particleSystem_); 110 if (this->particleSystem_) 111 this->sceneNode_->detachObject(this->particleSystem_); 92 112 this->sceneNode_ = 0; 93 113 } … … 96 116 Ogre::ParticleEmitter* ParticleInterface::createNewEmitter() 97 117 { 98 if (this->particleSystem_ ->getNumEmitters() > 0)118 if (this->particleSystem_ && this->particleSystem_->getNumEmitters() > 0) 99 119 { 100 120 Ogre::ParticleEmitter* newemitter = this->particleSystem_->addEmitter(this->particleSystem_->getEmitter(0)->getType()); … … 107 127 Ogre::ParticleEmitter* ParticleInterface::getEmitter(unsigned int emitterNr) const 108 128 { 109 if ( emitterNr < this->particleSystem_->getNumEmitters())129 if (this->particleSystem_ && (emitterNr < this->particleSystem_->getNumEmitters())) 110 130 return this->particleSystem_->getEmitter(emitterNr); 111 131 else … … 114 134 void ParticleInterface::removeEmitter(unsigned int emitterNr) 115 135 { 116 if ( emitterNr < this->particleSystem_->getNumEmitters())136 if (this->particleSystem_ && (emitterNr < this->particleSystem_->getNumEmitters())) 117 137 this->particleSystem_->removeEmitter(emitterNr); 118 138 } 119 139 void ParticleInterface::removeAllEmitters() 120 140 { 121 this->particleSystem_->removeAllEmitters(); 141 if (this->particleSystem_) 142 this->particleSystem_->removeAllEmitters(); 122 143 } 123 144 unsigned int ParticleInterface::getNumEmitters() const 124 145 { 125 return this->particleSystem_->getNumEmitters(); 146 if (this->particleSystem_) 147 return this->particleSystem_->getNumEmitters(); 148 else 149 return 0; 126 150 } 127 151 128 152 Ogre::ParticleAffector* ParticleInterface::addAffector(const std::string& name) 129 153 { 130 return this->particleSystem_->addAffector(name); 154 if (this->particleSystem_) 155 return this->particleSystem_->addAffector(name); 156 else 157 return 0; 131 158 } 132 159 Ogre::ParticleAffector* ParticleInterface::getAffector(unsigned int affectorNr) const 133 160 { 134 if ( affectorNr < this->particleSystem_->getNumAffectors())161 if (this->particleSystem_ && (affectorNr < this->particleSystem_->getNumAffectors())) 135 162 return this->particleSystem_->getAffector(affectorNr); 136 163 else … … 139 166 void ParticleInterface::removeAffector(unsigned int affectorNr) 140 167 { 141 if ( affectorNr < this->particleSystem_->getNumAffectors())168 if (this->particleSystem_ && (affectorNr < this->particleSystem_->getNumAffectors())) 142 169 this->particleSystem_->removeAffector(affectorNr); 143 170 } 144 171 void ParticleInterface::removeAllAffectors() 145 172 { 146 this->particleSystem_->removeAllAffectors(); 173 if (this->particleSystem_) 174 this->particleSystem_->removeAllAffectors(); 147 175 } 148 176 unsigned int ParticleInterface::getNumAffectors() const 149 177 { 150 return this->particleSystem_->getNumAffectors(); 178 if (this->particleSystem_) 179 return this->particleSystem_->getNumAffectors(); 180 else 181 return 0; 151 182 } 152 183 … … 155 186 this->bEnabled_ = enable; 156 187 157 for (unsigned int i = 0; i < this->particleSystem_->getNumEmitters(); i++) 158 this->particleSystem_->getEmitter(i)->setEnabled(this->bEnabled_ && this->bAllowedByLOD_); 188 if (this->particleSystem_) 189 for (unsigned int i = 0; i < this->particleSystem_->getNumEmitters(); i++) 190 this->particleSystem_->getEmitter(i)->setEnabled(this->bEnabled_ && this->bAllowedByLOD_); 159 191 } 160 192 … … 163 195 this->bVisible_ = visible; 164 196 165 this->particleSystem_->setVisible(this->bVisible_ && this->bAllowedByLOD_); 197 if (this->particleSystem_) 198 this->particleSystem_->setVisible(this->bVisible_ && this->bAllowedByLOD_); 166 199 } 167 200 … … 169 202 { 170 203 this->detaillevel_ = level; 171 this->detailLevelChanged(GraphicsEngine::getInstance().getDetailLevelParticle()); 204 if (GraphicsEngine::getInstancePtr()) 205 this->detailLevelChanged(GraphicsEngine::getInstance().getDetailLevelParticle()); 172 206 } 173 207 … … 190 224 void ParticleInterface::setSpeedFactor(float factor) 191 225 { 192 //this->particleSystem_->setSpeedFactor(Orxonox::getInstance().getTimeFactor() * factor); 193 this->particleSystem_->setSpeedFactor(1.0f * factor); 226 if (this->particleSystem_) 227 { 228 // this->particleSystem_->setSpeedFactor(Orxonox::getInstance().getTimeFactor() * factor); 229 this->particleSystem_->setSpeedFactor(1.0f * factor); 230 } 194 231 } 195 232 float ParticleInterface::getSpeedFactor() const 196 233 { 197 //return (this->particleSystem_->getSpeedFactor() / Orxonox::getInstance().getTimeFactor()); 198 return (this->particleSystem_->getSpeedFactor() / 1.0f); 234 if (this->particleSystem_) 235 { 236 // return (this->particleSystem_->getSpeedFactor() / Orxonox::getInstance().getTimeFactor()); 237 return (this->particleSystem_->getSpeedFactor() / 1.0f); 238 } 239 else 240 return 1.0f; 199 241 } 200 242 201 243 bool ParticleInterface::getKeepParticlesInLocalSpace() const 202 244 { 203 return this->particleSystem_->getKeepParticlesInLocalSpace(); 245 if (this->particleSystem_) 246 return this->particleSystem_->getKeepParticlesInLocalSpace(); 247 else 248 return false; 204 249 } 205 250 void ParticleInterface::setKeepParticlesInLocalSpace(bool keep) 206 251 { 207 this->particleSystem_->setKeepParticlesInLocalSpace(keep); 252 if (this->particleSystem_) 253 this->particleSystem_->setKeepParticlesInLocalSpace(keep); 208 254 } 209 255 } -
code/trunk/src/orxonox/tools/Timer.h
r2087 r2171 28 28 29 29 /*! 30 @file Timer.h30 @file 31 31 @brief Definition and Implementation of the Timer class. 32 32 -
code/trunk/src/tolua/tolua-5.1.pkg
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/util
- Property svn:mergeinfo changed
/code/branches/objecthierarchy/src/util merged: 2111,2114,2123,2155,2158,2161-2162
- Property svn:mergeinfo changed
-
code/trunk/src/util/CRC32.cc
r1791 r2171 29 29 #include "CRC32.h" 30 30 31 namespace orxonox 32 { 33 void calcCRCBit(uint32_t &crc32, int bit) 34 { 35 int hbit = (crc32 & 0x80000000) ? 1 : 0; 36 if (hbit != bit) 37 crc32 = (crc32 << 1) ^ UTIL_CRC32POLY; 38 else 39 crc32 = crc32 << 1; 40 } 31 41 32 void calcCRCBit(uint32_t &crc32, int bit){ 33 int hbit; 42 uint32_t calcCRC(unsigned char *data, unsigned int dataLength) 43 { 44 uint32_t crc32 = 0; 45 for(unsigned int i = 0; i < dataLength; i++) 46 { 47 calcCRCBit(crc32, (data[i] & 0x1) >> 0); // 1st bit 48 calcCRCBit(crc32, (data[i] & 0x2) >> 1); // 2nd bit 49 calcCRCBit(crc32, (data[i] & 0x3) >> 2); // 3rd bit 50 calcCRCBit(crc32, (data[i] & 0x4) >> 3); // 4th bit 51 calcCRCBit(crc32, (data[i] & 0x5) >> 4); // 5th bit 52 calcCRCBit(crc32, (data[i] & 0x6) >> 5); // 6th bit 53 calcCRCBit(crc32, (data[i] & 0x7) >> 6); // 7th bit 54 calcCRCBit(crc32, (data[i] & 0x8) >> 7); // 8th bit 55 } 56 return crc32; 57 } 58 } 34 59 35 hbit=(crc32 & 0x80000000) ? 1 : 0;36 if (hbit != bit)37 crc32=(crc32<<1) ^ UTIL_CRC32POLY;38 else39 crc32=crc32<<1;40 }41 42 uint32_t calcCRC(unsigned char *data, unsigned int dataLength){43 uint32_t crc32=0;44 for(unsigned int i=0; i<dataLength; i++){45 calcCRCBit(crc32, (data[i]&0x1)>>0); // 1st bit46 calcCRCBit(crc32, (data[i]&0x2)>>1); // 2nd bit47 calcCRCBit(crc32, (data[i]&0x3)>>2); // 3rd bit48 calcCRCBit(crc32, (data[i]&0x4)>>3); // 4th bit49 calcCRCBit(crc32, (data[i]&0x5)>>4); // 5th bit50 calcCRCBit(crc32, (data[i]&0x6)>>5); // 6th bit51 calcCRCBit(crc32, (data[i]&0x7)>>6); // 7th bit52 calcCRCBit(crc32, (data[i]&0x8)>>7); // 8th bit53 }54 return crc32;55 }56 -
code/trunk/src/util/CRC32.h
r1791 r2171 34 34 #include "Integers.h" 35 35 36 const unsigned int UTIL_CRC32POLY = 0x04C11DB7; /* CRC-32 Polynom */ 36 namespace orxonox 37 { 38 const unsigned int UTIL_CRC32POLY = 0x04C11DB7; /* CRC-32 Polynom */ 37 39 38 _UtilExport void calcCRCBit(uint32_t &crc32, int bit);40 _UtilExport void calcCRCBit(uint32_t &crc32, int bit); 39 41 40 _UtilExport uint32_t calcCRC(unsigned char *data, unsigned int dataLength);41 42 _UtilExport uint32_t calcCRC(unsigned char *data, unsigned int dataLength); 43 } 42 44 43 45 #endif /* _Util_CRC_H__ */ -
code/trunk/src/util/Clipboard.cc
r1791 r2171 30 30 31 31 /** 32 @file Clipboard.cc32 @file 33 33 @brief OS-specific implementations of the clipboard functions. 34 34 */ … … 37 37 38 38 #if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 39 ///////////// 40 // Windows // 41 ///////////// 42 #include <windows.h> 43 #include "Debug.h" 39 40 ///////////// 41 // Windows // 42 ///////////// 43 44 #include <windows.h> 45 #include "Debug.h" 46 47 namespace orxonox 48 { 44 49 45 50 /** … … 97 102 return ""; 98 103 } 99 #else 100 ///////////// 101 // Default // 102 ///////////// 104 } 103 105 106 #else /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */ 107 108 ///////////// 109 // Default // 110 ///////////// 111 112 namespace orxonox 113 { 104 114 std::string clipboard = ""; //!< Keeps the text of our internal clipboard 105 115 … … 123 133 return clipboard; 124 134 } 125 #endif 135 } 136 137 #endif /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */ -
code/trunk/src/util/Clipboard.h
r1791 r2171 28 28 29 29 /** 30 @file Clipboard.h30 @file 31 31 @brief Some functions to exchange text between the OS clipboard and Orxonox. 32 32 … … 46 46 #include <string> 47 47 48 49 _UtilExport bool toClipboard(const std::string& text); 50 _UtilExport std::string fromClipboard(); 51 48 namespace orxonox 49 { 50 _UtilExport bool toClipboard(const std::string& text); 51 _UtilExport std::string fromClipboard(); 52 } 52 53 53 54 #endif /* _Clipboard_H__ */ -
code/trunk/src/util/Convert.h
r2087 r2171 68 68 #endif 69 69 70 template <class FromType, class ToType> 71 class ImplicitConversion 72 { 73 private: 74 ImplicitConversion(); ImplicitConversion(const ImplicitConversion&); ~ImplicitConversion(); 75 // Gets chosen only if there is an implicit conversion from FromType to ToType. 76 static char test(ToType); 77 // Accepts any argument. Why do we not use a template? The reason is that with templates, 78 // the function above is only taken iff it is an exact type match. But since we want to 79 // check for implicit conversion, we have to use the ellipsis. 80 static long long test(...); 81 static FromType object; // helper object to handle private c'tor and d'tor 82 public: 83 // test(object) only has 'long long' return type iff the compiler doesn't choose test(...) 84 enum { exists = (sizeof(test(object)) == sizeof(char)) }; 85 }; 70 namespace orxonox 71 { 72 template <class FromType, class ToType> 73 class ImplicitConversion 74 { 75 private: 76 ImplicitConversion(); ImplicitConversion(const ImplicitConversion&); ~ImplicitConversion(); 77 // Gets chosen only if there is an implicit conversion from FromType to ToType. 78 static char test(ToType); 79 // Accepts any argument. Why do we not use a template? The reason is that with templates, 80 // the function above is only taken iff it is an exact type match. But since we want to 81 // check for implicit conversion, we have to use the ellipsis. 82 static long long test(...); 83 static FromType object; // helper object to handle private c'tor and d'tor 84 public: 85 // test(object) only has 'long long' return type iff the compiler doesn't choose test(...) 86 enum { exists = (sizeof(test(object)) == sizeof(char)) }; 87 }; 88 } 86 89 87 90 #if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC … … 118 121 */ 119 122 120 namespace 121 { 122 //! Little template that maps integers to entire types (Alexandrescu 2001) 123 template <int I> 124 struct Int2Type { }; 123 namespace orxonox 124 { 125 namespace 126 { 127 //! Little template that maps integers to entire types (Alexandrescu 2001) 128 template <int I> 129 struct Int2Type { }; 130 } 131 132 133 /////////////////// 134 // No Conversion // 135 /////////////////// 136 137 // Default template. No conversion available at all. 138 template <class FromType, class ToType> 139 struct ConverterFallback 140 { 141 static bool convert(ToType* output, const FromType& input) 142 { 143 COUT(2) << "Could not convert value of type " << typeid(FromType).name() 144 << " to type " << typeid(ToType).name() << std::endl; 145 return false; 146 } 147 }; 148 149 // If all else fails, try a dynamic_cast for pointer types. 150 template <class FromType, class ToType> 151 struct ConverterFallback<FromType*, ToType*> 152 { 153 static bool convert(ToType** output, FromType* const input) 154 { 155 ToType* temp = dynamic_cast<ToType*>(input); 156 if (temp) 157 { 158 *output = temp; 159 return true; 160 } 161 else 162 return false; 163 } 164 }; 125 165 } 126 127 128 ///////////////////129 // No Conversion //130 ///////////////////131 132 // Default template. No conversion available at all.133 template <class FromType, class ToType>134 struct ConverterFallback135 {136 static bool convert(ToType* output, const FromType& input)137 {138 COUT(2) << "Could not convert value of type " << typeid(FromType).name()139 << " to type " << typeid(ToType).name() << std::endl;140 return false;141 }142 };143 144 // If all else fails, try a dynamic_cast for pointer types.145 template <class FromType, class ToType>146 struct ConverterFallback<FromType*, ToType*>147 {148 static bool convert(ToType** output, FromType* const input)149 {150 ToType* temp = dynamic_cast<ToType*>(input);151 if (temp)152 {153 *output = temp;154 return true;155 }156 else157 return false;158 }159 };160 166 161 167 … … 170 176 static bool convert(ToType* output, const FromType& input) 171 177 { 172 return ConverterFallback<FromType, ToType>::convert(output, input);178 return orxonox::ConverterFallback<FromType, ToType>::convert(output, input); 173 179 } 174 180 }; … … 185 191 { 186 192 std::string temp; 187 if ( ConverterFallback<FromType, std::string>::convert(&temp, input))193 if (orxonox::ConverterFallback<FromType, std::string>::convert(&temp, input)) 188 194 { 189 195 std::operator <<(outstream, temp); … … 224 230 inline bool operator >>(std::istream& instream, ToType& output) 225 231 { 226 return ConverterFallback<std::string, ToType>232 return orxonox::ConverterFallback<std::string, ToType> 227 233 ::convert(&output, static_cast<std::istringstream&>(instream).str()); 228 234 } … … 247 253 }; 248 254 249 250 /////////////////// 251 // Implicit Cast // 252 /////////////////// 253 254 // implicit cast not possible, try stringstream conversion next 255 template <class FromType, class ToType> 256 inline bool convertImplicitely(ToType* output, const FromType& input, ::Int2Type<false>) 257 { 258 return ConverterStringStream<FromType, ToType>::convert(output, input); 255 namespace orxonox 256 { 257 258 /////////////////// 259 // Implicit Cast // 260 /////////////////// 261 262 // implicit cast not possible, try stringstream conversion next 263 template <class FromType, class ToType> 264 inline bool convertImplicitely(ToType* output, const FromType& input, orxonox::Int2Type<false>) 265 { 266 return ConverterStringStream<FromType, ToType>::convert(output, input); 267 } 268 269 // We can cast implicitely 270 template <class FromType, class ToType> 271 inline bool convertImplicitely(ToType* output, const FromType& input, orxonox::Int2Type<true>) 272 { 273 (*output) = static_cast<ToType>(input); 274 return true; 275 } 276 277 278 //////////////////////////////// 279 // ConverterExplicit Fallback // 280 //////////////////////////////// 281 282 // Default template if no specialisation is available 283 template <class FromType, class ToType> 284 struct ConverterExplicit 285 { 286 static bool convert(ToType* output, const FromType& input) 287 { 288 // Try implict cast and probe first. If a simple cast is not possible, it will not compile 289 // We therefore have to out source it into another template function 290 const bool probe = ImplicitConversion<FromType, ToType>::exists; 291 return convertImplicitely(output, input, orxonox::Int2Type<probe>()); 292 } 293 }; 294 295 296 ////////////////////// 297 // Public Functions // 298 ////////////////////// 299 300 /** 301 @brief 302 Converts any value to any other as long as there exists a conversion. 303 Otherwise, the conversion will generate a runtime warning and return false. 304 For information about the different conversion methods (user defined too), see the section 305 'Actual conversion sequence' in this file above. 306 */ 307 template <class FromType, class ToType> 308 inline bool convertValue(ToType* output, const FromType& input) 309 { 310 return ConverterExplicit<FromType, ToType>::convert(output, input); 311 } 312 313 // For compatibility reasons. The same, but with capital ConvertValue 314 template<class FromType, class ToType> 315 inline bool ConvertValue(ToType* output, const FromType& input) 316 { 317 return convertValue(output, input); 318 } 319 320 // Calls convertValue and returns true if the conversion was successful. 321 // Otherwise the fallback is used. 322 /** 323 @brief 324 Converts any value to any other as long as there exists a conversion. 325 Otherwise, the conversion will generate a runtime warning and return false. 326 For information about the different conversion methods (user defined too), see the section 327 'Actual conversion sequence' in this file above. 328 If the conversion doesn't succeed, 'fallback' is written to '*output'. 329 @param fallback 330 A default value that gets written to '*output' if there is no conversion. 331 */ 332 template<class FromType, class ToType> 333 inline bool convertValue(ToType* output, const FromType& input, const ToType& fallback) 334 { 335 if (convertValue(output, input)) 336 return true; 337 else 338 { 339 (*output) = fallback; 340 return false; 341 } 342 } 343 344 // for compatibility reason. (capital 'c' in ConvertValue) 345 template<class FromType, class ToType> 346 inline bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback) 347 { 348 return convertValue(output, input, fallback); 349 } 350 351 // Directly returns the converted value, even if the conversion was not successful. 352 template<class FromType, class ToType> 353 inline ToType getConvertedValue(const FromType& input) 354 { 355 ToType output; 356 convertValue(&output, input); 357 return output; 358 } 359 360 // Directly returns the converted value, but uses the fallback on failure. 361 template<class FromType, class ToType> 362 inline ToType getConvertedValue(const FromType& input, const ToType& fallback) 363 { 364 ToType output; 365 convertValue(&output, input, fallback); 366 return output; 367 } 368 369 // Like getConvertedValue, but the template argument order is in reverse. 370 // That means you can call it exactly like static_cast<ToType>(fromTypeValue). 371 template<class ToType, class FromType> 372 inline ToType omni_cast(const FromType& input) 373 { 374 ToType output; 375 convertValue(&output, input); 376 return output; 377 } 378 379 // convert to string Shortcut 380 template <class FromType> 381 inline std::string convertToString(FromType value) 382 { 383 return getConvertedValue<FromType, std::string>(value); 384 } 385 386 // convert from string Shortcut 387 template <class ToType> 388 inline ToType convertFromString(std::string str) 389 { 390 return getConvertedValue<std::string, ToType>(str); 391 } 392 393 //////////////////////////////// 394 // Special string conversions // 395 //////////////////////////////// 396 397 // Delegate conversion from const char* to std::string 398 template <class ToType> 399 struct ConverterExplicit<const char*, ToType> 400 { 401 static bool convert(ToType* output, const char* input) 402 { 403 return convertValue<std::string, ToType>(output, input); 404 } 405 }; 406 407 // These conversions would exhibit ambiguous << or >> operators when using stringstream 408 template <> 409 struct ConverterExplicit<char, std::string> 410 { 411 static bool convert(std::string* output, const char input) 412 { 413 *output = std::string(1, input); 414 return true; 415 } 416 }; 417 template <> 418 struct ConverterExplicit<unsigned char, std::string> 419 { 420 static bool convert(std::string* output, const unsigned char input) 421 { 422 *output = std::string(1, input); 423 return true; 424 } 425 }; 426 template <> 427 struct ConverterExplicit<std::string, char> 428 { 429 static bool convert(char* output, const std::string input) 430 { 431 if (input != "") 432 *output = input[0]; 433 else 434 *output = '\0'; 435 return true; 436 } 437 }; 438 template <> 439 struct ConverterExplicit<std::string, unsigned char> 440 { 441 static bool convert(unsigned char* output, const std::string input) 442 { 443 if (input != "") 444 *output = input[0]; 445 else 446 *output = '\0'; 447 return true; 448 } 449 }; 450 451 452 // bool to std::string 453 template <> 454 struct ConverterExplicit<bool, std::string> 455 { 456 static bool convert(std::string* output, const bool& input) 457 { 458 if (input) 459 *output = "true"; 460 else 461 *output = "false"; 462 return false; 463 } 464 }; 465 466 // std::string to bool 467 template <> 468 struct ConverterExplicit<std::string, bool> 469 { 470 static bool convert(bool* output, const std::string& input) 471 { 472 std::string stripped = getLowercase(removeTrailingWhitespaces(input)); 473 if (stripped == "true" || stripped == "on" || stripped == "yes") 474 { 475 *output = true; 476 return true; 477 } 478 else if (stripped == "false" || stripped == "off" || stripped == "no") 479 { 480 *output = false; 481 return true; 482 } 483 484 std::istringstream iss(input); 485 if (iss >> (*output)) 486 return true; 487 else 488 return false; 489 } 490 }; 259 491 } 260 492 261 // We can cast implicitely262 template <class FromType, class ToType>263 inline bool convertImplicitely(ToType* output, const FromType& input, ::Int2Type<true>)264 {265 (*output) = static_cast<ToType>(input);266 return true;267 }268 269 270 ////////////////////////////////271 // ConverterExplicit Fallback //272 ////////////////////////////////273 274 // Default template if no specialisation is available275 template <class FromType, class ToType>276 struct ConverterExplicit277 {278 static bool convert(ToType* output, const FromType& input)279 {280 // Try implict cast and probe first. If a simple cast is not possible, it will not compile281 // We therefore have to out source it into another template function282 const bool probe = ImplicitConversion<FromType, ToType>::exists;283 return convertImplicitely(output, input, ::Int2Type<probe>());284 }285 };286 287 288 //////////////////////289 // Public Functions //290 //////////////////////291 292 /**293 @brief294 Converts any value to any other as long as there exists a conversion.295 Otherwise, the conversion will generate a runtime warning and return false.296 For information about the different conversion methods (user defined too), see the section297 'Actual conversion sequence' in this file above.298 */299 template <class FromType, class ToType>300 inline bool convertValue(ToType* output, const FromType& input)301 {302 return ConverterExplicit<FromType, ToType>::convert(output, input);303 }304 305 // For compatibility reasons. The same, but with capital ConvertValue306 template<class FromType, class ToType>307 inline bool ConvertValue(ToType* output, const FromType& input)308 {309 return convertValue(output, input);310 }311 312 // Calls convertValue and returns true if the conversion was successful.313 // Otherwise the fallback is used.314 /**315 @brief316 Converts any value to any other as long as there exists a conversion.317 Otherwise, the conversion will generate a runtime warning and return false.318 For information about the different conversion methods (user defined too), see the section319 'Actual conversion sequence' in this file above.320 If the conversion doesn't succeed, 'fallback' is written to '*output'.321 @param fallback322 A default value that gets written to '*output' if there is no conversion.323 */324 template<class FromType, class ToType>325 inline bool convertValue(ToType* output, const FromType& input, const ToType& fallback)326 {327 if (convertValue(output, input))328 return true;329 else330 {331 (*output) = fallback;332 return false;333 }334 }335 336 // for compatibility reason. (capital 'c' in ConvertValue)337 template<class FromType, class ToType>338 inline bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback)339 {340 return convertValue(output, input, fallback);341 }342 343 // Directly returns the converted value, even if the conversion was not successful.344 template<class FromType, class ToType>345 inline ToType getConvertedValue(const FromType& input)346 {347 ToType output;348 convertValue(&output, input);349 return output;350 }351 352 // Directly returns the converted value, but uses the fallback on failure.353 template<class FromType, class ToType>354 inline ToType getConvertedValue(const FromType& input, const ToType& fallback)355 {356 ToType output;357 convertValue(&output, input, fallback);358 return output;359 }360 361 // Like getConvertedValue, but the template argument order is in reverse.362 // That means you can call it exactly like static_cast<ToType>(fromTypeValue).363 template<class ToType, class FromType>364 inline ToType omni_cast(const FromType& input)365 {366 ToType output;367 convertValue(&output, input);368 return output;369 }370 371 // convert to string Shortcut372 template <class FromType>373 inline std::string convertToString(FromType value)374 {375 return getConvertedValue<FromType, std::string>(value);376 }377 378 // convert from string Shortcut379 template <class ToType>380 inline ToType convertFromString(std::string str)381 {382 return getConvertedValue<std::string, ToType>(str);383 }384 385 ////////////////////////////////386 // Special string conversions //387 ////////////////////////////////388 389 // Delegate conversion from const char* to std::string390 template <class ToType>391 struct ConverterExplicit<const char*, ToType>392 {393 static bool convert(ToType* output, const char* input)394 {395 return convertValue<std::string, ToType>(output, input);396 }397 };398 399 // These conversions would exhibit ambiguous << or >> operators when using stringstream400 template <>401 struct ConverterExplicit<char, std::string>402 {403 static bool convert(std::string* output, const char input)404 {405 *output = std::string(1, input);406 return true;407 }408 };409 template <>410 struct ConverterExplicit<unsigned char, std::string>411 {412 static bool convert(std::string* output, const unsigned char input)413 {414 *output = std::string(1, input);415 return true;416 }417 };418 template <>419 struct ConverterExplicit<std::string, char>420 {421 static bool convert(char* output, const std::string input)422 {423 if (input != "")424 *output = input[0];425 else426 *output = '\0';427 return true;428 }429 };430 template <>431 struct ConverterExplicit<std::string, unsigned char>432 {433 static bool convert(unsigned char* output, const std::string input)434 {435 if (input != "")436 *output = input[0];437 else438 *output = '\0';439 return true;440 }441 };442 443 444 // bool to std::string445 template <>446 struct ConverterExplicit<bool, std::string>447 {448 static bool convert(std::string* output, const bool& input)449 {450 if (input)451 *output = "true";452 else453 *output = "false";454 return false;455 }456 };457 458 // std::string to bool459 template <>460 struct ConverterExplicit<std::string, bool>461 {462 static bool convert(bool* output, const std::string& input)463 {464 std::string stripped = getLowercase(removeTrailingWhitespaces(input));465 if (stripped == "true" || stripped == "on" || stripped == "yes")466 {467 *output = true;468 return true;469 }470 else if (stripped == "false" || stripped == "off" || stripped == "no")471 {472 *output = false;473 return true;474 }475 476 std::istringstream iss(input);477 if (iss >> (*output))478 return true;479 else480 return false;481 }482 };483 484 493 #endif /* _Convert_H__ */ -
code/trunk/src/util/Debug.h
r2087 r2171 28 28 29 29 /** 30 @file Debug.h30 @file 31 31 @brief Handles different output-levels of errors, warnings, infos and debug informations. 32 32 … … 67 67 #include "OutputHandler.h" 68 68 69 70 /**71 @brief Returns the soft debug level, stored in the only existing instance of the OutputHandler class, configured in the config-file.72 @return The soft debug level73 */74 static inline int getSoftDebugLevel()75 {76 return orxonox::OutputHandler::getSoftDebugLevel();77 }78 79 69 namespace orxonox 80 70 { 71 /** 72 @brief Returns the soft debug level, stored in the only existing instance of the OutputHandler class, configured in the config-file. 73 @return The soft debug level 74 */ 75 static inline int getSoftDebugLevel() 76 { 77 return OutputHandler::getSoftDebugLevel(); 78 } 79 81 80 using std::endl; 82 81 } … … 115 114 #if ORX_HARD_DEBUG_LEVEL >= ORX_NONE 116 115 #define COUT0 \ 117 (getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : COUT_EXEC(0)116 (orxonox::getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : COUT_EXEC(0) 118 117 #else 119 118 #define COUT0 \ … … 123 122 #if ORX_HARD_DEBUG_LEVEL >= ORX_ERROR 124 123 #define COUT1 \ 125 ( getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : COUT_EXEC(1)124 (orxonox::getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : COUT_EXEC(1) 126 125 #else 127 126 #define COUT1 \ … … 131 130 #if ORX_HARD_DEBUG_LEVEL >= ORX_WARNING 132 131 #define COUT2 \ 133 ( getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : COUT_EXEC(2)132 (orxonox::getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : COUT_EXEC(2) 134 133 #else 135 134 #define COUT2 \ … … 139 138 #if ORX_HARD_DEBUG_LEVEL >= ORX_INFO 140 139 #define COUT3 \ 141 ( getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : COUT_EXEC(3)140 (orxonox::getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : COUT_EXEC(3) 142 141 #else 143 142 #define COUT3 \ … … 147 146 #if ORX_HARD_DEBUG_LEVEL >= ORX_DEBUG 148 147 #define COUT4 \ 149 ( getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : COUT_EXEC(4)148 (orxonox::getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : COUT_EXEC(4) 150 149 #else 151 150 #define COUT4 \ … … 155 154 #if ORX_HARD_DEBUG_LEVEL >= ORX_VERBOSE 156 155 #define COUT5 \ 157 ( getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : COUT_EXEC(5)156 (orxonox::getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : COUT_EXEC(5) 158 157 #else 159 158 #define COUT5 \ … … 163 162 #if ORX_HARD_DEBUG_LEVEL >= ORX_ULTRA 164 163 #define COUT6 \ 165 ( getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : COUT_EXEC(6)164 (orxonox::getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : COUT_EXEC(6) 166 165 #else 167 166 #define COUT6 \ … … 199 198 #if ORX_HARD_DEBUG_LEVEL >= ORX_NONE 200 199 #define CCOUT0 \ 201 ( getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : CCOUT_EXEC(0)200 (orxonox::getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : CCOUT_EXEC(0) 202 201 #else 203 202 #define CCOUT0 \ … … 207 206 #if ORX_HARD_DEBUG_LEVEL >= ORX_ERROR 208 207 #define CCOUT1 \ 209 ( getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : CCOUT_EXEC(1)208 (orxonox::getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : CCOUT_EXEC(1) 210 209 #else 211 210 #define CCOUT1 \ … … 215 214 #if ORX_HARD_DEBUG_LEVEL >= ORX_WARNING 216 215 #define CCOUT2 \ 217 ( getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : CCOUT_EXEC(2)216 (orxonox::getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : CCOUT_EXEC(2) 218 217 #else 219 218 #define CCOUT2 \ … … 223 222 #if ORX_HARD_DEBUG_LEVEL >= ORX_INFO 224 223 #define CCOUT3 \ 225 ( getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : CCOUT_EXEC(3)224 (orxonox::getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : CCOUT_EXEC(3) 226 225 #else 227 226 #define CCOUT3 \ … … 231 230 #if ORX_HARD_DEBUG_LEVEL >= ORX_DEBUG 232 231 #define CCOUT4 \ 233 ( getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : CCOUT_EXEC(4)232 (orxonox::getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : CCOUT_EXEC(4) 234 233 #else 235 234 #define CCOUT4 \ … … 239 238 #if ORX_HARD_DEBUG_LEVEL >= ORX_VERBOSE 240 239 #define CCOUT5 \ 241 ( getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : CCOUT_EXEC(5)240 (orxonox::getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : CCOUT_EXEC(5) 242 241 #else 243 242 #define CCOUT5 \ … … 247 246 #if ORX_HARD_DEBUG_LEVEL >= ORX_ULTRA 248 247 #define CCOUT6 \ 249 ( getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : CCOUT_EXEC(6)248 (orxonox::getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : CCOUT_EXEC(6) 250 249 #else 251 250 #define CCOUT6 \ -
code/trunk/src/util/Exception.cc
- Property svn:mergeinfo changed
/code/branches/objecthierarchy/src/util/Exception.cc merged: 2111
r2103 r2171 81 81 return fullDescription_; 82 82 } 83 84 85 83 } - Property svn:mergeinfo changed
-
code/trunk/src/util/Exception.h
- Property svn:mergeinfo changed
/code/branches/objecthierarchy/src/util/Exception.h merged: 2111,2161-2162
r2103 r2171 43 43 #include "Debug.h" 44 44 45 // Define some ugly macros to make things more clear46 #define CREATE_ORXONOX_EXCEPTION(name) typedef SpecificException<Exception::name> name##Exception;47 #define RETURN_EXCEPTION_CODE(name) \48 case Exception::name: \49 return #name;50 51 52 45 namespace orxonox 53 46 { … … 55 48 { 56 49 public: 57 enum ExceptionType58 {59 General,60 FileNotFound,61 Argument,62 PluginsNotFound,63 InitialisationFailed,64 NotImplemented,65 GameState66 };67 50 68 51 Exception(const std::string& description, int lineNumber, … … 74 57 75 58 virtual const std::string& getFullDescription() const; 76 virtual ExceptionType getType() const = 0;77 59 virtual std::string getTypeName() const = 0; 78 60 virtual const std::string& getDescription() const { return this->description_; } … … 93 75 94 76 95 template <Exception::ExceptionType Type> 96 class SpecificException : public Exception 97 { 98 public: 99 SpecificException(const std::string& description, int lineNumber, 100 const char* filename, const char* functionName) 101 : Exception(description, lineNumber, filename, functionName) 102 { 103 // let the catcher decide whether to display the message below level 4 104 COUT(4) << this->getFullDescription() << std::endl; 105 } 106 107 SpecificException(const std::string& description) 108 : Exception(description) 109 { 110 // let the catcher decide whether to display the message below level 4 111 COUT(4) << this->getFullDescription() << std::endl; 112 } 113 114 ~SpecificException() throw() { } 115 116 ExceptionType getType() const { return Type; } 117 std::string getTypeName() const 118 { 119 // note: break is not necessary due to the return in the macros. 120 switch (Type) 121 { 122 RETURN_EXCEPTION_CODE(General) 123 RETURN_EXCEPTION_CODE(FileNotFound); 124 RETURN_EXCEPTION_CODE(Argument); 125 RETURN_EXCEPTION_CODE(PluginsNotFound); 126 RETURN_EXCEPTION_CODE(InitialisationFailed); 127 RETURN_EXCEPTION_CODE(NotImplemented); 128 RETURN_EXCEPTION_CODE(GameState); 129 default: 130 return ""; 131 } 132 } 77 #define CREATE_ORXONOX_EXCEPTION(ExceptionName) \ 78 class ExceptionName##Exception : public Exception \ 79 { \ 80 public: \ 81 ExceptionName##Exception(const std::string& description, int lineNumber, \ 82 const char* filename, const char* functionName) \ 83 : Exception(description, lineNumber, filename, functionName) \ 84 { \ 85 /* Let the catcher decide whether to display the message below level 4 \ 86 Note: Don't place this code in Exception c'tor because getTypeName() \ 87 is still pure virtual at that time. */ \ 88 COUT(4) << this->getFullDescription() << std::endl; \ 89 } \ 90 \ 91 ExceptionName##Exception(const std::string& description) \ 92 : Exception(description) \ 93 { COUT(4) << this->getFullDescription() << std::endl; } \ 94 \ 95 ~ExceptionName##Exception() throw() { } \ 96 \ 97 std::string getTypeName() const { return #ExceptionName; } \ 133 98 }; 134 99 135 // define the template spcialisations 100 // Creates all possible exception types. 101 // If you want to add a new type, simply copy and adjust a new line here. 136 102 CREATE_ORXONOX_EXCEPTION(General); 137 103 CREATE_ORXONOX_EXCEPTION(FileNotFound); … … 141 107 CREATE_ORXONOX_EXCEPTION(NotImplemented); 142 108 CREATE_ORXONOX_EXCEPTION(GameState); 109 CREATE_ORXONOX_EXCEPTION(NoGraphics); 110 CREATE_ORXONOX_EXCEPTION(AbortLoading); 111 } 143 112 144 #define ThrowException( type, description) \145 throw SpecificException<Exception::type>(description, __LINE__, __FILE__, __FUNCTIONNAME__)113 #define ThrowException(Type, Description) \ 114 throw Type##Exception(Description, __LINE__, __FILE__, __FUNCTIONNAME__) 146 115 147 116 // define an assert macro that can display a message 148 117 #ifndef NDEBUG 149 #define OrxAssert( assertion, errorMessage) \150 assertion ? ((void)0) : (void)(orxonox::OutputHandler::getOutStream().setOutputLevel(ORX_ERROR) << errorMessage << std::endl); \151 assert( assertion)118 #define OrxAssert(Assertion, ErrorMessage) \ 119 Assertion ? ((void)0) : (void)(orxonox::OutputHandler::getOutStream().setOutputLevel(ORX_ERROR) << ErrorMessage << std::endl); \ 120 assert(Assertion) 152 121 #else 153 122 #define OrxAssert(condition, errorMessage) ((void)0) 154 123 #endif 155 124 156 }157 158 125 #endif /* _Exception_H__ */ - Property svn:mergeinfo changed
-
code/trunk/src/util/ExprParser.cc
r1894 r2171 45 45 #define PARSE_BLANKS while (*reading_stream == ' ') ++reading_stream 46 46 47 ExprParser::ExprParser(const std::string& str) 47 namespace orxonox 48 48 { 49 this->failed_ = false; 50 this->reading_stream = str.c_str(); 51 if (str.size() == 0 || *reading_stream == '\0') 52 { 53 this->failed_ = true; 54 this->result_ = 0.0; 55 } 56 else 57 { 58 this->result_ = parse_expr_8(); 59 this->remains_ = reading_stream; 49 ExprParser::ExprParser(const std::string& str) 50 { 51 this->failed_ = false; 52 this->reading_stream = str.c_str(); 53 if (str.size() == 0 || *reading_stream == '\0') 54 { 55 this->failed_ = true; 56 this->result_ = 0.0; 57 } 58 else 59 { 60 this->result_ = parse_expr_8(); 61 this->remains_ = reading_stream; 62 } 63 } 64 65 //Private functions: 66 /******************/ 67 double ExprParser::parse_argument() 68 { 69 double value = parse_expr_8(); 70 if (*reading_stream == ',') 71 { 72 ++reading_stream; 73 return value; 74 } 75 else 76 { 77 this->failed_ = true; 78 return 0; 79 } 80 } 81 82 double ExprParser::parse_last_argument() 83 { 84 double value = parse_expr_8(); 85 if (*reading_stream == ')') 86 { 87 ++reading_stream; 88 return value; 89 } 90 else 91 { 92 this->failed_ = true; 93 return 0; 94 } 95 } 96 97 double ExprParser::parse_expr_8() 98 { 99 double value = parse_expr_7(); 100 for(;;) 101 { 102 switch (op) 103 { 104 case oder: 105 value = parse_expr_7() || value; 106 break; 107 default: return value; 108 } 109 }; 110 } 111 112 113 double ExprParser::parse_expr_7() 114 { 115 double value = parse_expr_6(); 116 for(;;) 117 { 118 switch (op) 119 { 120 case und: 121 value = value && parse_expr_6(); 122 break; 123 default: return value; 124 } 125 }; 126 } 127 128 double ExprParser::parse_expr_6() 129 { 130 double value = parse_expr_5(); 131 for(;;) 132 { 133 switch (op) 134 { 135 case gleich: 136 value = (value == parse_expr_5()); 137 break; 138 case ungleich: 139 value = (value != parse_expr_5()); 140 break; 141 default: 142 return value; 143 } 144 }; 145 } 146 147 double ExprParser::parse_expr_5() 148 { 149 double value = parse_expr_4(); 150 for(;;) 151 { 152 switch (op) 153 { 154 case kleiner: 155 value = (value < parse_expr_4()); 156 break; 157 case kleinergleich: 158 value = (value <= parse_expr_4()); 159 break; 160 case groesser: 161 value = (value > parse_expr_4()); 162 break; 163 case groessergleich: 164 value = (value >= parse_expr_4()); 165 break; 166 default: 167 return value; 168 } 169 }; 170 } 171 172 double ExprParser::parse_expr_4() 173 { 174 double value = parse_expr_3(); 175 for(;;) 176 { 177 switch (op) 178 { 179 case b_plus: 180 value += parse_expr_3(); 181 break; 182 case b_minus: 183 value -= parse_expr_3(); 184 break; 185 default: 186 return value; 187 } 188 }; 189 } 190 191 double ExprParser::parse_expr_3() 192 { 193 double value = parse_expr_2(); 194 for(;;) 195 { 196 switch (op) 197 { 198 case mal: 199 value *= parse_expr_2(); 200 break; 201 case durch: 202 value /= parse_expr_2(); 203 break; 204 case modulo: 205 { 206 double temp = parse_expr_2(); 207 value = value - floor(value/temp)*temp; 208 break; 209 } 210 default: 211 return value; 212 } 213 }; 214 } 215 216 double ExprParser::parse_expr_2() 217 { 218 double value = parse_expr_1(); 219 while (*reading_stream != '\0') 220 { 221 op = parse_binary_operator(); 222 switch (op) 223 { 224 case hoch: 225 value = pow(value,parse_expr_1()); 226 break; 227 default: 228 return value; 229 } 230 }; 231 op = undef; 232 return value; 233 } 234 235 double ExprParser::parse_expr_1() 236 { 237 PARSE_BLANKS; 238 double value; 239 240 unary_operator op = parse_unary_operator(); 241 PARSE_BLANKS; 242 243 if (*reading_stream == '\0') 244 { 245 // end of string 246 this->failed_ = true; 247 return 0; 248 } 249 else if (*reading_stream > 47 && *reading_stream < 59 || *reading_stream == 46) 250 { // number 251 value = strtod(reading_stream, const_cast<char**>(&reading_stream)); 252 } 253 else if (*reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46) 254 { // variable or function 255 char* word = new char[256]; 256 parse_word(word); 257 PARSE_BLANKS; 258 if (*reading_stream == '(') 259 { 260 ++reading_stream; 261 #define SWITCH word 262 CASE_1("sin") 263 value = sin(parse_last_argument()); 264 CASE("asin") 265 value = asin(parse_last_argument()); 266 CASE("sinh") 267 value = sinh(parse_last_argument()); 268 CASE("asinh") 269 { 270 value = parse_last_argument(); 271 value = log(sqrt(pow(value, 2) + 1) + value); 272 } 273 CASE("cos") 274 value = cos(parse_last_argument()); 275 CASE("acos") 276 value = acos(parse_last_argument()); 277 CASE("cosh") 278 value = cosh(parse_last_argument()); 279 CASE("acosh") 280 { 281 value = parse_last_argument(); 282 value = log(sqrt(pow(value, 2) - 1) + value); 283 } 284 CASE("tan") 285 value = tan(parse_last_argument()); 286 CASE("atan") 287 value = atan(parse_last_argument()); 288 CASE("atan2") 289 value = atan2(parse_argument(),parse_last_argument()); 290 CASE("tanh") 291 value = tanh(parse_last_argument()); 292 CASE("atanh") 293 { 294 value = parse_last_argument(); 295 value = 0.5*log((value + 1)/(value - 1)); 296 } 297 CASE("int") 298 value = floor(parse_last_argument()); 299 CASE("floor") 300 value = floor(parse_last_argument()); 301 CASE("ceil") 302 value = ceil(parse_last_argument()); 303 CASE("abs") 304 value = fabs(parse_last_argument()); 305 CASE("exp") 306 value = exp(parse_last_argument()); 307 CASE("log") 308 value = log10(parse_last_argument()); 309 CASE("ln") 310 value = log(parse_last_argument()); 311 CASE("sign") 312 { 313 value = parse_last_argument(); 314 value = (value>0 ? 1 : (value<0 ? -1 : 0)); 315 } 316 CASE("sqrt") 317 value = sqrt(parse_last_argument()); 318 CASE("degrees") 319 value = parse_last_argument()*180/3.1415926535897932; 320 CASE("radians") 321 value = parse_last_argument()*3.1415926535897932/180; 322 CASE("mod") 323 { 324 value = parse_argument(); 325 double value2 = parse_last_argument(); 326 value = value - floor(value/value2)*value2; 327 } 328 CASE("pow") 329 value = pow(parse_argument(),parse_last_argument()); 330 CASE("div") 331 value = floor(parse_argument()/parse_last_argument()); 332 CASE("max") 333 value = std::max(parse_argument(),parse_last_argument()); 334 CASE("min") 335 value = std::min(parse_argument(),parse_last_argument()); 336 CASE_ELSE 337 { 338 this->failed_ = true; 339 delete[] word; 340 return 0; 341 } 342 } 343 else 344 { 345 #define SWITCH word 346 CASE_1("pi") 347 value = 3.1415926535897932; 348 CASE("e") 349 value = 2.7182818284590452; 350 CASE_ELSE 351 { 352 this->failed_ = true; 353 delete[] word; 354 return 0; 355 } 356 } 357 delete[] word; 358 } 359 else if (*reading_stream == 40) 360 { // expresion in paranthesis 361 ++reading_stream; 362 value = parse_last_argument(); 363 } 364 else 365 { 366 this->failed_ = true; 367 return 0; 368 } 369 370 PARSE_BLANKS; 371 switch (op) 372 { 373 case u_nicht: return !value; 374 case u_plus: return value; 375 case u_minus: return -value; 376 default: 377 this->failed_ = true; 378 return 0; 379 } 380 } 381 382 char* ExprParser::parse_word(char* str) 383 { 384 char* word = str; 385 int counter = 0; 386 while (*reading_stream > 47 && *reading_stream < 58 || *reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46) 387 { 388 *word++ = *reading_stream++; 389 counter++; 390 if (counter > 255) 391 { 392 this->failed_ = true; 393 return '\0'; 394 } 395 }; 396 *word = '\0'; 397 return str; 398 } 399 400 ExprParser::binary_operator ExprParser::parse_binary_operator() 401 { 402 binary_operator op; 403 switch (*reading_stream) 404 { 405 case '+': op = b_plus; break; 406 case '-': op = b_minus; break; 407 case '*': op = mal; break; 408 case '/': op = durch; break; 409 case '^': op = hoch; break; 410 case '%': op = modulo; break; 411 case '&': op = und; break; 412 case '|': op = oder; break; 413 case '=': op = gleich; break; 414 case '!': op = b_nicht; break; 415 case '<': op = kleiner; break; 416 case '>': op = groesser; break; 417 default: return undef; 418 } 419 if (*++reading_stream == '=') 420 { 421 if (op > 9) 422 { 423 ++reading_stream; 424 return (binary_operator)(op + 3); 425 } 426 else 427 { 428 --reading_stream; 429 return undef; 430 } 431 } 432 else 433 return op; 434 } 435 436 ExprParser::unary_operator ExprParser::parse_unary_operator() 437 { 438 switch (*reading_stream) 439 { 440 case '!': 441 ++reading_stream; 442 return u_nicht; 443 case '+': 444 ++reading_stream; 445 return u_plus; 446 case '-': 447 ++reading_stream; 448 return u_minus; 449 default : 450 return u_plus; 451 } 60 452 } 61 453 } 62 63 //Private functions:64 /******************/65 double ExprParser::parse_argument()66 {67 double value = parse_expr_8();68 if (*reading_stream == ',')69 {70 ++reading_stream;71 return value;72 }73 else74 {75 this->failed_ = true;76 return 0;77 }78 }79 80 double ExprParser::parse_last_argument()81 {82 double value = parse_expr_8();83 if (*reading_stream == ')')84 {85 ++reading_stream;86 return value;87 }88 else89 {90 this->failed_ = true;91 return 0;92 }93 }94 95 double ExprParser::parse_expr_8()96 {97 double value = parse_expr_7();98 for(;;)99 {100 switch (op)101 {102 case oder:103 value = parse_expr_7() || value;104 break;105 default: return value;106 }107 };108 }109 110 111 double ExprParser::parse_expr_7()112 {113 double value = parse_expr_6();114 for(;;)115 {116 switch (op)117 {118 case und:119 value = value && parse_expr_6();120 break;121 default: return value;122 }123 };124 }125 126 double ExprParser::parse_expr_6()127 {128 double value = parse_expr_5();129 for(;;)130 {131 switch (op)132 {133 case gleich:134 value = (value == parse_expr_5());135 break;136 case ungleich:137 value = (value != parse_expr_5());138 break;139 default:140 return value;141 }142 };143 }144 145 double ExprParser::parse_expr_5()146 {147 double value = parse_expr_4();148 for(;;)149 {150 switch (op)151 {152 case kleiner:153 value = (value < parse_expr_4());154 break;155 case kleinergleich:156 value = (value <= parse_expr_4());157 break;158 case groesser:159 value = (value > parse_expr_4());160 break;161 case groessergleich:162 value = (value >= parse_expr_4());163 break;164 default:165 return value;166 }167 };168 }169 170 double ExprParser::parse_expr_4()171 {172 double value = parse_expr_3();173 for(;;)174 {175 switch (op)176 {177 case b_plus:178 value += parse_expr_3();179 break;180 case b_minus:181 value -= parse_expr_3();182 break;183 default:184 return value;185 }186 };187 }188 189 double ExprParser::parse_expr_3()190 {191 double value = parse_expr_2();192 for(;;)193 {194 switch (op)195 {196 case mal:197 value *= parse_expr_2();198 break;199 case durch:200 value /= parse_expr_2();201 break;202 case modulo:203 {204 double temp = parse_expr_2();205 value = value - floor(value/temp)*temp;206 break;207 }208 default:209 return value;210 }211 };212 }213 214 double ExprParser::parse_expr_2()215 {216 double value = parse_expr_1();217 while (*reading_stream != '\0')218 {219 op = parse_binary_operator();220 switch (op)221 {222 case hoch:223 value = pow(value,parse_expr_1());224 break;225 default:226 return value;227 }228 };229 op = undef;230 return value;231 }232 233 double ExprParser::parse_expr_1()234 {235 PARSE_BLANKS;236 double value;237 238 unary_operator op = parse_unary_operator();239 PARSE_BLANKS;240 241 if (*reading_stream == '\0')242 {243 // end of string244 this->failed_ = true;245 return 0;246 }247 else if (*reading_stream > 47 && *reading_stream < 59 || *reading_stream == 46)248 { // number249 value = strtod(reading_stream, const_cast<char**>(&reading_stream));250 }251 else if (*reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46)252 { // variable or function253 char* word = new char[256];254 parse_word(word);255 PARSE_BLANKS;256 if (*reading_stream == '(')257 {258 ++reading_stream;259 #define SWITCH word260 CASE_1("sin")261 value = sin(parse_last_argument());262 CASE("asin")263 value = asin(parse_last_argument());264 CASE("sinh")265 value = sinh(parse_last_argument());266 CASE("asinh")267 {268 value = parse_last_argument();269 value = log(sqrt(pow(value, 2) + 1) + value);270 }271 CASE("cos")272 value = cos(parse_last_argument());273 CASE("acos")274 value = acos(parse_last_argument());275 CASE("cosh")276 value = cosh(parse_last_argument());277 CASE("acosh")278 {279 value = parse_last_argument();280 value = log(sqrt(pow(value, 2) - 1) + value);281 }282 CASE("tan")283 value = tan(parse_last_argument());284 CASE("atan")285 value = atan(parse_last_argument());286 CASE("atan2")287 value = atan2(parse_argument(),parse_last_argument());288 CASE("tanh")289 value = tanh(parse_last_argument());290 CASE("atanh")291 {292 value = parse_last_argument();293 value = 0.5*log((value + 1)/(value - 1));294 }295 CASE("int")296 value = floor(parse_last_argument());297 CASE("floor")298 value = floor(parse_last_argument());299 CASE("ceil")300 value = ceil(parse_last_argument());301 CASE("abs")302 value = fabs(parse_last_argument());303 CASE("exp")304 value = exp(parse_last_argument());305 CASE("log")306 value = log10(parse_last_argument());307 CASE("ln")308 value = log(parse_last_argument());309 CASE("sign")310 {311 value = parse_last_argument();312 value = (value>0 ? 1 : (value<0 ? -1 : 0));313 }314 CASE("sqrt")315 value = sqrt(parse_last_argument());316 CASE("degrees")317 value = parse_last_argument()*180/3.1415926535897932;318 CASE("radians")319 value = parse_last_argument()*3.1415926535897932/180;320 CASE("mod")321 {322 value = parse_argument();323 double value2 = parse_last_argument();324 value = value - floor(value/value2)*value2;325 }326 CASE("pow")327 value = pow(parse_argument(),parse_last_argument());328 CASE("div")329 value = floor(parse_argument()/parse_last_argument());330 CASE("max")331 value = std::max(parse_argument(),parse_last_argument());332 CASE("min")333 value = std::min(parse_argument(),parse_last_argument());334 CASE_ELSE335 {336 this->failed_ = true;337 delete[] word;338 return 0;339 }340 }341 else342 {343 #define SWITCH word344 CASE_1("pi")345 value = 3.1415926535897932;346 CASE("e")347 value = 2.7182818284590452;348 CASE_ELSE349 {350 this->failed_ = true;351 delete[] word;352 return 0;353 }354 }355 delete[] word;356 }357 else if (*reading_stream == 40)358 { // expresion in paranthesis359 ++reading_stream;360 value = parse_last_argument();361 }362 else363 {364 this->failed_ = true;365 return 0;366 }367 368 PARSE_BLANKS;369 switch (op)370 {371 case u_nicht: return !value;372 case u_plus: return value;373 case u_minus: return -value;374 default:375 this->failed_ = true;376 return 0;377 }378 }379 380 char* ExprParser::parse_word(char* str)381 {382 char* word = str;383 int counter = 0;384 while (*reading_stream > 47 && *reading_stream < 58 || *reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46)385 {386 *word++ = *reading_stream++;387 counter++;388 if (counter > 255)389 {390 this->failed_ = true;391 return '\0';392 }393 };394 *word = '\0';395 return str;396 }397 398 ExprParser::binary_operator ExprParser::parse_binary_operator()399 {400 binary_operator op;401 switch (*reading_stream)402 {403 case '+': op = b_plus; break;404 case '-': op = b_minus; break;405 case '*': op = mal; break;406 case '/': op = durch; break;407 case '^': op = hoch; break;408 case '%': op = modulo; break;409 case '&': op = und; break;410 case '|': op = oder; break;411 case '=': op = gleich; break;412 case '!': op = b_nicht; break;413 case '<': op = kleiner; break;414 case '>': op = groesser; break;415 default: return undef;416 }417 if (*++reading_stream == '=')418 {419 if (op > 9)420 {421 ++reading_stream;422 return (binary_operator)(op + 3);423 }424 else425 {426 --reading_stream;427 return undef;428 }429 }430 else431 return op;432 }433 434 ExprParser::unary_operator ExprParser::parse_unary_operator()435 {436 switch (*reading_stream)437 {438 case '!':439 ++reading_stream;440 return u_nicht;441 case '+':442 ++reading_stream;443 return u_plus;444 case '-':445 ++reading_stream;446 return u_minus;447 default :448 return u_plus;449 }450 } -
code/trunk/src/util/ExprParser.h
r1894 r2171 38 38 #include <string> 39 39 40 class _UtilExport ExprParser 40 namespace orxonox 41 41 { 42 public: 43 enum binary_operator 42 class _UtilExport ExprParser 44 43 { 45 b_plus, 46 b_minus, 47 mal, 48 durch, 49 modulo, 50 hoch, 51 undef, 52 oder, 53 und, 54 gleich, 55 b_nicht, 56 kleiner, 57 groesser, 58 ungleich, 59 kleinergleich, 60 groessergleich 44 public: 45 enum binary_operator 46 { 47 b_plus, 48 b_minus, 49 mal, 50 durch, 51 modulo, 52 hoch, 53 undef, 54 oder, 55 und, 56 gleich, 57 b_nicht, 58 kleiner, 59 groesser, 60 ungleich, 61 kleinergleich, 62 groessergleich 63 }; 64 65 enum unary_operator 66 { 67 u_plus, 68 u_minus, 69 u_nicht 70 }; 71 72 73 ExprParser(const std::string& str); 74 std::string& getRemains() { return this->remains_; } 75 double getResult() { return this->result_; } 76 bool getSuccess() { return !this->failed_; } 77 78 private: 79 double parse_expr_1(); 80 double parse_expr_2(); 81 double parse_expr_3(); 82 double parse_expr_4(); 83 double parse_expr_5(); 84 double parse_expr_6(); 85 double parse_expr_7(); 86 double parse_expr_8(); 87 char* parse_word(char* str); 88 binary_operator parse_binary_operator(); 89 unary_operator parse_unary_operator(); 90 91 double parse_argument(); 92 double parse_last_argument(); 93 94 binary_operator op; 95 const char* reading_stream; 96 bool failed_; 97 double result_; 98 std::string remains_; 99 61 100 }; 62 101 63 enum unary_operator 64 { 65 u_plus, 66 u_minus, 67 u_nicht 68 }; 69 70 71 ExprParser(const std::string& str); 72 std::string& getRemains() { return this->remains_; } 73 double getResult() { return this->result_; } 74 bool getSuccess() { return !this->failed_; } 75 76 private: 77 double parse_expr_1(); 78 double parse_expr_2(); 79 double parse_expr_3(); 80 double parse_expr_4(); 81 double parse_expr_5(); 82 double parse_expr_6(); 83 double parse_expr_7(); 84 double parse_expr_8(); 85 char* parse_word(char* str); 86 binary_operator parse_binary_operator(); 87 unary_operator parse_unary_operator(); 88 89 double parse_argument(); 90 double parse_last_argument(); 91 92 binary_operator op; 93 const char* reading_stream; 94 bool failed_; 95 double result_; 96 std::string remains_; 97 98 }; 99 100 //Endzeichen für float expression: ')', '}', ']', ',', ';' 101 _UtilExport bool parse_float(char* const, char**, double*); 102 //Endzeichen angegeben 103 _UtilExport bool parse_float(char* const, char**, char, double*); 104 //Letzter Teil-float eines Vektors parsen (keine Vergleichs- und Logikoperationen) 105 _UtilExport bool parse_vector_float(char* const, char**, bool, double*); 102 //Endzeichen für float expression: ')', '}', ']', ',', ';' 103 _UtilExport bool parse_float(char* const, char**, double*); 104 //Endzeichen angegeben 105 _UtilExport bool parse_float(char* const, char**, char, double*); 106 //Letzter Teil-float eines Vektors parsen (keine Vergleichs- und Logikoperationen) 107 _UtilExport bool parse_vector_float(char* const, char**, bool, double*); 108 } 106 109 107 110 #endif /* _FloatParser_H__ */ -
code/trunk/src/util/Math.cc
r2087 r2171 38 38 #include "SubString.h" 39 39 40 / **41 @brief Function for writing a Radian to a stream. 42 */ 43 std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian) 40 // Do not remove this include to avoid linker errors. 41 #include "mbool.h" 42 43 namespace orxonox 44 44 { 45 out << radian.valueRadians(); 46 return out; 45 /** 46 @brief Function for writing a Radian to a stream. 47 */ 48 std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian) 49 { 50 out << radian.valueRadians(); 51 return out; 52 } 53 54 /** 55 @brief Function for reading a Radian from a stream. 56 */ 57 std::istream& operator>>(std::istream& in, orxonox::Radian& radian) 58 { 59 float temp; 60 in >> temp; 61 radian = temp; 62 return in; 63 } 64 65 /** 66 @brief Function for writing a Degree to a stream. 67 */ 68 std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree) 69 { 70 out << degree.valueDegrees(); 71 return out; 72 } 73 74 /** 75 @brief Function for reading a Degree from a stream. 76 */ 77 std::istream& operator>>(std::istream& in, orxonox::Degree& degree) 78 { 79 float temp; 80 in >> temp; 81 degree = temp; 82 return in; 83 } 84 85 86 /** 87 @brief Gets the angle between my viewing direction and the direction to the position of the other object. 88 @param myposition My position 89 @param mydirection My viewing direction 90 @param otherposition The position of the other object 91 @return The angle 92 93 @example 94 If the other object is exactly in front of me, the function returns 0. 95 If the other object is exactly behind me, the function returns pi. 96 If the other object is exactly right/left to me (or above/below), the function returns pi/2. 97 */ 98 float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition) 99 { 100 orxonox::Vector3 distance = otherposition - myposition; 101 float distancelength = distance.length(); 102 if (distancelength == 0) 103 return 0; 104 else 105 return acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1)); 106 } 107 108 /** 109 @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object. 110 @param myposition My position 111 @param mydirection My viewing direction 112 @param myorthonormal My orthonormalvector (pointing upwards through my head) 113 @param otherposition The position of the other object 114 @return The viewing direction 115 116 @example 117 If the other object is exactly in front of me, the function returns Vector2(0, 0). 118 If the other object is exactly at my left, the function returns Vector2(-1, 0). 119 If the other object is exactly at my right, the function returns Vector2(1, 0). 120 If the other object is only a bit at my right, the function still returns Vector2(1, 0). 121 If the other object is exactly above me, the function returns Vector2(0, 1). 122 */ 123 orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition) 124 { 125 orxonox::Vector3 distance = otherposition - myposition; 126 127 // project difference vector on our plane 128 orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance); 129 130 float projectionlength = projection.length(); 131 if (projectionlength == 0) return orxonox::Vector2(0, 0); 132 float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1)); 133 134 if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0) 135 return orxonox::Vector2(sin(angle), cos(angle)); 136 else 137 return orxonox::Vector2(-sin(angle), cos(angle)); 138 } 139 140 /** 141 @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object, multiplied with the viewing distance to the object (0° = 0, 180° = 1). 142 @param myposition My position 143 @param mydirection My viewing direction 144 @param myorthonormal My orthonormalvector (pointing upwards through my head) 145 @param otherposition The position of the other object 146 @return The viewing direction 147 148 @example 149 If the other object is exactly in front of me, the function returns Vector2(0, 0). 150 If the other object is exactly at my left, the function returns Vector2(-0.5, 0). 151 If the other object is exactly at my right, the function returns Vector2(0.5, 0). 152 If the other object is only a bit at my right, the function still returns Vector2(0.01, 0). 153 If the other object is exactly above me, the function returns Vector2(0, 0.5). 154 */ 155 orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition) 156 { 157 orxonox::Vector3 distance = otherposition - myposition; 158 159 // project difference vector on our plane 160 orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance); 161 162 float projectionlength = projection.length(); 163 if (projectionlength == 0) return orxonox::Vector2(0, 0); 164 float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1)); 165 166 float distancelength = distance.length(); 167 if (distancelength == 0) return orxonox::Vector2(0, 0); 168 float radius = acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1)) / Ogre::Math::PI; 169 170 if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0) 171 return orxonox::Vector2(sin(angle) * radius, cos(angle) * radius); 172 else 173 return orxonox::Vector2(-sin(angle) * radius, cos(angle) * radius); 174 } 175 176 /** 177 @brief Returns the predicted position I have to aim at, if I want to hit a moving target with a moving projectile. 178 @param myposition My position 179 @param projectilespeed The speed of my projectile 180 @param targetposition The position of my target 181 @param targetvelocity The velocity of my target 182 @return The predicted position 183 184 The function predicts the position based on a linear velocity of the target. If the target changes speed or direction, the projectile will miss. 185 */ 186 orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity) 187 { 188 float squaredProjectilespeed = projectilespeed * projectilespeed; 189 orxonox::Vector3 distance = targetposition - myposition; 190 float a = distance.squaredLength(); 191 float b = 2 * (distance.x + distance.y + distance.z) * (targetvelocity.x + targetvelocity.y + targetvelocity.z); 192 float c = targetvelocity.squaredLength(); 193 194 float temp = 4*squaredProjectilespeed*c + a*a - 4*b*c; 195 if (temp < 0) 196 return orxonox::Vector3::ZERO; 197 198 temp = sqrt(temp); 199 float time = (temp + a) / (2 * (squaredProjectilespeed - b)); 200 return (targetposition + targetvelocity * time); 201 } 202 203 unsigned long getUniqueNumber() 204 { 205 static unsigned long aNumber = 135; 206 return aNumber++; 207 } 208 209 210 ////////////////////////// 211 // Conversion functions // 212 ////////////////////////// 213 214 // std::string to Vector2 215 bool ConverterFallback<std::string, orxonox::Vector2>::convert(orxonox::Vector2* output, const std::string& input) 216 { 217 size_t opening_parenthesis, closing_parenthesis = input.find(')'); 218 if ((opening_parenthesis = input.find('(')) == std::string::npos) 219 opening_parenthesis = 0; 220 else 221 opening_parenthesis++; 222 223 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), 224 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0'); 225 if (tokens.size() >= 2) 226 { 227 if (!ConvertValue(&(output->x), tokens[0])) 228 return false; 229 if (!ConvertValue(&(output->y), tokens[1])) 230 return false; 231 232 return true; 233 } 234 return false; 235 } 236 237 // std::string to Vector3 238 bool ConverterFallback<std::string, orxonox::Vector3>::convert(orxonox::Vector3* output, const std::string& input) 239 { 240 size_t opening_parenthesis, closing_parenthesis = input.find(')'); 241 if ((opening_parenthesis = input.find('(')) == std::string::npos) 242 opening_parenthesis = 0; 243 else 244 opening_parenthesis++; 245 246 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), 247 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0'); 248 if (tokens.size() >= 3) 249 { 250 if (!ConvertValue(&(output->x), tokens[0])) 251 return false; 252 if (!ConvertValue(&(output->y), tokens[1])) 253 return false; 254 if (!ConvertValue(&(output->z), tokens[2])) 255 return false; 256 257 return true; 258 } 259 return false; 260 } 261 262 // std::string to Vector4 263 bool ConverterFallback<std::string, orxonox::Vector4>::convert(orxonox::Vector4* output, const std::string& input) 264 { 265 size_t opening_parenthesis, closing_parenthesis = input.find(')'); 266 if ((opening_parenthesis = input.find('(')) == std::string::npos) 267 opening_parenthesis = 0; 268 else 269 opening_parenthesis++; 270 271 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), 272 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0'); 273 if (tokens.size() >= 4) 274 { 275 if (!ConvertValue(&(output->x), tokens[0])) 276 return false; 277 if (!ConvertValue(&(output->y), tokens[1])) 278 return false; 279 if (!ConvertValue(&(output->z), tokens[2])) 280 return false; 281 if (!ConvertValue(&(output->w), tokens[3])) 282 return false; 283 284 return true; 285 } 286 return false; 287 } 288 289 // std::string to Quaternion 290 bool ConverterFallback<std::string, orxonox::Quaternion>::convert(orxonox::Quaternion* output, const std::string& input) 291 { 292 size_t opening_parenthesis, closing_parenthesis = input.find(')'); 293 if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; } 294 295 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0'); 296 if (tokens.size() >= 4) 297 { 298 if (!ConvertValue(&(output->w), tokens[0])) 299 return false; 300 if (!ConvertValue(&(output->x), tokens[1])) 301 return false; 302 if (!ConvertValue(&(output->y), tokens[2])) 303 return false; 304 if (!ConvertValue(&(output->z), tokens[3])) 305 return false; 306 307 return true; 308 } 309 return false; 310 } 311 312 // std::string to ColourValue 313 bool ConverterFallback<std::string, orxonox::ColourValue>::convert(orxonox::ColourValue* output, const std::string& input) 314 { 315 size_t opening_parenthesis, closing_parenthesis = input.find(')'); 316 if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; } 317 318 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0'); 319 if (tokens.size() >= 3) 320 { 321 if (!ConvertValue(&(output->r), tokens[0])) 322 return false; 323 if (!ConvertValue(&(output->g), tokens[1])) 324 return false; 325 if (!ConvertValue(&(output->b), tokens[2])) 326 return false; 327 if (tokens.size() >= 4) 328 { 329 if (!ConvertValue(&(output->a), tokens[3])) 330 return false; 331 } 332 else 333 output->a = 1.0; 334 335 return true; 336 } 337 return false; 338 } 47 339 } 48 49 /**50 @brief Function for reading a Radian from a stream.51 */52 std::istream& operator>>(std::istream& in, orxonox::Radian& radian)53 {54 float temp;55 in >> temp;56 radian = temp;57 return in;58 }59 60 /**61 @brief Function for writing a Degree to a stream.62 */63 std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree)64 {65 out << degree.valueDegrees();66 return out;67 }68 69 /**70 @brief Function for reading a Degree from a stream.71 */72 std::istream& operator>>(std::istream& in, orxonox::Degree& degree)73 {74 float temp;75 in >> temp;76 degree = temp;77 return in;78 }79 80 81 /**82 @brief Gets the angle between my viewing direction and the direction to the position of the other object.83 @param myposition My position84 @param mydirection My viewing direction85 @param otherposition The position of the other object86 @return The angle87 88 @example89 If the other object is exactly in front of me, the function returns 0.90 If the other object is exactly behind me, the function returns pi.91 If the other object is exactly right/left to me (or above/below), the function returns pi/2.92 */93 float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition)94 {95 orxonox::Vector3 distance = otherposition - myposition;96 float distancelength = distance.length();97 if (distancelength == 0)98 return 0;99 else100 return acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1));101 }102 103 /**104 @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object.105 @param myposition My position106 @param mydirection My viewing direction107 @param myorthonormal My orthonormalvector (pointing upwards through my head)108 @param otherposition The position of the other object109 @return The viewing direction110 111 @example112 If the other object is exactly in front of me, the function returns Vector2(0, 0).113 If the other object is exactly at my left, the function returns Vector2(-1, 0).114 If the other object is exactly at my right, the function returns Vector2(1, 0).115 If the other object is only a bit at my right, the function still returns Vector2(1, 0).116 If the other object is exactly above me, the function returns Vector2(0, 1).117 */118 orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)119 {120 orxonox::Vector3 distance = otherposition - myposition;121 122 // project difference vector on our plane123 orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);124 125 float projectionlength = projection.length();126 if (projectionlength == 0) return orxonox::Vector2(0, 0);127 float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1));128 129 if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)130 return orxonox::Vector2(sin(angle), cos(angle));131 else132 return orxonox::Vector2(-sin(angle), cos(angle));133 }134 135 /**136 @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object, multiplied with the viewing distance to the object (0° = 0, 180° = 1).137 @param myposition My position138 @param mydirection My viewing direction139 @param myorthonormal My orthonormalvector (pointing upwards through my head)140 @param otherposition The position of the other object141 @return The viewing direction142 143 @example144 If the other object is exactly in front of me, the function returns Vector2(0, 0).145 If the other object is exactly at my left, the function returns Vector2(-0.5, 0).146 If the other object is exactly at my right, the function returns Vector2(0.5, 0).147 If the other object is only a bit at my right, the function still returns Vector2(0.01, 0).148 If the other object is exactly above me, the function returns Vector2(0, 0.5).149 */150 orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)151 {152 orxonox::Vector3 distance = otherposition - myposition;153 154 // project difference vector on our plane155 orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);156 157 float projectionlength = projection.length();158 if (projectionlength == 0) return orxonox::Vector2(0, 0);159 float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1));160 161 float distancelength = distance.length();162 if (distancelength == 0) return orxonox::Vector2(0, 0);163 float radius = acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1)) / Ogre::Math::PI;164 165 if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)166 return orxonox::Vector2(sin(angle) * radius, cos(angle) * radius);167 else168 return orxonox::Vector2(-sin(angle) * radius, cos(angle) * radius);169 }170 171 /**172 @brief Returns the predicted position I have to aim at, if I want to hit a moving target with a moving projectile.173 @param myposition My position174 @param projectilespeed The speed of my projectile175 @param targetposition The position of my target176 @param targetvelocity The velocity of my target177 @return The predicted position178 179 The function predicts the position based on a linear velocity of the target. If the target changes speed or direction, the projectile will miss.180 */181 orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity)182 {183 float squaredProjectilespeed = projectilespeed * projectilespeed;184 orxonox::Vector3 distance = targetposition - myposition;185 float a = distance.squaredLength();186 float b = 2 * (distance.x + distance.y + distance.z) * (targetvelocity.x + targetvelocity.y + targetvelocity.z);187 float c = targetvelocity.squaredLength();188 189 float temp = 4*squaredProjectilespeed*c + a*a - 4*b*c;190 if (temp < 0)191 return orxonox::Vector3::ZERO;192 193 temp = sqrt(temp);194 float time = (temp + a) / (2 * (squaredProjectilespeed - b));195 return (targetposition + targetvelocity * time);196 }197 198 unsigned long getUniqueNumber()199 {200 static unsigned long aNumber = 135;201 return aNumber++;202 }203 204 205 //////////////////////////206 // Conversion functions //207 //////////////////////////208 209 // std::string to Vector2210 bool ConverterFallback<std::string, orxonox::Vector2>::convert(orxonox::Vector2* output, const std::string& input)211 {212 size_t opening_parenthesis, closing_parenthesis = input.find(')');213 if ((opening_parenthesis = input.find('(')) == std::string::npos)214 opening_parenthesis = 0;215 else216 opening_parenthesis++;217 218 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),219 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');220 if (tokens.size() >= 2)221 {222 if (!ConvertValue(&(output->x), tokens[0]))223 return false;224 if (!ConvertValue(&(output->y), tokens[1]))225 return false;226 227 return true;228 }229 return false;230 }231 232 // std::string to Vector3233 bool ConverterFallback<std::string, orxonox::Vector3>::convert(orxonox::Vector3* output, const std::string& input)234 {235 size_t opening_parenthesis, closing_parenthesis = input.find(')');236 if ((opening_parenthesis = input.find('(')) == std::string::npos)237 opening_parenthesis = 0;238 else239 opening_parenthesis++;240 241 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),242 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');243 if (tokens.size() >= 3)244 {245 if (!ConvertValue(&(output->x), tokens[0]))246 return false;247 if (!ConvertValue(&(output->y), tokens[1]))248 return false;249 if (!ConvertValue(&(output->z), tokens[2]))250 return false;251 252 return true;253 }254 return false;255 }256 257 // std::string to Vector4258 bool ConverterFallback<std::string, orxonox::Vector4>::convert(orxonox::Vector4* output, const std::string& input)259 {260 size_t opening_parenthesis, closing_parenthesis = input.find(')');261 if ((opening_parenthesis = input.find('(')) == std::string::npos)262 opening_parenthesis = 0;263 else264 opening_parenthesis++;265 266 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),267 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');268 if (tokens.size() >= 4)269 {270 if (!ConvertValue(&(output->x), tokens[0]))271 return false;272 if (!ConvertValue(&(output->y), tokens[1]))273 return false;274 if (!ConvertValue(&(output->z), tokens[2]))275 return false;276 if (!ConvertValue(&(output->w), tokens[3]))277 return false;278 279 return true;280 }281 return false;282 }283 284 // std::string to Quaternion285 bool ConverterFallback<std::string, orxonox::Quaternion>::convert(orxonox::Quaternion* output, const std::string& input)286 {287 size_t opening_parenthesis, closing_parenthesis = input.find(')');288 if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }289 290 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');291 if (tokens.size() >= 4)292 {293 if (!ConvertValue(&(output->w), tokens[0]))294 return false;295 if (!ConvertValue(&(output->x), tokens[1]))296 return false;297 if (!ConvertValue(&(output->y), tokens[2]))298 return false;299 if (!ConvertValue(&(output->z), tokens[3]))300 return false;301 302 return true;303 }304 return false;305 }306 307 // std::string to ColourValue308 bool ConverterFallback<std::string, orxonox::ColourValue>::convert(orxonox::ColourValue* output, const std::string& input)309 {310 size_t opening_parenthesis, closing_parenthesis = input.find(')');311 if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }312 313 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');314 if (tokens.size() >= 3)315 {316 if (!ConvertValue(&(output->r), tokens[0]))317 return false;318 if (!ConvertValue(&(output->g), tokens[1]))319 return false;320 if (!ConvertValue(&(output->b), tokens[2]))321 return false;322 if (tokens.size() >= 4)323 {324 if (!ConvertValue(&(output->a), tokens[3]))325 return false;326 }327 else328 output->a = 1.0;329 330 return true;331 }332 return false;333 } -
code/trunk/src/util/Math.h
r2087 r2171 28 28 29 29 /** 30 @file Math.h30 @file 31 31 @brief Declaration and implementation of several math-functions, typedefs of some Ogre::Math classes to the orxonox namespace. 32 32 */ … … 39 39 #include <ostream> 40 40 #include <string> 41 #include <cmath> 41 42 #include <boost/static_assert.hpp> 42 43 … … 49 50 #include <OgreQuaternion.h> 50 51 #include <OgreColourValue.h> 51 52 namespace orxonox53 {54 typedef Ogre::Radian Radian;55 typedef Ogre::Degree Degree;56 typedef Ogre::Vector2 Vector2;57 typedef Ogre::Vector3 Vector3;58 typedef Ogre::Vector4 Vector4;59 typedef Ogre::Matrix3 Matrix3;60 typedef Ogre::Matrix4 Matrix4;61 typedef Ogre::Quaternion Quaternion;62 typedef Ogre::ColourValue ColourValue;63 }64 65 _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian);66 _UtilExport std::istream& operator>>(std::istream& in, orxonox::Radian& radian);67 _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree);68 _UtilExport std::istream& operator>>(std::istream& in, orxonox::Degree& degree);69 70 _UtilExport float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition);71 _UtilExport orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);72 _UtilExport orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);73 _UtilExport orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity);74 52 75 53 //Get around Windows hackery … … 83 61 #endif 84 62 85 /** 86 @brief Returns the sign of the given value. 87 @param x The value 88 @return 1 if the value is positive or zero, -1 if the value is negative 89 */ 90 template <typename T> 91 inline T sgn(T x) 63 namespace orxonox 92 64 { 93 return (x >= 0) ? 1 : -1; 65 typedef Ogre::Radian Radian; 66 typedef Ogre::Degree Degree; 67 typedef Ogre::Vector2 Vector2; 68 typedef Ogre::Vector3 Vector3; 69 typedef Ogre::Vector4 Vector4; 70 typedef Ogre::Matrix3 Matrix3; 71 typedef Ogre::Matrix4 Matrix4; 72 typedef Ogre::Quaternion Quaternion; 73 typedef Ogre::ColourValue ColourValue; 74 75 _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian); 76 _UtilExport std::istream& operator>>(std::istream& in, orxonox::Radian& radian); 77 _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree); 78 _UtilExport std::istream& operator>>(std::istream& in, orxonox::Degree& degree); 79 80 _UtilExport float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition); 81 _UtilExport orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition); 82 _UtilExport orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition); 83 _UtilExport orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity); 84 85 /** 86 @brief Returns the sign of the given value. 87 @param x The value 88 @return 1 if the value is positive or zero, -1 if the value is negative 89 */ 90 template <typename T> 91 inline T sgn(T x) 92 { 93 return (x >= 0) ? 1 : -1; 94 } 95 96 /** 97 @brief Returns the smaller of two values. 98 */ 99 template <typename T> 100 inline T min(T a, T b) 101 { 102 return (a <= b) ? a : b; 103 } 104 105 /** 106 @brief Returns the greater of two values. 107 */ 108 template <typename T> 109 inline T max(T a, T b) 110 { 111 return (a >= b) ? a : b; 112 } 113 114 /** 115 @brief Keeps a value between a lower and an upper limit. 116 @param x The value 117 @param min The lower limit 118 @param max The upper limit 119 */ 120 template <typename T> 121 inline T clamp(T x, T min, T max) 122 { 123 if (x < min) 124 return min; 125 126 if (x > max) 127 return max; 128 129 return x; 130 } 131 132 /** 133 @brief Returns the square value (x^2). 134 */ 135 template <typename T> 136 inline T square(T x) 137 { 138 return x*x; 139 } 140 141 /** 142 @brief Returns the cube value (x^3). 143 */ 144 template <typename T> 145 inline T cube(T x) 146 { 147 return x*x*x; 148 } 149 150 /** 151 @brief Rounds the value. 152 */ 153 template <typename T> 154 inline int round(T x) 155 { 156 return (int)(x + 0.5); 157 } 158 159 /** 160 @brief The modulo operation, enhanced to work properly with negative values. 161 @param x The value 162 @param max The operand 163 */ 164 template <typename T> 165 inline int mod(T x, int max) 166 { 167 if (x >= 0) 168 return (x % max); 169 else 170 return ((x % max) + max); 171 } 172 173 template <typename T> 174 inline T zeroise() 175 { 176 BOOST_STATIC_ASSERT(sizeof(T) == 0); 177 return T(); 178 } 179 180 template <> inline char zeroise<char>() { return 0; } 181 template <> inline unsigned char zeroise<unsigned char>() { return 0; } 182 template <> inline short zeroise<short>() { return 0; } 183 template <> inline unsigned short zeroise<unsigned short>() { return 0; } 184 template <> inline int zeroise<int>() { return 0; } 185 template <> inline unsigned int zeroise<unsigned int>() { return 0; } 186 template <> inline long zeroise<long>() { return 0; } 187 template <> inline unsigned long zeroise<unsigned long>() { return 0; } 188 template <> inline long long zeroise<long long>() { return 0; } 189 template <> inline unsigned long long zeroise<unsigned long long>() { return 0; } 190 template <> inline float zeroise<float>() { return 0; } 191 template <> inline double zeroise<double>() { return 0; } 192 template <> inline long double zeroise<long double>() { return 0; } 193 template <> inline bool zeroise<bool>() { return 0; } 194 template <> inline void* zeroise<void*>() { return 0; } 195 template <> inline std::string zeroise<std::string>() { return ""; } 196 template <> inline orxonox::Radian zeroise<orxonox::Radian>() { return orxonox::Radian(0.0f); } 197 template <> inline orxonox::Degree zeroise<orxonox::Degree>() { return orxonox::Degree(0.0f); } 198 template <> inline orxonox::Vector2 zeroise<orxonox::Vector2>() { return orxonox::Vector2 (0, 0) ; } 199 template <> inline orxonox::Vector3 zeroise<orxonox::Vector3>() { return orxonox::Vector3 (0, 0, 0) ; } 200 template <> inline orxonox::Vector4 zeroise<orxonox::Vector4>() { return orxonox::Vector4 (0, 0, 0, 0); } 201 template <> inline orxonox::ColourValue zeroise<orxonox::ColourValue>() { return orxonox::ColourValue(0, 0, 0, 0); } 202 template <> inline orxonox::Quaternion zeroise<orxonox::Quaternion>() { return orxonox::Quaternion (0, 0, 0, 0); } 203 204 /** 205 @brief Interpolates between two values for a time between 0 and 1. 206 @param time The time is a value between 0 and 1 - the function returns start if time is 0 and end if time is 1 and interpolates if time is between 0 and 1. 207 @param start The value at time = 0 208 @param end The value at time = 1 209 @return The interpolation at a given time 210 */ 211 template <typename T> 212 T interpolate(float time, const T& start, const T& end) 213 { 214 return time * (end - start) + start; 215 } 216 217 /** 218 @brief Interpolates smoothly between two values for a time between 0 and 1. The function starts slowly, increases faster and stops slowly again. 219 @param time The time is a value between 0 and 1 - the function returns start if time is 0 and end if time is 1 and interpolates if time is between 0 and 1. 220 @param start The value at time = 0 221 @param end The value at time = 1 222 @return The smoothed interpolation at a given time 223 */ 224 template <typename T> 225 T interpolateSmooth(float time, const T& start, const T& end) 226 { 227 return (-2 * (end - start) * cube(time)) + (3 * (end - start) * square(time)) + start; 228 } 229 230 /** 231 @brief Returns a random number between 0 and almost 1: 0 <= rnd < 1. 232 */ 233 inline float rnd() 234 { 235 return rand() / (RAND_MAX + 1.0); 236 } 237 238 /** 239 @brief Returns a random number between 0 and almost max: 0 <= rnd < max. 240 @param max The maximum 241 */ 242 inline float rnd(float max) 243 { 244 return rnd() * max; 245 } 246 247 /** 248 @brief Returns a random number between min and almost max: min <= rnd < max. 249 @param min The minimum 250 @param max The maximum 251 */ 252 inline float rnd(float min, float max) 253 { 254 return rnd(max - min) + min; 255 } 256 257 _UtilExport unsigned long getUniqueNumber(); 258 259 class IntVector2 260 { 261 public: 262 IntVector2() : x(0), y(0) { } 263 IntVector2(int _x, int _y) : x(_x), y(_y) { } 264 int x; 265 int y; 266 }; 267 268 class IntVector3 269 { 270 public: 271 IntVector3() : x(0), y(0), z(0) { } 272 IntVector3(int _x, int _y, int _z) : x(_x), y(_y), z(_z) { } 273 int x; 274 int y; 275 int z; 276 }; 94 277 } 95 278 96 /**97 @brief Returns the smaller of two values.98 */99 template <typename T>100 inline T min(T a, T b)101 {102 return (a <= b) ? a : b;103 }104 105 /**106 @brief Returns the greater of two values.107 */108 template <typename T>109 inline T max(T a, T b)110 {111 return (a >= b) ? a : b;112 }113 114 /**115 @brief Keeps a value between a lower and an upper limit.116 @param x The value117 @param min The lower limit118 @param max The upper limit119 */120 template <typename T>121 inline T clamp(T x, T min, T max)122 {123 if (x < min)124 return min;125 126 if (x > max)127 return max;128 129 return x;130 }131 132 /**133 @brief Returns the square value (x^2).134 */135 template <typename T>136 inline T square(T x)137 {138 return x*x;139 }140 141 /**142 @brief Returns the cube value (x^3).143 */144 template <typename T>145 inline T cube(T x)146 {147 return x*x*x;148 }149 150 /**151 @brief Rounds the value down.152 */153 template <typename T>154 inline int floor(T x)155 {156 return (int)(x);157 }158 159 /**160 @brief Rounds the value up.161 */162 template <typename T>163 inline int ceil(T x)164 {165 int temp = floor(x);166 return (temp != x) ? (temp + 1) : temp;167 }168 169 /**170 @brief Rounds the value.171 */172 template <typename T>173 inline int round(T x)174 {175 return (int)(x + 0.5);176 }177 178 /**179 @brief The modulo operation, enhanced to work properly with negative values.180 @param x The value181 @param max The operand182 */183 template <typename T>184 inline int mod(T x, int max)185 {186 if (x >= 0)187 return (x % max);188 else189 return ((x % max) + max);190 }191 192 template <typename T>193 inline T zeroise()194 {195 BOOST_STATIC_ASSERT(sizeof(T) == 0);196 return T();197 }198 199 template <> inline char zeroise<char>() { return 0; }200 template <> inline unsigned char zeroise<unsigned char>() { return 0; }201 template <> inline short zeroise<short>() { return 0; }202 template <> inline unsigned short zeroise<unsigned short>() { return 0; }203 template <> inline int zeroise<int>() { return 0; }204 template <> inline unsigned int zeroise<unsigned int>() { return 0; }205 template <> inline long zeroise<long>() { return 0; }206 template <> inline unsigned long zeroise<unsigned long>() { return 0; }207 template <> inline long long zeroise<long long>() { return 0; }208 template <> inline unsigned long long zeroise<unsigned long long>() { return 0; }209 template <> inline float zeroise<float>() { return 0; }210 template <> inline double zeroise<double>() { return 0; }211 template <> inline long double zeroise<long double>() { return 0; }212 template <> inline bool zeroise<bool>() { return 0; }213 template <> inline void* zeroise<void*>() { return 0; }214 template <> inline std::string zeroise<std::string>() { return ""; }215 template <> inline orxonox::Radian zeroise<orxonox::Radian>() { return orxonox::Radian(0.0f); }216 template <> inline orxonox::Degree zeroise<orxonox::Degree>() { return orxonox::Degree(0.0f); }217 template <> inline orxonox::Vector2 zeroise<orxonox::Vector2>() { return orxonox::Vector2 (0, 0) ; }218 template <> inline orxonox::Vector3 zeroise<orxonox::Vector3>() { return orxonox::Vector3 (0, 0, 0) ; }219 template <> inline orxonox::Vector4 zeroise<orxonox::Vector4>() { return orxonox::Vector4 (0, 0, 0, 0); }220 template <> inline orxonox::ColourValue zeroise<orxonox::ColourValue>() { return orxonox::ColourValue(0, 0, 0, 0); }221 template <> inline orxonox::Quaternion zeroise<orxonox::Quaternion>() { return orxonox::Quaternion (0, 0, 0, 0); }222 223 /**224 @brief Interpolates between two values for a time between 0 and 1.225 @param time The time is a value between 0 and 1 - the function returns start if time is 0 and end if time is 1 and interpolates if time is between 0 and 1.226 @param start The value at time = 0227 @param end The value at time = 1228 @return The interpolation at a given time229 */230 template <typename T>231 T interpolate(float time, const T& start, const T& end)232 {233 return time * (end - start) + start;234 }235 236 /**237 @brief Interpolates smoothly between two values for a time between 0 and 1. The function starts slowly, increases faster and stops slowly again.238 @param time The time is a value between 0 and 1 - the function returns start if time is 0 and end if time is 1 and interpolates if time is between 0 and 1.239 @param start The value at time = 0240 @param end The value at time = 1241 @return The smoothed interpolation at a given time242 */243 template <typename T>244 T interpolateSmooth(float time, const T& start, const T& end)245 {246 return (-2 * (end - start) * cube(time)) + (3 * (end - start) * square(time)) + start;247 }248 249 /**250 @brief Returns a random number between 0 and almost 1: 0 <= rnd < 1.251 */252 inline _UtilExport float rnd()253 {254 return rand() / (RAND_MAX + 1.0);255 }256 257 /**258 @brief Returns a random number between 0 and almost max: 0 <= rnd < max.259 @param max The maximum260 */261 inline _UtilExport float rnd(float max)262 {263 return rnd() * max;264 }265 266 /**267 @brief Returns a random number between min and almost max: min <= rnd < max.268 @param min The minimum269 @param max The maximum270 */271 inline _UtilExport float rnd(float min, float max)272 {273 return rnd(max - min) + min;274 }275 276 _UtilExport unsigned long getUniqueNumber();277 278 class _UtilExport IntVector2279 {280 public:281 IntVector2() : x(0), y(0) { }282 IntVector2(int _x, int _y) : x(_x), y(_y) { }283 int x;284 int y;285 };286 287 class _UtilExport IntVector3288 {289 public:290 IntVector3() : x(0), y(0), z(0) { }291 IntVector3(int _x, int _y, int _z) : x(_x), y(_y), z(_z) { }292 int x;293 int y;294 int z;295 };296 297 279 #endif /* _Util_Math_H__ */ -
code/trunk/src/util/MathConvert.h
r2087 r2171 40 40 #include "Convert.h" 41 41 42 43 //////////////////// 44 // Math to string // 45 //////////////////// 46 47 // Vector2 to std::string 48 template <> 49 struct ConverterExplicit<orxonox::Vector2, std::string> 42 namespace orxonox 50 43 { 51 static bool convert(std::string* output, const orxonox::Vector2& input) 52 { 53 std::ostringstream ostream; 54 if (ostream << input.x << "," << input.y) 55 { 56 (*output) = ostream.str(); 57 return true; 58 } 59 return false; 60 } 61 }; 62 63 // Vector3 to std::string 64 template <> 65 struct ConverterExplicit<orxonox::Vector3, std::string> 66 { 67 static bool convert(std::string* output, const orxonox::Vector3& input) 68 { 69 std::ostringstream ostream; 70 if (ostream << input.x << "," << input.y << "," << input.z) 71 { 72 (*output) = ostream.str(); 73 return true; 74 } 75 return false; 76 } 77 }; 78 79 // Vector4 to std::string 80 template <> 81 struct ConverterExplicit<orxonox::Vector4, std::string> 82 { 83 static bool convert(std::string* output, const orxonox::Vector4& input) 84 { 85 std::ostringstream ostream; 86 if (ostream << input.x << "," << input.y << "," << input.z << "," << input.w) 87 { 88 (*output) = ostream.str(); 89 return true; 90 } 91 return false; 92 } 93 }; 94 95 // Quaternion to std::string 96 template <> 97 struct ConverterExplicit<orxonox::Quaternion, std::string> 98 { 99 static bool convert(std::string* output, const orxonox::Quaternion& input) 100 { 101 std::ostringstream ostream; 102 if (ostream << input.w << "," << input.x << "," << input.y << "," << input.z) 103 { 104 (*output) = ostream.str(); 105 return true; 106 } 107 return false; 108 } 109 }; 110 111 // ColourValue to std::string 112 template <> 113 struct ConverterExplicit<orxonox::ColourValue, std::string> 114 { 115 static bool convert(std::string* output, const orxonox::ColourValue& input) 116 { 117 std::ostringstream ostream; 118 if (ostream << input.r << "," << input.g << "," << input.b << "," << input.a) 119 { 120 (*output) = ostream.str(); 121 return true; 122 } 123 return false; 124 } 125 }; 126 127 128 //////////////////// 129 // string to Math // 130 //////////////////// 131 132 // std::string to Vector2 133 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector2> 134 { static bool convert(orxonox::Vector2* output, const std::string& input); }; 135 // std::string to Vector3 136 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector3> 137 { static bool convert(orxonox::Vector3* output, const std::string& input); }; 138 // std::string to Vector4 139 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector4> 140 { static bool convert(orxonox::Vector4* output, const std::string& input); }; 141 // std::string to Quaternion 142 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Quaternion> 143 { static bool convert(orxonox::Quaternion* output, const std::string& input); }; 144 // std::string to ColourValue 145 template <> struct _UtilExport ConverterFallback<std::string, orxonox::ColourValue> 146 { static bool convert(orxonox::ColourValue* output, const std::string& input); }; 147 148 149 /////////////////////////////// 150 // From and to Radian/Degree // 151 /////////////////////////////// 152 153 // From Radian 154 template <class ToType> 155 struct ConverterFallback<orxonox::Radian, ToType> 156 { 157 static bool convert(ToType* output, const orxonox::Radian& input) 158 { 159 return convertValue<Ogre::Real, ToType>(output, input.valueRadians()); 160 } 161 }; 162 163 // From Degree 164 template <class ToType> 165 struct ConverterFallback<orxonox::Degree, ToType> 166 { 167 static bool convert(ToType* output, const orxonox::Degree& input) 168 { 169 return convertValue<Ogre::Real, ToType>(output, input.valueDegrees()); 170 } 171 }; 172 173 // To Radian 174 template <class FromType> 175 struct ConverterFallback<FromType, orxonox::Radian> 176 { 177 static bool convert(orxonox::Radian* output, const FromType& input) 178 { 179 float temp; 180 if (convertValue(&temp, input)) 181 { 182 *output = temp; 183 return true; 184 } 185 else 186 return false; 187 } 188 }; 189 190 // To Degree 191 template <class FromType> 192 struct ConverterFallback<FromType, orxonox::Degree> 193 { 194 static bool convert(orxonox::Degree* output, const FromType& input) 195 { 196 float temp; 197 if (convertValue(&temp, input)) 198 { 199 *output = temp; 200 return true; 201 } 202 else 203 return false; 204 } 205 }; 44 //////////////////// 45 // Math to string // 46 //////////////////// 47 48 // Vector2 to std::string 49 template <> 50 struct ConverterExplicit<orxonox::Vector2, std::string> 51 { 52 static bool convert(std::string* output, const orxonox::Vector2& input) 53 { 54 std::ostringstream ostream; 55 if (ostream << input.x << "," << input.y) 56 { 57 (*output) = ostream.str(); 58 return true; 59 } 60 return false; 61 } 62 }; 63 64 // Vector3 to std::string 65 template <> 66 struct ConverterExplicit<orxonox::Vector3, std::string> 67 { 68 static bool convert(std::string* output, const orxonox::Vector3& input) 69 { 70 std::ostringstream ostream; 71 if (ostream << input.x << "," << input.y << "," << input.z) 72 { 73 (*output) = ostream.str(); 74 return true; 75 } 76 return false; 77 } 78 }; 79 80 // Vector4 to std::string 81 template <> 82 struct ConverterExplicit<orxonox::Vector4, std::string> 83 { 84 static bool convert(std::string* output, const orxonox::Vector4& input) 85 { 86 std::ostringstream ostream; 87 if (ostream << input.x << "," << input.y << "," << input.z << "," << input.w) 88 { 89 (*output) = ostream.str(); 90 return true; 91 } 92 return false; 93 } 94 }; 95 96 // Quaternion to std::string 97 template <> 98 struct ConverterExplicit<orxonox::Quaternion, std::string> 99 { 100 static bool convert(std::string* output, const orxonox::Quaternion& input) 101 { 102 std::ostringstream ostream; 103 if (ostream << input.w << "," << input.x << "," << input.y << "," << input.z) 104 { 105 (*output) = ostream.str(); 106 return true; 107 } 108 return false; 109 } 110 }; 111 112 // ColourValue to std::string 113 template <> 114 struct ConverterExplicit<orxonox::ColourValue, std::string> 115 { 116 static bool convert(std::string* output, const orxonox::ColourValue& input) 117 { 118 std::ostringstream ostream; 119 if (ostream << input.r << "," << input.g << "," << input.b << "," << input.a) 120 { 121 (*output) = ostream.str(); 122 return true; 123 } 124 return false; 125 } 126 }; 127 128 129 //////////////////// 130 // string to Math // 131 //////////////////// 132 133 // std::string to Vector2 134 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector2> 135 { static bool convert(orxonox::Vector2* output, const std::string& input); }; 136 // std::string to Vector3 137 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector3> 138 { static bool convert(orxonox::Vector3* output, const std::string& input); }; 139 // std::string to Vector4 140 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector4> 141 { static bool convert(orxonox::Vector4* output, const std::string& input); }; 142 // std::string to Quaternion 143 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Quaternion> 144 { static bool convert(orxonox::Quaternion* output, const std::string& input); }; 145 // std::string to ColourValue 146 template <> struct _UtilExport ConverterFallback<std::string, orxonox::ColourValue> 147 { static bool convert(orxonox::ColourValue* output, const std::string& input); }; 148 149 150 /////////////////////////////// 151 // From and to Radian/Degree // 152 /////////////////////////////// 153 154 // From Radian 155 template <class ToType> 156 struct ConverterFallback<orxonox::Radian, ToType> 157 { 158 static bool convert(ToType* output, const orxonox::Radian& input) 159 { 160 return convertValue<Ogre::Real, ToType>(output, input.valueRadians()); 161 } 162 }; 163 164 // From Degree 165 template <class ToType> 166 struct ConverterFallback<orxonox::Degree, ToType> 167 { 168 static bool convert(ToType* output, const orxonox::Degree& input) 169 { 170 return convertValue<Ogre::Real, ToType>(output, input.valueDegrees()); 171 } 172 }; 173 174 // To Radian 175 template <class FromType> 176 struct ConverterFallback<FromType, orxonox::Radian> 177 { 178 static bool convert(orxonox::Radian* output, const FromType& input) 179 { 180 float temp; 181 if (convertValue(&temp, input)) 182 { 183 *output = temp; 184 return true; 185 } 186 else 187 return false; 188 } 189 }; 190 191 // To Degree 192 template <class FromType> 193 struct ConverterFallback<FromType, orxonox::Degree> 194 { 195 static bool convert(orxonox::Degree* output, const FromType& input) 196 { 197 float temp; 198 if (convertValue(&temp, input)) 199 { 200 *output = temp; 201 return true; 202 } 203 else 204 return false; 205 } 206 }; 207 } 206 208 207 209 #endif /* _MathConvert_H__ */ -
code/trunk/src/util/MultiType.cc
r2087 r2171 28 28 29 29 /** 30 @file MultiType.cc30 @file 31 31 @brief Implementation of the MultiType. 32 32 */ … … 35 35 #include "MultiTypeValue.h" 36 36 37 /** 38 @brief Converts the current value of the MultiType to a new type. 39 @param type The type 40 */ 41 bool MultiType::convert(MT_Type type) 37 namespace orxonox 42 38 { 43 switch (type) 39 /** 40 @brief Converts the current value of the MultiType to a new type. 41 @param type The type 42 */ 43 bool MultiType::convert(MT_Type type) 44 44 { 45 case MT_char: 46 return this->convert<char>(); break; 47 case MT_uchar: 48 return this->convert<unsigned char>(); break; 49 case MT_short: 50 return this->convert<short>(); break; 51 case MT_ushort: 52 return this->convert<unsigned short>(); break; 53 case MT_int: 54 return this->convert<int>(); break; 55 case MT_uint: 56 return this->convert<unsigned int>(); break; 57 case MT_long: 58 return this->convert<long>(); break; 59 case MT_ulong: 60 return this->convert<unsigned long>(); break; 61 case MT_longlong: 62 return this->convert<long long>(); break; 63 case MT_ulonglong: 64 return this->convert<unsigned long long>(); break; 65 case MT_float: 66 return this->convert<float>(); break; 67 case MT_double: 68 return this->convert<double>(); break; 69 case MT_longdouble: 70 return this->convert<long double>(); break; 71 case MT_bool: 72 return this->convert<bool>(); break; 73 case MT_void: 74 return this->convert<void*>(); break; 75 case MT_string: 76 return this->convert<std::string>(); break; 77 case MT_vector2: 78 return this->convert<orxonox::Vector2>(); break; 79 case MT_vector3: 80 return this->convert<orxonox::Vector3>(); break; 81 case MT_vector4: 82 return this->convert<orxonox::Vector4>(); break; 83 case MT_colourvalue: 84 return this->convert<orxonox::ColourValue>(); break; 85 case MT_quaternion: 86 return this->convert<orxonox::Quaternion>(); break; 87 case MT_radian: 88 return this->convert<orxonox::Radian>(); break; 89 case MT_degree: 90 return this->convert<orxonox::Degree>(); break; 91 default: 92 this->reset(); return false; break; 93 }; 45 switch (type) 46 { 47 case MT_char: 48 return this->convert<char>(); break; 49 case MT_uchar: 50 return this->convert<unsigned char>(); break; 51 case MT_short: 52 return this->convert<short>(); break; 53 case MT_ushort: 54 return this->convert<unsigned short>(); break; 55 case MT_int: 56 return this->convert<int>(); break; 57 case MT_uint: 58 return this->convert<unsigned int>(); break; 59 case MT_long: 60 return this->convert<long>(); break; 61 case MT_ulong: 62 return this->convert<unsigned long>(); break; 63 case MT_longlong: 64 return this->convert<long long>(); break; 65 case MT_ulonglong: 66 return this->convert<unsigned long long>(); break; 67 case MT_float: 68 return this->convert<float>(); break; 69 case MT_double: 70 return this->convert<double>(); break; 71 case MT_longdouble: 72 return this->convert<long double>(); break; 73 case MT_bool: 74 return this->convert<bool>(); break; 75 case MT_void: 76 return this->convert<void*>(); break; 77 case MT_string: 78 return this->convert<std::string>(); break; 79 case MT_vector2: 80 return this->convert<orxonox::Vector2>(); break; 81 case MT_vector3: 82 return this->convert<orxonox::Vector3>(); break; 83 case MT_vector4: 84 return this->convert<orxonox::Vector4>(); break; 85 case MT_colourvalue: 86 return this->convert<orxonox::ColourValue>(); break; 87 case MT_quaternion: 88 return this->convert<orxonox::Quaternion>(); break; 89 case MT_radian: 90 return this->convert<orxonox::Radian>(); break; 91 case MT_degree: 92 return this->convert<orxonox::Degree>(); break; 93 default: 94 this->reset(); return false; break; 95 }; 96 } 97 98 /** 99 @brief Returns the name of the current type. 100 @return The name 101 */ 102 std::string MultiType::getTypename() const 103 { 104 MT_Type type = (this->value_) ? this->value_->type_ : MT_null; 105 106 switch (type) 107 { 108 case MT_char: 109 return "char"; break; 110 case MT_uchar: 111 return "unsigned char"; break; 112 case MT_short: 113 return "short"; break; 114 case MT_ushort: 115 return "unsigned short"; break; 116 case MT_int: 117 return "int"; break; 118 case MT_uint: 119 return "unsigned int"; break; 120 case MT_long: 121 return "long"; break; 122 case MT_ulong: 123 return "unsigned long"; break; 124 case MT_longlong: 125 return "long long"; break; 126 case MT_ulonglong: 127 return "unsigned long long"; break; 128 case MT_float: 129 return "float"; break; 130 case MT_double: 131 return "double"; break; 132 case MT_longdouble: 133 return "long double"; break; 134 case MT_bool: 135 return "bool"; break; 136 case MT_void: 137 return "void*"; break; 138 case MT_string: 139 return "std::string"; break; 140 case MT_vector2: 141 return "orxonox::Vector2"; break; 142 case MT_vector3: 143 return "orxonox::Vector3"; break; 144 case MT_vector4: 145 return "orxonox::Vector4"; break; 146 case MT_colourvalue: 147 return "orxonox::ColourValue"; break; 148 case MT_quaternion: 149 return "orxonox::Quaternion"; break; 150 case MT_radian: 151 return "orxonox::Radian"; break; 152 case MT_degree: 153 return "orxonox::Degree"; break; 154 default: 155 return "unknown"; break; 156 }; 157 } 158 159 MultiType::operator char() const { return (this->value_) ? ((this->value_->type_ == MT_char ) ? ((MT_Value<char> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 160 MultiType::operator unsigned char() const { return (this->value_) ? ((this->value_->type_ == MT_uchar ) ? ((MT_Value<unsigned char> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 161 MultiType::operator short() const { return (this->value_) ? ((this->value_->type_ == MT_short ) ? ((MT_Value<short> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 162 MultiType::operator unsigned short() const { return (this->value_) ? ((this->value_->type_ == MT_ushort ) ? ((MT_Value<unsigned short> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 163 MultiType::operator int() const { return (this->value_) ? ((this->value_->type_ == MT_int ) ? ((MT_Value<int> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 164 MultiType::operator unsigned int() const { return (this->value_) ? ((this->value_->type_ == MT_uint ) ? ((MT_Value<unsigned int> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 165 MultiType::operator long() const { return (this->value_) ? ((this->value_->type_ == MT_long ) ? ((MT_Value<long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 166 MultiType::operator unsigned long() const { return (this->value_) ? ((this->value_->type_ == MT_ulong ) ? ((MT_Value<unsigned long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 167 MultiType::operator long long() const { return (this->value_) ? ((this->value_->type_ == MT_longlong ) ? ((MT_Value<long long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 168 MultiType::operator unsigned long long() const { return (this->value_) ? ((this->value_->type_ == MT_ulonglong ) ? ((MT_Value<unsigned long long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 169 MultiType::operator float() const { return (this->value_) ? ((this->value_->type_ == MT_float ) ? ((MT_Value<float> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 170 MultiType::operator double() const { return (this->value_) ? ((this->value_->type_ == MT_double ) ? ((MT_Value<double> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 171 MultiType::operator long double() const { return (this->value_) ? ((this->value_->type_ == MT_longdouble ) ? ((MT_Value<long double> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 172 MultiType::operator bool() const { return (this->value_) ? ((this->value_->type_ == MT_bool ) ? ((MT_Value<bool> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 173 MultiType::operator void*() const { return (this->value_) ? ((this->value_->type_ == MT_void ) ? ((MT_Value<void*> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 174 MultiType::operator std::string() const { return (this->value_) ? ((this->value_->type_ == MT_string ) ? ((MT_Value<std::string> *)this->value_)->value_ : (*this->value_)) : zeroise<std::string>(); } /** @brief Returns the current value, converted to the requested type. */ 175 MultiType::operator orxonox::Vector2() const { return (this->value_) ? ((this->value_->type_ == MT_vector2 ) ? ((MT_Value<orxonox::Vector2> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Vector2>(); } /** @brief Returns the current value, converted to the requested type. */ 176 MultiType::operator orxonox::Vector3() const { return (this->value_) ? ((this->value_->type_ == MT_vector3 ) ? ((MT_Value<orxonox::Vector3> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Vector3>(); } /** @brief Returns the current value, converted to the requested type. */ 177 MultiType::operator orxonox::Vector4() const { return (this->value_) ? ((this->value_->type_ == MT_vector4 ) ? ((MT_Value<orxonox::Vector4> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Vector4>(); } /** @brief Returns the current value, converted to the requested type. */ 178 MultiType::operator orxonox::ColourValue() const { return (this->value_) ? ((this->value_->type_ == MT_colourvalue) ? ((MT_Value<orxonox::ColourValue>*)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::ColourValue>(); } /** @brief Returns the current value, converted to the requested type. */ 179 MultiType::operator orxonox::Quaternion() const { return (this->value_) ? ((this->value_->type_ == MT_quaternion ) ? ((MT_Value<orxonox::Quaternion> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Quaternion>(); } /** @brief Returns the current value, converted to the requested type. */ 180 MultiType::operator orxonox::Radian() const { return (this->value_) ? ((this->value_->type_ == MT_radian ) ? ((MT_Value<orxonox::Radian> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Radian>(); } /** @brief Returns the current value, converted to the requested type. */ 181 MultiType::operator orxonox::Degree() const { return (this->value_) ? ((this->value_->type_ == MT_degree ) ? ((MT_Value<orxonox::Degree> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Degree>(); } /** @brief Returns the current value, converted to the requested type. */ 182 183 template <> void MultiType::createNewValueContainer(const char& value) { this->value_ = new MT_Value<char> (value, MT_char ); } /** @brief Creates a new value container for the given type. */ 184 template <> void MultiType::createNewValueContainer(const unsigned char& value) { this->value_ = new MT_Value<unsigned char> (value, MT_uchar ); } /** @brief Creates a new value container for the given type. */ 185 template <> void MultiType::createNewValueContainer(const short& value) { this->value_ = new MT_Value<short> (value, MT_short ); } /** @brief Creates a new value container for the given type. */ 186 template <> void MultiType::createNewValueContainer(const unsigned short& value) { this->value_ = new MT_Value<unsigned short> (value, MT_ushort ); } /** @brief Creates a new value container for the given type. */ 187 template <> void MultiType::createNewValueContainer(const int& value) { this->value_ = new MT_Value<int> (value, MT_int ); } /** @brief Creates a new value container for the given type. */ 188 template <> void MultiType::createNewValueContainer(const unsigned int& value) { this->value_ = new MT_Value<unsigned int> (value, MT_uint ); } /** @brief Creates a new value container for the given type. */ 189 template <> void MultiType::createNewValueContainer(const long& value) { this->value_ = new MT_Value<long> (value, MT_long ); } /** @brief Creates a new value container for the given type. */ 190 template <> void MultiType::createNewValueContainer(const unsigned long& value) { this->value_ = new MT_Value<unsigned long> (value, MT_ulong ); } /** @brief Creates a new value container for the given type. */ 191 template <> void MultiType::createNewValueContainer(const long long& value) { this->value_ = new MT_Value<long long> (value, MT_longlong ); } /** @brief Creates a new value container for the given type. */ 192 template <> void MultiType::createNewValueContainer(const unsigned long long& value) { this->value_ = new MT_Value<unsigned long long> (value, MT_ulonglong ); } /** @brief Creates a new value container for the given type. */ 193 template <> void MultiType::createNewValueContainer(const float& value) { this->value_ = new MT_Value<float> (value, MT_float ); } /** @brief Creates a new value container for the given type. */ 194 template <> void MultiType::createNewValueContainer(const double& value) { this->value_ = new MT_Value<double> (value, MT_double ); } /** @brief Creates a new value container for the given type. */ 195 template <> void MultiType::createNewValueContainer(const long double& value) { this->value_ = new MT_Value<long double> (value, MT_longdouble ); } /** @brief Creates a new value container for the given type. */ 196 template <> void MultiType::createNewValueContainer(const bool& value) { this->value_ = new MT_Value<bool> (value, MT_bool ); } /** @brief Creates a new value container for the given type. */ 197 template <> void MultiType::createNewValueContainer( void* const& value) { this->value_ = new MT_Value<void*> (value, MT_void ); } /** @brief Creates a new value container for the given type. */ 198 template <> void MultiType::createNewValueContainer(const std::string& value) { this->value_ = new MT_Value<std::string> (value, MT_string ); } /** @brief Creates a new value container for the given type. */ 199 template <> void MultiType::createNewValueContainer(const orxonox::Vector2& value) { this->value_ = new MT_Value<orxonox::Vector2> (value, MT_vector2 ); } /** @brief Creates a new value container for the given type. */ 200 template <> void MultiType::createNewValueContainer(const orxonox::Vector3& value) { this->value_ = new MT_Value<orxonox::Vector3> (value, MT_vector3 ); } /** @brief Creates a new value container for the given type. */ 201 template <> void MultiType::createNewValueContainer(const orxonox::Vector4& value) { this->value_ = new MT_Value<orxonox::Vector4> (value, MT_vector4 ); } /** @brief Creates a new value container for the given type. */ 202 template <> void MultiType::createNewValueContainer(const orxonox::ColourValue& value) { this->value_ = new MT_Value<orxonox::ColourValue>(value, MT_colourvalue); } /** @brief Creates a new value container for the given type. */ 203 template <> void MultiType::createNewValueContainer(const orxonox::Quaternion& value) { this->value_ = new MT_Value<orxonox::Quaternion> (value, MT_quaternion ); } /** @brief Creates a new value container for the given type. */ 204 template <> void MultiType::createNewValueContainer(const orxonox::Radian& value) { this->value_ = new MT_Value<orxonox::Radian> (value, MT_radian ); } /** @brief Creates a new value container for the given type. */ 205 template <> void MultiType::createNewValueContainer(const orxonox::Degree& value) { this->value_ = new MT_Value<orxonox::Degree> (value, MT_degree ); } /** @brief Creates a new value container for the given type. */ 94 206 } 95 96 /**97 @brief Returns the name of the current type.98 @return The name99 */100 std::string MultiType::getTypename() const101 {102 MT_Type type = (this->value_) ? this->value_->type_ : MT_null;103 104 switch (type)105 {106 case MT_char:107 return "char"; break;108 case MT_uchar:109 return "unsigned char"; break;110 case MT_short:111 return "short"; break;112 case MT_ushort:113 return "unsigned short"; break;114 case MT_int:115 return "int"; break;116 case MT_uint:117 return "unsigned int"; break;118 case MT_long:119 return "long"; break;120 case MT_ulong:121 return "unsigned long"; break;122 case MT_longlong:123 return "long long"; break;124 case MT_ulonglong:125 return "unsigned long long"; break;126 case MT_float:127 return "float"; break;128 case MT_double:129 return "double"; break;130 case MT_longdouble:131 return "long double"; break;132 case MT_bool:133 return "bool"; break;134 case MT_void:135 return "void*"; break;136 case MT_string:137 return "std::string"; break;138 case MT_vector2:139 return "orxonox::Vector2"; break;140 case MT_vector3:141 return "orxonox::Vector3"; break;142 case MT_vector4:143 return "orxonox::Vector4"; break;144 case MT_colourvalue:145 return "orxonox::ColourValue"; break;146 case MT_quaternion:147 return "orxonox::Quaternion"; break;148 case MT_radian:149 return "orxonox::Radian"; break;150 case MT_degree:151 return "orxonox::Degree"; break;152 default:153 return "unknown"; break;154 };155 }156 157 MultiType::operator char() const { return (this->value_) ? ((this->value_->type_ == MT_char ) ? ((MT_Value<char> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */158 MultiType::operator unsigned char() const { return (this->value_) ? ((this->value_->type_ == MT_uchar ) ? ((MT_Value<unsigned char> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */159 MultiType::operator short() const { return (this->value_) ? ((this->value_->type_ == MT_short ) ? ((MT_Value<short> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */160 MultiType::operator unsigned short() const { return (this->value_) ? ((this->value_->type_ == MT_ushort ) ? ((MT_Value<unsigned short> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */161 MultiType::operator int() const { return (this->value_) ? ((this->value_->type_ == MT_int ) ? ((MT_Value<int> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */162 MultiType::operator unsigned int() const { return (this->value_) ? ((this->value_->type_ == MT_uint ) ? ((MT_Value<unsigned int> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */163 MultiType::operator long() const { return (this->value_) ? ((this->value_->type_ == MT_long ) ? ((MT_Value<long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */164 MultiType::operator unsigned long() const { return (this->value_) ? ((this->value_->type_ == MT_ulong ) ? ((MT_Value<unsigned long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */165 MultiType::operator long long() const { return (this->value_) ? ((this->value_->type_ == MT_longlong ) ? ((MT_Value<long long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */166 MultiType::operator unsigned long long() const { return (this->value_) ? ((this->value_->type_ == MT_ulonglong ) ? ((MT_Value<unsigned long long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */167 MultiType::operator float() const { return (this->value_) ? ((this->value_->type_ == MT_float ) ? ((MT_Value<float> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */168 MultiType::operator double() const { return (this->value_) ? ((this->value_->type_ == MT_double ) ? ((MT_Value<double> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */169 MultiType::operator long double() const { return (this->value_) ? ((this->value_->type_ == MT_longdouble ) ? ((MT_Value<long double> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */170 MultiType::operator bool() const { return (this->value_) ? ((this->value_->type_ == MT_bool ) ? ((MT_Value<bool> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */171 MultiType::operator void*() const { return (this->value_) ? ((this->value_->type_ == MT_void ) ? ((MT_Value<void*> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */172 MultiType::operator std::string() const { return (this->value_) ? ((this->value_->type_ == MT_string ) ? ((MT_Value<std::string> *)this->value_)->value_ : (*this->value_)) : zeroise<std::string>(); } /** @brief Returns the current value, converted to the requested type. */173 MultiType::operator orxonox::Vector2() const { return (this->value_) ? ((this->value_->type_ == MT_vector2 ) ? ((MT_Value<orxonox::Vector2> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Vector2>(); } /** @brief Returns the current value, converted to the requested type. */174 MultiType::operator orxonox::Vector3() const { return (this->value_) ? ((this->value_->type_ == MT_vector3 ) ? ((MT_Value<orxonox::Vector3> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Vector3>(); } /** @brief Returns the current value, converted to the requested type. */175 MultiType::operator orxonox::Vector4() const { return (this->value_) ? ((this->value_->type_ == MT_vector4 ) ? ((MT_Value<orxonox::Vector4> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Vector4>(); } /** @brief Returns the current value, converted to the requested type. */176 MultiType::operator orxonox::ColourValue() const { return (this->value_) ? ((this->value_->type_ == MT_colourvalue) ? ((MT_Value<orxonox::ColourValue>*)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::ColourValue>(); } /** @brief Returns the current value, converted to the requested type. */177 MultiType::operator orxonox::Quaternion() const { return (this->value_) ? ((this->value_->type_ == MT_quaternion ) ? ((MT_Value<orxonox::Quaternion> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Quaternion>(); } /** @brief Returns the current value, converted to the requested type. */178 MultiType::operator orxonox::Radian() const { return (this->value_) ? ((this->value_->type_ == MT_radian ) ? ((MT_Value<orxonox::Radian> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Radian>(); } /** @brief Returns the current value, converted to the requested type. */179 MultiType::operator orxonox::Degree() const { return (this->value_) ? ((this->value_->type_ == MT_degree ) ? ((MT_Value<orxonox::Degree> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Degree>(); } /** @brief Returns the current value, converted to the requested type. */180 181 template <> void MultiType::createNewValueContainer(const char& value) { this->value_ = new MT_Value<char> (value, MT_char ); } /** @brief Creates a new value container for the given type. */182 template <> void MultiType::createNewValueContainer(const unsigned char& value) { this->value_ = new MT_Value<unsigned char> (value, MT_uchar ); } /** @brief Creates a new value container for the given type. */183 template <> void MultiType::createNewValueContainer(const short& value) { this->value_ = new MT_Value<short> (value, MT_short ); } /** @brief Creates a new value container for the given type. */184 template <> void MultiType::createNewValueContainer(const unsigned short& value) { this->value_ = new MT_Value<unsigned short> (value, MT_ushort ); } /** @brief Creates a new value container for the given type. */185 template <> void MultiType::createNewValueContainer(const int& value) { this->value_ = new MT_Value<int> (value, MT_int ); } /** @brief Creates a new value container for the given type. */186 template <> void MultiType::createNewValueContainer(const unsigned int& value) { this->value_ = new MT_Value<unsigned int> (value, MT_uint ); } /** @brief Creates a new value container for the given type. */187 template <> void MultiType::createNewValueContainer(const long& value) { this->value_ = new MT_Value<long> (value, MT_long ); } /** @brief Creates a new value container for the given type. */188 template <> void MultiType::createNewValueContainer(const unsigned long& value) { this->value_ = new MT_Value<unsigned long> (value, MT_ulong ); } /** @brief Creates a new value container for the given type. */189 template <> void MultiType::createNewValueContainer(const long long& value) { this->value_ = new MT_Value<long long> (value, MT_longlong ); } /** @brief Creates a new value container for the given type. */190 template <> void MultiType::createNewValueContainer(const unsigned long long& value) { this->value_ = new MT_Value<unsigned long long> (value, MT_ulonglong ); } /** @brief Creates a new value container for the given type. */191 template <> void MultiType::createNewValueContainer(const float& value) { this->value_ = new MT_Value<float> (value, MT_float ); } /** @brief Creates a new value container for the given type. */192 template <> void MultiType::createNewValueContainer(const double& value) { this->value_ = new MT_Value<double> (value, MT_double ); } /** @brief Creates a new value container for the given type. */193 template <> void MultiType::createNewValueContainer(const long double& value) { this->value_ = new MT_Value<long double> (value, MT_longdouble ); } /** @brief Creates a new value container for the given type. */194 template <> void MultiType::createNewValueContainer(const bool& value) { this->value_ = new MT_Value<bool> (value, MT_bool ); } /** @brief Creates a new value container for the given type. */195 template <> void MultiType::createNewValueContainer( void* const& value) { this->value_ = new MT_Value<void*> (value, MT_void ); } /** @brief Creates a new value container for the given type. */196 template <> void MultiType::createNewValueContainer(const std::string& value) { this->value_ = new MT_Value<std::string> (value, MT_string ); } /** @brief Creates a new value container for the given type. */197 template <> void MultiType::createNewValueContainer(const orxonox::Vector2& value) { this->value_ = new MT_Value<orxonox::Vector2> (value, MT_vector2 ); } /** @brief Creates a new value container for the given type. */198 template <> void MultiType::createNewValueContainer(const orxonox::Vector3& value) { this->value_ = new MT_Value<orxonox::Vector3> (value, MT_vector3 ); } /** @brief Creates a new value container for the given type. */199 template <> void MultiType::createNewValueContainer(const orxonox::Vector4& value) { this->value_ = new MT_Value<orxonox::Vector4> (value, MT_vector4 ); } /** @brief Creates a new value container for the given type. */200 template <> void MultiType::createNewValueContainer(const orxonox::ColourValue& value) { this->value_ = new MT_Value<orxonox::ColourValue>(value, MT_colourvalue); } /** @brief Creates a new value container for the given type. */201 template <> void MultiType::createNewValueContainer(const orxonox::Quaternion& value) { this->value_ = new MT_Value<orxonox::Quaternion> (value, MT_quaternion ); } /** @brief Creates a new value container for the given type. */202 template <> void MultiType::createNewValueContainer(const orxonox::Radian& value) { this->value_ = new MT_Value<orxonox::Radian> (value, MT_radian ); } /** @brief Creates a new value container for the given type. */203 template <> void MultiType::createNewValueContainer(const orxonox::Degree& value) { this->value_ = new MT_Value<orxonox::Degree> (value, MT_degree ); } /** @brief Creates a new value container for the given type. */ -
code/trunk/src/util/MultiType.h
r2087 r2171 28 28 29 29 /** 30 @file MultiType.h30 @file 31 31 @brief Declaration of the MultiType and some helper constructs. 32 32 … … 73 73 #include "Math.h" 74 74 75 /** 76 @brief Enum of all possible types of a MultiType. 77 */ 78 enum MT_Type 75 namespace orxonox 79 76 { 80 MT_null,81 MT_char,82 MT_uchar,83 MT_short,84 MT_ushort,85 MT_int,86 MT_uint,87 MT_long,88 MT_ulong,89 MT_longlong,90 MT_ulonglong,91 MT_float,92 MT_double,93 MT_longdouble,94 MT_bool,95 MT_void,96 MT_string,97 MT_vector2,98 MT_vector3,99 MT_vector4,100 MT_colourvalue,101 MT_quaternion,102 MT_radian,103 MT_degree104 };105 106 /**107 @brief The MultiType can hold a value of many possible types and convert them to other types.108 109 The following types are supported by the MultiType:110 - all primitves111 - all pointers112 - string113 - Vector2, Vector3, Vector4114 - Quaternion115 - ColourValue116 - Radian, Degree117 118 The internal type of a MultiType is determined by the first assigned value, but can be119 changed by using setType<T>(), convert<T>() or setValue<T>(value). If a value gets assigned120 the normal way (operator=, setValue(value)), the value gets converted to the current internal121 type of the MultiType.122 */123 class _UtilExport MultiType124 {125 _UtilExport friend std::ostream& operator<<(std::ostream& outstream, const MultiType& mt);126 template <typename T> friend struct MT_Value;127 128 77 /** 129 @brief MT_ValueBase is an almost pure virtual baseclass of MT_Value<T>, which holds the value of the MultiType. 130 This class is only used within the MultiType. 78 @brief Enum of all possible types of a MultiType. 131 79 */ 132 struct _UtilExport MT_ValueBase80 enum MT_Type 133 81 { 134 MT_ValueBase(MT_Type type) : type_(type), bHasDefaultValue_(false) {} 135 virtual ~MT_ValueBase() {} 136 137 virtual MT_ValueBase* clone() const = 0; 138 139 virtual void reset() = 0; 140 virtual bool assimilate(const MultiType& other) = 0; 141 142 /** @brief Returns the type of the current value. */ 143 const MT_Type& getType() const { return this->type_; } 144 145 /** @brief Checks whether the value is a default one. */ 146 bool hasDefaultValue() const { return this->bHasDefaultValue_; } 147 148 virtual bool setValue(const char& value) = 0; 149 virtual bool setValue(const unsigned char& value) = 0; 150 virtual bool setValue(const short& value) = 0; 151 virtual bool setValue(const unsigned short& value) = 0; 152 virtual bool setValue(const int& value) = 0; 153 virtual bool setValue(const unsigned int& value) = 0; 154 virtual bool setValue(const long& value) = 0; 155 virtual bool setValue(const unsigned long& value) = 0; 156 virtual bool setValue(const long long& value) = 0; 157 virtual bool setValue(const unsigned long long& value) = 0; 158 virtual bool setValue(const float& value) = 0; 159 virtual bool setValue(const double& value) = 0; 160 virtual bool setValue(const long double& value) = 0; 161 virtual bool setValue(const bool& value) = 0; 162 virtual bool setValue( void* const& value) = 0; 163 virtual bool setValue(const std::string& value) = 0; 164 virtual bool setValue(const orxonox::Vector2& value) = 0; 165 virtual bool setValue(const orxonox::Vector3& value) = 0; 166 virtual bool setValue(const orxonox::Vector4& value) = 0; 167 virtual bool setValue(const orxonox::ColourValue& value) = 0; 168 virtual bool setValue(const orxonox::Quaternion& value) = 0; 169 virtual bool setValue(const orxonox::Radian& value) = 0; 170 virtual bool setValue(const orxonox::Degree& value) = 0; 171 172 virtual bool getValue(char* value) const = 0; 173 virtual bool getValue(unsigned char* value) const = 0; 174 virtual bool getValue(short* value) const = 0; 175 virtual bool getValue(unsigned short* value) const = 0; 176 virtual bool getValue(int* value) const = 0; 177 virtual bool getValue(unsigned int* value) const = 0; 178 virtual bool getValue(long* value) const = 0; 179 virtual bool getValue(unsigned long* value) const = 0; 180 virtual bool getValue(long long* value) const = 0; 181 virtual bool getValue(unsigned long long* value) const = 0; 182 virtual bool getValue(float* value) const = 0; 183 virtual bool getValue(double* value) const = 0; 184 virtual bool getValue(long double* value) const = 0; 185 virtual bool getValue(bool* value) const = 0; 186 virtual bool getValue(void** value) const = 0; 187 virtual bool getValue(std::string* value) const = 0; 188 virtual bool getValue(orxonox::Vector2* value) const = 0; 189 virtual bool getValue(orxonox::Vector3* value) const = 0; 190 virtual bool getValue(orxonox::Vector4* value) const = 0; 191 virtual bool getValue(orxonox::ColourValue* value) const = 0; 192 virtual bool getValue(orxonox::Quaternion* value) const = 0; 193 virtual bool getValue(orxonox::Radian* value) const = 0; 194 virtual bool getValue(orxonox::Degree* value) const = 0; 195 196 virtual operator char() const = 0; 197 virtual operator unsigned char() const = 0; 198 virtual operator short() const = 0; 199 virtual operator unsigned short() const = 0; 200 virtual operator int() const = 0; 201 virtual operator unsigned int() const = 0; 202 virtual operator long() const = 0; 203 virtual operator unsigned long() const = 0; 204 virtual operator long long() const = 0; 205 virtual operator unsigned long long() const = 0; 206 virtual operator float() const = 0; 207 virtual operator double() const = 0; 208 virtual operator long double() const = 0; 209 virtual operator bool() const = 0; 210 virtual operator void*() const = 0; 211 virtual operator std::string() const = 0; 212 virtual operator orxonox::Vector2() const = 0; 213 virtual operator orxonox::Vector3() const = 0; 214 virtual operator orxonox::Vector4() const = 0; 215 virtual operator orxonox::ColourValue() const = 0; 216 virtual operator orxonox::Quaternion() const = 0; 217 virtual operator orxonox::Radian() const = 0; 218 virtual operator orxonox::Degree() const = 0; 219 220 virtual void toString(std::ostream& outstream) const = 0; 221 222 MT_Type type_; //!< The type of the current value 223 bool bHasDefaultValue_; //!< True if the last conversion wasn't successful 82 MT_null, 83 MT_char, 84 MT_uchar, 85 MT_short, 86 MT_ushort, 87 MT_int, 88 MT_uint, 89 MT_long, 90 MT_ulong, 91 MT_longlong, 92 MT_ulonglong, 93 MT_float, 94 MT_double, 95 MT_longdouble, 96 MT_bool, 97 MT_void, 98 MT_string, 99 MT_vector2, 100 MT_vector3, 101 MT_vector4, 102 MT_colourvalue, 103 MT_quaternion, 104 MT_radian, 105 MT_degree 224 106 }; 225 107 108 /** 109 @brief The MultiType can hold a value of many possible types and convert them to other types. 110 111 The following types are supported by the MultiType: 112 - all primitves 113 - all pointers 114 - string 115 - Vector2, Vector3, Vector4 116 - Quaternion 117 - ColourValue 118 - Radian, Degree 119 120 The internal type of a MultiType is determined by the first assigned value, but can be 121 changed by using setType<T>(), convert<T>() or setValue<T>(value). If a value gets assigned 122 the normal way (operator=, setValue(value)), the value gets converted to the current internal 123 type of the MultiType. 124 */ 125 class _UtilExport MultiType 126 { 127 _UtilExport friend std::ostream& operator<<(std::ostream& outstream, const MultiType& mt); 128 template <typename T> friend class MT_Value; 129 226 130 public: 227 inline MultiType() : value_(0) {} /** @brief Default constructor: Assigns no value and no type. The type will be determined by the first assignment of a value. */ 228 inline MultiType(const char& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 229 inline MultiType(const unsigned char& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 230 inline MultiType(const short& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 231 inline MultiType(const unsigned short& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 232 inline MultiType(const int& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 233 inline MultiType(const unsigned int& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 234 inline MultiType(const long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 235 inline MultiType(const unsigned long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 236 inline MultiType(const long long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 237 inline MultiType(const unsigned long long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 238 inline MultiType(const float& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 239 inline MultiType(const double& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 240 inline MultiType(const long double& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 241 inline MultiType(const bool& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 242 inline MultiType( void* const& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 243 inline MultiType(const std::string& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 244 inline MultiType(const orxonox::Vector2& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 245 inline MultiType(const orxonox::Vector3& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 246 inline MultiType(const orxonox::Vector4& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 247 inline MultiType(const orxonox::ColourValue& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 248 inline MultiType(const orxonox::Quaternion& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 249 inline MultiType(const orxonox::Radian& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 250 inline MultiType(const orxonox::Degree& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 251 inline MultiType(const char* value) : value_(0) { this->setValue(std::string(value)); } /** @brief Constructor: Converts the char array to a std::string, assigns the value and sets the type. */ 252 inline MultiType(const MultiType& other) : value_(0) { this->setValue(other); } /** @brief Copyconstructor: Assigns value and type of the other MultiType. */ 253 inline MultiType(MT_Type type) : value_(0) { this->setType(type); } /** @brief Constructor: Sets the type, the next assignment will determine the value. */ 254 255 /** @brief Destructor: Deletes the MT_Value. */ 256 inline ~MultiType() { if (this->value_) { delete this->value_; } } 257 258 template <typename V> inline const MultiType& operator=(const V& value) { this->setValue(value); return (*this); } /** @brief Assigns a new value. The value will be converted to the current type of the MultiType. */ 259 template <typename V> inline const MultiType& operator=(V* value) { this->setValue(value); return (*this); } /** @brief Assigns a pointer. */ 260 inline const MultiType& operator=(const MultiType& other) { this->setValue(other); return (*this); } /** @brief Assigns the value of the other MultiType and converts it to the current type of the MultiType. */ 261 inline const MultiType& operator=(MT_Type type) { this->setType(type); return (*this); } /** @brief Resets the value and changes the type. */ 262 263 inline bool setValue(const char& value); 264 inline bool setValue(const unsigned char& value); 265 inline bool setValue(const short& value); 266 inline bool setValue(const unsigned short& value); 267 inline bool setValue(const int& value); 268 inline bool setValue(const unsigned int& value); 269 inline bool setValue(const long& value); 270 inline bool setValue(const unsigned long& value); 271 inline bool setValue(const long long& value); 272 inline bool setValue(const unsigned long long& value); 273 inline bool setValue(const float& value); 274 inline bool setValue(const double& value); 275 inline bool setValue(const long double& value); 276 inline bool setValue(const bool& value); 277 inline bool setValue( void* const& value); 278 inline bool setValue(const std::string& value); 279 inline bool setValue(const orxonox::Vector2& value); 280 inline bool setValue(const orxonox::Vector3& value); 281 inline bool setValue(const orxonox::Vector4& value); 282 inline bool setValue(const orxonox::ColourValue& value); 283 inline bool setValue(const orxonox::Quaternion& value); 284 inline bool setValue(const orxonox::Radian& value); 285 inline bool setValue(const orxonox::Degree& value); 286 inline bool setValue(const char* value); 287 /** @brief Assigns a pointer. */ 288 template <typename V> inline bool setValue(V* value) { if (this->value_) { return this->value_->setValue((void*)value); } else { return this->assignValue((void*)value); } } 289 /** @brief Assigns the value of the other MultiType and converts it to the current type. */ 290 bool setValue(const MultiType& other) { if (this->value_) { return this->value_->assimilate(other); } else { if (other.value_) { this->value_ = other.value_->clone(); } return true; } } 291 /** @brief Changes the type to T and assigns the new value (which might be of another type than T - it gets converted). */ 292 template <typename T, typename V> inline bool setValue(const V& value) { this->setType<T>(); return this->setValue(value); } 293 294 295 /** @brief Copies the other MultiType by assigning value and type. */ 296 inline void copy(const MultiType& other) { if (this == &other) { return; } if (this->value_) { delete this->value_; } this->value_ = (other.value_) ? other.value_->clone() : 0; } 297 298 template <typename T> inline bool convert() { return this->setValue<T>((T)(*this)); } /** @brief Converts the current value to type T. */ 299 inline bool convert(const MultiType& other) { return this->convert(other.getType()); } /** @brief Converts the current value to the type of the other MultiType. */ 300 bool convert(MT_Type type); 301 302 /** @brief Current content gets deleted. New type is MT_null */ 303 inline void reset() { if (this->value_) this->value_->reset(); } 304 305 template <typename T> inline void setType() { this->assignValue(T()); } /** @brief Resets the value and changes the internal type to T. */ 306 inline void setType(const MultiType& other) { this->setType(other.getType()); } /** @brief Resets the value and changes the internal type to the type of the other MultiType. */ 307 inline void setType(MT_Type type) { this->reset(); this->convert(type); this->reset(); } /** @brief Resets the value and changes the internal type to the given type. */ 308 309 /** @brief Returns the current type. */ 310 inline MT_Type getType() const { return (this->value_) ? this->value_->type_ : MT_null; } 311 /** @brief Returns true if the current type equals the given type. */ 312 inline bool isType(MT_Type type) const { return (this->value_) ? (this->value_->type_ == type) : (type == MT_null); } 313 /** @brief Returns true if the current type is T. */ 314 template <typename T> inline bool isType() const { return false; } // Only works for specialized values - see below 315 std::string getTypename() const; 316 317 /** @brief Checks whether the value is a default one. */ 318 bool hasDefaultValue() const { return this->value_->hasDefaultValue(); } 319 320 operator char() const; 321 operator unsigned char() const; 322 operator short() const; 323 operator unsigned short() const; 324 operator int() const; 325 operator unsigned int() const; 326 operator long() const; 327 operator unsigned long() const; 328 operator long long() const; 329 operator unsigned long long() const; 330 operator float() const; 331 operator double() const; 332 operator long double() const; 333 operator bool() const; 334 operator void*() const; 335 operator std::string() const; 336 operator orxonox::Vector2() const; 337 operator orxonox::Vector3() const; 338 operator orxonox::Vector4() const; 339 operator orxonox::ColourValue() const; 340 operator orxonox::Quaternion() const; 341 operator orxonox::Radian() const; 342 operator orxonox::Degree() const; 343 /** @brief Returns the current value, converted to a T* pointer. */ 344 template <class T> operator T*() const { return ((T*)this->operator void*()); } 345 346 inline bool getValue(char* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 347 inline bool getValue(unsigned char* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 348 inline bool getValue(short* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 349 inline bool getValue(unsigned short* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 350 inline bool getValue(int* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 351 inline bool getValue(unsigned int* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 352 inline bool getValue(long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 353 inline bool getValue(unsigned long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 354 inline bool getValue(long long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 355 inline bool getValue(unsigned long long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 356 inline bool getValue(float* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 357 inline bool getValue(double* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 358 inline bool getValue(long double* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 359 inline bool getValue(bool* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 360 inline bool getValue(void** value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 361 inline bool getValue(std::string* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 362 inline bool getValue(orxonox::Vector2* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 363 inline bool getValue(orxonox::Vector3* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 364 inline bool getValue(orxonox::Vector4* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 365 inline bool getValue(orxonox::ColourValue* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 366 inline bool getValue(orxonox::Quaternion* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 367 inline bool getValue(orxonox::Radian* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 368 inline bool getValue(orxonox::Degree* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 369 370 inline char getChar() const { return this->operator char(); } /** @brief Returns the current value, converted to the requested type. */ 371 inline unsigned char getUnsignedChar() const { return this->operator unsigned char(); } /** @brief Returns the current value, converted to the requested type. */ 372 inline short getShort() const { return this->operator short(); } /** @brief Returns the current value, converted to the requested type. */ 373 inline unsigned short getUnsignedShort() const { return this->operator unsigned short(); } /** @brief Returns the current value, converted to the requested type. */ 374 inline int getInt() const { return this->operator int(); } /** @brief Returns the current value, converted to the requested type. */ 375 inline unsigned int getUnsignedInt() const { return this->operator unsigned int(); } /** @brief Returns the current value, converted to the requested type. */ 376 inline long getLong() const { return this->operator long(); } /** @brief Returns the current value, converted to the requested type. */ 377 inline unsigned long getUnsignedLong() const { return this->operator unsigned long(); } /** @brief Returns the current value, converted to the requested type. */ 378 inline long long getLongLong() const { return this->operator long long(); } /** @brief Returns the current value, converted to the requested type. */ 379 inline unsigned long long getUnsignedLongLong() const { return this->operator unsigned long long(); } /** @brief Returns the current value, converted to the requested type. */ 380 inline float getFloat() const { return this->operator float(); } /** @brief Returns the current value, converted to the requested type. */ 381 inline double getDouble() const { return this->operator double(); } /** @brief Returns the current value, converted to the requested type. */ 382 inline long double getLongDouble() const { return this->operator long double(); } /** @brief Returns the current value, converted to the requested type. */ 383 inline bool getBool() const { return this->operator bool(); } /** @brief Returns the current value, converted to the requested type. */ 384 inline void* getVoid() const { return this->operator void*(); } /** @brief Returns the current value, converted to the requested type. */ 385 inline std::string getString() const { return this->operator std::string(); } /** @brief Returns the current value, converted to the requested type. */ 386 inline orxonox::Vector2 getVector2() const { return this->operator orxonox::Vector2(); } /** @brief Returns the current value, converted to the requested type. */ 387 inline orxonox::Vector3 getVector3() const { return this->operator orxonox::Vector3(); } /** @brief Returns the current value, converted to the requested type. */ 388 inline orxonox::Vector4 getVector4() const { return this->operator orxonox::Vector4(); } /** @brief Returns the current value, converted to the requested type. */ 389 inline orxonox::ColourValue getColourValue() const { return this->operator orxonox::ColourValue(); } /** @brief Returns the current value, converted to the requested type. */ 390 inline orxonox::Quaternion getQuaternion() const { return this->operator orxonox::Quaternion(); } /** @brief Returns the current value, converted to the requested type. */ 391 inline orxonox::Radian getRadian() const { return this->operator orxonox::Radian(); } /** @brief Returns the current value, converted to the requested type. */ 392 inline orxonox::Degree getDegree() const { return this->operator orxonox::Degree(); } /** @brief Returns the current value, converted to the requested type. */ 393 template <typename T> inline T* getPointer() const { return ((T*)this->getVoid()); } /** @brief Returns the current value, converted to a T* pointer. */ 394 395 private: 396 inline bool assignValue(const char& value) { if (this->value_ && this->value_->type_ == MT_char) { return this->value_->setValue(value); } else { this->changeValueContainer<char>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 397 inline bool assignValue(const unsigned char& value) { if (this->value_ && this->value_->type_ == MT_uchar) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned char>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 398 inline bool assignValue(const short& value) { if (this->value_ && this->value_->type_ == MT_short) { return this->value_->setValue(value); } else { this->changeValueContainer<short>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 399 inline bool assignValue(const unsigned short& value) { if (this->value_ && this->value_->type_ == MT_ushort) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned short>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 400 inline bool assignValue(const int& value) { if (this->value_ && this->value_->type_ == MT_int) { return this->value_->setValue(value); } else { this->changeValueContainer<int>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 401 inline bool assignValue(const unsigned int& value) { if (this->value_ && this->value_->type_ == MT_uint) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned int>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 402 inline bool assignValue(const long& value) { if (this->value_ && this->value_->type_ == MT_long) { return this->value_->setValue(value); } else { this->changeValueContainer<long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 403 inline bool assignValue(const unsigned long& value) { if (this->value_ && this->value_->type_ == MT_ulong) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 404 inline bool assignValue(const long long& value) { if (this->value_ && this->value_->type_ == MT_longlong) { return this->value_->setValue(value); } else { this->changeValueContainer<long long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 405 inline bool assignValue(const unsigned long long& value) { if (this->value_ && this->value_->type_ == MT_ulonglong) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 406 inline bool assignValue(const float& value) { if (this->value_ && this->value_->type_ == MT_float) { return this->value_->setValue(value); } else { this->changeValueContainer<float>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 407 inline bool assignValue(const double& value) { if (this->value_ && this->value_->type_ == MT_double) { return this->value_->setValue(value); } else { this->changeValueContainer<double>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 408 inline bool assignValue(const long double& value) { if (this->value_ && this->value_->type_ == MT_longdouble) { return this->value_->setValue(value); } else { this->changeValueContainer<long double>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 409 inline bool assignValue(const bool& value) { if (this->value_ && this->value_->type_ == MT_bool) { return this->value_->setValue(value); } else { this->changeValueContainer<bool>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 410 inline bool assignValue( void* const& value) { if (this->value_ && this->value_->type_ == MT_void) { return this->value_->setValue(value); } else { this->changeValueContainer<void*>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 411 inline bool assignValue(const std::string& value) { if (this->value_ && this->value_->type_ == MT_string) { return this->value_->setValue(value); } else { this->changeValueContainer<std::string>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 412 inline bool assignValue(const orxonox::Vector2& value) { if (this->value_ && this->value_->type_ == MT_vector2) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector2>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 413 inline bool assignValue(const orxonox::Vector3& value) { if (this->value_ && this->value_->type_ == MT_vector3) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector3>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 414 inline bool assignValue(const orxonox::Vector4& value) { if (this->value_ && this->value_->type_ == MT_vector4) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector4>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 415 inline bool assignValue(const orxonox::ColourValue& value) { if (this->value_ && this->value_->type_ == MT_colourvalue) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::ColourValue>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 416 inline bool assignValue(const orxonox::Quaternion& value) { if (this->value_ && this->value_->type_ == MT_quaternion) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Quaternion>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 417 inline bool assignValue(const orxonox::Radian& value) { if (this->value_ && this->value_->type_ == MT_radian) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Radian>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 418 inline bool assignValue(const orxonox::Degree& value) { if (this->value_ && this->value_->type_ == MT_degree) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Degree>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 419 420 /** @brief Changes the value container. */ 421 template <typename T> inline void changeValueContainer(const T& value) { if (this->value_) { delete this->value_; } this->createNewValueContainer<T>(value); } 422 /** @brief Creates a new value container (works only with specialized types). */ 423 template <typename T> void createNewValueContainer(const T& value) { BOOST_STATIC_ASSERT(sizeof(T) == 0); return false; } 424 425 MT_ValueBase* value_; //!< A pointer to the value container 426 }; 427 428 /** @brief Puts the MultiType on a stream by using the native << operator of the current type. */ 429 _UtilExport inline std::ostream& operator<<(std::ostream& outstream, const MultiType& mt) { if (mt.value_) { mt.value_->toString(outstream); } return outstream; } 430 431 template <> inline bool MultiType::isType<char>() const { return (this->value_ && this->value_->type_ == MT_char); } /** @brief Returns true if the current type equals the given type. */ 432 template <> inline bool MultiType::isType<unsigned char>() const { return (this->value_ && this->value_->type_ == MT_uchar); } /** @brief Returns true if the current type equals the given type. */ 433 template <> inline bool MultiType::isType<short>() const { return (this->value_ && this->value_->type_ == MT_short); } /** @brief Returns true if the current type equals the given type. */ 434 template <> inline bool MultiType::isType<unsigned short>() const { return (this->value_ && this->value_->type_ == MT_ushort); } /** @brief Returns true if the current type equals the given type. */ 435 template <> inline bool MultiType::isType<int>() const { return (this->value_ && this->value_->type_ == MT_int); } /** @brief Returns true if the current type equals the given type. */ 436 template <> inline bool MultiType::isType<unsigned int>() const { return (this->value_ && this->value_->type_ == MT_uint); } /** @brief Returns true if the current type equals the given type. */ 437 template <> inline bool MultiType::isType<long>() const { return (this->value_ && this->value_->type_ == MT_long); } /** @brief Returns true if the current type equals the given type. */ 438 template <> inline bool MultiType::isType<unsigned long>() const { return (this->value_ && this->value_->type_ == MT_ulong); } /** @brief Returns true if the current type equals the given type. */ 439 template <> inline bool MultiType::isType<long long>() const { return (this->value_ && this->value_->type_ == MT_longlong); } /** @brief Returns true if the current type equals the given type. */ 440 template <> inline bool MultiType::isType<unsigned long long>() const { return (this->value_ && this->value_->type_ == MT_ulonglong); } /** @brief Returns true if the current type equals the given type. */ 441 template <> inline bool MultiType::isType<float>() const { return (this->value_ && this->value_->type_ == MT_float); } /** @brief Returns true if the current type equals the given type. */ 442 template <> inline bool MultiType::isType<double>() const { return (this->value_ && this->value_->type_ == MT_double); } /** @brief Returns true if the current type equals the given type. */ 443 template <> inline bool MultiType::isType<long double>() const { return (this->value_ && this->value_->type_ == MT_longdouble); } /** @brief Returns true if the current type equals the given type. */ 444 template <> inline bool MultiType::isType<bool>() const { return (this->value_ && this->value_->type_ == MT_bool); } /** @brief Returns true if the current type equals the given type. */ 445 template <> inline bool MultiType::isType<void*>() const { return (this->value_ && this->value_->type_ == MT_void); } /** @brief Returns true if the current type equals the given type. */ 446 template <> inline bool MultiType::isType<std::string>() const { return (this->value_ && this->value_->type_ == MT_string); } /** @brief Returns true if the current type equals the given type. */ 447 template <> inline bool MultiType::isType<orxonox::Vector2>() const { return (this->value_ && this->value_->type_ == MT_vector2); } /** @brief Returns true if the current type equals the given type. */ 448 template <> inline bool MultiType::isType<orxonox::Vector3>() const { return (this->value_ && this->value_->type_ == MT_vector3); } /** @brief Returns true if the current type equals the given type. */ 449 template <> inline bool MultiType::isType<orxonox::Vector4>() const { return (this->value_ && this->value_->type_ == MT_vector4); } /** @brief Returns true if the current type equals the given type. */ 450 template <> inline bool MultiType::isType<orxonox::ColourValue>() const { return (this->value_ && this->value_->type_ == MT_colourvalue); } /** @brief Returns true if the current type equals the given type. */ 451 template <> inline bool MultiType::isType<orxonox::Quaternion>() const { return (this->value_ && this->value_->type_ == MT_quaternion); } /** @brief Returns true if the current type equals the given type. */ 452 template <> inline bool MultiType::isType<orxonox::Radian>() const { return (this->value_ && this->value_->type_ == MT_radian); } /** @brief Returns true if the current type equals the given type. */ 453 template <> inline bool MultiType::isType<orxonox::Degree>() const { return (this->value_ && this->value_->type_ == MT_degree); } /** @brief Returns true if the current type equals the given type. */ 454 455 // Specialization to avoid ambiguities with the conversion operator 456 template <> inline bool MultiType::convert<std::string>() { return this->setValue<std::string> (this->operator std::string()); } /** @brief Converts the current value to the given type. */ 457 template <> inline bool MultiType::convert<orxonox::Vector2>() { return this->setValue<orxonox::Vector2> (this->operator orxonox::Vector2()); } /** @brief Converts the current value to the given type. */ 458 template <> inline bool MultiType::convert<orxonox::Vector3>() { return this->setValue<orxonox::Vector3> (this->operator orxonox::Vector3()); } /** @brief Converts the current value to the given type. */ 459 template <> inline bool MultiType::convert<orxonox::Vector4>() { return this->setValue<orxonox::Vector4> (this->operator orxonox::Vector4()); } /** @brief Converts the current value to the given type. */ 460 template <> inline bool MultiType::convert<orxonox::ColourValue>() { return this->setValue<orxonox::ColourValue>(this->operator orxonox::ColourValue()); } /** @brief Converts the current value to the given type. */ 461 template <> inline bool MultiType::convert<orxonox::Quaternion>() { return this->setValue<orxonox::Quaternion> (this->operator orxonox::Quaternion()); } /** @brief Converts the current value to the given type. */ 462 template <> inline bool MultiType::convert<orxonox::Radian>() { return this->setValue<orxonox::Radian> (this->operator orxonox::Radian()); } /** @brief Converts the current value to the given type. */ 463 template <> inline bool MultiType::convert<orxonox::Degree>() { return this->setValue<orxonox::Degree> (this->operator orxonox::Degree()); } /** @brief Converts the current value to the given type. */ 464 465 // Specialization to avoid ambiguities with the conversion operator 466 template <> inline bool MultiType::convert<const std::string&>() { return this->convert<std::string>(); } /** @brief Converts the current value to the given type. */ 467 template <> inline bool MultiType::convert<const orxonox::Vector2&>() { return this->convert<orxonox::Vector2>(); } /** @brief Converts the current value to the given type. */ 468 template <> inline bool MultiType::convert<const orxonox::Vector3&>() { return this->convert<orxonox::Vector3>(); } /** @brief Converts the current value to the given type. */ 469 template <> inline bool MultiType::convert<const orxonox::Vector4&>() { return this->convert<orxonox::Vector4>(); } /** @brief Converts the current value to the given type. */ 470 template <> inline bool MultiType::convert<const orxonox::ColourValue&>() { return this->convert<orxonox::ColourValue>(); } /** @brief Converts the current value to the given type. */ 471 template <> inline bool MultiType::convert<const orxonox::Quaternion&>() { return this->convert<orxonox::Quaternion>(); } /** @brief Converts the current value to the given type. */ 472 template <> inline bool MultiType::convert<const orxonox::Radian&>() { return this->convert<orxonox::Radian>(); } /** @brief Converts the current value to the given type. */ 473 template <> inline bool MultiType::convert<const orxonox::Degree&>() { return this->convert<orxonox::Degree>(); } /** @brief Converts the current value to the given type. */ 474 475 template <> void MultiType::createNewValueContainer(const char& value); 476 template <> void MultiType::createNewValueContainer(const unsigned char& value); 477 template <> void MultiType::createNewValueContainer(const short& value); 478 template <> void MultiType::createNewValueContainer(const unsigned short& value); 479 template <> void MultiType::createNewValueContainer(const int& value); 480 template <> void MultiType::createNewValueContainer(const unsigned int& value); 481 template <> void MultiType::createNewValueContainer(const long& value); 482 template <> void MultiType::createNewValueContainer(const unsigned long& value); 483 template <> void MultiType::createNewValueContainer(const long long& value); 484 template <> void MultiType::createNewValueContainer(const unsigned long long& value); 485 template <> void MultiType::createNewValueContainer(const float& value); 486 template <> void MultiType::createNewValueContainer(const double& value); 487 template <> void MultiType::createNewValueContainer(const bool& value); 488 template <> void MultiType::createNewValueContainer(const long double& value); 489 template <> void MultiType::createNewValueContainer( void* const& value); 490 template <> void MultiType::createNewValueContainer(const std::string& value); 491 template <> void MultiType::createNewValueContainer(const orxonox::Vector2& value); 492 template <> void MultiType::createNewValueContainer(const orxonox::Vector3& value); 493 template <> void MultiType::createNewValueContainer(const orxonox::Vector4& value); 494 template <> void MultiType::createNewValueContainer(const orxonox::ColourValue& value); 495 template <> void MultiType::createNewValueContainer(const orxonox::Quaternion& value); 496 template <> void MultiType::createNewValueContainer(const orxonox::Radian& value); 497 template <> void MultiType::createNewValueContainer(const orxonox::Degree& value); 498 499 inline bool MultiType::setValue(const char& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 500 inline bool MultiType::setValue(const unsigned char& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 501 inline bool MultiType::setValue(const short& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 502 inline bool MultiType::setValue(const unsigned short& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 503 inline bool MultiType::setValue(const int& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 504 inline bool MultiType::setValue(const unsigned int& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 505 inline bool MultiType::setValue(const long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 506 inline bool MultiType::setValue(const unsigned long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 507 inline bool MultiType::setValue(const long long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 508 inline bool MultiType::setValue(const unsigned long long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 509 inline bool MultiType::setValue(const float& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 510 inline bool MultiType::setValue(const double& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 511 inline bool MultiType::setValue(const long double& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 512 inline bool MultiType::setValue(const bool& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 513 inline bool MultiType::setValue( void* const& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 514 inline bool MultiType::setValue(const std::string& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 515 inline bool MultiType::setValue(const orxonox::Vector2& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 516 inline bool MultiType::setValue(const orxonox::Vector3& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 517 inline bool MultiType::setValue(const orxonox::Vector4& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 518 inline bool MultiType::setValue(const orxonox::ColourValue& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 519 inline bool MultiType::setValue(const orxonox::Quaternion& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 520 inline bool MultiType::setValue(const orxonox::Radian& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 521 inline bool MultiType::setValue(const orxonox::Degree& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 522 523 inline bool MultiType::setValue(const char* value) { if (this->value_) { return this->value_->setValue(std::string(value)); } else { return this->assignValue(std::string(value)); } } /** @brief Assigns the given value and converts it to the current type. */ 131 /** 132 @brief MT_ValueBase is an almost pure virtual baseclass of MT_Value<T>, which holds the value of the MultiType. 133 This class is only used within the MultiType. 134 */ 135 class _UtilExport MT_ValueBase 136 { 137 public: 138 MT_ValueBase(MT_Type type) : type_(type), bHasDefaultValue_(false) {} 139 virtual ~MT_ValueBase() {} 140 141 virtual MT_ValueBase* clone() const = 0; 142 143 virtual void reset() = 0; 144 virtual bool assimilate(const MultiType& other) = 0; 145 146 /** @brief Returns the type of the current value. */ 147 const MT_Type& getType() const { return this->type_; } 148 149 /** @brief Checks whether the value is a default one. */ 150 bool hasDefaultValue() const { return this->bHasDefaultValue_; } 151 152 virtual bool setValue(const char& value) = 0; 153 virtual bool setValue(const unsigned char& value) = 0; 154 virtual bool setValue(const short& value) = 0; 155 virtual bool setValue(const unsigned short& value) = 0; 156 virtual bool setValue(const int& value) = 0; 157 virtual bool setValue(const unsigned int& value) = 0; 158 virtual bool setValue(const long& value) = 0; 159 virtual bool setValue(const unsigned long& value) = 0; 160 virtual bool setValue(const long long& value) = 0; 161 virtual bool setValue(const unsigned long long& value) = 0; 162 virtual bool setValue(const float& value) = 0; 163 virtual bool setValue(const double& value) = 0; 164 virtual bool setValue(const long double& value) = 0; 165 virtual bool setValue(const bool& value) = 0; 166 virtual bool setValue( void* const& value) = 0; 167 virtual bool setValue(const std::string& value) = 0; 168 virtual bool setValue(const orxonox::Vector2& value) = 0; 169 virtual bool setValue(const orxonox::Vector3& value) = 0; 170 virtual bool setValue(const orxonox::Vector4& value) = 0; 171 virtual bool setValue(const orxonox::ColourValue& value) = 0; 172 virtual bool setValue(const orxonox::Quaternion& value) = 0; 173 virtual bool setValue(const orxonox::Radian& value) = 0; 174 virtual bool setValue(const orxonox::Degree& value) = 0; 175 176 virtual bool getValue(char* value) const = 0; 177 virtual bool getValue(unsigned char* value) const = 0; 178 virtual bool getValue(short* value) const = 0; 179 virtual bool getValue(unsigned short* value) const = 0; 180 virtual bool getValue(int* value) const = 0; 181 virtual bool getValue(unsigned int* value) const = 0; 182 virtual bool getValue(long* value) const = 0; 183 virtual bool getValue(unsigned long* value) const = 0; 184 virtual bool getValue(long long* value) const = 0; 185 virtual bool getValue(unsigned long long* value) const = 0; 186 virtual bool getValue(float* value) const = 0; 187 virtual bool getValue(double* value) const = 0; 188 virtual bool getValue(long double* value) const = 0; 189 virtual bool getValue(bool* value) const = 0; 190 virtual bool getValue(void** value) const = 0; 191 virtual bool getValue(std::string* value) const = 0; 192 virtual bool getValue(orxonox::Vector2* value) const = 0; 193 virtual bool getValue(orxonox::Vector3* value) const = 0; 194 virtual bool getValue(orxonox::Vector4* value) const = 0; 195 virtual bool getValue(orxonox::ColourValue* value) const = 0; 196 virtual bool getValue(orxonox::Quaternion* value) const = 0; 197 virtual bool getValue(orxonox::Radian* value) const = 0; 198 virtual bool getValue(orxonox::Degree* value) const = 0; 199 200 virtual operator char() const = 0; 201 virtual operator unsigned char() const = 0; 202 virtual operator short() const = 0; 203 virtual operator unsigned short() const = 0; 204 virtual operator int() const = 0; 205 virtual operator unsigned int() const = 0; 206 virtual operator long() const = 0; 207 virtual operator unsigned long() const = 0; 208 virtual operator long long() const = 0; 209 virtual operator unsigned long long() const = 0; 210 virtual operator float() const = 0; 211 virtual operator double() const = 0; 212 virtual operator long double() const = 0; 213 virtual operator bool() const = 0; 214 virtual operator void*() const = 0; 215 virtual operator std::string() const = 0; 216 virtual operator orxonox::Vector2() const = 0; 217 virtual operator orxonox::Vector3() const = 0; 218 virtual operator orxonox::Vector4() const = 0; 219 virtual operator orxonox::ColourValue() const = 0; 220 virtual operator orxonox::Quaternion() const = 0; 221 virtual operator orxonox::Radian() const = 0; 222 virtual operator orxonox::Degree() const = 0; 223 224 virtual void toString(std::ostream& outstream) const = 0; 225 226 MT_Type type_; //!< The type of the current value 227 bool bHasDefaultValue_; //!< True if the last conversion wasn't successful 228 }; 229 230 public: 231 inline MultiType() : value_(0) {} /** @brief Default constructor: Assigns no value and no type. The type will be determined by the first assignment of a value. */ 232 inline MultiType(const char& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 233 inline MultiType(const unsigned char& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 234 inline MultiType(const short& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 235 inline MultiType(const unsigned short& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 236 inline MultiType(const int& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 237 inline MultiType(const unsigned int& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 238 inline MultiType(const long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 239 inline MultiType(const unsigned long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 240 inline MultiType(const long long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 241 inline MultiType(const unsigned long long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 242 inline MultiType(const float& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 243 inline MultiType(const double& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 244 inline MultiType(const long double& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 245 inline MultiType(const bool& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 246 inline MultiType( void* const& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 247 inline MultiType(const std::string& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 248 inline MultiType(const orxonox::Vector2& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 249 inline MultiType(const orxonox::Vector3& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 250 inline MultiType(const orxonox::Vector4& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 251 inline MultiType(const orxonox::ColourValue& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 252 inline MultiType(const orxonox::Quaternion& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 253 inline MultiType(const orxonox::Radian& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 254 inline MultiType(const orxonox::Degree& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 255 inline MultiType(const char* value) : value_(0) { this->setValue(std::string(value)); } /** @brief Constructor: Converts the char array to a std::string, assigns the value and sets the type. */ 256 inline MultiType(const MultiType& other) : value_(0) { this->setValue(other); } /** @brief Copyconstructor: Assigns value and type of the other MultiType. */ 257 inline MultiType(MT_Type type) : value_(0) { this->setType(type); } /** @brief Constructor: Sets the type, the next assignment will determine the value. */ 258 259 /** @brief Destructor: Deletes the MT_Value. */ 260 inline ~MultiType() { if (this->value_) { delete this->value_; } } 261 262 template <typename V> inline const MultiType& operator=(const V& value) { this->setValue(value); return (*this); } /** @brief Assigns a new value. The value will be converted to the current type of the MultiType. */ 263 template <typename V> inline const MultiType& operator=(V* value) { this->setValue(value); return (*this); } /** @brief Assigns a pointer. */ 264 inline const MultiType& operator=(const MultiType& other) { this->setValue(other); return (*this); } /** @brief Assigns the value of the other MultiType and converts it to the current type of the MultiType. */ 265 inline const MultiType& operator=(MT_Type type) { this->setType(type); return (*this); } /** @brief Resets the value and changes the type. */ 266 267 inline bool setValue(const char& value); 268 inline bool setValue(const unsigned char& value); 269 inline bool setValue(const short& value); 270 inline bool setValue(const unsigned short& value); 271 inline bool setValue(const int& value); 272 inline bool setValue(const unsigned int& value); 273 inline bool setValue(const long& value); 274 inline bool setValue(const unsigned long& value); 275 inline bool setValue(const long long& value); 276 inline bool setValue(const unsigned long long& value); 277 inline bool setValue(const float& value); 278 inline bool setValue(const double& value); 279 inline bool setValue(const long double& value); 280 inline bool setValue(const bool& value); 281 inline bool setValue( void* const& value); 282 inline bool setValue(const std::string& value); 283 inline bool setValue(const orxonox::Vector2& value); 284 inline bool setValue(const orxonox::Vector3& value); 285 inline bool setValue(const orxonox::Vector4& value); 286 inline bool setValue(const orxonox::ColourValue& value); 287 inline bool setValue(const orxonox::Quaternion& value); 288 inline bool setValue(const orxonox::Radian& value); 289 inline bool setValue(const orxonox::Degree& value); 290 inline bool setValue(const char* value); 291 /** @brief Assigns a pointer. */ 292 template <typename V> inline bool setValue(V* value) { if (this->value_) { return this->value_->setValue((void*)value); } else { return this->assignValue((void*)value); } } 293 /** @brief Assigns the value of the other MultiType and converts it to the current type. */ 294 bool setValue(const MultiType& other) { if (this->value_) { return this->value_->assimilate(other); } else { if (other.value_) { this->value_ = other.value_->clone(); } return true; } } 295 /** @brief Changes the type to T and assigns the new value (which might be of another type than T - it gets converted). */ 296 template <typename T, typename V> inline bool setValue(const V& value) { this->setType<T>(); return this->setValue(value); } 297 298 299 /** @brief Copies the other MultiType by assigning value and type. */ 300 inline void copy(const MultiType& other) { if (this == &other) { return; } if (this->value_) { delete this->value_; } this->value_ = (other.value_) ? other.value_->clone() : 0; } 301 302 template <typename T> inline bool convert() { return this->setValue<T>((T)(*this)); } /** @brief Converts the current value to type T. */ 303 inline bool convert(const MultiType& other) { return this->convert(other.getType()); } /** @brief Converts the current value to the type of the other MultiType. */ 304 bool convert(MT_Type type); 305 306 /** @brief Current content gets deleted. New type is MT_null */ 307 inline void reset() { if (this->value_) this->value_->reset(); } 308 309 template <typename T> inline void setType() { this->assignValue(T()); } /** @brief Resets the value and changes the internal type to T. */ 310 inline void setType(const MultiType& other) { this->setType(other.getType()); } /** @brief Resets the value and changes the internal type to the type of the other MultiType. */ 311 inline void setType(MT_Type type) { this->reset(); this->convert(type); this->reset(); } /** @brief Resets the value and changes the internal type to the given type. */ 312 313 /** @brief Returns the current type. */ 314 inline MT_Type getType() const { return (this->value_) ? this->value_->type_ : MT_null; } 315 /** @brief Returns true if the current type equals the given type. */ 316 inline bool isType(MT_Type type) const { return (this->value_) ? (this->value_->type_ == type) : (type == MT_null); } 317 /** @brief Returns true if the current type is T. */ 318 template <typename T> inline bool isType() const { return false; } // Only works for specialized values - see below 319 std::string getTypename() const; 320 321 /** @brief Checks whether the value is a default one. */ 322 bool hasDefaultValue() const { return this->value_->hasDefaultValue(); } 323 324 operator char() const; 325 operator unsigned char() const; 326 operator short() const; 327 operator unsigned short() const; 328 operator int() const; 329 operator unsigned int() const; 330 operator long() const; 331 operator unsigned long() const; 332 operator long long() const; 333 operator unsigned long long() const; 334 operator float() const; 335 operator double() const; 336 operator long double() const; 337 operator bool() const; 338 operator void*() const; 339 operator std::string() const; 340 operator orxonox::Vector2() const; 341 operator orxonox::Vector3() const; 342 operator orxonox::Vector4() const; 343 operator orxonox::ColourValue() const; 344 operator orxonox::Quaternion() const; 345 operator orxonox::Radian() const; 346 operator orxonox::Degree() const; 347 /** @brief Returns the current value, converted to a T* pointer. */ 348 template <class T> operator T*() const { return ((T*)this->operator void*()); } 349 350 inline bool getValue(char* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 351 inline bool getValue(unsigned char* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 352 inline bool getValue(short* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 353 inline bool getValue(unsigned short* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 354 inline bool getValue(int* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 355 inline bool getValue(unsigned int* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 356 inline bool getValue(long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 357 inline bool getValue(unsigned long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 358 inline bool getValue(long long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 359 inline bool getValue(unsigned long long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 360 inline bool getValue(float* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 361 inline bool getValue(double* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 362 inline bool getValue(long double* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 363 inline bool getValue(bool* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 364 inline bool getValue(void** value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 365 inline bool getValue(std::string* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 366 inline bool getValue(orxonox::Vector2* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 367 inline bool getValue(orxonox::Vector3* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 368 inline bool getValue(orxonox::Vector4* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 369 inline bool getValue(orxonox::ColourValue* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 370 inline bool getValue(orxonox::Quaternion* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 371 inline bool getValue(orxonox::Radian* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 372 inline bool getValue(orxonox::Degree* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 373 374 inline char getChar() const { return this->operator char(); } /** @brief Returns the current value, converted to the requested type. */ 375 inline unsigned char getUnsignedChar() const { return this->operator unsigned char(); } /** @brief Returns the current value, converted to the requested type. */ 376 inline short getShort() const { return this->operator short(); } /** @brief Returns the current value, converted to the requested type. */ 377 inline unsigned short getUnsignedShort() const { return this->operator unsigned short(); } /** @brief Returns the current value, converted to the requested type. */ 378 inline int getInt() const { return this->operator int(); } /** @brief Returns the current value, converted to the requested type. */ 379 inline unsigned int getUnsignedInt() const { return this->operator unsigned int(); } /** @brief Returns the current value, converted to the requested type. */ 380 inline long getLong() const { return this->operator long(); } /** @brief Returns the current value, converted to the requested type. */ 381 inline unsigned long getUnsignedLong() const { return this->operator unsigned long(); } /** @brief Returns the current value, converted to the requested type. */ 382 inline long long getLongLong() const { return this->operator long long(); } /** @brief Returns the current value, converted to the requested type. */ 383 inline unsigned long long getUnsignedLongLong() const { return this->operator unsigned long long(); } /** @brief Returns the current value, converted to the requested type. */ 384 inline float getFloat() const { return this->operator float(); } /** @brief Returns the current value, converted to the requested type. */ 385 inline double getDouble() const { return this->operator double(); } /** @brief Returns the current value, converted to the requested type. */ 386 inline long double getLongDouble() const { return this->operator long double(); } /** @brief Returns the current value, converted to the requested type. */ 387 inline bool getBool() const { return this->operator bool(); } /** @brief Returns the current value, converted to the requested type. */ 388 inline void* getVoid() const { return this->operator void*(); } /** @brief Returns the current value, converted to the requested type. */ 389 inline std::string getString() const { return this->operator std::string(); } /** @brief Returns the current value, converted to the requested type. */ 390 inline orxonox::Vector2 getVector2() const { return this->operator orxonox::Vector2(); } /** @brief Returns the current value, converted to the requested type. */ 391 inline orxonox::Vector3 getVector3() const { return this->operator orxonox::Vector3(); } /** @brief Returns the current value, converted to the requested type. */ 392 inline orxonox::Vector4 getVector4() const { return this->operator orxonox::Vector4(); } /** @brief Returns the current value, converted to the requested type. */ 393 inline orxonox::ColourValue getColourValue() const { return this->operator orxonox::ColourValue(); } /** @brief Returns the current value, converted to the requested type. */ 394 inline orxonox::Quaternion getQuaternion() const { return this->operator orxonox::Quaternion(); } /** @brief Returns the current value, converted to the requested type. */ 395 inline orxonox::Radian getRadian() const { return this->operator orxonox::Radian(); } /** @brief Returns the current value, converted to the requested type. */ 396 inline orxonox::Degree getDegree() const { return this->operator orxonox::Degree(); } /** @brief Returns the current value, converted to the requested type. */ 397 template <typename T> inline T* getPointer() const { return ((T*)this->getVoid()); } /** @brief Returns the current value, converted to a T* pointer. */ 398 399 private: 400 inline bool assignValue(const char& value) { if (this->value_ && this->value_->type_ == MT_char) { return this->value_->setValue(value); } else { this->changeValueContainer<char>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 401 inline bool assignValue(const unsigned char& value) { if (this->value_ && this->value_->type_ == MT_uchar) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned char>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 402 inline bool assignValue(const short& value) { if (this->value_ && this->value_->type_ == MT_short) { return this->value_->setValue(value); } else { this->changeValueContainer<short>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 403 inline bool assignValue(const unsigned short& value) { if (this->value_ && this->value_->type_ == MT_ushort) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned short>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 404 inline bool assignValue(const int& value) { if (this->value_ && this->value_->type_ == MT_int) { return this->value_->setValue(value); } else { this->changeValueContainer<int>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 405 inline bool assignValue(const unsigned int& value) { if (this->value_ && this->value_->type_ == MT_uint) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned int>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 406 inline bool assignValue(const long& value) { if (this->value_ && this->value_->type_ == MT_long) { return this->value_->setValue(value); } else { this->changeValueContainer<long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 407 inline bool assignValue(const unsigned long& value) { if (this->value_ && this->value_->type_ == MT_ulong) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 408 inline bool assignValue(const long long& value) { if (this->value_ && this->value_->type_ == MT_longlong) { return this->value_->setValue(value); } else { this->changeValueContainer<long long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 409 inline bool assignValue(const unsigned long long& value) { if (this->value_ && this->value_->type_ == MT_ulonglong) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 410 inline bool assignValue(const float& value) { if (this->value_ && this->value_->type_ == MT_float) { return this->value_->setValue(value); } else { this->changeValueContainer<float>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 411 inline bool assignValue(const double& value) { if (this->value_ && this->value_->type_ == MT_double) { return this->value_->setValue(value); } else { this->changeValueContainer<double>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 412 inline bool assignValue(const long double& value) { if (this->value_ && this->value_->type_ == MT_longdouble) { return this->value_->setValue(value); } else { this->changeValueContainer<long double>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 413 inline bool assignValue(const bool& value) { if (this->value_ && this->value_->type_ == MT_bool) { return this->value_->setValue(value); } else { this->changeValueContainer<bool>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 414 inline bool assignValue( void* const& value) { if (this->value_ && this->value_->type_ == MT_void) { return this->value_->setValue(value); } else { this->changeValueContainer<void*>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 415 inline bool assignValue(const std::string& value) { if (this->value_ && this->value_->type_ == MT_string) { return this->value_->setValue(value); } else { this->changeValueContainer<std::string>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 416 inline bool assignValue(const orxonox::Vector2& value) { if (this->value_ && this->value_->type_ == MT_vector2) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector2>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 417 inline bool assignValue(const orxonox::Vector3& value) { if (this->value_ && this->value_->type_ == MT_vector3) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector3>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 418 inline bool assignValue(const orxonox::Vector4& value) { if (this->value_ && this->value_->type_ == MT_vector4) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector4>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 419 inline bool assignValue(const orxonox::ColourValue& value) { if (this->value_ && this->value_->type_ == MT_colourvalue) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::ColourValue>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 420 inline bool assignValue(const orxonox::Quaternion& value) { if (this->value_ && this->value_->type_ == MT_quaternion) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Quaternion>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 421 inline bool assignValue(const orxonox::Radian& value) { if (this->value_ && this->value_->type_ == MT_radian) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Radian>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 422 inline bool assignValue(const orxonox::Degree& value) { if (this->value_ && this->value_->type_ == MT_degree) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Degree>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 423 424 /** @brief Changes the value container. */ 425 template <typename T> inline void changeValueContainer(const T& value) { if (this->value_) { delete this->value_; } this->createNewValueContainer<T>(value); } 426 /** @brief Creates a new value container (works only with specialized types). */ 427 template <typename T> void createNewValueContainer(const T& value) { BOOST_STATIC_ASSERT(sizeof(T) == 0); return false; } 428 429 MT_ValueBase* value_; //!< A pointer to the value container 430 }; 431 432 /** @brief Puts the MultiType on a stream by using the native << operator of the current type. */ 433 _UtilExport inline std::ostream& operator<<(std::ostream& outstream, const MultiType& mt) { if (mt.value_) { mt.value_->toString(outstream); } return outstream; } 434 435 template <> inline bool MultiType::isType<char>() const { return (this->value_ && this->value_->type_ == MT_char); } /** @brief Returns true if the current type equals the given type. */ 436 template <> inline bool MultiType::isType<unsigned char>() const { return (this->value_ && this->value_->type_ == MT_uchar); } /** @brief Returns true if the current type equals the given type. */ 437 template <> inline bool MultiType::isType<short>() const { return (this->value_ && this->value_->type_ == MT_short); } /** @brief Returns true if the current type equals the given type. */ 438 template <> inline bool MultiType::isType<unsigned short>() const { return (this->value_ && this->value_->type_ == MT_ushort); } /** @brief Returns true if the current type equals the given type. */ 439 template <> inline bool MultiType::isType<int>() const { return (this->value_ && this->value_->type_ == MT_int); } /** @brief Returns true if the current type equals the given type. */ 440 template <> inline bool MultiType::isType<unsigned int>() const { return (this->value_ && this->value_->type_ == MT_uint); } /** @brief Returns true if the current type equals the given type. */ 441 template <> inline bool MultiType::isType<long>() const { return (this->value_ && this->value_->type_ == MT_long); } /** @brief Returns true if the current type equals the given type. */ 442 template <> inline bool MultiType::isType<unsigned long>() const { return (this->value_ && this->value_->type_ == MT_ulong); } /** @brief Returns true if the current type equals the given type. */ 443 template <> inline bool MultiType::isType<long long>() const { return (this->value_ && this->value_->type_ == MT_longlong); } /** @brief Returns true if the current type equals the given type. */ 444 template <> inline bool MultiType::isType<unsigned long long>() const { return (this->value_ && this->value_->type_ == MT_ulonglong); } /** @brief Returns true if the current type equals the given type. */ 445 template <> inline bool MultiType::isType<float>() const { return (this->value_ && this->value_->type_ == MT_float); } /** @brief Returns true if the current type equals the given type. */ 446 template <> inline bool MultiType::isType<double>() const { return (this->value_ && this->value_->type_ == MT_double); } /** @brief Returns true if the current type equals the given type. */ 447 template <> inline bool MultiType::isType<long double>() const { return (this->value_ && this->value_->type_ == MT_longdouble); } /** @brief Returns true if the current type equals the given type. */ 448 template <> inline bool MultiType::isType<bool>() const { return (this->value_ && this->value_->type_ == MT_bool); } /** @brief Returns true if the current type equals the given type. */ 449 template <> inline bool MultiType::isType<void*>() const { return (this->value_ && this->value_->type_ == MT_void); } /** @brief Returns true if the current type equals the given type. */ 450 template <> inline bool MultiType::isType<std::string>() const { return (this->value_ && this->value_->type_ == MT_string); } /** @brief Returns true if the current type equals the given type. */ 451 template <> inline bool MultiType::isType<orxonox::Vector2>() const { return (this->value_ && this->value_->type_ == MT_vector2); } /** @brief Returns true if the current type equals the given type. */ 452 template <> inline bool MultiType::isType<orxonox::Vector3>() const { return (this->value_ && this->value_->type_ == MT_vector3); } /** @brief Returns true if the current type equals the given type. */ 453 template <> inline bool MultiType::isType<orxonox::Vector4>() const { return (this->value_ && this->value_->type_ == MT_vector4); } /** @brief Returns true if the current type equals the given type. */ 454 template <> inline bool MultiType::isType<orxonox::ColourValue>() const { return (this->value_ && this->value_->type_ == MT_colourvalue); } /** @brief Returns true if the current type equals the given type. */ 455 template <> inline bool MultiType::isType<orxonox::Quaternion>() const { return (this->value_ && this->value_->type_ == MT_quaternion); } /** @brief Returns true if the current type equals the given type. */ 456 template <> inline bool MultiType::isType<orxonox::Radian>() const { return (this->value_ && this->value_->type_ == MT_radian); } /** @brief Returns true if the current type equals the given type. */ 457 template <> inline bool MultiType::isType<orxonox::Degree>() const { return (this->value_ && this->value_->type_ == MT_degree); } /** @brief Returns true if the current type equals the given type. */ 458 459 // Specialization to avoid ambiguities with the conversion operator 460 template <> inline bool MultiType::convert<std::string>() { return this->setValue<std::string> (this->operator std::string()); } /** @brief Converts the current value to the given type. */ 461 template <> inline bool MultiType::convert<orxonox::Vector2>() { return this->setValue<orxonox::Vector2> (this->operator orxonox::Vector2()); } /** @brief Converts the current value to the given type. */ 462 template <> inline bool MultiType::convert<orxonox::Vector3>() { return this->setValue<orxonox::Vector3> (this->operator orxonox::Vector3()); } /** @brief Converts the current value to the given type. */ 463 template <> inline bool MultiType::convert<orxonox::Vector4>() { return this->setValue<orxonox::Vector4> (this->operator orxonox::Vector4()); } /** @brief Converts the current value to the given type. */ 464 template <> inline bool MultiType::convert<orxonox::ColourValue>() { return this->setValue<orxonox::ColourValue>(this->operator orxonox::ColourValue()); } /** @brief Converts the current value to the given type. */ 465 template <> inline bool MultiType::convert<orxonox::Quaternion>() { return this->setValue<orxonox::Quaternion> (this->operator orxonox::Quaternion()); } /** @brief Converts the current value to the given type. */ 466 template <> inline bool MultiType::convert<orxonox::Radian>() { return this->setValue<orxonox::Radian> (this->operator orxonox::Radian()); } /** @brief Converts the current value to the given type. */ 467 template <> inline bool MultiType::convert<orxonox::Degree>() { return this->setValue<orxonox::Degree> (this->operator orxonox::Degree()); } /** @brief Converts the current value to the given type. */ 468 469 // Specialization to avoid ambiguities with the conversion operator 470 template <> inline bool MultiType::convert<const std::string&>() { return this->convert<std::string>(); } /** @brief Converts the current value to the given type. */ 471 template <> inline bool MultiType::convert<const orxonox::Vector2&>() { return this->convert<orxonox::Vector2>(); } /** @brief Converts the current value to the given type. */ 472 template <> inline bool MultiType::convert<const orxonox::Vector3&>() { return this->convert<orxonox::Vector3>(); } /** @brief Converts the current value to the given type. */ 473 template <> inline bool MultiType::convert<const orxonox::Vector4&>() { return this->convert<orxonox::Vector4>(); } /** @brief Converts the current value to the given type. */ 474 template <> inline bool MultiType::convert<const orxonox::ColourValue&>() { return this->convert<orxonox::ColourValue>(); } /** @brief Converts the current value to the given type. */ 475 template <> inline bool MultiType::convert<const orxonox::Quaternion&>() { return this->convert<orxonox::Quaternion>(); } /** @brief Converts the current value to the given type. */ 476 template <> inline bool MultiType::convert<const orxonox::Radian&>() { return this->convert<orxonox::Radian>(); } /** @brief Converts the current value to the given type. */ 477 template <> inline bool MultiType::convert<const orxonox::Degree&>() { return this->convert<orxonox::Degree>(); } /** @brief Converts the current value to the given type. */ 478 479 template <> void MultiType::createNewValueContainer(const char& value); 480 template <> void MultiType::createNewValueContainer(const unsigned char& value); 481 template <> void MultiType::createNewValueContainer(const short& value); 482 template <> void MultiType::createNewValueContainer(const unsigned short& value); 483 template <> void MultiType::createNewValueContainer(const int& value); 484 template <> void MultiType::createNewValueContainer(const unsigned int& value); 485 template <> void MultiType::createNewValueContainer(const long& value); 486 template <> void MultiType::createNewValueContainer(const unsigned long& value); 487 template <> void MultiType::createNewValueContainer(const long long& value); 488 template <> void MultiType::createNewValueContainer(const unsigned long long& value); 489 template <> void MultiType::createNewValueContainer(const float& value); 490 template <> void MultiType::createNewValueContainer(const double& value); 491 template <> void MultiType::createNewValueContainer(const bool& value); 492 template <> void MultiType::createNewValueContainer(const long double& value); 493 template <> void MultiType::createNewValueContainer( void* const& value); 494 template <> void MultiType::createNewValueContainer(const std::string& value); 495 template <> void MultiType::createNewValueContainer(const orxonox::Vector2& value); 496 template <> void MultiType::createNewValueContainer(const orxonox::Vector3& value); 497 template <> void MultiType::createNewValueContainer(const orxonox::Vector4& value); 498 template <> void MultiType::createNewValueContainer(const orxonox::ColourValue& value); 499 template <> void MultiType::createNewValueContainer(const orxonox::Quaternion& value); 500 template <> void MultiType::createNewValueContainer(const orxonox::Radian& value); 501 template <> void MultiType::createNewValueContainer(const orxonox::Degree& value); 502 503 inline bool MultiType::setValue(const char& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 504 inline bool MultiType::setValue(const unsigned char& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 505 inline bool MultiType::setValue(const short& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 506 inline bool MultiType::setValue(const unsigned short& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 507 inline bool MultiType::setValue(const int& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 508 inline bool MultiType::setValue(const unsigned int& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 509 inline bool MultiType::setValue(const long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 510 inline bool MultiType::setValue(const unsigned long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 511 inline bool MultiType::setValue(const long long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 512 inline bool MultiType::setValue(const unsigned long long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 513 inline bool MultiType::setValue(const float& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 514 inline bool MultiType::setValue(const double& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 515 inline bool MultiType::setValue(const long double& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 516 inline bool MultiType::setValue(const bool& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 517 inline bool MultiType::setValue( void* const& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 518 inline bool MultiType::setValue(const std::string& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 519 inline bool MultiType::setValue(const orxonox::Vector2& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 520 inline bool MultiType::setValue(const orxonox::Vector3& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 521 inline bool MultiType::setValue(const orxonox::Vector4& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 522 inline bool MultiType::setValue(const orxonox::ColourValue& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 523 inline bool MultiType::setValue(const orxonox::Quaternion& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 524 inline bool MultiType::setValue(const orxonox::Radian& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 525 inline bool MultiType::setValue(const orxonox::Degree& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 526 527 inline bool MultiType::setValue(const char* value) { if (this->value_) { return this->value_->setValue(std::string(value)); } else { return this->assignValue(std::string(value)); } } /** @brief Assigns the given value and converts it to the current type. */ 528 } 524 529 525 530 #endif /* _MultiType_H__ */ -
code/trunk/src/util/MultiTypeValue.h
r2087 r2171 28 28 29 29 /** 30 @file MultiTypeValue.h30 @file 31 31 @brief Declaration and Implementation of the MT_Value<T> class. 32 32 … … 41 41 #include "MultiType.h" 42 42 43 /** 44 @brief The MT_Value<T> class is used to hold a value of type T within a MultiType. 45 */ 46 template <typename T> 47 struct MT_Value : public MultiType::MT_ValueBase 43 namespace orxonox 48 44 { 49 /** @brief Constructor: Assigns the value and the type identifier. */ 50 MT_Value(const T& value, MT_Type type) : MT_ValueBase(type), value_(value) {} 45 /** 46 @brief The MT_Value<T> class is used to hold a value of type T within a MultiType. 47 */ 48 template <typename T> 49 class MT_Value : public MultiType::MT_ValueBase 50 { 51 public: 52 /** @brief Constructor: Assigns the value and the type identifier. */ 53 MT_Value(const T& value, MT_Type type) : MT_ValueBase(type), value_(value) {} 51 54 52 /** @brief Creates a copy of itself. */53 inline MT_ValueBase* clone() const { return new MT_Value<T>(this->value_, this->type_); }55 /** @brief Creates a copy of itself. */ 56 inline MT_ValueBase* clone() const { return new MT_Value<T>(this->value_, this->type_); } 54 57 55 /** @brief Resets the current value to the default. */56 inline void reset() { this->value_ = zeroise<T>(); bHasDefaultValue_ = true; }58 /** @brief Resets the current value to the default. */ 59 inline void reset() { this->value_ = zeroise<T>(); bHasDefaultValue_ = true; } 57 60 58 /** @brief Assigns the value of the other MultiType, converted to T. @param other The other MultiType */ 59 inline bool assimilate(const MultiType& other) 60 { 61 if (other.value_) 61 /** @brief Assigns the value of the other MultiType, converted to T. @param other The other MultiType */ 62 inline bool assimilate(const MultiType& other) 62 63 { 63 return !(bHasDefaultValue_ = !other.value_->getValue(&value_)); 64 if (other.value_) 65 { 66 return !(bHasDefaultValue_ = !other.value_->getValue(&value_)); 67 } 68 else 69 { 70 this->value_ = zeroise<T>(); 71 return !(bHasDefaultValue_ = true); 72 } 64 73 } 65 else66 {67 this->value_ = zeroise<T>();68 return !(bHasDefaultValue_ = true);69 }70 }71 74 72 inline bool getValue(char* value) const { return ConvertValue<T, char >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */73 inline bool getValue(unsigned char* value) const { return ConvertValue<T, unsigned char >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */74 inline bool getValue(short* value) const { return ConvertValue<T, short >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */75 inline bool getValue(unsigned short* value) const { return ConvertValue<T, unsigned short >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */76 inline bool getValue(int* value) const { return ConvertValue<T, int >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */77 inline bool getValue(unsigned int* value) const { return ConvertValue<T, unsigned int >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */78 inline bool getValue(long* value) const { return ConvertValue<T, long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */79 inline bool getValue(unsigned long* value) const { return ConvertValue<T, unsigned long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */80 inline bool getValue(long long* value) const { return ConvertValue<T, long long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */81 inline bool getValue(unsigned long long* value) const { return ConvertValue<T, unsigned long long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */82 inline bool getValue(float* value) const { return ConvertValue<T, float >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */83 inline bool getValue(double* value) const { return ConvertValue<T, double >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */84 inline bool getValue(long double* value) const { return ConvertValue<T, long double >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */85 inline bool getValue(bool* value) const { return ConvertValue<T, bool >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */86 inline bool getValue(void** value) const { return ConvertValue<T, void* >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */87 inline bool getValue(std::string* value) const { return ConvertValue<T, std::string >(value, value_, zeroise<std::string> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */88 inline bool getValue(orxonox::Vector2* value) const { return ConvertValue<T, orxonox::Vector2 >(value, value_, zeroise<orxonox::Vector2> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */89 inline bool getValue(orxonox::Vector3* value) const { return ConvertValue<T, orxonox::Vector3 >(value, value_, zeroise<orxonox::Vector3> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */90 inline bool getValue(orxonox::Vector4* value) const { return ConvertValue<T, orxonox::Vector4 >(value, value_, zeroise<orxonox::Vector4> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */91 inline bool getValue(orxonox::ColourValue* value) const { return ConvertValue<T, orxonox::ColourValue>(value, value_, zeroise<orxonox::ColourValue>()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */92 inline bool getValue(orxonox::Quaternion* value) const { return ConvertValue<T, orxonox::Quaternion >(value, value_, zeroise<orxonox::Quaternion> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */93 inline bool getValue(orxonox::Radian* value) const { return ConvertValue<T, orxonox::Radian >(value, value_, zeroise<orxonox::Radian> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */94 inline bool getValue(orxonox::Degree* value) const { return ConvertValue<T, orxonox::Degree >(value, value_, zeroise<orxonox::Degree> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */75 inline bool getValue(char* value) const { return ConvertValue<T, char >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 76 inline bool getValue(unsigned char* value) const { return ConvertValue<T, unsigned char >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 77 inline bool getValue(short* value) const { return ConvertValue<T, short >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 78 inline bool getValue(unsigned short* value) const { return ConvertValue<T, unsigned short >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 79 inline bool getValue(int* value) const { return ConvertValue<T, int >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 80 inline bool getValue(unsigned int* value) const { return ConvertValue<T, unsigned int >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 81 inline bool getValue(long* value) const { return ConvertValue<T, long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 82 inline bool getValue(unsigned long* value) const { return ConvertValue<T, unsigned long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 83 inline bool getValue(long long* value) const { return ConvertValue<T, long long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 84 inline bool getValue(unsigned long long* value) const { return ConvertValue<T, unsigned long long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 85 inline bool getValue(float* value) const { return ConvertValue<T, float >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 86 inline bool getValue(double* value) const { return ConvertValue<T, double >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 87 inline bool getValue(long double* value) const { return ConvertValue<T, long double >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 88 inline bool getValue(bool* value) const { return ConvertValue<T, bool >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 89 inline bool getValue(void** value) const { return ConvertValue<T, void* >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 90 inline bool getValue(std::string* value) const { return ConvertValue<T, std::string >(value, value_, zeroise<std::string> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 91 inline bool getValue(orxonox::Vector2* value) const { return ConvertValue<T, orxonox::Vector2 >(value, value_, zeroise<orxonox::Vector2> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 92 inline bool getValue(orxonox::Vector3* value) const { return ConvertValue<T, orxonox::Vector3 >(value, value_, zeroise<orxonox::Vector3> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 93 inline bool getValue(orxonox::Vector4* value) const { return ConvertValue<T, orxonox::Vector4 >(value, value_, zeroise<orxonox::Vector4> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 94 inline bool getValue(orxonox::ColourValue* value) const { return ConvertValue<T, orxonox::ColourValue>(value, value_, zeroise<orxonox::ColourValue>()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 95 inline bool getValue(orxonox::Quaternion* value) const { return ConvertValue<T, orxonox::Quaternion >(value, value_, zeroise<orxonox::Quaternion> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 96 inline bool getValue(orxonox::Radian* value) const { return ConvertValue<T, orxonox::Radian >(value, value_, zeroise<orxonox::Radian> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 97 inline bool getValue(orxonox::Degree* value) const { return ConvertValue<T, orxonox::Degree >(value, value_, zeroise<orxonox::Degree> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 95 98 96 inline bool setValue(const char& value) { return !(bHasDefaultValue_ = !ConvertValue<char , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */97 inline bool setValue(const unsigned char& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned char , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */98 inline bool setValue(const short& value) { return !(bHasDefaultValue_ = !ConvertValue<short , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */99 inline bool setValue(const unsigned short& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned short , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */100 inline bool setValue(const int& value) { return !(bHasDefaultValue_ = !ConvertValue<int , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */101 inline bool setValue(const unsigned int& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned int , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */102 inline bool setValue(const long& value) { return !(bHasDefaultValue_ = !ConvertValue<long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */103 inline bool setValue(const unsigned long& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */104 inline bool setValue(const long long& value) { return !(bHasDefaultValue_ = !ConvertValue<long long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */105 inline bool setValue(const unsigned long long& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned long long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */106 inline bool setValue(const float& value) { return !(bHasDefaultValue_ = !ConvertValue<float , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */107 inline bool setValue(const double& value) { return !(bHasDefaultValue_ = !ConvertValue<double , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */108 inline bool setValue(const long double& value) { return !(bHasDefaultValue_ = !ConvertValue<long double , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */109 inline bool setValue(const bool& value) { return !(bHasDefaultValue_ = !ConvertValue<bool , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */110 inline bool setValue( void* const& value) { return !(bHasDefaultValue_ = !ConvertValue<void* , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */111 inline bool setValue(const std::string& value) { return !(bHasDefaultValue_ = !ConvertValue<std::string , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */112 inline bool setValue(const orxonox::Vector2& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Vector2 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */113 inline bool setValue(const orxonox::Vector3& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Vector3 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */114 inline bool setValue(const orxonox::Vector4& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Vector4 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */115 inline bool setValue(const orxonox::ColourValue& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::ColourValue, T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */116 inline bool setValue(const orxonox::Quaternion& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Quaternion , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */117 inline bool setValue(const orxonox::Radian& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Radian , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */118 inline bool setValue(const orxonox::Degree& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Degree , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */99 inline bool setValue(const char& value) { return !(bHasDefaultValue_ = !ConvertValue<char , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 100 inline bool setValue(const unsigned char& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned char , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 101 inline bool setValue(const short& value) { return !(bHasDefaultValue_ = !ConvertValue<short , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 102 inline bool setValue(const unsigned short& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned short , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 103 inline bool setValue(const int& value) { return !(bHasDefaultValue_ = !ConvertValue<int , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 104 inline bool setValue(const unsigned int& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned int , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 105 inline bool setValue(const long& value) { return !(bHasDefaultValue_ = !ConvertValue<long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 106 inline bool setValue(const unsigned long& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 107 inline bool setValue(const long long& value) { return !(bHasDefaultValue_ = !ConvertValue<long long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 108 inline bool setValue(const unsigned long long& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned long long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 109 inline bool setValue(const float& value) { return !(bHasDefaultValue_ = !ConvertValue<float , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 110 inline bool setValue(const double& value) { return !(bHasDefaultValue_ = !ConvertValue<double , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 111 inline bool setValue(const long double& value) { return !(bHasDefaultValue_ = !ConvertValue<long double , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 112 inline bool setValue(const bool& value) { return !(bHasDefaultValue_ = !ConvertValue<bool , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 113 inline bool setValue( void* const& value) { return !(bHasDefaultValue_ = !ConvertValue<void* , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 114 inline bool setValue(const std::string& value) { return !(bHasDefaultValue_ = !ConvertValue<std::string , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 115 inline bool setValue(const orxonox::Vector2& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Vector2 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 116 inline bool setValue(const orxonox::Vector3& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Vector3 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 117 inline bool setValue(const orxonox::Vector4& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Vector4 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 118 inline bool setValue(const orxonox::ColourValue& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::ColourValue, T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 119 inline bool setValue(const orxonox::Quaternion& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Quaternion , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 120 inline bool setValue(const orxonox::Radian& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Radian , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 121 inline bool setValue(const orxonox::Degree& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Degree , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 119 122 120 inline operator char() const { return getConvertedValue<T, char> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */121 inline operator unsigned char() const { return getConvertedValue<T, unsigned char> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */122 inline operator short() const { return getConvertedValue<T, short> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */123 inline operator unsigned short() const { return getConvertedValue<T, unsigned short> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */124 inline operator int() const { return getConvertedValue<T, int> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */125 inline operator unsigned int() const { return getConvertedValue<T, unsigned int> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */126 inline operator long() const { return getConvertedValue<T, long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */127 inline operator unsigned long() const { return getConvertedValue<T, unsigned long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */128 inline operator long long() const { return getConvertedValue<T, long long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */129 inline operator unsigned long long() const { return getConvertedValue<T, unsigned long long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */130 inline operator float() const { return getConvertedValue<T, float> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */131 inline operator double() const { return getConvertedValue<T, double> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */132 inline operator long double() const { return getConvertedValue<T, long double> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */133 inline operator bool() const { return getConvertedValue<T, bool> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */134 inline operator void*() const { return getConvertedValue<T, void*> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */135 inline operator std::string() const { return getConvertedValue<T, std::string> (this->value_, zeroise<std::string >()); } /** @brief Returns the current value, converted to the requested type. */136 inline operator orxonox::Vector2() const { return getConvertedValue<T, orxonox::Vector2> (this->value_, zeroise<orxonox::Vector2 >()); } /** @brief Returns the current value, converted to the requested type. */137 inline operator orxonox::Vector3() const { return getConvertedValue<T, orxonox::Vector3> (this->value_, zeroise<orxonox::Vector3 >()); } /** @brief Returns the current value, converted to the requested type. */138 inline operator orxonox::Vector4() const { return getConvertedValue<T, orxonox::Vector4> (this->value_, zeroise<orxonox::Vector4 >()); } /** @brief Returns the current value, converted to the requested type. */139 inline operator orxonox::ColourValue() const { return getConvertedValue<T, orxonox::ColourValue>(this->value_, zeroise<orxonox::ColourValue>()); } /** @brief Returns the current value, converted to the requested type. */140 inline operator orxonox::Quaternion() const { return getConvertedValue<T, orxonox::Quaternion> (this->value_, zeroise<orxonox::Quaternion >()); } /** @brief Returns the current value, converted to the requested type. */141 inline operator orxonox::Radian() const { return getConvertedValue<T, orxonox::Radian> (this->value_, zeroise<orxonox::Radian >()); } /** @brief Returns the current value, converted to the requested type. */142 inline operator orxonox::Degree() const { return getConvertedValue<T, orxonox::Degree> (this->value_, zeroise<orxonox::Degree >()); } /** @brief Returns the current value, converted to the requested type. */123 inline operator char() const { return getConvertedValue<T, char> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 124 inline operator unsigned char() const { return getConvertedValue<T, unsigned char> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 125 inline operator short() const { return getConvertedValue<T, short> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 126 inline operator unsigned short() const { return getConvertedValue<T, unsigned short> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 127 inline operator int() const { return getConvertedValue<T, int> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 128 inline operator unsigned int() const { return getConvertedValue<T, unsigned int> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 129 inline operator long() const { return getConvertedValue<T, long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 130 inline operator unsigned long() const { return getConvertedValue<T, unsigned long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 131 inline operator long long() const { return getConvertedValue<T, long long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 132 inline operator unsigned long long() const { return getConvertedValue<T, unsigned long long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 133 inline operator float() const { return getConvertedValue<T, float> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 134 inline operator double() const { return getConvertedValue<T, double> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 135 inline operator long double() const { return getConvertedValue<T, long double> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 136 inline operator bool() const { return getConvertedValue<T, bool> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 137 inline operator void*() const { return getConvertedValue<T, void*> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 138 inline operator std::string() const { return getConvertedValue<T, std::string> (this->value_, zeroise<std::string >()); } /** @brief Returns the current value, converted to the requested type. */ 139 inline operator orxonox::Vector2() const { return getConvertedValue<T, orxonox::Vector2> (this->value_, zeroise<orxonox::Vector2 >()); } /** @brief Returns the current value, converted to the requested type. */ 140 inline operator orxonox::Vector3() const { return getConvertedValue<T, orxonox::Vector3> (this->value_, zeroise<orxonox::Vector3 >()); } /** @brief Returns the current value, converted to the requested type. */ 141 inline operator orxonox::Vector4() const { return getConvertedValue<T, orxonox::Vector4> (this->value_, zeroise<orxonox::Vector4 >()); } /** @brief Returns the current value, converted to the requested type. */ 142 inline operator orxonox::ColourValue() const { return getConvertedValue<T, orxonox::ColourValue>(this->value_, zeroise<orxonox::ColourValue>()); } /** @brief Returns the current value, converted to the requested type. */ 143 inline operator orxonox::Quaternion() const { return getConvertedValue<T, orxonox::Quaternion> (this->value_, zeroise<orxonox::Quaternion >()); } /** @brief Returns the current value, converted to the requested type. */ 144 inline operator orxonox::Radian() const { return getConvertedValue<T, orxonox::Radian> (this->value_, zeroise<orxonox::Radian >()); } /** @brief Returns the current value, converted to the requested type. */ 145 inline operator orxonox::Degree() const { return getConvertedValue<T, orxonox::Degree> (this->value_, zeroise<orxonox::Degree >()); } /** @brief Returns the current value, converted to the requested type. */ 143 146 144 /** @brief Puts the current value on the stream */145 inline void toString(std::ostream& outstream) const { outstream << this->value_; }147 /** @brief Puts the current value on the stream */ 148 inline void toString(std::ostream& outstream) const { outstream << this->value_; } 146 149 147 T value_; //!< The stored value 148 }; 150 T value_; //!< The stored value 151 }; 152 } 149 153 150 154 #endif /* _MultiTypeValue_H__ */ -
code/trunk/src/util/OutputBuffer.cc
r1791 r2171 28 28 29 29 /** 30 @file OutputBuffer.cc30 @file 31 31 @brief Implementation of the OutputBuffer. 32 32 */ -
code/trunk/src/util/OutputBuffer.h
r1854 r2171 28 28 29 29 /** 30 @file OutputBuffer.h30 @file 31 31 @brief Declaration of the OutputBuffer class. 32 32 … … 58 58 an OutputBuffer and this buffer changes. 59 59 */ 60 class _UtilExportOutputBufferListener60 class OutputBufferListener 61 61 { 62 62 friend class OutputBuffer; -
code/trunk/src/util/OutputHandler.cc
r2087 r2171 28 28 29 29 /** 30 @file OutputHandler.cc30 @file 31 31 @brief Implementation of the OutputHandler class. 32 32 */ -
code/trunk/src/util/OutputHandler.h
r1791 r2171 28 28 29 29 /** 30 @file OutputHandler.h30 @file 31 31 @brief Definition of the OutputHandler class. 32 32 -
code/trunk/src/util/SignalHandler.cc
- Property svn:mergeinfo changed
/code/branches/objecthierarchy/src/util/SignalHandler.cc merged: 2111
r2103 r2171 40 40 #include <cstring> 41 41 42 SignalHandler * SignalHandler::singletonRef = NULL; 42 namespace orxonox 43 { 44 SignalHandler * SignalHandler::singletonRef = NULL; 45 } 43 46 44 47 #if ORXONOX_PLATFORM != ORXONOX_PLATFORM_WIN32 … … 49 52 #include <X11/keysym.h> 50 53 51 bool SignalHandler::bXAutoKeyRepeatOn_ = false; 52 53 SignalHandler::SignalHandler() 54 namespace orxonox 54 55 { 56 bool SignalHandler::bXAutoKeyRepeatOn_ = false; 57 58 SignalHandler::SignalHandler() 59 { 60 } 61 62 /** 63 * register signal handlers for SIGSEGV and SIGABRT 64 * @param appName path to executable eg argv[0] 65 * @param filename filename to append backtrace to 66 */ 67 void SignalHandler::doCatch( const std::string & appName, const std::string & filename ) 68 { 69 this->appName = appName; 70 this->filename = filename; 71 72 // prepare for restoring XAutoKeyRepeat 73 Display* display; 74 if ((display = XOpenDisplay(0))) 75 { 76 XKeyboardState oldState; 77 XGetKeyboardControl(display, &oldState); 78 if (oldState.global_auto_repeat == AutoRepeatModeOn) 79 bXAutoKeyRepeatOn_ = true; 80 else 81 bXAutoKeyRepeatOn_ = false; 82 XCloseDisplay(display); 83 } 84 else 85 { 86 std::cout << "Warning: couldn't open X display to restore XAutoKeyRepeat." << std::endl; 87 bXAutoKeyRepeatOn_ = false; 88 } 89 90 91 // make sure doCatch is only called once without calling dontCatch 92 assert( sigRecList.size() == 0 ); 93 94 catchSignal( SIGSEGV ); 95 catchSignal( SIGABRT ); 96 catchSignal( SIGILL ); 97 } 98 99 /** 100 * restore previous signal handlers 101 */ 102 void SignalHandler::dontCatch() 103 { 104 for ( SignalRecList::iterator it = sigRecList.begin(); it != sigRecList.end(); it++ ) 105 { 106 signal( it->signal, it->handler ); 107 } 108 109 sigRecList.clear(); 110 } 111 112 /** 113 * catch signal sig 114 * @param sig signal to catch 115 */ 116 void SignalHandler::catchSignal( int sig ) 117 { 118 sig_t handler = signal( sig, SignalHandler::sigHandler ); 119 120 assert( handler != SIG_ERR ); 121 122 SignalRec rec; 123 rec.signal = sig; 124 rec.handler = handler; 125 126 sigRecList.push_front( rec ); 127 } 128 129 /** 130 * sigHandler is called when receiving signals 131 * @param sig 132 */ 133 void SignalHandler::sigHandler( int sig ) 134 { 135 for ( SignalCallbackList::iterator it = SignalHandler::getInstance()->callbackList.begin(); it != SignalHandler::getInstance()->callbackList.end(); it++ ) 136 { 137 (*(it->cb))( it->someData ); 138 } 139 140 std::string sigName = "UNKNOWN"; 141 142 switch ( sig ) 143 { 144 case SIGSEGV: 145 sigName = "SIGSEGV"; 146 break; 147 case SIGABRT: 148 sigName = "SIGABRT"; 149 break; 150 case SIGILL: 151 sigName = "SIGILL"; 152 break; 153 } 154 155 if (bXAutoKeyRepeatOn_) 156 { 157 std::cout << "Trying to restore XAutoKeyRepeat" << std::endl; 158 Display* display; 159 if ((display = XOpenDisplay(0))) 160 { 161 XAutoRepeatOn(display); 162 XCloseDisplay(display); 163 } 164 } 165 166 COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "try to write backtrace to file orxonox.log" << std::endl; 167 168 int sigPipe[2]; 169 if ( pipe(sigPipe) == -1 ) 170 { 171 perror("pipe failed!\n"); 172 exit(EXIT_FAILURE); 173 } 174 175 int sigPid = fork(); 176 177 if ( sigPid == -1 ) 178 { 179 perror("fork failed!\n"); 180 exit(EXIT_FAILURE); 181 } 182 183 // gdb will be attached to this process 184 if ( sigPid == 0 ) 185 { 186 getInstance()->dontCatch(); 187 // wait for message from parent when it has attached gdb 188 int someData; 189 190 read( sigPipe[0], &someData, sizeof(someData) ); 191 192 if ( someData != 0x12345678 ) 193 { 194 COUT(0) << "something went wrong :(" << std::endl; 195 } 196 197 return; 198 } 199 200 int gdbIn[2]; 201 int gdbOut[2]; 202 int gdbErr[2]; 203 204 if ( pipe(gdbIn) == -1 || pipe(gdbOut) == -1 || pipe(gdbErr) == -1 ) 205 { 206 perror("pipe failed!\n"); 207 kill( sigPid, SIGTERM ); 208 waitpid( sigPid, NULL, 0 ); 209 exit(EXIT_FAILURE); 210 } 211 212 int gdbPid = fork(); 213 // this process will run gdb 214 215 if ( gdbPid == -1 ) 216 { 217 perror("fork failed\n"); 218 kill( sigPid, SIGTERM ); 219 waitpid( sigPid, NULL, 0 ); 220 exit(EXIT_FAILURE); 221 } 222 223 if ( gdbPid == 0 ) 224 { 225 // start gdb 226 227 close(gdbIn[1]); 228 close(gdbOut[0]); 229 close(gdbErr[0]); 230 231 dup2( gdbIn[0], STDIN_FILENO ); 232 dup2( gdbOut[1], STDOUT_FILENO ); 233 dup2( gdbErr[1], STDERR_FILENO ); 234 235 execlp( "sh", "sh", "-c", "gdb", (void*)NULL); 236 } 237 238 char cmd[256]; 239 snprintf( cmd, 256, "file %s\nattach %d\nc\n", getInstance()->appName.c_str(), sigPid ); 240 write( gdbIn[1], cmd, strlen(cmd) ); 241 242 int charsFound = 0; 243 int promptFound = 0; 244 char byte; 245 while ( read( gdbOut[0], &byte, 1 ) == 1 ) 246 { 247 if ( 248 charsFound == 0 && byte == '(' || 249 charsFound == 1 && byte == 'g' || 250 charsFound == 2 && byte == 'd' || 251 charsFound == 3 && byte == 'b' || 252 charsFound == 4 && byte == ')' || 253 charsFound == 5 && byte == ' ' 254 ) 255 charsFound++; 256 else 257 charsFound = 0; 258 259 if ( charsFound == 6 ) 260 { 261 promptFound++; 262 charsFound = 0; 263 } 264 265 if ( promptFound == 3 ) 266 { 267 break; 268 } 269 } 270 271 int someData = 0x12345678; 272 write( sigPipe[1], &someData, sizeof(someData) ); 273 274 write( gdbIn[1], "bt\nk\nq\n", 7 ); 275 276 277 charsFound = 0; 278 promptFound = 0; 279 std::string bt; 280 while ( read( gdbOut[0], &byte, 1 ) == 1 ) 281 { 282 bt += std::string( &byte, 1 ); 283 284 if ( 285 charsFound == 0 && byte == '(' || 286 charsFound == 1 && byte == 'g' || 287 charsFound == 2 && byte == 'd' || 288 charsFound == 3 && byte == 'b' || 289 charsFound == 4 && byte == ')' || 290 charsFound == 5 && byte == ' ' 291 ) 292 charsFound++; 293 else 294 charsFound = 0; 295 296 if ( charsFound == 6 ) 297 { 298 promptFound++; 299 charsFound = 0; 300 bt += "\n"; 301 } 302 303 if ( promptFound == 3 ) 304 { 305 break; 306 } 307 } 308 309 310 waitpid( sigPid, NULL, 0 ); 311 waitpid( gdbPid, NULL, 0 ); 312 313 int wsRemoved = 0; 314 315 while ( wsRemoved < 2 && bt.length() > 0 ) 316 { 317 if ( bt[1] == '\n' ) 318 wsRemoved++; 319 bt.erase(0, 1); 320 } 321 322 if ( bt.length() > 0 ) 323 bt.erase(0, 1); 324 325 time_t now = time(NULL); 326 327 std::string timeString = "\n\n\n\n" 328 "=======================================================\n" 329 "= time: " + std::string(ctime(&now)) + 330 "=======================================================\n"; 331 bt.insert(0, timeString); 332 333 FILE * f = fopen( getInstance()->filename.c_str(), "a" ); 334 335 if ( !f ) 336 { 337 perror( ( std::string( "could not append to " ) + getInstance()->filename ).c_str() ); 338 exit(EXIT_FAILURE); 339 } 340 341 if ( fwrite( bt.c_str(), 1, bt.length(), f ) != bt.length() ) 342 { 343 COUT(0) << "could not write " << bt.length() << " byte to " << getInstance()->filename << std::endl; 344 exit(EXIT_FAILURE); 345 } 346 347 exit(EXIT_FAILURE); 348 } 349 350 void SignalHandler::registerCallback( SignalCallback cb, void * someData ) 351 { 352 SignalCallbackRec rec; 353 rec.cb = cb; 354 rec.someData = someData; 355 356 callbackList.push_back(rec); 357 } 55 358 } 56 359 57 /**58 * register signal handlers for SIGSEGV and SIGABRT59 * @param appName path to executable eg argv[0]60 * @param filename filename to append backtrace to61 */62 void SignalHandler::doCatch( const std::string & appName, const std::string & filename )63 {64 this->appName = appName;65 this->filename = filename;66 67 // prepare for restoring XAutoKeyRepeat68 Display* display;69 if ((display = XOpenDisplay(0)))70 {71 XKeyboardState oldState;72 XGetKeyboardControl(display, &oldState);73 if (oldState.global_auto_repeat == AutoRepeatModeOn)74 bXAutoKeyRepeatOn_ = true;75 else76 bXAutoKeyRepeatOn_ = false;77 XCloseDisplay(display);78 }79 else80 {81 std::cout << "Warning: couldn't open X display to restore XAutoKeyRepeat." << std::endl;82 bXAutoKeyRepeatOn_ = false;83 }84 85 86 // make sure doCatch is only called once without calling dontCatch87 assert( sigRecList.size() == 0 );88 89 catchSignal( SIGSEGV );90 catchSignal( SIGABRT );91 catchSignal( SIGILL );92 }93 94 /**95 * restore previous signal handlers96 */97 void SignalHandler::dontCatch()98 {99 for ( SignalRecList::iterator it = sigRecList.begin(); it != sigRecList.end(); it++ )100 {101 signal( it->signal, it->handler );102 }103 104 sigRecList.clear();105 }106 107 /**108 * catch signal sig109 * @param sig signal to catch110 */111 void SignalHandler::catchSignal( int sig )112 {113 sig_t handler = signal( sig, SignalHandler::sigHandler );114 115 assert( handler != SIG_ERR );116 117 SignalRec rec;118 rec.signal = sig;119 rec.handler = handler;120 121 sigRecList.push_front( rec );122 }123 124 /**125 * sigHandler is called when receiving signals126 * @param sig127 */128 void SignalHandler::sigHandler( int sig )129 {130 for ( SignalCallbackList::iterator it = SignalHandler::getInstance()->callbackList.begin(); it != SignalHandler::getInstance()->callbackList.end(); it++ )131 {132 (*(it->cb))( it->someData );133 }134 135 std::string sigName = "UNKNOWN";136 137 switch ( sig )138 {139 case SIGSEGV:140 sigName = "SIGSEGV";141 break;142 case SIGABRT:143 sigName = "SIGABRT";144 break;145 case SIGILL:146 sigName = "SIGILL";147 break;148 }149 150 if (bXAutoKeyRepeatOn_)151 {152 std::cout << "Trying to restore XAutoKeyRepeat" << std::endl;153 Display* display;154 if ((display = XOpenDisplay(0)))155 {156 XAutoRepeatOn(display);157 XCloseDisplay(display);158 }159 }160 161 COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "try to write backtrace to file orxonox.log" << std::endl;162 163 int sigPipe[2];164 if ( pipe(sigPipe) == -1 )165 {166 perror("pipe failed!\n");167 exit(EXIT_FAILURE);168 }169 170 int sigPid = fork();171 172 if ( sigPid == -1 )173 {174 perror("fork failed!\n");175 exit(EXIT_FAILURE);176 }177 178 // gdb will be attached to this process179 if ( sigPid == 0 )180 {181 getInstance()->dontCatch();182 // wait for message from parent when it has attached gdb183 int someData;184 185 read( sigPipe[0], &someData, sizeof(someData) );186 187 if ( someData != 0x12345678 )188 {189 COUT(0) << "something went wrong :(" << std::endl;190 }191 192 return;193 }194 195 int gdbIn[2];196 int gdbOut[2];197 int gdbErr[2];198 199 if ( pipe(gdbIn) == -1 || pipe(gdbOut) == -1 || pipe(gdbErr) == -1 )200 {201 perror("pipe failed!\n");202 kill( sigPid, SIGTERM );203 waitpid( sigPid, NULL, 0 );204 exit(EXIT_FAILURE);205 }206 207 int gdbPid = fork();208 // this process will run gdb209 210 if ( gdbPid == -1 )211 {212 perror("fork failed\n");213 kill( sigPid, SIGTERM );214 waitpid( sigPid, NULL, 0 );215 exit(EXIT_FAILURE);216 }217 218 if ( gdbPid == 0 )219 {220 // start gdb221 222 close(gdbIn[1]);223 close(gdbOut[0]);224 close(gdbErr[0]);225 226 dup2( gdbIn[0], STDIN_FILENO );227 dup2( gdbOut[1], STDOUT_FILENO );228 dup2( gdbErr[1], STDERR_FILENO );229 230 execlp( "sh", "sh", "-c", "gdb", (void*)NULL);231 }232 233 char cmd[256];234 snprintf( cmd, 256, "file %s\nattach %d\nc\n", getInstance()->appName.c_str(), sigPid );235 write( gdbIn[1], cmd, strlen(cmd) );236 237 int charsFound = 0;238 int promptFound = 0;239 char byte;240 while ( read( gdbOut[0], &byte, 1 ) == 1 )241 {242 if (243 charsFound == 0 && byte == '(' ||244 charsFound == 1 && byte == 'g' ||245 charsFound == 2 && byte == 'd' ||246 charsFound == 3 && byte == 'b' ||247 charsFound == 4 && byte == ')' ||248 charsFound == 5 && byte == ' '249 )250 charsFound++;251 else252 charsFound = 0;253 254 if ( charsFound == 6 )255 {256 promptFound++;257 charsFound = 0;258 }259 260 if ( promptFound == 3 )261 {262 break;263 }264 }265 266 int someData = 0x12345678;267 write( sigPipe[1], &someData, sizeof(someData) );268 269 write( gdbIn[1], "bt\nk\nq\n", 7 );270 271 272 charsFound = 0;273 promptFound = 0;274 std::string bt;275 while ( read( gdbOut[0], &byte, 1 ) == 1 )276 {277 bt += std::string( &byte, 1 );278 279 if (280 charsFound == 0 && byte == '(' ||281 charsFound == 1 && byte == 'g' ||282 charsFound == 2 && byte == 'd' ||283 charsFound == 3 && byte == 'b' ||284 charsFound == 4 && byte == ')' ||285 charsFound == 5 && byte == ' '286 )287 charsFound++;288 else289 charsFound = 0;290 291 if ( charsFound == 6 )292 {293 promptFound++;294 charsFound = 0;295 bt += "\n";296 }297 298 if ( promptFound == 3 )299 {300 break;301 }302 }303 304 305 waitpid( sigPid, NULL, 0 );306 waitpid( gdbPid, NULL, 0 );307 308 int wsRemoved = 0;309 310 while ( wsRemoved < 2 && bt.length() > 0 )311 {312 if ( bt[1] == '\n' )313 wsRemoved++;314 bt.erase(0, 1);315 }316 317 if ( bt.length() > 0 )318 bt.erase(0, 1);319 320 time_t now = time(NULL);321 322 std::string timeString = "\n\n\n\n"323 "=======================================================\n"324 "= time: " + std::string(ctime(&now)) +325 "=======================================================\n";326 bt.insert(0, timeString);327 328 FILE * f = fopen( getInstance()->filename.c_str(), "a" );329 330 if ( !f )331 {332 perror( ( std::string( "could not append to " ) + getInstance()->filename ).c_str() );333 exit(EXIT_FAILURE);334 }335 336 if ( fwrite( bt.c_str(), 1, bt.length(), f ) != bt.length() )337 {338 COUT(0) << "could not write " << bt.length() << " byte to " << getInstance()->filename << std::endl;339 exit(EXIT_FAILURE);340 }341 342 exit(EXIT_FAILURE);343 }344 345 void SignalHandler::registerCallback( SignalCallback cb, void * someData )346 {347 SignalCallbackRec rec;348 rec.cb = cb;349 rec.someData = someData;350 351 callbackList.push_back(rec);352 }353 354 360 #endif /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */ - Property svn:mergeinfo changed
-
code/trunk/src/util/SignalHandler.h
- Property svn:mergeinfo changed
/code/branches/objecthierarchy/src/util/SignalHandler.h merged: 2111
r2103 r2171 40 40 #include <string> 41 41 42 typedef int (*SignalCallback)( void * someData ); 42 namespace orxonox 43 { 44 typedef int (*SignalCallback)( void * someData ); 45 } 43 46 44 47 #if ORXONOX_PLATFORM != ORXONOX_PLATFORM_WIN32 45 48 #include <signal.h> 46 49 47 struct SignalRec 50 namespace orxonox 48 51 { 49 int signal; 50 sig_t handler; 51 }; 52 struct SignalRec 53 { 54 int signal; 55 sig_t handler; 56 }; 52 57 53 struct SignalCallbackRec54 {55 SignalCallback cb;56 void * someData;57 };58 struct SignalCallbackRec 59 { 60 SignalCallback cb; 61 void * someData; 62 }; 58 63 59 64 60 typedef std::list<SignalRec> SignalRecList;61 typedef std::list<SignalCallbackRec> SignalCallbackList;65 typedef std::list<SignalRec> SignalRecList; 66 typedef std::list<SignalCallbackRec> SignalCallbackList; 62 67 63 class SignalHandler64 {65 private:66 SignalHandler();67 public:68 inline static SignalHandler* getInstance() { if (!SignalHandler::singletonRef) SignalHandler::singletonRef = new SignalHandler(); return SignalHandler::singletonRef; }69 ~SignalHandler(){ SignalHandler::singletonRef = NULL; }68 class SignalHandler 69 { 70 private: 71 SignalHandler(); 72 public: 73 inline static SignalHandler* getInstance() { if (!SignalHandler::singletonRef) SignalHandler::singletonRef = new SignalHandler(); return SignalHandler::singletonRef; } 74 ~SignalHandler(){ SignalHandler::singletonRef = NULL; } 70 75 71 void registerCallback( SignalCallback cb, void * someData );76 void registerCallback( SignalCallback cb, void * someData ); 72 77 73 void doCatch( const std::string & appName, const std::string & filename );74 void dontCatch();78 void doCatch( const std::string & appName, const std::string & filename ); 79 void dontCatch(); 75 80 76 private:77 static void sigHandler( int sig );81 private: 82 static void sigHandler( int sig ); 78 83 79 void catchSignal( int sig );80 SignalRecList sigRecList;84 void catchSignal( int sig ); 85 SignalRecList sigRecList; 81 86 82 SignalCallbackList callbackList;87 SignalCallbackList callbackList; 83 88 84 static SignalHandler * singletonRef;89 static SignalHandler * singletonRef; 85 90 86 std::string appName;87 std::string filename;91 std::string appName; 92 std::string filename; 88 93 89 // used to turn on KeyAutoRepeat if OIS crashes 90 static bool bXAutoKeyRepeatOn_; 91 }; 94 // used to turn on KeyAutoRepeat if OIS crashes 95 static bool bXAutoKeyRepeatOn_; 96 }; 97 } 92 98 93 99 #else /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */ 94 100 95 class _UtilExport SignalHandler 101 namespace orxonox 96 102 { 97 public: 98 inline static SignalHandler* getInstance() { if (!SignalHandler::singletonRef) SignalHandler::singletonRef = new SignalHandler(); return SignalHandler::singletonRef; }; 99 void doCatch( const std::string & appName, const std::string & filename ) {}; 100 void dontCatch() {}; 101 void registerCallback( SignalCallback cb, void * someData ) {}; 103 class _UtilExport SignalHandler 104 { 105 public: 106 inline static SignalHandler* getInstance() { if (!SignalHandler::singletonRef) SignalHandler::singletonRef = new SignalHandler(); return SignalHandler::singletonRef; }; 107 void doCatch( const std::string & appName, const std::string & filename ) {}; 108 void dontCatch() {}; 109 void registerCallback( SignalCallback cb, void * someData ) {}; 102 110 103 private: 104 static SignalHandler * singletonRef; 105 }; 111 private: 112 static SignalHandler * singletonRef; 113 }; 114 } 106 115 107 116 #endif /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */ - Property svn:mergeinfo changed
-
code/trunk/src/util/Sleep.h
r1841 r2171 41 41 #include <winbase.h> 42 42 43 inline void usleep(DWORD dwMicroseconds) 43 namespace orxonox 44 44 { 45 Sleep(dwMicroseconds / 1000); 46 } 45 inline void usleep(DWORD dwMicroseconds) 46 { 47 Sleep(dwMicroseconds / 1000); 48 } 47 49 48 inline void msleep(DWORD dwMilliseconds)49 {50 Sleep(dwMilliseconds);51 }50 inline void msleep(DWORD dwMilliseconds) 51 { 52 Sleep(dwMilliseconds); 53 } 52 54 53 inline void sleep(DWORD dwSeconds) 54 { 55 Sleep(dwSeconds * 1000); 55 inline void sleep(DWORD dwSeconds) 56 { 57 Sleep(dwSeconds * 1000); 58 } 56 59 } 57 60 … … 60 63 #include <unistd.h> 61 64 62 inline void msleep(unsigned long msec) 65 namespace orxonox 63 66 { 64 usleep(msec * 1000); 67 inline void usleep(unsigned long usec) 68 { 69 ::usleep(usec); 70 } 71 inline void msleep(unsigned long msec) 72 { 73 ::usleep(msec * 1000); 74 } 75 inline void sleep(unsigned long sec) 76 { 77 ::usleep(sec * 1000000); 78 } 65 79 } 66 80 -
code/trunk/src/util/String.cc
r2087 r2171 28 28 29 29 /** 30 @file String.cc30 @file 31 31 @brief Implementation of several string manipulation functions. 32 32 */ … … 40 40 #include "Math.h" 41 41 42 std::string BLANKSTRING(""); 43 44 std::string getUniqueNumberString() 42 namespace orxonox 45 43 { 46 return convertToString(getUniqueNumber()); 44 std::string BLANKSTRING(""); 45 46 std::string getUniqueNumberString() 47 { 48 return convertToString(getUniqueNumber()); 49 } 50 51 /** 52 @brief Removes all whitespaces from a string. 53 @param str The string to strip 54 */ 55 void strip(std::string* str) 56 { 57 size_t pos; 58 while ((pos = (*str).find(" ")) < (*str).length()) 59 (*str).erase(pos, 1); 60 while ((pos = (*str).find("\t")) < (*str).length()) 61 (*str).erase(pos, 1); 62 while ((pos = (*str).find("\n")) < (*str).length()) 63 (*str).erase(pos, 1); 64 } 65 66 /** 67 @brief Returns a copy of a string without whitespaces. 68 @param str The string to strip 69 @return The stripped line 70 */ 71 std::string getStripped(const std::string& str) 72 { 73 std::string output = std::string(str); 74 strip(&output); 75 return output; 76 } 77 78 /** 79 @brief Returns a copy of a string without trailing whitespaces. 80 @param str The string 81 @return The modified copy 82 */ 83 std::string removeTrailingWhitespaces(const std::string& str) 84 { 85 size_t pos1 = 0; 86 int pos2 = str.size() - 1; 87 for (; pos1 < str.size() && (str[pos1] == ' ' || str[pos1] == '\t' || str[pos1] == '\n'); pos1++); 88 for (; pos2 > 0 && (str[pos2] == ' ' || str[pos2] == '\t' || str[pos2] == '\n'); pos2--); 89 return str.substr(pos1, pos2 - pos1 + 1); 90 } 91 92 /** 93 @brief Returns the position of the next quote in the string, starting with start. 94 @param str The string 95 @param start The startposition 96 @return The position of the next quote (std::string::npos if there is no next quote) 97 */ 98 size_t getNextQuote(const std::string& str, size_t start) 99 { 100 size_t quote = start - 1; 101 102 while ((quote = str.find('\"', quote + 1)) != std::string::npos) 103 { 104 size_t backslash = quote; 105 size_t numbackslashes = 0; 106 for (; backslash > 0; backslash--, numbackslashes++) 107 if (str[backslash - 1] != '\\') 108 break; 109 110 if (numbackslashes % 2 == 0) 111 break; 112 } 113 114 return quote; 115 } 116 117 /** 118 @brief Returns true if pos is between two quotes. 119 @param str The string 120 @param pos The position to check 121 @return True if pos is between two quotes 122 */ 123 bool isBetweenQuotes(const std::string& str, size_t pos) 124 { 125 if (pos == std::string::npos) 126 return false; 127 128 size_t quotecount = 0; 129 size_t quote = (size_t)-1; 130 while ((quote = getNextQuote(str, quote + 1)) < pos) 131 { 132 if (quote == pos) 133 return false; 134 quotecount++; 135 } 136 137 if (quote == std::string::npos) 138 return false; 139 140 return ((quotecount % 2) == 1); 141 } 142 143 /** 144 @brief Returns true if the string contains something like '..."between quotes"...'. 145 @param The string 146 @return True if there is something between quotes 147 */ 148 bool hasStringBetweenQuotes(const std::string& str) 149 { 150 size_t pos1 = getNextQuote(str, 0); 151 size_t pos2 = getNextQuote(str, pos1 + 1); 152 return (pos1 != std::string::npos && pos2 != std::string::npos && pos2 > pos1 + 1); 153 } 154 155 /** 156 @brief If the string contains something like '..."between quotes"...' then 'between quotes' gets returned (without quotes). 157 @param The string 158 @param The string between the quotes 159 */ 160 std::string getStringBetweenQuotes(const std::string& str) 161 { 162 size_t pos1 = getNextQuote(str, 0); 163 size_t pos2 = getNextQuote(str, pos1 + 1); 164 if (pos1 != std::string::npos && pos2 != std::string::npos) 165 return str.substr(pos1, pos2 - pos1 + 1); 166 else 167 return ""; 168 } 169 170 /** 171 @brief Removes enclosing quotes if available (including whitespaces at the outside of the quotes). 172 @brief str The string to strip 173 @return The string with removed quotes 174 */ 175 std::string stripEnclosingQuotes(const std::string& str) 176 { 177 size_t start = std::string::npos; 178 size_t end = 0; 179 180 for (size_t pos = 0; (pos < str.size()) && (pos < std::string::npos); pos++) 181 { 182 if (str[pos] == '"') 183 { 184 start = pos; 185 break; 186 } 187 188 if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n')) 189 return str; 190 } 191 192 for (size_t pos = str.size() - 1; pos < std::string::npos; pos--) 193 { 194 if (str[pos] == '"') 195 { 196 end = pos; 197 break; 198 } 199 200 if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n')) 201 return str; 202 } 203 204 if ((start != std::string::npos) && (end != 0)) 205 return str.substr(start + 1, end - start - 1); 206 else 207 return str; 208 } 209 210 /** 211 @brief Removes enclosing {braces} (braces must be exactly on the beginning and the end of the string). 212 @param str The string to strip 213 @return The striped string 214 */ 215 std::string stripEnclosingBraces(const std::string& str) 216 { 217 std::string output = str; 218 219 while (output.size() >= 2 && output[0] == '{' && output[output.size() - 1] == '}') 220 output = output.substr(1, output.size() - 2); 221 222 return output; 223 } 224 225 /** 226 @brief Determines if a string is a comment (starts with a comment-symbol). 227 @param str The string to check 228 @return True = it's a comment 229 230 A comment is defined by a leading '#', '%', ';' or '//'. 231 */ 232 bool isComment(const std::string& str) 233 { 234 // Strip the line, whitespaces are disturbing 235 std::string teststring = getStripped(str); 236 237 // There are four possible comment-symbols: 238 // 1) #comment in script-language style 239 // 2) %comment in matlab style 240 // 3) ;comment in unreal tournament config-file style 241 // 4) //comment in code style 242 if (teststring.size() >= 2) 243 { 244 if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';' || (teststring[0] == '/' && teststring[1] == '/')) 245 return true; 246 } 247 else if (teststring.size() == 1) 248 { 249 if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';') 250 return true; 251 } 252 253 return false; 254 } 255 256 /** 257 @brief Determines if a string is empty (contains only whitespaces). 258 @param str The string to check 259 @return True = it's empty 260 */ 261 bool isEmpty(const std::string& str) 262 { 263 std::string temp = getStripped(str); 264 return ((temp == "") || (temp.size() == 0)); 265 } 266 267 /** 268 @brief Determines if a string contains only numbers and maximal one '.'. 269 @param str The string to check 270 @return True = it's a number 271 */ 272 bool isNumeric(const std::string& str) 273 { 274 bool foundPoint = false; 275 276 for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) 277 { 278 if (((*it) < '0' || (*it) > '9')) 279 { 280 if ((*it) != '.' && !foundPoint) 281 foundPoint = true; 282 else 283 return false; 284 } 285 } 286 287 return true; 288 } 289 290 /** 291 @brief Adds backslashes to the given string which makes special chars visible. Existing slashes will be doubled. 292 @param str The string to manipulate 293 @return The string with added slashes 294 */ 295 std::string addSlashes(const std::string& str) 296 { 297 std::string output = str; 298 299 for (size_t pos = 0; (pos = output.find('\\', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\\\"); } 300 for (size_t pos = 0; (pos = output.find('\n', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\n"); } 301 for (size_t pos = 0; (pos = output.find('\t', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\t"); } 302 for (size_t pos = 0; (pos = output.find('\v', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\v"); } 303 for (size_t pos = 0; (pos = output.find('\b', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\b"); } 304 for (size_t pos = 0; (pos = output.find('\r', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\r"); } 305 for (size_t pos = 0; (pos = output.find('\f', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\f"); } 306 for (size_t pos = 0; (pos = output.find('\a', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\a"); } 307 for (size_t pos = 0; (pos = output.find('"', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\\""); } 308 for (size_t pos = 0; (pos = output.find('\0', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\0"); } 309 310 return output; 311 } 312 313 /** 314 @brief Removes backslashes from the given string. Double backslashes are interpreted as one backslash. 315 @param str The string to manipulate 316 @return The string with removed slashes 317 */ 318 std::string removeSlashes(const std::string& str) 319 { 320 if (str.size() <= 1) 321 return str; 322 323 std::string output = ""; 324 for (size_t pos = 0; pos < str.size() - 1; ) 325 { 326 if (str[pos] == '\\') 327 { 328 if (str[pos + 1] == '\\') { output += '\\'; pos += 2; continue; } 329 else if (str[pos + 1] == 'n') { output += '\n'; pos += 2; continue; } 330 else if (str[pos + 1] == 't') { output += '\t'; pos += 2; continue; } 331 else if (str[pos + 1] == 'v') { output += '\v'; pos += 2; continue; } 332 else if (str[pos + 1] == 'b') { output += '\b'; pos += 2; continue; } 333 else if (str[pos + 1] == 'r') { output += '\r'; pos += 2; continue; } 334 else if (str[pos + 1] == 'f') { output += '\f'; pos += 2; continue; } 335 else if (str[pos + 1] == 'a') { output += '\a'; pos += 2; continue; } 336 else if (str[pos + 1] == '"') { output += '"'; pos += 2; continue; } 337 else if (str[pos + 1] == '0') { output += '\0'; pos += 2; continue; } 338 } 339 output += str[pos]; 340 pos++; 341 if (pos == str.size() - 1) 342 output += str[pos]; 343 } 344 345 return output; 346 } 347 348 /** 349 @brief Replaces each char between A and Z with its lowercase equivalent. 350 @param str The string to convert 351 */ 352 void lowercase(std::string* str) 353 { 354 for (size_t i = 0; i < str->size(); ++i) 355 { 356 (*str)[i] = (char)tolower((*str)[i]); 357 } 358 } 359 360 /** 361 @brief Returns a copy of the given string without uppercase chars. 362 @param str The string 363 @return The copy 364 */ 365 std::string getLowercase(const std::string& str) 366 { 367 std::string output = std::string(str); 368 lowercase(&output); 369 return output; 370 } 371 372 /** 373 @brief Replaces each char between a and z with its uppercase equivalent. 374 @param str The string to convert 375 */ 376 void uppercase(std::string* str) 377 { 378 for (size_t i = 0; i < str->size(); ++i) 379 { 380 (*str)[i] = (char)toupper((*str)[i]); 381 } 382 } 383 384 /** 385 @brief Returns a copy of the given string without lowercase chars. 386 @param str The string 387 @return The copy 388 */ 389 std::string getUppercase(const std::string& str) 390 { 391 std::string output = std::string(str); 392 uppercase(&output); 393 return output; 394 } 395 396 /** 397 @brief Compares two strings ignoring different casing. 398 @param s1 First string 399 @param s2 Second string 400 */ 401 int nocaseCmp(const std::string& s1, const std::string& s2) 402 { 403 std::string::const_iterator it1=s1.begin(); 404 std::string::const_iterator it2=s2.begin(); 405 406 //stop when either string's end has been reached 407 while ( (it1!=s1.end()) && (it2!=s2.end()) ) 408 { 409 if(::toupper(*it1) != ::toupper(*it2)) //letters differ? 410 // return -1 to indicate smaller than, 1 otherwise 411 return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1; 412 //proceed to the next character in each string 413 ++it1; 414 ++it2; 415 } 416 size_t size1=s1.size(), size2=s2.size();// cache lengths 417 //return -1,0 or 1 according to strings' lengths 418 if (size1==size2) 419 return 0; 420 return (size1<size2) ? -1 : 1; 421 } 422 423 424 /** 425 @brief Compares the first 'len' chars of two strings ignoring different casing. 426 @param s1 First string 427 @param s2 Second string 428 @param len Maximal number of chars to compare 429 */ 430 int nocaseCmp(const std::string& s1, const std::string& s2, size_t len) 431 { 432 if (len == 0) 433 return 0; 434 std::string::const_iterator it1=s1.begin(); 435 std::string::const_iterator it2=s2.begin(); 436 437 //stop when either string's end has been reached 438 while ( (it1!=s1.end()) && (it2!=s2.end()) && len-- > 0) 439 { 440 if(::toupper(*it1) != ::toupper(*it2)) //letters differ? 441 // return -1 to indicate smaller than, 1 otherwise 442 return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1; 443 //proceed to the next character in each string 444 ++it1; 445 ++it2; 446 } 447 return 0; 448 } 449 450 /** 451 @brief Returns true if the string contains a comment, introduced by #, %, ; or //. 452 @param str The string 453 @return True if the string contains a comment 454 */ 455 bool hasComment(const std::string& str) 456 { 457 return (getCommentPosition(str) != std::string::npos); 458 } 459 460 /** 461 @brief If the string contains a comment, the comment gets returned (including the comment symbol), an empty string otherwise. 462 @param str The string 463 @return The comment 464 */ 465 std::string getComment(const std::string& str) 466 { 467 return str.substr(getCommentPosition(str)); 468 } 469 470 /** 471 @brief If the string contains a comment, the position of the comment-symbol gets returned, std::string::npos otherwise. 472 @param str The string 473 @return The position 474 */ 475 size_t getCommentPosition(const std::string& str) 476 { 477 return getNextCommentPosition(str, 0); 478 } 479 480 /** 481 @brief Returns the position of the next comment-symbol, starting with start. 482 @param str The string 483 @param start The startposition 484 @return The position 485 */ 486 size_t getNextCommentPosition(const std::string& str, size_t start) 487 { 488 for (size_t i = start; i < str.size(); i++) 489 if (isComment(str.substr(i))) 490 return i; 491 492 return std::string::npos; 493 } 47 494 } 48 49 /**50 @brief Removes all whitespaces from a string.51 @param str The string to strip52 */53 void strip(std::string* str)54 {55 size_t pos;56 while ((pos = (*str).find(" ")) < (*str).length())57 (*str).erase(pos, 1);58 while ((pos = (*str).find("\t")) < (*str).length())59 (*str).erase(pos, 1);60 while ((pos = (*str).find("\n")) < (*str).length())61 (*str).erase(pos, 1);62 }63 64 /**65 @brief Returns a copy of a string without whitespaces.66 @param str The string to strip67 @return The stripped line68 */69 std::string getStripped(const std::string& str)70 {71 std::string output = std::string(str);72 strip(&output);73 return output;74 }75 76 /**77 @brief Returns a copy of a string without trailing whitespaces.78 @param str The string79 @return The modified copy80 */81 std::string removeTrailingWhitespaces(const std::string& str)82 {83 size_t pos1 = 0;84 int pos2 = str.size() - 1;85 for (; pos1 < str.size() && (str[pos1] == ' ' || str[pos1] == '\t' || str[pos1] == '\n'); pos1++);86 for (; pos2 > 0 && (str[pos2] == ' ' || str[pos2] == '\t' || str[pos2] == '\n'); pos2--);87 return str.substr(pos1, pos2 - pos1 + 1);88 }89 90 /**91 @brief Returns the position of the next quote in the string, starting with start.92 @param str The string93 @param start The startposition94 @return The position of the next quote (std::string::npos if there is no next quote)95 */96 size_t getNextQuote(const std::string& str, size_t start)97 {98 size_t quote = start - 1;99 100 while ((quote = str.find('\"', quote + 1)) != std::string::npos)101 {102 size_t backslash = quote;103 size_t numbackslashes = 0;104 for (; backslash > 0; backslash--, numbackslashes++)105 if (str[backslash - 1] != '\\')106 break;107 108 if (numbackslashes % 2 == 0)109 break;110 }111 112 return quote;113 }114 115 /**116 @brief Returns true if pos is between two quotes.117 @param str The string118 @param pos The position to check119 @return True if pos is between two quotes120 */121 bool isBetweenQuotes(const std::string& str, size_t pos)122 {123 if (pos == std::string::npos)124 return false;125 126 size_t quotecount = 0;127 size_t quote = (size_t)-1;128 while ((quote = getNextQuote(str, quote + 1)) < pos)129 {130 if (quote == pos)131 return false;132 quotecount++;133 }134 135 if (quote == std::string::npos)136 return false;137 138 return ((quotecount % 2) == 1);139 }140 141 /**142 @brief Returns true if the string contains something like '..."between quotes"...'.143 @param The string144 @return True if there is something between quotes145 */146 bool hasStringBetweenQuotes(const std::string& str)147 {148 size_t pos1 = getNextQuote(str, 0);149 size_t pos2 = getNextQuote(str, pos1 + 1);150 return (pos1 != std::string::npos && pos2 != std::string::npos && pos2 > pos1 + 1);151 }152 153 /**154 @brief If the string contains something like '..."between quotes"...' then 'between quotes' gets returned (without quotes).155 @param The string156 @param The string between the quotes157 */158 std::string getStringBetweenQuotes(const std::string& str)159 {160 size_t pos1 = getNextQuote(str, 0);161 size_t pos2 = getNextQuote(str, pos1 + 1);162 if (pos1 != std::string::npos && pos2 != std::string::npos)163 return str.substr(pos1, pos2 - pos1 + 1);164 else165 return "";166 }167 168 /**169 @brief Removes enclosing quotes if available (including whitespaces at the outside of the quotes).170 @brief str The string to strip171 @return The string with removed quotes172 */173 std::string stripEnclosingQuotes(const std::string& str)174 {175 size_t start = std::string::npos;176 size_t end = 0;177 178 for (size_t pos = 0; (pos < str.size()) && (pos < std::string::npos); pos++)179 {180 if (str[pos] == '"')181 {182 start = pos;183 break;184 }185 186 if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n'))187 return str;188 }189 190 for (size_t pos = str.size() - 1; pos < std::string::npos; pos--)191 {192 if (str[pos] == '"')193 {194 end = pos;195 break;196 }197 198 if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n'))199 return str;200 }201 202 if ((start != std::string::npos) && (end != 0))203 return str.substr(start + 1, end - start - 1);204 else205 return str;206 }207 208 /**209 @brief Removes enclosing {braces} (braces must be exactly on the beginning and the end of the string).210 @param str The string to strip211 @return The striped string212 */213 std::string stripEnclosingBraces(const std::string& str)214 {215 std::string output = str;216 217 while (output.size() >= 2 && output[0] == '{' && output[output.size() - 1] == '}')218 output = output.substr(1, output.size() - 2);219 220 return output;221 }222 223 /**224 @brief Determines if a string is a comment (starts with a comment-symbol).225 @param str The string to check226 @return True = it's a comment227 228 A comment is defined by a leading '#', '%', ';' or '//'.229 */230 bool isComment(const std::string& str)231 {232 // Strip the line, whitespaces are disturbing233 std::string teststring = getStripped(str);234 235 // There are four possible comment-symbols:236 // 1) #comment in script-language style237 // 2) %comment in matlab style238 // 3) ;comment in unreal tournament config-file style239 // 4) //comment in code style240 if (teststring.size() >= 2)241 {242 if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';' || (teststring[0] == '/' && teststring[1] == '/'))243 return true;244 }245 else if (teststring.size() == 1)246 {247 if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';')248 return true;249 }250 251 return false;252 }253 254 /**255 @brief Determines if a string is empty (contains only whitespaces).256 @param str The string to check257 @return True = it's empty258 */259 bool isEmpty(const std::string& str)260 {261 std::string temp = getStripped(str);262 return ((temp == "") || (temp.size() == 0));263 }264 265 /**266 @brief Determines if a string contains only numbers and maximal one '.'.267 @param str The string to check268 @return True = it's a number269 */270 bool isNumeric(const std::string& str)271 {272 bool foundPoint = false;273 274 for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)275 {276 if (((*it) < '0' || (*it) > '9'))277 {278 if ((*it) != '.' && !foundPoint)279 foundPoint = true;280 else281 return false;282 }283 }284 285 return true;286 }287 288 /**289 @brief Adds backslashes to the given string which makes special chars visible. Existing slashes will be doubled.290 @param str The string to manipulate291 @return The string with added slashes292 */293 std::string addSlashes(const std::string& str)294 {295 std::string output = str;296 297 for (size_t pos = 0; (pos = output.find('\\', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\\\"); }298 for (size_t pos = 0; (pos = output.find('\n', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\n"); }299 for (size_t pos = 0; (pos = output.find('\t', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\t"); }300 for (size_t pos = 0; (pos = output.find('\v', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\v"); }301 for (size_t pos = 0; (pos = output.find('\b', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\b"); }302 for (size_t pos = 0; (pos = output.find('\r', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\r"); }303 for (size_t pos = 0; (pos = output.find('\f', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\f"); }304 for (size_t pos = 0; (pos = output.find('\a', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\a"); }305 for (size_t pos = 0; (pos = output.find('"', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\\""); }306 for (size_t pos = 0; (pos = output.find('\0', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\0"); }307 308 return output;309 }310 311 /**312 @brief Removes backslashes from the given string. Double backslashes are interpreted as one backslash.313 @param str The string to manipulate314 @return The string with removed slashes315 */316 std::string removeSlashes(const std::string& str)317 {318 if (str.size() <= 1)319 return str;320 321 std::string output = "";322 for (size_t pos = 0; pos < str.size() - 1; )323 {324 if (str[pos] == '\\')325 {326 if (str[pos + 1] == '\\') { output += '\\'; pos += 2; continue; }327 else if (str[pos + 1] == 'n') { output += '\n'; pos += 2; continue; }328 else if (str[pos + 1] == 't') { output += '\t'; pos += 2; continue; }329 else if (str[pos + 1] == 'v') { output += '\v'; pos += 2; continue; }330 else if (str[pos + 1] == 'b') { output += '\b'; pos += 2; continue; }331 else if (str[pos + 1] == 'r') { output += '\r'; pos += 2; continue; }332 else if (str[pos + 1] == 'f') { output += '\f'; pos += 2; continue; }333 else if (str[pos + 1] == 'a') { output += '\a'; pos += 2; continue; }334 else if (str[pos + 1] == '"') { output += '"'; pos += 2; continue; }335 else if (str[pos + 1] == '0') { output += '\0'; pos += 2; continue; }336 }337 output += str[pos];338 pos++;339 if (pos == str.size() - 1)340 output += str[pos];341 }342 343 return output;344 }345 346 /**347 @brief Replaces each char between A and Z with its lowercase equivalent.348 @param str The string to convert349 */350 void lowercase(std::string* str)351 {352 for (size_t i = 0; i < str->size(); ++i)353 {354 (*str)[i] = (char)tolower((*str)[i]);355 }356 }357 358 /**359 @brief Returns a copy of the given string without uppercase chars.360 @param str The string361 @return The copy362 */363 std::string getLowercase(const std::string& str)364 {365 std::string output = std::string(str);366 lowercase(&output);367 return output;368 }369 370 /**371 @brief Replaces each char between a and z with its uppercase equivalent.372 @param str The string to convert373 */374 void uppercase(std::string* str)375 {376 for (size_t i = 0; i < str->size(); ++i)377 {378 (*str)[i] = (char)toupper((*str)[i]);379 }380 }381 382 /**383 @brief Returns a copy of the given string without lowercase chars.384 @param str The string385 @return The copy386 */387 std::string getUppercase(const std::string& str)388 {389 std::string output = std::string(str);390 uppercase(&output);391 return output;392 }393 394 /**395 @brief Compares two strings ignoring different casing.396 @param s1 First string397 @param s2 Second string398 */399 int nocaseCmp(const std::string& s1, const std::string& s2)400 {401 std::string::const_iterator it1=s1.begin();402 std::string::const_iterator it2=s2.begin();403 404 //stop when either string's end has been reached405 while ( (it1!=s1.end()) && (it2!=s2.end()) )406 {407 if(::toupper(*it1) != ::toupper(*it2)) //letters differ?408 // return -1 to indicate smaller than, 1 otherwise409 return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;410 //proceed to the next character in each string411 ++it1;412 ++it2;413 }414 size_t size1=s1.size(), size2=s2.size();// cache lengths415 //return -1,0 or 1 according to strings' lengths416 if (size1==size2)417 return 0;418 return (size1<size2) ? -1 : 1;419 }420 421 422 /**423 @brief Compares the first 'len' chars of two strings ignoring different casing.424 @param s1 First string425 @param s2 Second string426 @param len Maximal number of chars to compare427 */428 int nocaseCmp(const std::string& s1, const std::string& s2, size_t len)429 {430 if (len == 0)431 return 0;432 std::string::const_iterator it1=s1.begin();433 std::string::const_iterator it2=s2.begin();434 435 //stop when either string's end has been reached436 while ( (it1!=s1.end()) && (it2!=s2.end()) && len-- > 0)437 {438 if(::toupper(*it1) != ::toupper(*it2)) //letters differ?439 // return -1 to indicate smaller than, 1 otherwise440 return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;441 //proceed to the next character in each string442 ++it1;443 ++it2;444 }445 return 0;446 }447 448 /**449 @brief Returns true if the string contains a comment, introduced by #, %, ; or //.450 @param str The string451 @return True if the string contains a comment452 */453 bool hasComment(const std::string& str)454 {455 return (getCommentPosition(str) != std::string::npos);456 }457 458 /**459 @brief If the string contains a comment, the comment gets returned (including the comment symbol), an empty string otherwise.460 @param str The string461 @return The comment462 */463 std::string getComment(const std::string& str)464 {465 return str.substr(getCommentPosition(str));466 }467 468 /**469 @brief If the string contains a comment, the position of the comment-symbol gets returned, std::string::npos otherwise.470 @param str The string471 @return The position472 */473 size_t getCommentPosition(const std::string& str)474 {475 return getNextCommentPosition(str, 0);476 }477 478 /**479 @brief Returns the position of the next comment-symbol, starting with start.480 @param str The string481 @param start The startposition482 @return The position483 */484 size_t getNextCommentPosition(const std::string& str, size_t start)485 {486 for (size_t i = start; i < str.size(); i++)487 if (isComment(str.substr(i)))488 return i;489 490 return std::string::npos;491 } -
code/trunk/src/util/String.h
r2087 r2171 28 28 29 29 /** 30 @file String.h30 @file 31 31 @brief Declaration of several string manipulation functions, used in many parts of the game. 32 32 */ … … 40 40 #include <sstream> 41 41 42 extern _UtilExport std::string BLANKSTRING; 43 _UtilExport std::string getUniqueNumberString(); 42 namespace orxonox 43 { 44 extern _UtilExport std::string BLANKSTRING; 45 _UtilExport std::string getUniqueNumberString(); 44 46 45 _UtilExport void strip(std::string* str);46 _UtilExport std::string getStripped(const std::string& str);47 _UtilExport void strip(std::string* str); 48 _UtilExport std::string getStripped(const std::string& str); 47 49 48 _UtilExport std::string removeTrailingWhitespaces(const std::string& str);50 _UtilExport std::string removeTrailingWhitespaces(const std::string& str); 49 51 50 _UtilExport size_t getNextQuote(const std::string& str, size_t start);51 _UtilExport bool isBetweenQuotes(const std::string& str, size_t pos);52 _UtilExport size_t getNextQuote(const std::string& str, size_t start); 53 _UtilExport bool isBetweenQuotes(const std::string& str, size_t pos); 52 54 53 _UtilExport bool hasStringBetweenQuotes(const std::string& str);54 _UtilExport std::string getStringBetweenQuotes(const std::string& str);55 _UtilExport bool hasStringBetweenQuotes(const std::string& str); 56 _UtilExport std::string getStringBetweenQuotes(const std::string& str); 55 57 56 _UtilExport std::string stripEnclosingQuotes(const std::string& str);57 _UtilExport std::string stripEnclosingBraces(const std::string& str);58 _UtilExport std::string stripEnclosingQuotes(const std::string& str); 59 _UtilExport std::string stripEnclosingBraces(const std::string& str); 58 60 59 _UtilExport bool isEmpty(const std::string& str);60 _UtilExport bool isComment(const std::string& str);61 _UtilExport bool isNumeric(const std::string& str);61 _UtilExport bool isEmpty(const std::string& str); 62 _UtilExport bool isComment(const std::string& str); 63 _UtilExport bool isNumeric(const std::string& str); 62 64 63 _UtilExport std::string addSlashes(const std::string& str);64 _UtilExport std::string removeSlashes(const std::string& str);65 _UtilExport std::string addSlashes(const std::string& str); 66 _UtilExport std::string removeSlashes(const std::string& str); 65 67 66 _UtilExport void lowercase(std::string* str);67 _UtilExport std::string getLowercase(const std::string& str);68 _UtilExport void lowercase(std::string* str); 69 _UtilExport std::string getLowercase(const std::string& str); 68 70 69 _UtilExport void uppercase(std::string* str);70 _UtilExport std::string getUppercase(const std::string& str);71 _UtilExport void uppercase(std::string* str); 72 _UtilExport std::string getUppercase(const std::string& str); 71 73 72 _UtilExport int nocaseCmp(const std::string& s1, const std::string& s2);73 _UtilExport int nocaseCmp(const std::string& s1, const std::string& s2, size_t len);74 _UtilExport int nocaseCmp(const std::string& s1, const std::string& s2); 75 _UtilExport int nocaseCmp(const std::string& s1, const std::string& s2, size_t len); 74 76 75 _UtilExport bool hasComment(const std::string& str); 76 _UtilExport std::string getComment(const std::string& str); 77 _UtilExport size_t getCommentPosition(const std::string& str); 78 _UtilExport size_t getNextCommentPosition(const std::string& str, size_t start = 0); 77 _UtilExport bool hasComment(const std::string& str); 78 _UtilExport std::string getComment(const std::string& str); 79 _UtilExport size_t getCommentPosition(const std::string& str); 80 _UtilExport size_t getNextCommentPosition(const std::string& str, size_t start = 0); 81 } 79 82 80 83 #endif /* _Util_String_H__ */ -
code/trunk/src/util/SubString.cc
r1791 r2171 40 40 #include "SubString.h" 41 41 42 /** 43 * @brief default constructor 44 */ 45 SubString::SubString() 46 {} 47 48 49 /** 50 * @brief create a SubString from 51 * @param string the String to Split 52 * @param delimiter the Character at which to split string (delimiter) 53 */ 54 SubString::SubString(const std::string& string, char delimiter) 42 namespace orxonox 55 43 { 56 this->split(string, delimiter); 57 } 58 59 60 /** 61 * @brief Splits a String into multiple splitters. 62 * @param string the String to split 63 * @param delimiters multiple set of characters at what to split. (delimiters) 64 * @param delimiterNeighbours neighbours of the delimiters, that will be erased only when near a delimiter. 65 * @param emptyEntries If empty entries should be allewed or removed. 66 * @param escapeChar The Escape Character that overrides splitters commends and so on... 67 * @param safemode_char within these characters splitting won't happen 68 * @param comment_char the Comment character. 69 */ 70 SubString::SubString(const std::string& string, 71 const std::string& delimiters, const std::string& delimiterNeighbours, bool emptyEntries, 72 char escapeChar, bool removeEscapeChar, char safemode_char, bool removeSafemodeChar, 73 char openparenthesis_char, char closeparenthesis_char, bool removeParenthesisChars, char comment_char) 74 { 75 SubString::splitLine(this->strings, this->bInSafemode, string, delimiters, delimiterNeighbours, emptyEntries, escapeChar, removeEscapeChar, safemode_char, removeSafemodeChar, openparenthesis_char, closeparenthesis_char, removeParenthesisChars, comment_char); 76 } 77 78 /** 79 * @brief creates a SubSet of a SubString. 80 * @param subString the SubString to take a set from. 81 * @param subSetBegin the beginning to the end 82 */ 83 SubString::SubString(const SubString& subString, unsigned int subSetBegin) 84 { 85 for (unsigned int i = subSetBegin; i < subString.size(); i++) 86 { 87 this->strings.push_back(subString[i]); 88 this->bInSafemode.push_back(subString.isInSafemode(i)); 89 } 90 } 91 92 93 /** 94 * @brief creates a SubSet of a SubString. 95 * @param subString the SubString to take a Set from 96 * @param subSetBegin the beginning to the end 97 * @param subSetEnd the end of the SubSet (max subString.size() will be checked internaly) 98 */ 99 SubString::SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd) 100 { 101 for (unsigned int i = subSetBegin; i < subString.size() && i < subSetEnd; i++) 102 { 103 this->strings.push_back(subString[i]); 104 this->bInSafemode.push_back(subString.isInSafemode(i)); 105 } 106 } 107 108 /** 109 * @brief creates a Substring from a count and values set. 110 * @param argc: the Arguments Count. 111 * @param argv: Argument Values. 112 */ 113 SubString::SubString(unsigned int argc, const char** argv) 114 { 115 for(unsigned int i = 0; i < argc; ++i) 116 { 117 this->strings.push_back(std::string(argv[i])); 118 this->bInSafemode.push_back(false); 119 } 120 } 121 122 /** 123 * @brief removes the object from memory 124 */ 125 SubString::~SubString() 126 { } 127 128 /** @brief An empty String */ 129 // const std::string SubString::emptyString = ""; 130 /** @brief Helper that gets you a String consisting of all White Spaces */ 131 const std::string SubString::WhiteSpaces = " \n\t"; 132 /** @brief Helper that gets you a String consisting of all WhiteSpaces and the Comma */ 133 const std::string SubString::WhiteSpacesWithComma = " \n\t,"; 134 /** An Empty SubString */ 135 const SubString SubString::NullSubString = SubString(); 136 137 /** 138 * @brief stores the Value of subString in this SubString 139 * @param subString will be copied into this String. 140 * @returns this SubString. 141 */ 142 SubString& SubString::operator=(const SubString& subString) 143 { 144 this->strings = subString.strings; 145 this->bInSafemode = subString.bInSafemode; 146 return *this; 147 } 148 149 150 /** 151 * @brief comparator. 152 * @param subString the SubString to compare against this one. 153 * @returns true if the Stored Strings match 154 */ 155 bool SubString::operator==(const SubString& subString) const 156 { 157 return ((this->strings == subString.strings) && (this->bInSafemode == subString.bInSafemode)); 158 } 159 160 /** 161 * @brief comparator. 162 * @param subString the SubString to compare against this one. 163 * @returns true if the Stored Strings match 164 */ 165 bool SubString::compare(const SubString& subString) const 166 { 167 return (*this == subString); 168 } 169 170 /** 171 * @brief comparator. 172 * @param subString the SubString to compare against this one. 173 * @param length how many entries to compare. (from 0 to length) 174 * @returns true if the Stored Strings match 175 */ 176 bool SubString::compare(const SubString& subString, unsigned int length) const 177 { 178 if (length > this->size() || length > subString.size()) 179 return false; 180 181 for (unsigned int i = 0; i < length; i++) 182 if ((this->strings[i] != subString.strings[i]) || (this->bInSafemode[i] != subString.bInSafemode[i])) 183 return false; 184 return true; 185 } 186 187 188 /** 189 * @brief append operator 190 * @param subString the String to append. 191 * @returns a SubString where this and subString are appended. 192 */ 193 SubString SubString::operator+(const SubString& subString) const 194 { 195 return SubString(*this) += subString; 196 } 197 198 199 /** 200 * @brief append operator. 201 * @param subString append subString to this SubString. 202 * @returns this substring appended with subString 203 */ 204 SubString& SubString::operator+=(const SubString& subString) 205 { 206 for (unsigned int i = 0; i < subString.size(); i++) 207 { 208 this->strings.push_back(subString[i]); 209 this->bInSafemode.push_back(subString.isInSafemode(i)); 210 } 211 return *this; 212 } 213 214 215 /** 216 * @brief Split the String at 217 * @param string where to split 218 * @param splitter delimiter. 219 */ 220 unsigned int SubString::split(const std::string& string, char splitter) 221 { 222 this->strings.clear(); 223 this->bInSafemode.clear(); 224 char split[2]; 225 split[0] = splitter; 226 split[1] = '\0'; 227 SubString::splitLine(this->strings, this->bInSafemode, string, split); 228 return strings.size(); 229 } 230 231 232 /** 233 * @brief Splits a String into multiple splitters. 234 * @param string the String to split 235 * @param delimiters multiple set of characters at what to split. (delimiters) 236 * @param delimiterNeighbours: Neighbours to the Delimiters that will be erased too. 237 * @param emptyEntries: If empty entries are added to the List of SubStrings 238 * @param escapeChar The Escape Character that overrides splitters commends and so on... 239 * @param safemode_char within these characters splitting won't happen 240 * @param comment_char the Comment character. 241 */ 242 unsigned int SubString::split(const std::string& string, 243 const std::string& delimiters, const std::string& delimiterNeighbours, bool emptyEntries, 244 char escapeChar, bool removeExcapeChar, char safemode_char, bool removeSafemodeChar, 245 char openparenthesis_char, char closeparenthesis_char, bool removeParenthesisChars, char comment_char) 246 { 247 this->strings.clear(); 248 this->bInSafemode.clear(); 249 SubString::splitLine(this->strings, this->bInSafemode, string, delimiters, delimiterNeighbours, emptyEntries, escapeChar, removeExcapeChar, safemode_char, removeSafemodeChar, openparenthesis_char, closeparenthesis_char, removeParenthesisChars, comment_char); 250 return this->strings.size(); 251 } 252 253 254 /** 255 * @brief joins together all Strings of this Substring. 256 * @param delimiter the String between the subStrings. 257 * @returns the joined String. 258 */ 259 std::string SubString::join(const std::string& delimiter) const 260 { 261 if (!this->strings.empty()) 262 { 263 std::string retVal = this->strings[0]; 264 for (unsigned int i = 1; i < this->strings.size(); i++) 265 retVal += delimiter + this->strings[i]; 266 return retVal; 267 } 268 else 269 { 270 static std::string empty; 271 return empty; 272 } 273 } 274 275 276 /** 277 * @brief creates a SubSet of a SubString. 278 * @param subSetBegin the beginning to the end 279 * @returns the SubSet 280 * 281 * This function is added for your convenience, and does the same as 282 * SubString::SubString(const SubString& subString, unsigned int subSetBegin) 283 */ 284 SubString SubString::subSet(unsigned int subSetBegin) const 285 { 286 return SubString(*this, subSetBegin); 287 } 288 289 290 /** 291 * @brief creates a SubSet of a SubString. 292 * @param subSetBegin the beginning to 293 * @param subSetEnd the end of the SubSet to select (if bigger than subString.size() it will be downset.) 294 * @returns the SubSet 295 * 296 * This function is added for your convenience, and does the same as 297 * SubString::SubString(const SubString& subString, unsigned int subSetBegin) 298 */ 299 SubString SubString::subSet(unsigned int subSetBegin, unsigned int subSetEnd) const 300 { 301 return SubString(*this, subSetBegin, subSetEnd); 302 } 303 304 305 /** 306 * @brief splits line into tokens and stores them in ret. 307 * @param ret the Array, where the Splitted strings will be stored in 308 * to the beginning of the current token is stored 309 * @param line the inputLine to split 310 * @param delimiters a String of Delimiters (here the input will be splitted) 311 * @param delimiterNeighbours Naighbours to the Delimitter, that will be removed if they are to the left or the right of a Delimiter. 312 * @param emptyEntries: if empty Strings are added to the List of Strings. 313 * @param escape_char: Escape carater (escapes splitters) 314 * @param safemode_char: the beginning of the safemode is marked with this 315 * @param removeSafemodeChar removes the safemode_char from the beginning and the ending of a token 316 * @param openparenthesis_char the beginning of a safemode is marked with this 317 * @param closeparenthesis_char the ending of a safemode is marked with this 318 * @param removeParenthesisChars removes the parenthesis from the beginning and the ending of a token 319 * @param comment_char: the beginning of a comment is marked with this: (until the end of a Line) 320 * @param start_state: the Initial state on how to parse the String. 321 * @return SPLIT_LINE_STATE the parser was in when returning 322 * 323 * This is the Actual Splitting Algorithm from Clemens Wacha 324 * Supports delimiters, escape characters, 325 * ignores special characters between safemode_char and between comment_char and linend '\n'. 326 */ 327 SubString::SPLIT_LINE_STATE 328 SubString::splitLine(std::vector<std::string>& ret, 329 std::vector<bool>& bInSafemode, 330 const std::string& line, 331 const std::string& delimiters, 332 const std::string& delimiterNeighbours, 333 bool emptyEntries, 334 char escape_char, 335 bool removeExcapeChar, 336 char safemode_char, 337 bool removeSafemodeChar, 338 char openparenthesis_char, 339 char closeparenthesis_char, 340 bool removeParenthesisChars, 341 char comment_char, 342 SPLIT_LINE_STATE start_state) 343 { 344 SPLIT_LINE_STATE state = start_state; 345 unsigned int i = 0; 346 unsigned int fallBackNeighbours = 0; 347 348 std::string token; 349 bool inSafemode = false; 350 351 if(start_state != SL_NORMAL && ret.size() > 0) 352 { 353 token = ret[ret.size()-1]; 354 ret.pop_back(); 355 } 356 if(start_state != SL_NORMAL && bInSafemode.size() > 0) 357 { 358 inSafemode = bInSafemode[bInSafemode.size()-1]; 359 bInSafemode.pop_back(); 360 } 361 362 while(i < line.size()) 363 { 364 switch(state) 365 { 366 case SL_NORMAL: 367 if(line[i] == escape_char) 368 { 369 state = SL_ESCAPE; 370 if (!removeExcapeChar) 371 token += line[i]; 372 } 373 else if(line[i] == safemode_char) 374 { 375 state = SL_SAFEMODE; 376 inSafemode = true; 377 if (!removeSafemodeChar) 378 token += line[i]; 379 } 380 else if(line[i] == openparenthesis_char) 381 { 382 state = SL_PARENTHESES; 383 inSafemode = true; 384 if (!removeParenthesisChars) 385 token += line[i]; 386 } 387 else if(line[i] == comment_char) 388 { 389 if (fallBackNeighbours > 0) 44 /** 45 * @brief default constructor 46 */ 47 SubString::SubString() 48 {} 49 50 51 /** 52 * @brief create a SubString from 53 * @param string the String to Split 54 * @param delimiter the Character at which to split string (delimiter) 55 */ 56 SubString::SubString(const std::string& string, char delimiter) 57 { 58 this->split(string, delimiter); 59 } 60 61 62 /** 63 * @brief Splits a String into multiple splitters. 64 * @param string the String to split 65 * @param delimiters multiple set of characters at what to split. (delimiters) 66 * @param delimiterNeighbours neighbours of the delimiters, that will be erased only when near a delimiter. 67 * @param emptyEntries If empty entries should be allewed or removed. 68 * @param escapeChar The Escape Character that overrides splitters commends and so on... 69 * @param safemode_char within these characters splitting won't happen 70 * @param comment_char the Comment character. 71 */ 72 SubString::SubString(const std::string& string, 73 const std::string& delimiters, const std::string& delimiterNeighbours, bool emptyEntries, 74 char escapeChar, bool removeEscapeChar, char safemode_char, bool removeSafemodeChar, 75 char openparenthesis_char, char closeparenthesis_char, bool removeParenthesisChars, char comment_char) 76 { 77 SubString::splitLine(this->strings, this->bInSafemode, string, delimiters, delimiterNeighbours, emptyEntries, escapeChar, removeEscapeChar, safemode_char, removeSafemodeChar, openparenthesis_char, closeparenthesis_char, removeParenthesisChars, comment_char); 78 } 79 80 /** 81 * @brief creates a SubSet of a SubString. 82 * @param subString the SubString to take a set from. 83 * @param subSetBegin the beginning to the end 84 */ 85 SubString::SubString(const SubString& subString, unsigned int subSetBegin) 86 { 87 for (unsigned int i = subSetBegin; i < subString.size(); i++) 88 { 89 this->strings.push_back(subString[i]); 90 this->bInSafemode.push_back(subString.isInSafemode(i)); 91 } 92 } 93 94 95 /** 96 * @brief creates a SubSet of a SubString. 97 * @param subString the SubString to take a Set from 98 * @param subSetBegin the beginning to the end 99 * @param subSetEnd the end of the SubSet (max subString.size() will be checked internaly) 100 */ 101 SubString::SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd) 102 { 103 for (unsigned int i = subSetBegin; i < subString.size() && i < subSetEnd; i++) 104 { 105 this->strings.push_back(subString[i]); 106 this->bInSafemode.push_back(subString.isInSafemode(i)); 107 } 108 } 109 110 /** 111 * @brief creates a Substring from a count and values set. 112 * @param argc: the Arguments Count. 113 * @param argv: Argument Values. 114 */ 115 SubString::SubString(unsigned int argc, const char** argv) 116 { 117 for(unsigned int i = 0; i < argc; ++i) 118 { 119 this->strings.push_back(std::string(argv[i])); 120 this->bInSafemode.push_back(false); 121 } 122 } 123 124 /** 125 * @brief removes the object from memory 126 */ 127 SubString::~SubString() 128 { } 129 130 /** @brief An empty String */ 131 // const std::string SubString::emptyString = ""; 132 /** @brief Helper that gets you a String consisting of all White Spaces */ 133 const std::string SubString::WhiteSpaces = " \n\t"; 134 /** @brief Helper that gets you a String consisting of all WhiteSpaces and the Comma */ 135 const std::string SubString::WhiteSpacesWithComma = " \n\t,"; 136 /** An Empty SubString */ 137 const SubString SubString::NullSubString = SubString(); 138 139 /** 140 * @brief stores the Value of subString in this SubString 141 * @param subString will be copied into this String. 142 * @returns this SubString. 143 */ 144 SubString& SubString::operator=(const SubString& subString) 145 { 146 this->strings = subString.strings; 147 this->bInSafemode = subString.bInSafemode; 148 return *this; 149 } 150 151 152 /** 153 * @brief comparator. 154 * @param subString the SubString to compare against this one. 155 * @returns true if the Stored Strings match 156 */ 157 bool SubString::operator==(const SubString& subString) const 158 { 159 return ((this->strings == subString.strings) && (this->bInSafemode == subString.bInSafemode)); 160 } 161 162 /** 163 * @brief comparator. 164 * @param subString the SubString to compare against this one. 165 * @returns true if the Stored Strings match 166 */ 167 bool SubString::compare(const SubString& subString) const 168 { 169 return (*this == subString); 170 } 171 172 /** 173 * @brief comparator. 174 * @param subString the SubString to compare against this one. 175 * @param length how many entries to compare. (from 0 to length) 176 * @returns true if the Stored Strings match 177 */ 178 bool SubString::compare(const SubString& subString, unsigned int length) const 179 { 180 if (length > this->size() || length > subString.size()) 181 return false; 182 183 for (unsigned int i = 0; i < length; i++) 184 if ((this->strings[i] != subString.strings[i]) || (this->bInSafemode[i] != subString.bInSafemode[i])) 185 return false; 186 return true; 187 } 188 189 190 /** 191 * @brief append operator 192 * @param subString the String to append. 193 * @returns a SubString where this and subString are appended. 194 */ 195 SubString SubString::operator+(const SubString& subString) const 196 { 197 return SubString(*this) += subString; 198 } 199 200 201 /** 202 * @brief append operator. 203 * @param subString append subString to this SubString. 204 * @returns this substring appended with subString 205 */ 206 SubString& SubString::operator+=(const SubString& subString) 207 { 208 for (unsigned int i = 0; i < subString.size(); i++) 209 { 210 this->strings.push_back(subString[i]); 211 this->bInSafemode.push_back(subString.isInSafemode(i)); 212 } 213 return *this; 214 } 215 216 217 /** 218 * @brief Split the String at 219 * @param string where to split 220 * @param splitter delimiter. 221 */ 222 unsigned int SubString::split(const std::string& string, char splitter) 223 { 224 this->strings.clear(); 225 this->bInSafemode.clear(); 226 char split[2]; 227 split[0] = splitter; 228 split[1] = '\0'; 229 SubString::splitLine(this->strings, this->bInSafemode, string, split); 230 return strings.size(); 231 } 232 233 234 /** 235 * @brief Splits a String into multiple splitters. 236 * @param string the String to split 237 * @param delimiters multiple set of characters at what to split. (delimiters) 238 * @param delimiterNeighbours: Neighbours to the Delimiters that will be erased too. 239 * @param emptyEntries: If empty entries are added to the List of SubStrings 240 * @param escapeChar The Escape Character that overrides splitters commends and so on... 241 * @param safemode_char within these characters splitting won't happen 242 * @param comment_char the Comment character. 243 */ 244 unsigned int SubString::split(const std::string& string, 245 const std::string& delimiters, const std::string& delimiterNeighbours, bool emptyEntries, 246 char escapeChar, bool removeExcapeChar, char safemode_char, bool removeSafemodeChar, 247 char openparenthesis_char, char closeparenthesis_char, bool removeParenthesisChars, char comment_char) 248 { 249 this->strings.clear(); 250 this->bInSafemode.clear(); 251 SubString::splitLine(this->strings, this->bInSafemode, string, delimiters, delimiterNeighbours, emptyEntries, escapeChar, removeExcapeChar, safemode_char, removeSafemodeChar, openparenthesis_char, closeparenthesis_char, removeParenthesisChars, comment_char); 252 return this->strings.size(); 253 } 254 255 256 /** 257 * @brief joins together all Strings of this Substring. 258 * @param delimiter the String between the subStrings. 259 * @returns the joined String. 260 */ 261 std::string SubString::join(const std::string& delimiter) const 262 { 263 if (!this->strings.empty()) 264 { 265 std::string retVal = this->strings[0]; 266 for (unsigned int i = 1; i < this->strings.size(); i++) 267 retVal += delimiter + this->strings[i]; 268 return retVal; 269 } 270 else 271 { 272 static std::string empty; 273 return empty; 274 } 275 } 276 277 278 /** 279 * @brief creates a SubSet of a SubString. 280 * @param subSetBegin the beginning to the end 281 * @returns the SubSet 282 * 283 * This function is added for your convenience, and does the same as 284 * SubString::SubString(const SubString& subString, unsigned int subSetBegin) 285 */ 286 SubString SubString::subSet(unsigned int subSetBegin) const 287 { 288 return SubString(*this, subSetBegin); 289 } 290 291 292 /** 293 * @brief creates a SubSet of a SubString. 294 * @param subSetBegin the beginning to 295 * @param subSetEnd the end of the SubSet to select (if bigger than subString.size() it will be downset.) 296 * @returns the SubSet 297 * 298 * This function is added for your convenience, and does the same as 299 * SubString::SubString(const SubString& subString, unsigned int subSetBegin) 300 */ 301 SubString SubString::subSet(unsigned int subSetBegin, unsigned int subSetEnd) const 302 { 303 return SubString(*this, subSetBegin, subSetEnd); 304 } 305 306 307 /** 308 * @brief splits line into tokens and stores them in ret. 309 * @param ret the Array, where the Splitted strings will be stored in 310 * to the beginning of the current token is stored 311 * @param line the inputLine to split 312 * @param delimiters a String of Delimiters (here the input will be splitted) 313 * @param delimiterNeighbours Naighbours to the Delimitter, that will be removed if they are to the left or the right of a Delimiter. 314 * @param emptyEntries: if empty Strings are added to the List of Strings. 315 * @param escape_char: Escape carater (escapes splitters) 316 * @param safemode_char: the beginning of the safemode is marked with this 317 * @param removeSafemodeChar removes the safemode_char from the beginning and the ending of a token 318 * @param openparenthesis_char the beginning of a safemode is marked with this 319 * @param closeparenthesis_char the ending of a safemode is marked with this 320 * @param removeParenthesisChars removes the parenthesis from the beginning and the ending of a token 321 * @param comment_char: the beginning of a comment is marked with this: (until the end of a Line) 322 * @param start_state: the Initial state on how to parse the String. 323 * @return SPLIT_LINE_STATE the parser was in when returning 324 * 325 * This is the Actual Splitting Algorithm from Clemens Wacha 326 * Supports delimiters, escape characters, 327 * ignores special characters between safemode_char and between comment_char and linend '\n'. 328 */ 329 SubString::SPLIT_LINE_STATE 330 SubString::splitLine(std::vector<std::string>& ret, 331 std::vector<bool>& bInSafemode, 332 const std::string& line, 333 const std::string& delimiters, 334 const std::string& delimiterNeighbours, 335 bool emptyEntries, 336 char escape_char, 337 bool removeExcapeChar, 338 char safemode_char, 339 bool removeSafemodeChar, 340 char openparenthesis_char, 341 char closeparenthesis_char, 342 bool removeParenthesisChars, 343 char comment_char, 344 SPLIT_LINE_STATE start_state) 345 { 346 SPLIT_LINE_STATE state = start_state; 347 unsigned int i = 0; 348 unsigned int fallBackNeighbours = 0; 349 350 std::string token; 351 bool inSafemode = false; 352 353 if(start_state != SL_NORMAL && ret.size() > 0) 354 { 355 token = ret[ret.size()-1]; 356 ret.pop_back(); 357 } 358 if(start_state != SL_NORMAL && bInSafemode.size() > 0) 359 { 360 inSafemode = bInSafemode[bInSafemode.size()-1]; 361 bInSafemode.pop_back(); 362 } 363 364 while(i < line.size()) 365 { 366 switch(state) 367 { 368 case SL_NORMAL: 369 if(line[i] == escape_char) 370 { 371 state = SL_ESCAPE; 372 if (!removeExcapeChar) 373 token += line[i]; 374 } 375 else if(line[i] == safemode_char) 376 { 377 state = SL_SAFEMODE; 378 inSafemode = true; 379 if (!removeSafemodeChar) 380 token += line[i]; 381 } 382 else if(line[i] == openparenthesis_char) 383 { 384 state = SL_PARENTHESES; 385 inSafemode = true; 386 if (!removeParenthesisChars) 387 token += line[i]; 388 } 389 else if(line[i] == comment_char) 390 { 391 if (fallBackNeighbours > 0) 392 token = token.substr(0, token.size() - fallBackNeighbours); 393 /// FINISH 394 if(emptyEntries || token.size() > 0) 395 { 396 ret.push_back(token); 397 token.clear(); 398 bInSafemode.push_back(inSafemode); 399 inSafemode = false; 400 } 401 token += line[i]; // EAT 402 state = SL_COMMENT; 403 } 404 else if(delimiters.find(line[i]) != std::string::npos) 405 { 406 // line[i] is a delimiter 407 if (fallBackNeighbours > 0) 408 token = token.substr(0, token.size() - fallBackNeighbours); 409 /// FINISH 410 if(emptyEntries || token.size() > 0) 411 { 412 ret.push_back(token); 413 token.clear(); 414 bInSafemode.push_back(inSafemode); 415 inSafemode = false; 416 } 417 state = SL_NORMAL; 418 } 419 else 420 { 421 if (delimiterNeighbours.find(line[i]) != std::string::npos) 422 { 423 if (token.size() > 0) 424 ++fallBackNeighbours; 425 else 426 { 427 i++; 428 continue; 429 } 430 } 431 else 432 fallBackNeighbours = 0; 433 token += line[i]; // EAT 434 } 435 break; 436 case SL_ESCAPE: 437 if (!removeSafemodeChar) 438 token += line[i]; 439 else 440 { 441 if(line[i] == 'n') token += '\n'; 442 else if(line[i] == 't') token += '\t'; 443 else if(line[i] == 'v') token += '\v'; 444 else if(line[i] == 'b') token += '\b'; 445 else if(line[i] == 'r') token += '\r'; 446 else if(line[i] == 'f') token += '\f'; 447 else if(line[i] == 'a') token += '\a'; 448 else if(line[i] == '?') token += '\?'; 449 else token += line[i]; // EAT 450 } 451 state = SL_NORMAL; 452 break; 453 case SL_SAFEMODE: 454 if(line[i] == safemode_char) 455 { 456 state = SL_NORMAL; 457 if (!removeSafemodeChar) 458 token += line[i]; 459 } 460 else if(line[i] == escape_char) 461 { 462 state = SL_SAFEESCAPE; 463 } 464 else 465 { 466 token += line[i]; // EAT 467 } 468 break; 469 470 case SL_SAFEESCAPE: 471 if(line[i] == 'n') token += '\n'; 472 else if(line[i] == 't') token += '\t'; 473 else if(line[i] == 'v') token += '\v'; 474 else if(line[i] == 'b') token += '\b'; 475 else if(line[i] == 'r') token += '\r'; 476 else if(line[i] == 'f') token += '\f'; 477 else if(line[i] == 'a') token += '\a'; 478 else if(line[i] == '?') token += '\?'; 479 else token += line[i]; // EAT 480 state = SL_SAFEMODE; 481 break; 482 483 case SL_PARENTHESES: 484 if(line[i] == closeparenthesis_char) 485 { 486 state = SL_NORMAL; 487 if (!removeParenthesisChars) 488 token += line[i]; 489 } 490 else if(line[i] == escape_char) 491 { 492 state = SL_PARENTHESESESCAPE; 493 } 494 else 495 { 496 token += line[i]; // EAT 497 } 498 break; 499 500 case SL_PARENTHESESESCAPE: 501 if(line[i] == 'n') token += '\n'; 502 else if(line[i] == 't') token += '\t'; 503 else if(line[i] == 'v') token += '\v'; 504 else if(line[i] == 'b') token += '\b'; 505 else if(line[i] == 'r') token += '\r'; 506 else if(line[i] == 'f') token += '\f'; 507 else if(line[i] == 'a') token += '\a'; 508 else if(line[i] == '?') token += '\?'; 509 else token += line[i]; // EAT 510 state = SL_PARENTHESES; 511 break; 512 513 case SL_COMMENT: 514 if(line[i] == '\n') 515 { 516 /// FINISH 517 if(token.size() > 0) 518 { 519 ret.push_back(token); 520 token.clear(); 521 bInSafemode.push_back(inSafemode); 522 inSafemode = false; 523 } 524 state = SL_NORMAL; 525 } 526 else 527 { 528 token += line[i]; // EAT 529 } 530 break; 531 532 default: 533 // nothing 534 break; 535 } 536 i++; 537 } 538 539 /// FINISH 540 if (fallBackNeighbours > 0) 390 541 token = token.substr(0, token.size() - fallBackNeighbours); 391 /// FINISH 392 if(emptyEntries || token.size() > 0) 393 { 542 if(emptyEntries || token.size() > 0) 543 { 394 544 ret.push_back(token); 395 545 token.clear(); 396 546 bInSafemode.push_back(inSafemode); 397 547 inSafemode = false; 398 } 399 token += line[i]; // EAT 400 state = SL_COMMENT; 401 } 402 else if(delimiters.find(line[i]) != std::string::npos) 403 { 404 // line[i] is a delimiter 405 if (fallBackNeighbours > 0) 406 token = token.substr(0, token.size() - fallBackNeighbours); 407 /// FINISH 408 if(emptyEntries || token.size() > 0) 409 { 410 ret.push_back(token); 411 token.clear(); 412 bInSafemode.push_back(inSafemode); 413 inSafemode = false; 414 } 415 state = SL_NORMAL; 416 } 417 else 418 { 419 if (delimiterNeighbours.find(line[i]) != std::string::npos) 420 { 421 if (token.size() > 0) 422 ++fallBackNeighbours; 423 else 424 { 425 i++; 426 continue; 427 } 428 } 429 else 430 fallBackNeighbours = 0; 431 token += line[i]; // EAT 432 } 433 break; 434 case SL_ESCAPE: 435 if (!removeSafemodeChar) 436 token += line[i]; 437 else 438 { 439 if(line[i] == 'n') token += '\n'; 440 else if(line[i] == 't') token += '\t'; 441 else if(line[i] == 'v') token += '\v'; 442 else if(line[i] == 'b') token += '\b'; 443 else if(line[i] == 'r') token += '\r'; 444 else if(line[i] == 'f') token += '\f'; 445 else if(line[i] == 'a') token += '\a'; 446 else if(line[i] == '?') token += '\?'; 447 else token += line[i]; // EAT 448 } 449 state = SL_NORMAL; 450 break; 451 case SL_SAFEMODE: 452 if(line[i] == safemode_char) 453 { 454 state = SL_NORMAL; 455 if (!removeSafemodeChar) 456 token += line[i]; 457 } 458 else if(line[i] == escape_char) 459 { 460 state = SL_SAFEESCAPE; 461 } 462 else 463 { 464 token += line[i]; // EAT 465 } 466 break; 467 468 case SL_SAFEESCAPE: 469 if(line[i] == 'n') token += '\n'; 470 else if(line[i] == 't') token += '\t'; 471 else if(line[i] == 'v') token += '\v'; 472 else if(line[i] == 'b') token += '\b'; 473 else if(line[i] == 'r') token += '\r'; 474 else if(line[i] == 'f') token += '\f'; 475 else if(line[i] == 'a') token += '\a'; 476 else if(line[i] == '?') token += '\?'; 477 else token += line[i]; // EAT 478 state = SL_SAFEMODE; 479 break; 480 481 case SL_PARENTHESES: 482 if(line[i] == closeparenthesis_char) 483 { 484 state = SL_NORMAL; 485 if (!removeParenthesisChars) 486 token += line[i]; 487 } 488 else if(line[i] == escape_char) 489 { 490 state = SL_PARENTHESESESCAPE; 491 } 492 else 493 { 494 token += line[i]; // EAT 495 } 496 break; 497 498 case SL_PARENTHESESESCAPE: 499 if(line[i] == 'n') token += '\n'; 500 else if(line[i] == 't') token += '\t'; 501 else if(line[i] == 'v') token += '\v'; 502 else if(line[i] == 'b') token += '\b'; 503 else if(line[i] == 'r') token += '\r'; 504 else if(line[i] == 'f') token += '\f'; 505 else if(line[i] == 'a') token += '\a'; 506 else if(line[i] == '?') token += '\?'; 507 else token += line[i]; // EAT 508 state = SL_PARENTHESES; 509 break; 510 511 case SL_COMMENT: 512 if(line[i] == '\n') 513 { 514 /// FINISH 515 if(token.size() > 0) 516 { 517 ret.push_back(token); 518 token.clear(); 519 bInSafemode.push_back(inSafemode); 520 inSafemode = false; 521 } 522 state = SL_NORMAL; 523 } 524 else 525 { 526 token += line[i]; // EAT 527 } 528 break; 529 530 default: 531 // nothing 532 break; 533 } 534 i++; 535 } 536 537 /// FINISH 538 if (fallBackNeighbours > 0) 539 token = token.substr(0, token.size() - fallBackNeighbours); 540 if(emptyEntries || token.size() > 0) 541 { 542 ret.push_back(token); 543 token.clear(); 544 bInSafemode.push_back(inSafemode); 545 inSafemode = false; 546 } 547 return(state); 548 } 549 return(state); 550 } 551 552 553 /** 554 * @brief Some nice debug information about this SubString 555 */ 556 void SubString::debug() const 557 { 558 printf("Substring-information::count=%d ::", this->strings.size()); 559 for (unsigned int i = 0; i < this->strings.size(); i++) 560 printf("s%d='%s'::", i, this->strings[i].c_str()); 561 printf("\n"); 562 } 548 563 } 549 550 551 /**552 * @brief Some nice debug information about this SubString553 */554 void SubString::debug() const555 {556 printf("Substring-information::count=%d ::", this->strings.size());557 for (unsigned int i = 0; i < this->strings.size(); i++)558 printf("s%d='%s'::", i, this->strings[i].c_str());559 printf("\n");560 } -
code/trunk/src/util/SubString.h
r1791 r2171 38 38 39 39 /*! 40 * @file substring.h40 * @file 41 41 * @brief a small class to get the parts of a string separated by commas 42 42 * … … 64 64 #include <string> 65 65 66 //! A class that can load one string and split it in multipe ones 67 /** 68 * SubString is a very Powerfull way to create a SubSet from a String 69 * It can be used, to Split strings append them and join them again. 70 */ 71 class _UtilExport SubString 66 namespace orxonox 72 67 { 73 public: 74 //! An enumerator for the State the Parser is in 75 typedef enum { 76 SL_NORMAL, //!< Normal state 77 SL_ESCAPE, //!< After an escape character 78 SL_SAFEMODE, //!< In safe mode (between "" mostly). 79 SL_SAFEESCAPE, //!< In safe mode with the internal escape character, that escapes even the savemode character. 80 SL_COMMENT, //!< In Comment mode. 81 SL_PARENTHESES, //!< Between parentheses (usually '(' and ')') 82 SL_PARENTHESESESCAPE, //!< Between parentheses with the internal escape character, that escapes even the closing paranthesis character. 83 } SPLIT_LINE_STATE; 68 //! A class that can load one string and split it in multipe ones 69 /** 70 * SubString is a very Powerfull way to create a SubSet from a String 71 * It can be used, to Split strings append them and join them again. 72 */ 73 class _UtilExport SubString 74 { 75 public: 76 //! An enumerator for the State the Parser is in 77 typedef enum { 78 SL_NORMAL, //!< Normal state 79 SL_ESCAPE, //!< After an escape character 80 SL_SAFEMODE, //!< In safe mode (between "" mostly). 81 SL_SAFEESCAPE, //!< In safe mode with the internal escape character, that escapes even the savemode character. 82 SL_COMMENT, //!< In Comment mode. 83 SL_PARENTHESES, //!< Between parentheses (usually '(' and ')') 84 SL_PARENTHESESESCAPE, //!< Between parentheses with the internal escape character, that escapes even the closing paranthesis character. 85 } SPLIT_LINE_STATE; 84 86 85 87 86 public:87 SubString();88 SubString(const std::string& string, char delimiter = ',');89 SubString(const std::string& string,90 const std::string& delimiters, const std::string& delimiterNeighbours = "", bool emptyEntries=false,91 char escapeChar ='\\', bool removeEscapeChar = true, char safemode_char = '"', bool removeSafemodeChar = true,92 char openparenthesis_char = '(', char closeparenthesis_char = ')', bool removeParenthesisChars = true, char comment_char = '\0');93 SubString(unsigned int argc, const char** argv);94 /** @brief create a Substring as a copy of another one. @param subString the SubString to copy. */95 SubString(const SubString& subString) { *this = subString; };96 SubString(const SubString& subString, unsigned int subSetBegin);97 SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd);98 ~SubString();88 public: 89 SubString(); 90 SubString(const std::string& string, char delimiter = ','); 91 SubString(const std::string& string, 92 const std::string& delimiters, const std::string& delimiterNeighbours = "", bool emptyEntries=false, 93 char escapeChar ='\\', bool removeEscapeChar = true, char safemode_char = '"', bool removeSafemodeChar = true, 94 char openparenthesis_char = '(', char closeparenthesis_char = ')', bool removeParenthesisChars = true, char comment_char = '\0'); 95 SubString(unsigned int argc, const char** argv); 96 /** @brief create a Substring as a copy of another one. @param subString the SubString to copy. */ 97 SubString(const SubString& subString) { *this = subString; }; 98 SubString(const SubString& subString, unsigned int subSetBegin); 99 SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd); 100 ~SubString(); 99 101 100 // operate on the SubString101 SubString& operator=(const SubString& subString);102 bool operator==(const SubString& subString) const;103 bool compare(const SubString& subString) const;104 bool compare(const SubString& subString, unsigned int length) const;105 SubString operator+(const SubString& subString) const;106 SubString& operator+=(const SubString& subString);107 /** @param subString the String to append @returns appended String. @brief added for convenience */108 SubString& append(const SubString subString) { return (*this += subString); };102 // operate on the SubString 103 SubString& operator=(const SubString& subString); 104 bool operator==(const SubString& subString) const; 105 bool compare(const SubString& subString) const; 106 bool compare(const SubString& subString, unsigned int length) const; 107 SubString operator+(const SubString& subString) const; 108 SubString& operator+=(const SubString& subString); 109 /** @param subString the String to append @returns appended String. @brief added for convenience */ 110 SubString& append(const SubString subString) { return (*this += subString); }; 109 111 110 /////////////////////////////////////////111 // Split and Join the any String. ///////112 unsigned int split(const std::string& string = "", char delimiter = ',');113 unsigned int split(const std::string& string,114 const std::string& delimiters, const std::string& delimiterNeighbours = "", bool emptyEntries = false,115 char escapeChar ='\\', bool removeExcapeChar = true, char safemode_char = '"', bool removeSafemodeChar = true,116 char openparenthesis_char = '(', char closeparenthesis_char = ')', bool removeParenthesisChars = true, char comment_char = '\0');117 std::string join(const std::string& delimiter = " ") const;118 ////////////////////////////////////////112 ///////////////////////////////////////// 113 // Split and Join the any String. /////// 114 unsigned int split(const std::string& string = "", char delimiter = ','); 115 unsigned int split(const std::string& string, 116 const std::string& delimiters, const std::string& delimiterNeighbours = "", bool emptyEntries = false, 117 char escapeChar ='\\', bool removeExcapeChar = true, char safemode_char = '"', bool removeSafemodeChar = true, 118 char openparenthesis_char = '(', char closeparenthesis_char = ')', bool removeParenthesisChars = true, char comment_char = '\0'); 119 std::string join(const std::string& delimiter = " ") const; 120 //////////////////////////////////////// 119 121 120 // retrieve a SubSet from the String121 SubString subSet(unsigned int subSetBegin) const;122 SubString subSet(unsigned int subSetBegin, unsigned int subSetEnd) const;122 // retrieve a SubSet from the String 123 SubString subSet(unsigned int subSetBegin) const; 124 SubString subSet(unsigned int subSetBegin, unsigned int subSetEnd) const; 123 125 124 // retrieve Information from within125 /** @brief Returns true if the SubString is empty */126 inline bool empty() const { return this->strings.empty(); };127 /** @brief Returns the count of Strings stored in this substring */128 inline unsigned int size() const { return this->strings.size(); };129 /** @brief Returns the i'th string from the subset of Strings @param i the i'th String */130 inline const std::string& operator[](unsigned int i) const { return this->strings[i]; };131 /** @brief Returns the i'th string from the subset of Strings @param i the i'th String */132 inline const std::string& getString(unsigned int i) const { return (*this)[i]; };133 /** @brief Returns all Strings as std::vector */134 inline const std::vector<std::string>& getAllStrings() const { return this->strings; }135 /** @brief Returns true if the token is in safemode. @param i the i'th token */136 inline bool isInSafemode(unsigned int i) const { return this->bInSafemode[i]; }137 /** @brief Returns the front of the StringList. */138 inline const std::string& front() const { return this->strings.front(); };139 /** @brief Returns the back of the StringList. */140 inline const std::string& back() const { return this->strings.back(); };141 /** @brief removes the back of the strings list. */142 inline void pop_back() { this->strings.pop_back(); this->bInSafemode.pop_back(); };126 // retrieve Information from within 127 /** @brief Returns true if the SubString is empty */ 128 inline bool empty() const { return this->strings.empty(); }; 129 /** @brief Returns the count of Strings stored in this substring */ 130 inline unsigned int size() const { return this->strings.size(); }; 131 /** @brief Returns the i'th string from the subset of Strings @param i the i'th String */ 132 inline const std::string& operator[](unsigned int i) const { return this->strings[i]; }; 133 /** @brief Returns the i'th string from the subset of Strings @param i the i'th String */ 134 inline const std::string& getString(unsigned int i) const { return (*this)[i]; }; 135 /** @brief Returns all Strings as std::vector */ 136 inline const std::vector<std::string>& getAllStrings() const { return this->strings; } 137 /** @brief Returns true if the token is in safemode. @param i the i'th token */ 138 inline bool isInSafemode(unsigned int i) const { return this->bInSafemode[i]; } 139 /** @brief Returns the front of the StringList. */ 140 inline const std::string& front() const { return this->strings.front(); }; 141 /** @brief Returns the back of the StringList. */ 142 inline const std::string& back() const { return this->strings.back(); }; 143 /** @brief removes the back of the strings list. */ 144 inline void pop_back() { this->strings.pop_back(); this->bInSafemode.pop_back(); }; 143 145 144 // the almighty algorithm.145 static SPLIT_LINE_STATE splitLine(std::vector<std::string>& ret,146 std::vector<bool>& bInSafemode,147 const std::string& line,148 const std::string& delimiters = SubString::WhiteSpaces,149 const std::string& delimiterNeighbours = "",150 bool emptyEntries = false,151 char escape_char = '\\',152 bool removeExcapeChar = true,153 char safemode_char = '"',154 bool removeSafemodeChar = true,155 char openparenthesis_char = '(',156 char closeparenthesis_char = ')',157 bool removeParenthesisChars = true,158 char comment_char = '\0',159 SPLIT_LINE_STATE start_state = SL_NORMAL);160 // debugging.161 void debug() const;146 // the almighty algorithm. 147 static SPLIT_LINE_STATE splitLine(std::vector<std::string>& ret, 148 std::vector<bool>& bInSafemode, 149 const std::string& line, 150 const std::string& delimiters = SubString::WhiteSpaces, 151 const std::string& delimiterNeighbours = "", 152 bool emptyEntries = false, 153 char escape_char = '\\', 154 bool removeExcapeChar = true, 155 char safemode_char = '"', 156 bool removeSafemodeChar = true, 157 char openparenthesis_char = '(', 158 char closeparenthesis_char = ')', 159 bool removeParenthesisChars = true, 160 char comment_char = '\0', 161 SPLIT_LINE_STATE start_state = SL_NORMAL); 162 // debugging. 163 void debug() const; 162 164 163 public:164 static const std::string WhiteSpaces;165 static const std::string WhiteSpacesWithComma;166 static const SubString NullSubString;165 public: 166 static const std::string WhiteSpaces; 167 static const std::string WhiteSpacesWithComma; 168 static const SubString NullSubString; 167 169 168 private: 169 std::vector<std::string> strings; //!< strings produced from a single string splitted in multiple strings 170 std::vector<bool> bInSafemode; 171 }; 170 private: 171 std::vector<std::string> strings; //!< strings produced from a single string splitted in multiple strings 172 std::vector<bool> bInSafemode; 173 }; 174 } 172 175 173 176 #endif /* __SubString_H__ */ -
code/trunk/src/util/UtilPrereqs.h
r1747 r2171 60 60 // Forward declarations 61 61 //----------------------------------------------------------------------- 62 class ArgReader;63 class Convert;64 class ExprParser;65 class MultiType;66 class SubString;67 62 namespace orxonox 68 63 { 64 class Exception; 65 class ExprParser; 66 class IntVector2; 67 class IntVector3; 68 class MultiType; 69 69 class OutputBuffer; 70 70 class OutputBufferListener; 71 class Error;72 71 class OutputHandler; 72 class SignalHandler; 73 class SubString; 73 74 } 74 75 -
code/trunk/visual_studio/vc8/audio.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/base.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/ceguilua.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/core.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/cpptcl.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/debug.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/directories.vsprops
- Property svn:mergeinfo changed
/code/branches/objecthierarchy/visual_studio/vc8/directories.vsprops merged: 2114-2115
- Property svn:mergeinfo changed
-
code/trunk/visual_studio/vc8/lua.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/network.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/orxonox.vcproj
r2107 r2171 167 167 </File> 168 168 <File 169 RelativePath="..\..\src\orxonox\PlayerManager.cc" 170 > 171 </File> 172 <File 169 173 RelativePath="..\..\src\orxonox\PrecompiledHeaderFiles.cc" 170 174 > … … 206 210 </File> 207 211 <File 212 RelativePath="..\..\src\orxonox\objects\Level.cc" 213 > 214 </File> 215 <File 208 216 RelativePath="..\..\src\orxonox\objects\Radar.cc" 209 217 > … … 358 366 <File 359 367 RelativePath="..\..\src\orxonox\objects\infos\Info.cc" 360 >361 </File>362 <File363 RelativePath="..\..\src\orxonox\objects\infos\Level.cc"364 368 > 365 369 </File> … … 827 831 </File> 828 832 <File 833 RelativePath="..\..\src\orxonox\PlayerManager.h" 834 > 835 </File> 836 <File 829 837 RelativePath="..\..\src\orxonox\Settings.h" 830 838 > … … 846 854 </File> 847 855 <File 856 RelativePath="..\..\src\orxonox\objects\Level.h" 857 > 858 </File> 859 <File 848 860 RelativePath="..\..\src\orxonox\objects\Radar.h" 849 861 > … … 978 990 <File 979 991 RelativePath="..\..\src\orxonox\objects\infos\Info.h" 980 >981 </File>982 <File983 RelativePath="..\..\src\orxonox\objects\infos\Level.h"984 992 > 985 993 </File> -
code/trunk/visual_studio/vc8/orxonox.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/orxonox_vc8.sln
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/release.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/tinyxml.vcproj
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/tinyxml.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/tolua.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/toluagen.vcproj
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/toluagen.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/toluagen_orxonox.vcproj
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/toluagen_orxonox.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/visual_studio/vc8/util.vcproj
r2087 r2171 235 235 </File> 236 236 <File 237 RelativePath="..\..\src\util\mbool.h" 238 > 239 </File> 240 <File 237 241 RelativePath="..\..\src\util\MultiType.h" 238 242 > -
code/trunk/visual_studio/vc8/util.vsprops
- Property svn:mergeinfo changed (with no actual effect on merging)
Note: See TracChangeset
for help on using the changeset viewer.