Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 2171


Ignore:
Timestamp:
Nov 10, 2008, 12:05:03 AM (15 years ago)
Author:
landauf
Message:

merged revisions 2111-2170 from objecthierarchy branch back to trunk.

Location:
code/trunk
Files:
2 deleted
201 edited
5 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/TODO

    r2087 r2171  
    11todo:
     2
     3        test network functionality with paketloss/delay: http://www.linuxfoundation.org/en/Net:Netem#Packet_loss
    24
    35        bidirectional
  • code/trunk/bin/run-script

    r1735 r2171  
    88fi
    99
    10 if [[ -ne orge.cfg ]] ; then
     10if [[ ! -f ogre.cfg ]] ; then
    1111        cp ogre.cfg-init ogre.cfg
    1212fi
  • code/trunk/src/audio/AudioBuffer.cc

    r2103 r2171  
    2929#include "AudioBuffer.h"
    3030
    31 namespace audio
     31namespace orxonox
    3232{
    3333    AudioBuffer::AudioBuffer(std::string filename)
  • code/trunk/src/audio/AudioBuffer.h

    r2103 r2171  
    3535#include <AL/al.h>
    3636
    37 namespace audio
     37namespace orxonox
    3838{
    3939    class _AudioExport AudioBuffer
  • code/trunk/src/audio/AudioManager.cc

    r1784 r2171  
    3737#include "AudioStream.h"
    3838
    39 namespace audio
     39namespace orxonox
    4040{
    4141    AudioManager::AudioManager()
  • code/trunk/src/audio/AudioManager.h

    r1784 r2171  
    3535#include <string>
    3636
    37 namespace audio
     37namespace orxonox
    3838{
    3939    class _AudioExport AudioManager
  • code/trunk/src/audio/AudioPrereqs.h

    r1505 r2171  
    6060// Forward declarations
    6161//-----------------------------------------------------------------------
    62 namespace audio
     62namespace orxonox
    6363{
    6464  class AudioBuffer;
  • code/trunk/src/audio/AudioSource.cc

    r1784 r2171  
    2929#include "AudioSource.h"
    3030
    31 namespace audio
     31namespace orxonox
    3232{
    3333    AudioSource::AudioSource()
  • code/trunk/src/audio/AudioSource.h

    r1784 r2171  
    3232#include "AudioPrereqs.h"
    3333
    34 namespace audio
     34namespace orxonox
    3535{
    3636    class _AudioExport AudioSource
  • code/trunk/src/audio/AudioStream.cc

    r1784 r2171  
    3030#include "util/Debug.h"
    3131
    32 namespace audio
     32namespace orxonox
    3333{
    3434    AudioStream::AudioStream(std::string path)
  • code/trunk/src/audio/AudioStream.h

    r1784 r2171  
    3939
    4040
    41 namespace audio
     41namespace orxonox
    4242{
    4343    const int BUFFER_SIZE = 4096 * 4;
  • code/trunk/src/core/BaseObject.cc

    r2087 r2171  
    4141#include "Template.h"
    4242#include "util/String.h"
     43#include "util/mbool.h"
    4344
    4445namespace orxonox
  • code/trunk/src/core/BaseObject.h

    r2087 r2171  
    2828
    2929/**
    30     @file BaseObject.h
     30    @file
    3131    @brief Definition of the BaseObject class.
    3232
     
    4545#include "XMLIncludes.h"
    4646#include "Event.h"
     47#include "util/mbool.h"
    4748
    4849namespace orxonox
     
    7273
    7374            /** @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            }
    7583            /** @brief Returns the state of the objects activity. @return The state of the activity */
    76             inline bool isActive() const { return this->bActive_; }
     84            inline const mbool& isActive() const { return this->bActive_; }
    7785            /** @brief This function gets called if the activity of the object changes. */
    7886            virtual void changedActivity() {}
    7987
    8088            /** @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            }
    8297            /** @brief Returns the state of the objects visibility. @return The state of the visibility */
    83             inline bool isVisible() const { return this->bVisible_; }
     98            inline const mbool& isVisible() const { return this->bVisible_; }
    8499            /** @brief This function gets called if the visibility of the object changes. */
    85100            virtual void changedVisibility() {}
     
    138153            std::string name_;                          //!< The name of the object
    139154            std::string oldName_;                       //!< The old name of the object
    140             bool bActive_;                              //!< True = the object is active
    141             bool bVisible_;                             //!< True = the object is visible
     155            mbool bActive_;                             //!< True = the object is active
     156            mbool bVisible_;                            //!< True = the object is visible
    142157
    143158        private:
  • code/trunk/src/core/ClassFactory.h

    r2087 r2171  
    2828
    2929/**
    30     @file ClassFactory.h
     30    @file
    3131    @brief Definition and implementation of the ClassFactory class
    3232
  • code/trunk/src/core/ClassTreeMask.cc

    r1757 r2171  
    2828
    2929/**
    30     @file ClassTreeMask.cc
     30    @file
    3131    @brief Implementation of the ClassTreeMask, ClassTreeMaskNode and ClassTreeMaskIterator classes.
    3232*/
  • code/trunk/src/core/ClassTreeMask.h

    r1759 r2171  
    2828
    2929/**
    30     @file ClassTreeMask.h
     30    @file
    3131    @brief Definition of the ClassTreeMask, ClassTreeMaskNode and ClassTreeMaskIterator classes.
    3232
  • code/trunk/src/core/Clock.h

    r1755 r2171  
    2828
    2929/**
    30     @file Core.h
     30    @file
    3131    @brief Declaration of the Core class.
    3232
  • code/trunk/src/core/ConfigValueContainer.cc

    r1887 r2171  
    2828
    2929/**
    30     @file ConfigValueContainer.cc
     30    @file
    3131    @brief Implementation of the ConfigValueContainer class.
    3232*/
  • code/trunk/src/core/ConfigValueContainer.h

    r2087 r2171  
    2828
    2929/**
    30     @file ConfigValueContainer.h
     30    @file
    3131    @brief Definition of the ConfigValueContainer class.
    3232
  • code/trunk/src/core/ConfigValueIncludes.h

    r2103 r2171  
    2828
    2929/**
    30     @file ConfigValueIncludes.h
     30    @file
    3131    @brief Definition of macros for config-values.
    3232*/
  • code/trunk/src/core/Core.cc

    r2087 r2171  
    2828
    2929/**
    30     @file Core.cc
     30    @file
    3131    @brief Implementation of the Core class.
    3232*/
  • code/trunk/src/core/Core.h

    r2087 r2171  
    2828
    2929/**
    30     @file Core.h
     30    @file
    3131    @brief Declaration of the Core class.
    3232
  • code/trunk/src/core/CoreIncludes.h

    r2103 r2171  
    2828
    2929/**
    30     @file CoreIncludes.h
     30    @file
    3131    @brief Definition of macros for Identifier and Factory.
    3232
  • code/trunk/src/core/Factory.cc

    r2087 r2171  
    2828
    2929/**
    30     @file Factory.cc
     30    @file
    3131    @brief Implementation of the Factory class.
    3232*/
  • code/trunk/src/core/Factory.h

    r2087 r2171  
    2828
    2929/**
    30     @file Factory.h
     30    @file
    3131    @brief Definition of the Factory and the BaseFactory class.
    3232
  • code/trunk/src/core/Identifier.cc

    r2087 r2171  
    2828
    2929/**
    30     @file Identifier.cc
     30    @file
    3131    @brief Implementation of the Identifier class.
    3232*/
  • code/trunk/src/core/Identifier.h

    r2103 r2171  
    2828
    2929/**
    30     @file Identifier.h
     30    @file
    3131    @brief Definition of the Identifier, ClassIdentifier and SubclassIdentifier classes, implementation of the ClassIdentifier and SubclassIdentifier classes.
    3232
  • code/trunk/src/core/Iterator.h

    r1854 r2171  
    2828
    2929/**
    30     @file Iterator.h
     30    @file
    3131    @brief Definition and implementation of the Iterator class.
    3232
  • code/trunk/src/core/Language.cc

    r2103 r2171  
    2828
    2929/**
    30     @file Language.cc
     30    @file
    3131    @brief Implementation of the Language and the LanguageEntry classes.
    3232*/
  • code/trunk/src/core/Language.h

    r2103 r2171  
    2828
    2929/**
    30     @file Language.h
     30    @file
    3131    @brief Definition of the Language and the LanguageEntry class.
    3232
  • code/trunk/src/core/Loader.cc

    r2087 r2171  
    3737#include "Namespace.h"
    3838#include "util/Debug.h"
     39#include "util/Exception.h"
    3940
    4041#include "tinyxml/ticpp.h"
     
    157158            return true;
    158159        }
    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)
    160177        {
    161178            COUT(1) << std::endl;
    162179            COUT(1) << "An error occurred in Loader.cc while loading " << file->getFilename() << ":" << std::endl;
    163180            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;
    164188            COUT(1) << "Loading aborted." << std::endl;
    165189            return false;
  • code/trunk/src/core/MetaObjectList.cc

    r1747 r2171  
    2828
    2929/**
    30     @file MetaObjectList.cc
     30    @file
    3131    @brief Implementation of the MetaObjectList class.
    3232*/
  • code/trunk/src/core/MetaObjectList.h

    r1747 r2171  
    2828
    2929/**
    30     @file MetaObjectList.h
     30    @file
    3131    @brief Definition of the MetaObjectList class.
    3232
  • code/trunk/src/core/ObjectList.h

    r1747 r2171  
    2828
    2929/**
    30     @file ObjectList.h
     30    @file
    3131    @brief Definition and implementation of the ObjectList class.
    3232
  • code/trunk/src/core/ObjectListBase.cc

    r1747 r2171  
    2828
    2929/**
    30     @file ObjectListBase.cc
     30    @file
    3131    @brief Implementation of the ObjectListBase class.
    3232
  • code/trunk/src/core/ObjectListBase.h

    r1854 r2171  
    2828
    2929/**
    30     @file ObjectListBase.h
     30    @file
    3131    @brief Definition of the ObjectListBase class.
    3232
  • code/trunk/src/core/OrxonoxClass.cc

    r1747 r2171  
    2828
    2929/**
    30     @file OrxonoxClass.cc
     30    @file
    3131    @brief Implementation of the OrxonoxClass Class.
    3232*/
  • code/trunk/src/core/OrxonoxClass.h

    r1755 r2171  
    2828
    2929/**
    30     @file OrxonoxClass.h
     30    @file
    3131    @brief Declaration of the OrxonoxClass Class.
    3232
  • code/trunk/src/core/Super.h

    r2087 r2171  
    2828
    2929/**
    30     @file Super.h
     30    @file
    3131    @brief Definition of all super-function related macros.
    3232
  • 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

    r2103 r2171  
    2828
    2929/**
    30     @file XMLIncludes.h
     30    @file
    3131    @brief Forward declarations of some XML classes.
    3232*/
  • code/trunk/src/core/XMLPort.h

    r2087 r2171  
    2828
    2929/**
    30     @file XMLPort.h
     30    @file
    3131    @brief Declaration of the XMLPort helper classes and macros.
    3232
     
    4444
    4545#include "util/Debug.h"
     46#include "util/Exception.h"
    4647#include "util/MultiType.h"
    4748#include "tinyxml/ticpp.h"
     
    495496                                            if (this->identifierIsIncludedInLoaderMask(identifier))
    496497                                            {
    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
    507499                                                {
    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;
    510526                                                }
    511                                                 else
     527                                                catch (AbortLoadingException& ex)
    512528                                                {
    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;
    514531                                                }
    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                                                }
    523541                                            }
    524542                                        }
  • code/trunk/src/network/ChatListener.cc

    r2087 r2171  
    3232#include "core/Core.h"
    3333
    34 namespace network
     34namespace orxonox
    3535{
    3636    ChatListener::ChatListener()
  • code/trunk/src/network/ChatListener.h

    r2087 r2171  
    3535#include "core/OrxonoxClass.h"
    3636
    37 namespace network
     37namespace orxonox
    3838{
    39     class _NetworkExport ChatListener : virtual public orxonox::OrxonoxClass
     39    class _NetworkExport ChatListener : virtual public OrxonoxClass
    4040    {
    4141        public:
  • code/trunk/src/network/Client.cc

    r2087 r2171  
    4949// #include "packet/Acknowledgement.h"
    5050
    51 namespace network
     51namespace orxonox
    5252{
    5353//   SetConsoleCommandShortcut(Client, chat);
  • code/trunk/src/network/Client.h

    r2087 r2171  
    5454
    5555
    56 namespace network
     56namespace orxonox
    5757{
    5858  /**
    59   network::Client *client;
     59  Client *client;
    6060  * The network/Client class
    6161  * This class implements all necessary function for the network communication
  • code/trunk/src/network/ClientConnection.cc

    r2087 r2171  
    4848#include "util/Debug.h"
    4949
    50 namespace network
     50namespace orxonox
    5151{
    5252  //static boost::thread_group network_threads;
  • code/trunk/src/network/ClientConnection.h

    r2087 r2171  
    5050namespace boost { class thread; }
    5151
    52 namespace network
     52namespace orxonox
    5353{
    5454
  • code/trunk/src/network/ClientConnectionListener.cc

    r2087 r2171  
    33#include "core/Core.h"
    44
    5 namespace network{
     5namespace orxonox{
    66
    77  ClientConnectionListener::ClientConnectionListener()
     
    1111
    1212  void ClientConnectionListener::getConnectedClients(){
    13     if(orxonox::Core::showsGraphics())
     13    if(Core::showsGraphics())
    1414      this->clientConnected(0); //server client id
    1515    ClientInformation *client = ClientInformation::getBegin();
  • code/trunk/src/network/ClientConnectionListener.h

    r2087 r2171  
    66#include "core/OrxonoxClass.h"
    77
    8 namespace network{
     8namespace orxonox{
    99
    10   class _NetworkExport ClientConnectionListener : virtual public orxonox::OrxonoxClass
     10  class _NetworkExport ClientConnectionListener : virtual public OrxonoxClass
    1111  {
    1212    friend class Server;
  • code/trunk/src/network/ClientInformation.cc

    r2087 r2171  
    4343#include <iostream> //debug
    4444
    45 namespace network
     45namespace orxonox
    4646{
    4747
  • code/trunk/src/network/ClientInformation.h

    r2087 r2171  
    4848// WATCH OUT: THE CLIENTINFORMATION LIST IS NOT THREADSAFE ANYMORE
    4949
    50 namespace network
     50namespace orxonox
    5151{
    5252  static const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1;
  • code/trunk/src/network/ConnectionManager.cc

    r2087 r2171  
    6565}
    6666
    67 namespace network
     67namespace orxonox
    6868{
    6969  //boost::thread_group network_threads;
     
    138138
    139139  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);
    141141    if(enet_peer_send(peer, NETWORK_DEFAULT_CHANNEL, packet)!=0)
    142142      return false;
     
    156156    if(!instance_)
    157157      return false;
    158     boost::recursive_mutex::scoped_lock lock(instance_->enet_mutex);
     158    boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex);
    159159    for(ClientInformation *i=ClientInformation::getBegin()->next(); i!=0; i=i->next()){
    160160      COUT(3) << "adding broadcast packet for client: " << i->getID() << std::endl;
     
    169169    if(server==NULL || !instance_)
    170170      return false;
    171     boost::recursive_mutex::scoped_lock lock(enet_mutex);
     171    boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex);
    172172    enet_host_flush(server);
    173173    lock.unlock();
     
    180180    atexit(enet_deinitialize);
    181181    { //scope of the mutex
    182       boost::recursive_mutex::scoped_lock lock(enet_mutex);
     182      boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex);
    183183      enet_initialize();
    184184      server = enet_host_create(&bindAddress, NETWORK_MAX_CONNECTIONS, 0, 0);
     
    194194    while(!quit){
    195195      { //mutex scope
    196         boost::recursive_mutex::scoped_lock lock(enet_mutex);
     196        boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex);
    197197        if(enet_host_service(server, event, NETWORK_WAIT_TIMEOUT)<0){
    198198          // we should never reach this point
     
    236236    // if we're finishied, destroy server
    237237    {
    238       boost::recursive_mutex::scoped_lock lock(enet_mutex);
     238      boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex);
    239239      enet_host_destroy(server);
    240240      lock.unlock();
     
    250250    while(temp!=0){
    251251      {
    252         boost::recursive_mutex::scoped_lock lock(enet_mutex);
     252        boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex);
    253253        enet_peer_disconnect(temp->getPeer(), 0);
    254254        lock.unlock();
     
    258258    //bugfix: might be the reason why server crashes when clients disconnects
    259259    temp = ClientInformation::getBegin()->next();
    260     boost::recursive_mutex::scoped_lock lock(enet_mutex);
     260    boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex);
    261261    while( temp!=0 && enet_host_service(server, &event, NETWORK_WAIT_TIMEOUT) >= 0){
    262262      switch (event.type)
     
    306306    unsigned int network_id=0, failures=0;
    307307    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()){
    311311      id = (*it).second;
    312312      if(id == NULL)
     
    332332  void ConnectionManager::disconnectClient(ClientInformation *client){
    333333    {
    334       boost::recursive_mutex::scoped_lock lock(enet_mutex);
     334      boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex);
    335335      enet_peer_disconnect(client->getPeer(), 0);
    336336      lock.unlock();
  • code/trunk/src/network/ConnectionManager.h

    r2087 r2171  
    5959}
    6060
    61 namespace network
     61namespace orxonox
    6262{
    6363    const int NETWORK_PORT = 55556;
  • code/trunk/src/network/GamestateClient.cc

    r2087 r2171  
    3939
    4040
    41 namespace network
     41namespace orxonox
    4242{
    4343  struct _NetworkExport GameStateItem{
     
    9494  * @return iterator pointing to the next object in the list
    9595  */
    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;
    9898    ++it;
    9999    delete  *temp;
  • code/trunk/src/network/GamestateClient.h

    r2087 r2171  
    5050const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1;
    5151
    52 namespace network
     52namespace orxonox
    5353{
    5454  class _NetworkExport GamestateClient: public GamestateHandler
     
    6666  private:
    6767    packet::Gamestate *processGamestate(packet::Gamestate *gs);
    68     void removeObject(orxonox::ObjectListIterator<Synchronisable> &it);
     68    void removeObject(ObjectListIterator<Synchronisable> &it);
    6969    void printGamestateMap();
    7070    bool sendAck(unsigned int gamestateID);
  • code/trunk/src/network/GamestateHandler.cc

    r1763 r2171  
    44#include "packet/Packet.h"
    55
    6 namespace network {
     6namespace orxonox {
    77
    88GamestateHandler *GamestateHandler::instance_=0;
     
    2222
    2323
    24 }//namespace network
     24}//namespace orxonox
  • code/trunk/src/network/GamestateHandler.h

    r2087 r2171  
    3434#include "packet/Chat.h"
    3535
    36 namespace network {
     36namespace orxonox {
    3737
    3838/**
  • code/trunk/src/network/GamestateManager.cc

    r2087 r2171  
    5151#include "Synchronisable.h"
    5252
    53 namespace network
     53namespace orxonox
    5454{
    5555  GamestateManager::GamestateManager() {
  • code/trunk/src/network/GamestateManager.h

    r2087 r2171  
    4747#include "packet/Gamestate.h"
    4848
    49 namespace network
     49namespace orxonox
    5050{
    5151
  • code/trunk/src/network/Host.cc

    r2087 r2171  
    3434#include "ChatListener.h"
    3535
    36 namespace network {
     36namespace orxonox {
    3737
    3838SetConsoleCommandShortcut(Host, Chat);
     
    8080// }
    8181
    82 // bool Host::receiveChat(network::packet::Chat *message, unsigned int clientID){
     82// bool Host::receiveChat(packet::Chat *message, unsigned int clientID){
    8383//   if(instance_)
    8484//     return instance_->processChat(message, clientID);
     
    110110
    111111bool 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)
    113113    it->incomingChat(message, playerID);
    114114
     
    116116}
    117117
    118 }//namespace network
     118}//namespace orxonox
  • code/trunk/src/network/Host.h

    r2087 r2171  
    3434#include "packet/Chat.h"
    3535
    36 namespace network {
     36namespace orxonox {
    3737
    3838/**
  • code/trunk/src/network/NetworkCallback.h

    r2087 r2171  
    44#include "NetworkPrereqs.h"
    55
    6 namespace network{
     6namespace orxonox{
    77  class _NetworkExport NetworkCallbackBase
    88  {
  • code/trunk/src/network/NetworkPrereqs.h

    r2087 r2171  
    5959// Forward declarations
    6060//-----------------------------------------------------------------------
    61 namespace network
     61namespace orxonox
    6262{
    6363  class Client;
  • code/trunk/src/network/PacketBuffer.cc

    r1505 r2171  
    3939#include <boost/thread/mutex.hpp>
    4040
    41 namespace network
     41namespace orxonox
    4242{
    4343   boost::recursive_mutex PacketBuffer::mutex_;
     
    147147  }
    148148
    149 } // namespace network
     149} // namespace orxonox
  • code/trunk/src/network/PacketBuffer.h

    r2087 r2171  
    4747#include <boost/thread/recursive_mutex.hpp>
    4848
    49 namespace network
     49namespace orxonox
    5050{
    5151  struct _NetworkExport PacketEnvelope{
  • code/trunk/src/network/Server.cc

    r2087 r2171  
    6060#include "ChatListener.h"
    6161
    62 namespace network
     62namespace orxonox
    6363{
    6464  const unsigned int MAX_FAILURES = 20;
     
    317317
    318318    // inform all the listeners
    319     orxonox::ObjectList<ClientConnectionListener>::iterator listener = orxonox::ObjectList<ClientConnectionListener>::begin();
     319    ObjectList<ClientConnectionListener>::iterator listener = ObjectList<ClientConnectionListener>::begin();
    320320    while(listener){
    321321      listener->clientConnected(newid);
     
    366366
    367367// inform all the listeners
    368     orxonox::ObjectList<ClientConnectionListener>::iterator listener = orxonox::ObjectList<ClientConnectionListener>::begin();
     368    ObjectList<ClientConnectionListener>::iterator listener = ObjectList<ClientConnectionListener>::begin();
    369369    while(listener){
    370370      listener->clientDisconnected(client->getID());
     
    404404    }
    405405//    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)
    407407      it->incomingChat(message, clientID);
    408408
  • code/trunk/src/network/Server.h

    r2087 r2171  
    4949#include "GamestateManager.h"
    5050
    51 namespace network
     51namespace orxonox
    5252{
    5353  const int CLIENTID_SERVER = 0;
  • code/trunk/src/network/Synchronisable.cc

    r2087 r2171  
    5050// #include "core/Identifier.h"
    5151
    52 namespace network
     52#include "Host.h"
     53namespace orxonox
    5354{
    5455
     
    5758  std::queue<unsigned int> Synchronisable::deletedObjects_;
    5859
    59   int Synchronisable::state_=0x1; // detemines wheter we are server (default) or client
     60  uint8_t Synchronisable::state_=0x1; // detemines wheter we are server (default) or client
    6061
    6162  /**
     
    6364  * Initializes all Variables and sets the right objectID
    6465  */
    65   Synchronisable::Synchronisable(orxonox::BaseObject* creator){
     66  Synchronisable::Synchronisable(BaseObject* creator){
    6667    RegisterRootObject(Synchronisable);
    6768    static uint32_t idCounter=0;
    6869    objectFrequency_=1;
    6970    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;
    7179    classID = (unsigned int)-1;
    7280    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
    7390
    7491    this->creatorID = OBJECTID_UNKNOWN;
     
    96113  Synchronisable::~Synchronisable(){
    97114    // delete callback function objects
    98     if(!orxonox::Identifier::isCreatingHierarchy()){
     115    if(!Identifier::isCreatingHierarchy()){
    99116      for(std::list<synchronisableVariable *>::iterator it = syncList->begin(); it!=syncList->end(); it++)
    100117        delete (*it)->callback;
    101       if (this->objectMode_ != 0x0)
     118      if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
    102119        deletedObjects_.push(objectID);
    103120//       COUT(3) << "destruct synchronisable +++" << objectID << " | " << classID << std::endl;
     
    106123//       objectMap_.erase(objectID);
    107124    }
     125    std::map<unsigned int, Synchronisable*>::iterator it;
     126    it = objectMap_.find(objectID);
     127    if (it != objectMap_.end())
     128      objectMap_.erase(it);
    108129  }
    109130
     
    143164   * @return pointer to the newly created synchronisable
    144165   */
    145   Synchronisable *Synchronisable::fabricate(uint8_t*& mem, int mode)
     166  Synchronisable *Synchronisable::fabricate(uint8_t*& mem, uint8_t mode)
    146167  {
    147168    synchronisableHeader *header = (synchronisableHeader *)mem;
     
    152173      return 0;
    153174    }
    154    
     175
    155176    COUT(4) << "fabricating object with id: " << header->objectID << std::endl;
    156177
    157     orxonox::Identifier* id = ClassByID(header->classID);
     178    Identifier* id = ClassByID(header->classID);
    158179    assert(id);
    159     orxonox::BaseObject* creator = 0;
     180    BaseObject* creator = 0;
    160181    if (header->creatorID != OBJECTID_UNKNOWN)
    161182    {
     
    167188      }
    168189      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);
    172194    assert(bo);
    173195    Synchronisable *no = dynamic_cast<Synchronisable *>(bo);
     
    214236   */
    215237  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      }
    220249    }
    221250    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;
    228251  }
    229252
     
    234257  * @param var pointer to the variable
    235258  * @param size size of the datatype the variable consists of
    236   * @param t the type of the variable (network::DATA or network::STRING
     259  * @param t the type of the variable (DATA or STRING
    237260  * @param mode same as in getData
    238261  * @param cb callback object that should get called, if the value of the variable changes
    239262  */
    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){
    241264    assert( mode==direction::toclient || mode==direction::toserver || mode==direction::serverMaster || mode==direction::clientMaster);
    242265    // create temporary synch.Var struct
     
    249272    if( ( mode & direction::bidirectional ) )
    250273    {
    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      }
    253283      temp->varReference = 0;
    254284    }
     
    265295#endif
    266296  }
     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
    267314
    268315  /**
     
    280327   * @return true: if !doSync or if everything was successfully saved
    281328   */
    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_;
    283332    //if this tick is we dont synchronise, then abort now
    284     if(!doSync(id))
     333    if(!doSync(id, mode))
    285334      return true;
    286335    //std::cout << "inside getData" << std::endl;
    287336    unsigned int tempsize = 0;
    288     if(mode==0x0)
    289       mode=state_;
    290337    if(classID==0)
    291338      COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
     
    307354    header->classID = this->classID;
    308355    header->dataAvailable = true;
    309     tempsize+=sizeof(synchronisableHeader);
    310     mem+=sizeof(synchronisableHeader);
     356    tempsize += sizeof(synchronisableHeader);
     357    mem += sizeof(synchronisableHeader);
    311358    // end copy header
    312359
     
    319366        continue;  // this variable should only be received
    320367      }
     368
     369      // =========== start bidirectional stuff =============
    321370      // if the variable gets synchronised bidirectional, then add the reference to the bytestream
    322371      if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
    323372      {
     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
    324394        *(uint8_t*)mem = (*i)->varReference;
    325395        mem += sizeof( (*i)->varReference );
    326396        tempsize += sizeof( (*i)->varReference );
    327397      }
     398      // ================== end bidirectional stuff
     399
    328400      switch((*i)->type){
    329401        case DATA:
    330402          memcpy( (void *)(mem), (void*)((*i)->var), (*i)->size);
    331           mem+=(*i)->size;
    332           tempsize+=(*i)->size;
     403          mem += (*i)->size;
     404          tempsize += (*i)->size;
    333405          break;
    334406        case STRING:
    335407          memcpy( (void *)(mem), (void *)&((*i)->size), sizeof(size_t) );
    336           mem+=sizeof(size_t);
     408          mem += sizeof(size_t);
    337409          const char *data = ( ( *(std::string *) (*i)->var).c_str());
    338410          memcpy( mem, (void*)data, (*i)->size);
    339411          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);
    342414          break;
    343415      }
     
    354426   * @return true/false
    355427   */
    356   bool Synchronisable::updateData(uint8_t*& mem, int mode, bool forceCallback){
     428  bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback){
    357429    if(mode==0x0)
    358430      mode=state_;
    359431    std::list<synchronisableVariable *>::iterator i;
     432    //assert(objectMode_!=0x0);
     433    //assert( (mode ^ objectMode_) != 0);
    360434    if(syncList->empty()){
    361435      COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl;
     
    367441    synchronisableHeader *syncHeader = (synchronisableHeader *)mem;
    368442    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 ?
    370445    if(syncHeader->dataAvailable==false){
    371       mem+=syncHeader->size;
     446      mem += syncHeader->size;
    372447      return true;
    373448    }
    374449
    375     mem+=sizeof(synchronisableHeader);
     450    mem += sizeof(synchronisableHeader);
    376451    // stop extract header
    377     assert(this->objectID==syncHeader->objectID);
    378 //    assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ?
    379452
    380453    COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl;
     
    382455      if( ((*i)->mode ^ mode) == 0 ){
    383456        COUT(5) << "synchronisable: not updating variable " << std::endl;
     457        // if we have a forcecallback then do the callback
    384458        continue;  // this variable should only be set
    385459      }
    386460      COUT(5) << "Synchronisable: element size: " << (*i)->size << " type: " << (*i)->type << std::endl;
    387461      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
    388508      switch((*i)->type){
    389509        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)
    391511          {
    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;
    407514          }
    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;
    413523          break;
    414524        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 )
    416532          {
    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)) );
    432536          }
    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
    439538          *((std::string *)((*i)->var)) = std::string((const char*)mem);
    440539          COUT(5) << "synchronisable: char: " << (const char*)mem << " string: " << std::string((const char*)mem) << std::endl;
     
    446545        (*i)->callback->call();
    447546    }
     547    assert(mem == data+syncHeader->size);
    448548    return true;
    449549  }
     
    455555  * @return amount of bytes
    456556  */
    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){
    460558    int tsize=sizeof(synchronisableHeader);
    461559    if(mode==0x0)
    462560      mode=state_;
     561    if(!doSync(id, mode))
     562      return 0;
    463563    std::list<synchronisableVariable *>::iterator i;
    464564    for(i=syncList->begin(); i!=syncList->end(); i++){
     
    489589   * @return true/false
    490590   */
    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() ) );
    493595  }
    494596
    495597  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);
    497600  }
    498601
     
    510613  /**
    511614   * This function sets the synchronisation mode of the object
     615   * If set to 0x0 variables will not be synchronised at all
    512616   * If set to 0x1 variables will only be synchronised to the client
    513617   * If set to 0x2 variables will only be synchronised to the server
     
    515619   * @param mode same as in registerVar
    516620   */
    517   void Synchronisable::setObjectMode(int mode){
     621  void Synchronisable::setObjectMode(uint8_t mode){
    518622    assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3);
    519623    objectMode_=mode;
  • code/trunk/src/network/Synchronisable.h

    r2087 r2171  
    4242
    4343#define REGISTERDATA(varname, ...) \
    44     registerVar((void*)&varname, sizeof(varname), network::DATA, __VA_ARGS__)
     44    registerVariable((void*)&varname, sizeof(varname), DATA, __VA_ARGS__)
    4545#define REGISTERSTRING(stringname, ...) \
    46     registerVar(&stringname, stringname.length()+1, network::STRING, __VA_ARGS__)
     46    registerVariable(&stringname, stringname.length()+1, STRING, __VA_ARGS__)
    4747
    48 namespace network
     48namespace orxonox
    4949{
    5050  static const unsigned int OBJECTID_UNKNOWN = (unsigned int)-1;
     
    6262  namespace syncmode{
    6363    enum mode{
    64       one=0,
     64      once=0,
    6565      always=1
    6666    };
     
    8181
    8282  struct _NetworkExport synchronisableVariable{
    83     unsigned int size;
    84     int mode; // this determines in which direction the variable gets synchronised
     83    size_t size;
     84    uint8_t mode; // this determines in which direction the variable gets synchronised
    8585    void *var;
    8686    variableType type;
     
    9595  * @author Oliver Scheuss
    9696  */
    97   class _NetworkExport Synchronisable : virtual public orxonox::OrxonoxClass{
     97  class _NetworkExport Synchronisable : virtual public OrxonoxClass{
    9898  public:
    9999    friend class packet::Gamestate;
    100     friend class GamestateClient;
    101     friend class Server;
     100//     friend class Server;
    102101    virtual ~Synchronisable();
    103102
     
    106105    static void setClient(bool b);
    107106
    108     static Synchronisable *fabricate(uint8_t*& mem, int mode=0x0);
     107    static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
    109108    static bool deleteObject(unsigned int objectID);
    110109    static Synchronisable *getSynchronisable(unsigned int objectID);
     
    115114    inline unsigned int getClassID(){return classID;}
    116115  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);
    120120    void setObjectFrequency(unsigned int freq){ objectFrequency_ = freq; }
    121121
    122122
    123123  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);
    127127    bool isMyData(uint8_t* mem);
    128128    bool doSelection(unsigned int id);
    129     bool doSync(unsigned int id);
     129    bool doSync(unsigned int id, uint8_t mode=0x0);
    130130
    131131    unsigned int objectID;
     
    134134
    135135    std::list<synchronisableVariable *> *syncList;
    136     static int state_; // detemines wheter we are server (default) or client
     136    static uint8_t state_; // detemines wheter we are server (default) or client
    137137    bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server)
    138138    unsigned int objectFrequency_;
  • code/trunk/src/network/packet/Acknowledgement.cc

    r1907 r2171  
    3333#include "core/CoreIncludes.h"
    3434
    35 namespace network {
     35namespace orxonox {
    3636namespace packet {
    3737
    3838#define PACKET_FLAGS_ACK    0
    3939#define _PACKETID           0
    40 #define _ACKID              _PACKETID + sizeof(network::packet::ENUM::Type)
     40#define _ACKID              _PACKETID + sizeof(packet::ENUM::Type)
    4141 
    4242Acknowledgement::Acknowledgement( unsigned int id, unsigned int clientID )
     
    7474
    7575} //namespace packet
    76 } //namespace network
     76} //namespace orxonox
  • code/trunk/src/network/packet/Acknowledgement.h

    r2087 r2171  
    3333
    3434
    35 namespace network {
     35namespace orxonox {
    3636namespace packet {
    3737/**
     
    5353
    5454} //namespace packet
    55 } //namespace network
     55} //namespace orxonox
    5656
    5757#endif
  • code/trunk/src/network/packet/Chat.cc

    r1907 r2171  
    3131#include "network/Host.h"
    3232
    33 namespace network {
     33namespace orxonox {
    3434namespace packet {
    3535 
     
    7777
    7878} //namespace packet
    79 } //namespace network
     79} //namespace orxonox
  • code/trunk/src/network/packet/Chat.h

    r2087 r2171  
    1010#include "Packet.h"
    1111
    12 namespace network {
     12namespace orxonox {
    1313namespace packet {
    1414/**
     
    3333
    3434} //namespace packet
    35 } //namespace network
     35} //namespace orxonox
    3636
    3737#endif
  • code/trunk/src/network/packet/ClassID.cc

    r1907 r2171  
    3434#include <assert.h>
    3535
    36 namespace network {
     36namespace orxonox {
    3737namespace packet {
    3838
     
    6868
    6969unsigned 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_;
    7171}
    7272
    7373bool ClassID::process(){
    7474  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) ));
    7676  if(id==NULL)
    7777    return false;
     
    8686
    8787} //namespace packet
    88 }//namespace network
     88}//namespace orxonox
  • code/trunk/src/network/packet/ClassID.h

    r2087 r2171  
    3535#include "Packet.h"
    3636
    37 namespace network {
     37namespace orxonox {
    3838namespace packet {
    3939
     
    5959
    6060} //namespace packet
    61 } //namespace network
     61} //namespace orxonox
    6262
    6363#endif
  • code/trunk/src/network/packet/DeleteObjects.cc

    r1907 r2171  
    3434#include <assert.h>
    3535
    36 namespace network {
     36namespace orxonox {
    3737namespace packet {
    3838
     
    9595
    9696} //namespace packet
    97 } //namespace network
     97} //namespace orxonox
  • code/trunk/src/network/packet/DeleteObjects.h

    r2087 r2171  
    3434
    3535
    36 namespace network {
     36namespace orxonox {
    3737namespace packet {
    3838/**
     
    5555
    5656} //namespace packet
    57 } //namespace network
     57} //namespace orxonox
    5858
    5959#endif
  • code/trunk/src/network/packet/Gamestate.cc

    r2087 r2171  
    3838
    3939
    40 namespace network {
     40namespace orxonox {
    4141
    4242namespace packet {
     
    7171}
    7272
    73 bool Gamestate::collectData(int id, int mode)
    74 {
    75   int tempsize=0, currentsize=0;
     73bool Gamestate::collectData(int id, uint8_t mode)
     74{
     75  unsigned int tempsize=0, currentsize=0;
    7676  assert(data_==0);
    77   int size = calcGamestateSize(id, mode);
     77  unsigned int size = calcGamestateSize(id, mode);
    7878
    7979  COUT(4) << "G.ST.Man: producing gamestate with id: " << id << std::endl;
     
    8686  }
    8787
    88 #ifndef NDEBUG
    89   std::list<Synchronisable*> slist;
    90   std::list<Synchronisable*>::iterator iit;
    91 #endif
    9288  //start collect data synchronisable by synchronisable
    9389  uint8_t *mem=data_;
    9490  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){
    9793    tempsize=it->getSize(id, mode);
    9894
    9995    if(currentsize+tempsize > size){
     96      assert(0); // if we don't use multithreading this part shouldn't be neccessary
    10097      // start allocate additional memory
    10198      COUT(3) << "G.St.Man: need additional memory" << std::endl;
    102       orxonox::ObjectList<Synchronisable>::iterator temp = it;
     99      ObjectList<Synchronisable>::iterator temp = it;
    103100      int addsize=tempsize;
    104101      while(++temp)
     
    110107    }// stop allocate additional memory
    111108
    112 #ifndef NDEBUG
    113     for(iit=slist.begin(); iit!=slist.end(); iit++)
    114       assert((*iit)!=*it);
    115     slist.push_back(*it);
    116 #endif
    117109
    118110    //if(it->doSelection(id))
     
    127119  //start write gamestate header
    128120  HEADER->packetType = ENUM::Gamestate;
    129   assert( *(ENUM::Type *)(data_) == ENUM::Gamestate);
    130121  HEADER->datasize = currentsize;
    131122  HEADER->id = id;
     
    140131}
    141132
    142 bool Gamestate::spreadData(int mode)
     133bool Gamestate::spreadData(uint8_t mode)
    143134{
    144135  assert(data_);
     
    147138  uint8_t *mem=data_+sizeof(GamestateHeader);
    148139    // 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();
    150141  Synchronisable *s;
    151142
     
    163154      bool b = s->updateData(mem, mode);
    164155      assert(b);
    165       //if(!s->updateData(mem, mode))
    166         //return false;
    167156    }
    168157  }
     
    367356    assert(it->second->objectID==oldobjectheader->objectID);
    368357    *newobjectheader = *oldobjectheader;
    369     objectOffset=sizeof(uint8_t)+sizeof(bool); //skip the size and the availableData variables in the objectheader
     358    objectOffset=sizeof(synchronisableHeader); //skip the size and the availableData variables in the objectheader
    370359    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);
    376362    }else{
    377363      newobjectheader->dataAvailable=false;
    378       while(objectOffset<objectsize){
    379         *(newdata+objectOffset)=0;    // set to 0
    380         objectOffset++;
    381       }
     364      memset(newdata+objectOffset, 0, objectsize-objectOffset);
    382365      assert(objectOffset==objectsize);
    383366    }
     
    565548
    566549
    567 unsigned int Gamestate::calcGamestateSize(unsigned int id, int mode)
    568 {
    569   int size=0;
     550unsigned int Gamestate::calcGamestateSize(unsigned int id, uint8_t mode)
     551{
     552  unsigned int size=0;
    570553    // get the start of the Synchronisable list
    571   orxonox::ObjectList<Synchronisable>::iterator it;
     554  ObjectList<Synchronisable>::iterator it;
    572555    // get total size of gamestate
    573   for(it = orxonox::ObjectList<Synchronisable>::begin(); it; ++it)
     556  for(it = ObjectList<Synchronisable>::begin(); it; ++it)
    574557    size+=it->getSize(id, mode); // size of the actual data of the synchronisable
    575558//  size+=sizeof(GamestateHeader);
     
    582565 * @return iterator pointing to the next object in the list
    583566 */
    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;
    586569    ++it;
    587570    delete  *temp;
  • code/trunk/src/network/packet/Gamestate.h

    r2087 r2171  
    4040#endif
    4141
    42 namespace network {
     42namespace orxonox {
    4343
    4444namespace packet {
     
    6969    ~Gamestate();
    7070
    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);
    7373    int getID();
    7474    bool isDiffed();
     
    9090    bool operator ==(packet::Gamestate gs);
    9191  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);
    9494    std::map<unsigned int, Synchronisable*> dataMap_;
    9595};
  • code/trunk/src/network/packet/Packet.cc

    r2087 r2171  
    4646#include "core/CoreIncludes.h"
    4747
    48 namespace network{
     48namespace orxonox{
    4949
    5050namespace packet{
     
    5353#define _PACKETID           0
    5454
    55 std::map<ENetPacket *, Packet *> Packet::packetMap_;
     55std::map<size_t, Packet *> Packet::packetMap_;
     56boost::recursive_mutex Packet::packetMap_mutex;
    5657
    5758Packet::Packet(){
     
    128129      return false;
    129130    }
     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);
    130134    // We deliver ENet the data address so that it doesn't memcpy everything again.
    131135    // --> We have to delete data_ ourselves!
     
    134138    // Add the packet to a global list so we can access it again once enet calls our
    135139    // 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;
    137141  }
    138142#ifndef NDEBUG
     
    153157//  ENetPacket *temp = enetPacket_;
    154158//  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_);
    156160  return true;
    157161}
     
    207211*/
    208212void Packet::deletePacket(ENetPacket *enetPacket){
     213  boost::recursive_mutex::scoped_lock lock(Packet::packetMap_mutex);
    209214  // 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);
    211216  assert(it != packetMap_.end());
    212217  // Make sure we don't delete it again in the destructor
    213218  it->second->enetPacket_ = 0;
    214219  delete it->second;
    215   //packetMap_.erase(it);
     220  packetMap_.erase(it);
    216221  COUT(4) << "PacketMap size: " << packetMap_.size() << std::endl;
    217222}
     
    219224} // namespace packet
    220225
    221 } // namespace network
    222 
     226} // namespace orxonox
     227
  • code/trunk/src/network/packet/Packet.h

    r2087 r2171  
    2929#define NETWORKPACKET_H
    3030
    31 #include "../NetworkPrereqs.h"
     31#include "network/NetworkPrereqs.h"
    3232
    3333#include <map>
    3434#include <enet/enet.h>
     35#include <boost/thread/recursive_mutex.hpp>
    3536
    3637#include "util/Integers.h"
    3738
    38 namespace network {
     39namespace orxonox {
    3940
    4041namespace packet{
     
    9293    bool bDataENetAllocated_;
    9394  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;
    9598    ENetPacket *enetPacket_;
    9699};
     
    98101} //namespace packet
    99102
    100 } //namespace network
     103} //namespace orxonox
    101104
    102105#endif
  • code/trunk/src/network/packet/Welcome.cc

    r1907 r2171  
    3636#include <assert.h>
    3737
    38 namespace network {
     38namespace orxonox {
    3939namespace packet {
    4040
     
    7070
    7171unsigned 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);
    7373}
    7474
     
    8787
    8888} //namespace packet
    89 }//namespace network
     89}//namespace orxonox
  • code/trunk/src/network/packet/Welcome.h

    r2087 r2171  
    3333#include "Packet.h"
    3434
    35 namespace network {
     35namespace orxonox {
    3636namespace packet {
    3737
     
    5454
    5555} //namespace packet
    56 } //namespace network
     56} //namespace orxonox
    5757
    5858#endif
  • code/trunk/src/orxonox/CMakeLists.txt

    r2130 r2171  
    44  LevelManager.cc
    55  Main.cc
     6  PlayerManager.cc
    67  Settings.cc
    78 
  • code/trunk/src/orxonox/CameraManager.cc

    • Property svn:mergeinfo changed (with no actual effect on merging)
  • code/trunk/src/orxonox/CameraManager.h

    r2103 r2171  
    2828
    2929 /**
    30  @file  CameraManager.h
     30 @file
    3131 @brief Handles the instances of Camera class
    3232 @author Benjamin Knecht <beni_at_orxonox.net>
  • code/trunk/src/orxonox/LevelManager.cc

    r2087 r2171  
    2828
    2929#include "OrxonoxStableHeaders.h"
    30 
    3130#include "LevelManager.h"
    3231
    33 #include "core/CoreIncludes.h"
    34 
    35 #include "objects/infos/Level.h"
     32#include "PlayerManager.h"
     33#include "objects/Level.h"
    3634#include "objects/infos/HumanPlayer.h"
    3735
     
    4240    LevelManager::LevelManager()
    4341    {
    44         RegisterRootObject(LevelManager);
    45 
    4642        assert(singletonRef_s == 0);
    4743        singletonRef_s = this;
    48 
    49         this->getConnectedClients();
    5044    }
    5145
     
    9589        {
    9690            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)
    9892                this->levels_s.front()->playerEntered(it->second);
    9993        }
    10094    }
    101 
    102 
    103     void LevelManager::clientConnected(unsigned int clientID)
    104     {
    105         COUT(3) << "client connected" << std::endl;
    106 
    107         // create new HumanPlayer instance
    108         HumanPlayer* player = new HumanPlayer(0);
    109         player->setClientID(clientID);
    110 
    111         // add to clients-map
    112         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-map
    124         PlayerInfo* player = this->clients_[clientID];
    125         this->clients_.erase(clientID);
    126 
    127         if (this->getActiveLevel())
    128             this->getActiveLevel()->playerLeft(player);
    129 
    130         // delete PlayerInfo instance
    131         if (player)
    132             delete player;
    133     }
    134 
    135 
    136     PlayerInfo* LevelManager::getClient(unsigned int clientID) const
    137     {
    138         std::map<unsigned int, PlayerInfo*>::const_iterator it = this->clients_.find(clientID);
    139         if (it != this->clients_.end())
    140             return it->second;
    141         else
    142             return 0;
    143     }
    14495}
  • code/trunk/src/orxonox/LevelManager.h

    r2087 r2171  
    3636#include <cassert>
    3737
    38 #include "network/ClientConnectionListener.h"
    39 
    4038namespace orxonox
    4139{
    42     class _OrxonoxExport LevelManager : public network::ClientConnectionListener
     40    class _OrxonoxExport LevelManager
    4341    {
    4442        public:
     
    5048            Level* getActiveLevel();
    5149
    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; }
    5651            static LevelManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
    5752
     
    5954            LevelManager(const LevelManager&);
    6055
    61             void clientConnected(unsigned int clientID);
    62             void clientDisconnected(unsigned int clientID);
    63 
    6456            void activateNextLevel();
    6557
    6658            std::list<Level*> levels_s;
    67             std::map<unsigned int, PlayerInfo*> clients_;
    68 
    6959            static LevelManager* singletonRef_s;
    7060    };
  • code/trunk/src/orxonox/OrxonoxPrereqs.h

    r2096 r2171  
    8282    class CameraManager;
    8383    class LevelManager;
     84    class PlayerManager;
    8485
    8586    // objects
     87    class Level;
    8688    class Scene;
    8789
     
    142144
    143145    class Info;
    144     class Level;
    145146    class PlayerInfo;
    146147    class HumanPlayer;
  • code/trunk/src/orxonox/Settings.h

    r2087 r2171  
    2828
    2929/**
    30     @file Core.h
     30    @file
    3131    @brief Declaration of the Settings class.
    3232
  • code/trunk/src/orxonox/gamestates/GSClient.cc

    r2087 r2171  
    5353        Core::setIsClient(true);
    5454
    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"));
    5656
    5757        if(!client_->establishConnection())
  • code/trunk/src/orxonox/gamestates/GSClient.h

    r2087 r2171  
    4949        void ticked(const Clock& time);
    5050
    51         network::Client* client_;
     51        Client* client_;
    5252    };
    5353}
  • code/trunk/src/orxonox/gamestates/GSDedicated.cc

    r2087 r2171  
    3232#include "core/CommandLine.h"
    3333#include "core/Core.h"
     34#include "core/Iterator.h"
    3435#include "network/Server.h"
     36#include "objects/Tickable.h"
    3537
    3638namespace orxonox
     
    5052        Core::setHasServer(true);
    5153
    52         this->server_ = new network::Server(CommandLine::getValue("port"));
     54        this->server_ = new Server(CommandLine::getValue("port"));
    5355        COUT(0) << "Loading scene in server mode" << std::endl;
    5456
  • code/trunk/src/orxonox/gamestates/GSDedicated.h

    r2087 r2171  
    4848        void ticked(const Clock& time);
    4949
    50         network::Server*      server_;
     50        Server*      server_;
    5151    };
    5252}
  • code/trunk/src/orxonox/gamestates/GSGraphics.cc

    r2103 r2171  
    5656#include "gui/GUIManager.h"
    5757#include "tools/WindowEventListener.h"
    58 #include "objects/Tickable.h"
    5958#include "Settings.h"
    6059
     
    242241        this->tickChild(time);
    243242
    244         /*** HACK *** HACK ***/
    245         // Call the Tickable objects
    246         for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)
    247             it->tick(time.getDeltaTime());
    248         /*** HACK *** HACK ***/
    249 
    250243        if (this->bWindowEventListenerUpdateRequired_)
    251244        {
  • code/trunk/src/orxonox/gamestates/GSRoot.cc

    r2087 r2171  
    4141#include "core/TclThreadManager.h"
    4242#include "tools/Timer.h"
     43#include "objects/Tickable.h"
    4344#include "Settings.h"
    4445
     
    143144            it->tick(time);
    144145
     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
    145152        this->tickChild(time);
    146153    }
  • code/trunk/src/orxonox/gamestates/GSServer.cc

    r2087 r2171  
    5252        Core::setHasServer(true);
    5353
    54         this->server_ = new network::Server(CommandLine::getValue("port"));
     54        this->server_ = new Server(CommandLine::getValue("port"));
    5555        COUT(0) << "Loading scene in server mode" << std::endl;
    5656
  • code/trunk/src/orxonox/gamestates/GSServer.h

    r2087 r2171  
    4848        void ticked(const Clock& time);
    4949
    50         network::Server*      server_;
     50        Server*      server_;
    5151    };
    5252}
  • code/trunk/src/orxonox/objects/CMakeLists.txt

    r2131 r2171  
    33  EventDispatcher.cc
    44  EventTarget.cc
     5  Level.cc
    56  Radar.cc
    67  RadarListener.cc
  • code/trunk/src/orxonox/objects/Scene.cc

    r2087 r2171  
    4343    CreateFactory(Scene);
    4444
    45     Scene::Scene(BaseObject* creator) : BaseObject(creator), network::Synchronisable(creator)
     45    Scene::Scene(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
    4646    {
    4747        RegisterObject(Scene);
     
    114114    void Scene::registerVariables()
    115115    {
    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));
    118118    }
    119119
     
    164164        return 0;
    165165    }
     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    }
    166175}
  • code/trunk/src/orxonox/objects/Scene.h

    r2087 r2171  
    3535#include "core/BaseObject.h"
    3636#include "util/Math.h"
     37#include "objects/Tickable.h"
    3738
    3839namespace orxonox
    3940{
    40     class _OrxonoxExport Scene : public BaseObject, public network::Synchronisable
     41    class _OrxonoxExport Scene : public BaseObject, public Synchronisable, public Tickable
    4142    {
    4243        public:
     
    6465                { return this->bShadows_; }
    6566
     67            virtual void tick(float dt);
     68
    6669        private:
    6770            void addObject(BaseObject* object);
  • code/trunk/src/orxonox/objects/Test.cc

    r2087 r2171  
    3030#include "core/CoreIncludes.h"
    3131#include "core/ConfigValueIncludes.h"
     32#include "core/ConsoleCommand.h"
    3233#include "Test.h"
    3334
     
    3536{
    3637        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;
    3745
    38         Test::Test(BaseObject* creator) : BaseObject(creator), network::Synchronisable(creator)
     46        Test::Test(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
    3947        {
     48    assert(instance_==0);
     49    instance_=this;
    4050                RegisterObject ( Test );
    41                 setConfigValues();
    42                 registerVariables();
     51    setConfigValues();
     52    registerVariables();
    4353                setObjectMode(0x3);
    4454        }
     
    4656        Test::~Test()
    4757        {
    48 
     58    instance_=0;
    4959        }
    5060
    5161        void Test::setConfigValues()
    5262        {
    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 )*/;
    5667        }
    5768
     
    5970        void Test::registerVariables()
    6071        {
    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 ) );
    6476        }
    6577
    66         void Test::checkV1(){
    67                 COUT(1) << "V1 changed: " << v1 << std::endl;
    68         }
     78  void Test::checkV1(){
     79    COUT(1) << "V1 changed: " << v1 << std::endl;
     80  }
    6981
    70         void Test::checkV2(){
    71                 COUT(1) << "V2 changed: " << v2 << std::endl;
    72         }
     82  void Test::checkV2(){
     83    COUT(1) << "V2 changed: " << v2 << std::endl;
     84  }
    7385
    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  }
    7793
    7894
  • code/trunk/src/orxonox/objects/Test.h

    r2087 r2171  
    3636namespace orxonox
    3737{
    38   class _OrxonoxExport Test: public BaseObject, public network::Synchronisable
     38  class _OrxonoxExport Test: public BaseObject, public Synchronisable
    3939  {
    4040    public:
     
    4848      void setV2(unsigned int value){ v2 = value; }
    4949      void setV3(unsigned int value){ v3 = value; }
     50      void setV4(unsigned int value){ v4 = value; }
    5051
    5152      void checkV1();
    5253      void checkV2();
    5354      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(); }
    5461
    5562    private:
     
    5764      unsigned int v2;
    5865      unsigned int v3;
     66      unsigned int v4;
     67     
     68      static Test* instance_;
    5969  };
    6070}
  • code/trunk/src/orxonox/objects/Tickable.h

    r1790 r2171  
    2828
    2929/*!
    30     @file Tickable.h
     30    @file
    3131    @brief Declaration of the Tickable interface.
    3232
  • code/trunk/src/orxonox/objects/gametypes/Gametype.cc

    r2087 r2171  
    6767        if (!this->bStarted_)
    6868            this->checkStart();
     69        else
     70            this->spawnDeadPlayersIfRequested();
    6971
    7072        this->assignDefaultPawnsIfNeeded();
    71         this->spawnDeadPlayersIfRequested();
    7273    }
    7374
     
    8889    void Gametype::playerEntered(PlayerInfo* player)
    8990    {
    90         this->players_.insert(player);
     91        this->players_[player] = PlayerState::Joined;
    9192
    9293        std::string message = player->getName() + " entered the game";
    9394        COUT(0) << message << std::endl;
    94         network::Host::Broadcast(message);
     95        Host::Broadcast(message);
    9596    }
    9697
    9798    void Gametype::playerLeft(PlayerInfo* player)
    9899    {
    99         std::set<PlayerInfo*>::iterator it = this->players_.find(player);
     100        std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.find(player);
    100101        if (it != this->players_.end())
    101102        {
     
    104105            std::string message = player->getName() + " left the game";
    105106            COUT(0) << message << std::endl;
    106             network::Host::Broadcast(message);
     107            Host::Broadcast(message);
    107108        }
    108109    }
     
    124125                std::string message = player->getOldName() + " changed name to " + player->getName();
    125126                COUT(0) << message << std::endl;
    126                 network::Host::Broadcast(message);
     127                Host::Broadcast(message);
    127128            }
    128129        }
     
    165166    }
    166167
    167     void Gametype::assignDefaultPawnsIfNeeded() const
    168     {
    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);
    174175                if (spawn)
    175176                {
     
    177178                    ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
    178179                    spawn->spawn(entity);
    179                     (*it)->startControl(entity);
     180                    it->first->startControl(entity);
     181                    it->second = PlayerState::Dead;
    180182                }
    181183                else
     
    210212                {
    211213                    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)
    213215                    {
    214                         if (!(*it)->isReadyToSpawn())
     216                        if (!it->first->isReadyToSpawn())
    215217                            allplayersready = false;
    216218                    }
     
    227229    void Gametype::spawnPlayersIfRequested()
    228230    {
    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);
    232234    }
    233235
    234236    void Gametype::spawnDeadPlayersIfRequested()
    235237    {
    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);
    240242    }
    241243
     
    246248        {
    247249            player->startControl(spawnpoint->spawn());
     250            this->players_[player] = PlayerState::Alive;
    248251        }
    249252        else
  • code/trunk/src/orxonox/objects/gametypes/Gametype.h

    r2087 r2171  
    4141namespace orxonox
    4242{
     43    namespace PlayerState
     44    {
     45        enum Enum
     46        {
     47            Uninitialized,
     48            Joined,
     49            Alive,
     50            Dead
     51        };
     52    }
     53
    4354    class _OrxonoxExport Gametype : public BaseObject, public Tickable
    4455    {
     
    7081            virtual void pawnPostSpawn(Pawn* pawn);
    7182
    72             inline const std::set<PlayerInfo*>& getPlayers() const
     83            inline const std::map<PlayerInfo*, PlayerState::Enum>& getPlayers() const
    7384                { return this->players_; }
    7485
     
    8798            void removePlayer(PlayerInfo* player);
    8899
    89             void assignDefaultPawnsIfNeeded() const;
     100            void assignDefaultPawnsIfNeeded();
    90101            void checkStart();
    91102            void spawnPlayer(PlayerInfo* player);
     
    102113            bool bStartCountdownRunning_;
    103114
    104             std::set<PlayerInfo*> players_;
     115            std::map<PlayerInfo*, PlayerState::Enum> players_;
    105116            std::set<SpawnPoint*> spawnpoints_;
    106117            SubclassIdentifier<ControllableEntity> defaultControllableEntity_;
  • code/trunk/src/orxonox/objects/infos/CMakeLists.txt

    r2131 r2171  
    11SET( SRC_FILES
    22  Info.cc
    3   Level.cc
    43  PlayerInfo.cc
    54  HumanPlayer.cc
  • code/trunk/src/orxonox/objects/infos/HumanPlayer.cc

    r2087 r2171  
    4646        RegisterObject(HumanPlayer);
    4747
    48         this->server_ready_ = Core::isMaster();
    49         this->client_ready_ = false;
     48        this->server_initialized_ = Core::isMaster();
     49        this->client_initialized_ = false;
    5050
    5151        this->bHumanPlayer_ = true;
     
    6767    void HumanPlayer::registerVariables()
    6868    {
    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));
    7070
    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));
    7474    }
    7575
     
    9292    void HumanPlayer::networkcallback_clientIDchanged()
    9393    {
    94         if (this->clientID_ == network::Host::getPlayerID())
     94        if (this->clientID_ == Host::getPlayerID())
    9595        {
    9696            this->bLocalPlayer_ = true;
    9797            this->synchronize_nick_ = this->nick_;
    98             this->client_ready_ = true;
     98            this->client_initialized_ = true;
    9999
    100100            if (!Core::isMaster())
    101                 this->setObjectMode(network::direction::bidirectional);
     101                this->setObjectMode(direction::bidirectional);
    102102            else
    103103                this->setName(this->nick_);
     
    107107    }
    108108
    109     void HumanPlayer::networkcallback_server_ready()
     109    void HumanPlayer::networkcallback_server_initialized()
    110110    {
    111         this->client_ready_ = true;
     111        this->client_initialized_ = true;
    112112    }
    113113
    114     void HumanPlayer::networkcallback_client_ready()
     114    void HumanPlayer::networkcallback_client_initialized()
    115115    {
    116116        if (this->getGametype())
     
    118118    }
    119119
    120     bool HumanPlayer::isReady() const
     120    bool HumanPlayer::isInitialized() const
    121121    {
    122         return (this->server_ready_ && this->client_ready_);
     122        return (this->server_initialized_ && this->client_initialized_);
    123123    }
    124124
    125125    float HumanPlayer::getPing() const
    126126    {
    127         return network::ClientInformation::findClient(this->getClientID())->getRTT();
     127        return ClientInformation::findClient(this->getClientID())->getRTT();
    128128    }
    129129
    130130    float HumanPlayer::getPacketLossRatio() const
    131131    {
    132         return network::ClientInformation::findClient(this->getClientID())->getPacketLoss();
     132        return ClientInformation::findClient(this->getClientID())->getPacketLoss();
    133133    }
    134134
  • code/trunk/src/orxonox/objects/infos/HumanPlayer.h

    r2087 r2171  
    4747            void setConfigValues();
    4848
    49             bool isReady() const;
     49            bool isInitialized() const;
    5050            float getPing() const;
    5151            float getPacketLossRatio() const;
     
    5757            void networkcallback_changednick();
    5858            void networkcallback_clientIDchanged();
    59             void networkcallback_server_ready();
    60             void networkcallback_client_ready();
     59            void networkcallback_server_initialized();
     60            void networkcallback_client_initialized();
    6161
    6262            std::string nick_;
    6363            std::string synchronize_nick_;
    64             bool server_ready_;
    65             bool client_ready_;
     64            bool server_initialized_;
     65            bool client_initialized_;
    6666    };
    6767}
  • code/trunk/src/orxonox/objects/infos/Info.cc

    r2087 r2171  
    3434namespace orxonox
    3535{
    36     Info::Info(BaseObject* creator) : BaseObject(creator), network::Synchronisable(creator)
     36    Info::Info(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
    3737    {
    3838        RegisterObject(Info);
  • code/trunk/src/orxonox/objects/infos/Info.h

    r2087 r2171  
    3737namespace orxonox
    3838{
    39     class _OrxonoxExport Info : public BaseObject, public network::Synchronisable
     39    class _OrxonoxExport Info : public BaseObject, public Synchronisable
    4040    {
    4141        public:
  • code/trunk/src/orxonox/objects/infos/PlayerInfo.cc

    r2087 r2171  
    4242        RegisterObject(PlayerInfo);
    4343
    44         this->clientID_ = network::CLIENTID_UNKNOWN;
     44        this->clientID_ = CLIENTID_UNKNOWN;
    4545        this->bHumanPlayer_ = false;
    4646        this->bLocalPlayer_ = false;
     
    4848        this->controller_ = 0;
    4949        this->controllableEntity_ = 0;
    50         this->controllableEntityID_ = network::CLIENTID_UNKNOWN;
     50        this->controllableEntityID_ = CLIENTID_UNKNOWN;
    5151
    5252        this->registerVariables();
     
    5555    PlayerInfo::~PlayerInfo()
    5656    {
    57         if (this->isInitialized())
     57        if (this->BaseObject::isInitialized())
    5858        {
    5959            this->stopControl(this->controllableEntity_);
     
    6969    void PlayerInfo::registerVariables()
    7070    {
    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);
    7474    }
    7575
    7676    void PlayerInfo::changedName()
    7777    {
    78         if (this->isReady() && this->getGametype())
     78        if (this->isInitialized() && this->getGametype())
    7979            this->getGametype()->playerChangedName(this);
    8080    }
     
    8282    void PlayerInfo::changedGametype()
    8383    {
    84         if (this->isReady())
     84        if (this->isInitialized())
    8585        {
    8686            if (this->getOldGametype())
     
    126126        else
    127127        {
    128             this->controllableEntityID_ = network::OBJECTID_UNKNOWN;
     128            this->controllableEntityID_ = OBJECTID_UNKNOWN;
    129129        }
    130130
     
    138138        {
    139139            this->controllableEntity_ = 0;
    140             this->controllableEntityID_ = network::OBJECTID_UNKNOWN;
     140            this->controllableEntityID_ = OBJECTID_UNKNOWN;
    141141
    142142            if (this->controller_)
     
    150150    void PlayerInfo::networkcallback_changedcontrollableentityID()
    151151    {
    152         if (this->controllableEntityID_ != network::OBJECTID_UNKNOWN)
     152        if (this->controllableEntityID_ != OBJECTID_UNKNOWN)
    153153        {
    154154            Synchronisable* temp = Synchronisable::getSynchronisable(this->controllableEntityID_);
  • code/trunk/src/orxonox/objects/infos/PlayerInfo.h

    r2087 r2171  
    5555            inline unsigned int getClientID() const
    5656                { return this->clientID_; }
    57             inline bool isReadyToSpawn() const
    58                 { return this->bReadyToSpawn_; }
    5957
    60             virtual bool isReady() const = 0;
     58            virtual bool isInitialized() const = 0;
    6159            virtual float getPing() const = 0;
    6260            virtual float getPacketLossRatio() const = 0;
     
    6462            inline void setReadyToSpawn(bool bReady)
    6563                { this->bReadyToSpawn_ = bReady; }
     64            inline bool isReadyToSpawn() const
     65                { return this->bReadyToSpawn_; }
    6666
    6767            void startControl(ControllableEntity* entity);
  • code/trunk/src/orxonox/objects/weaponSystem/WeaponSystem.h

  • 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  
    6464    void Billboard::registerVariables()
    6565    {
    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));
    6868    }
    6969
     
    7575            {
    7676                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());
    7879                this->billboard_.setVisible(this->isVisible());
    7980            }
     
    9091            {
    9192                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());
    9395                this->billboard_.setVisible(this->isVisible());
    9496            }
  • code/trunk/src/orxonox/objects/worldentities/BlinkingBillboard.cc

    r2087 r2171  
    6868    void BlinkingBillboard::registerVariables()
    6969    {
    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);
    7373    }
    7474
  • code/trunk/src/orxonox/objects/worldentities/Camera.cc

    r2103 r2171  
    3838#include <OgreViewport.h>
    3939
     40#include "util/Exception.h"
    4041#include "core/CoreIncludes.h"
    4142#include "core/ConfigValueIncludes.h"
     
    5152        RegisterObject(Camera);
    5253
    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.");
    5556
    5657        this->camera_ = this->getScene()->getSceneManager()->createCamera(getUniqueNumberString());
  • 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  
    5252        this->client_overwrite_ = 0;
    5353        this->player_ = 0;
    54         this->playerID_ = network::OBJECTID_UNKNOWN;
     54        this->playerID_ = OBJECTID_UNKNOWN;
    5555        this->hud_ = 0;
    5656        this->camera_ = 0;
     
    165165                this->client_overwrite_ = this->server_overwrite_;
    166166COUT(0) << "CE: bidirectional synchronization" << std::endl;
    167                 this->setObjectMode(network::direction::bidirectional);
     167                this->setObjectMode(direction::bidirectional);
    168168            }
    169169        }
     
    176176
    177177        this->player_ = 0;
    178         this->playerID_ = network::OBJECTID_UNKNOWN;
     178        this->playerID_ = OBJECTID_UNKNOWN;
    179179        this->bControlled_ = false;
    180         this->setObjectMode(network::direction::toclient);
     180        this->setObjectMode(direction::toclient);
    181181
    182182        if (this->bDestroyWhenPlayerLeft_)
     
    187187    {
    188188        // 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_));
    192192            if (this->player_ && (this->player_->getControllableEntity() != this))
    193193                this->player_->startControl(this);
     
    248248    void ControllableEntity::registerVariables()
    249249    {
    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_overwrite_,   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));
    265265    }
    266266
  • code/trunk/src/orxonox/objects/worldentities/Light.cc

    r2087 r2171  
    7979    void Light::registerVariables()
    8080    {
    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);
    8585    }
    8686
  • code/trunk/src/orxonox/objects/worldentities/Model.cc

    r2087 r2171  
    6161    void Model::registerVariables()
    6262    {
    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));
    6565    }
    6666
  • code/trunk/src/orxonox/objects/worldentities/MovableEntity.cc

    r2087 r2171  
    8484    void MovableEntity::registerVariables()
    8585    {
    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);
    8989
    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);
    9393
    94         REGISTERDATA(this->rotationRate_, network::direction::toclient);
     94        REGISTERDATA(this->rotationRate_, direction::toclient);
    9595
    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));
    9898    }
    9999
  • code/trunk/src/orxonox/objects/worldentities/MovableEntity.h

    r2087 r2171  
    3838namespace orxonox
    3939{
    40     class _OrxonoxExport MovableEntity : public WorldEntity, public Tickable, public network::ClientConnectionListener
     40    class _OrxonoxExport MovableEntity : public WorldEntity, public Tickable, public ClientConnectionListener
    4141    {
    4242        public:
  • code/trunk/src/orxonox/objects/worldentities/ParticleEmitter.cc

    r2087 r2171  
    2828
    2929/**
    30 * @file ParticleInterface.cc
     30* @file
    3131* @brief class to control praticle effects
    3232*/
     
    3737
    3838#include "tools/ParticleInterface.h"
     39#include "util/Exception.h"
    3940#include "core/CoreIncludes.h"
    4041#include "core/XMLPort.h"
     
    4950        RegisterObject(ParticleEmitter);
    5051
    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.");
    5354
    5455        this->particles_ = 0;
     
    7475    void ParticleEmitter::registerVariables()
    7576    {
    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));
    7879    }
    7980
  • 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  
    4848    void PositionableEntity::registerVariables()
    4949    {
    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);
    5353
    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);
    5858    }
    5959}
  • code/trunk/src/orxonox/objects/worldentities/WorldEntity.cc

    r2087 r2171  
    3636#include "core/XMLPort.h"
    3737#include "util/Convert.h"
     38#include "util/Exception.h"
    3839
    3940#include "objects/Scene.h"
     
    4849    const Vector3 WorldEntity::UP    = Vector3::UNIT_Y;
    4950
    50     WorldEntity::WorldEntity(BaseObject* creator) : BaseObject(creator), network::Synchronisable(creator)
     51    WorldEntity::WorldEntity(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
    5152    {
    5253        RegisterObject(WorldEntity);
    5354
    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.");
    5657
    5758        this->node_ = this->getScene()->getRootSceneNode()->createChildSceneNode();
    5859
    5960        this->parent_ = 0;
    60         this->parentID_ = (unsigned int)-1;
     61        this->parentID_ = OBJECTID_UNKNOWN;
    6162
    6263        this->node_->setPosition(Vector3::ZERO);
     
    9596    void WorldEntity::registerVariables()
    9697    {
    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));
    99100
    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);
    103104
    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));
    105106    }
    106107
    107108    void WorldEntity::updateParent()
    108109    {
    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        }
    112116    }
    113117
     
    134138        this->children_.erase(object);
    135139        object->parent_ = 0;
    136         object->parentID_ = (unsigned int)-1;
     140        object->parentID_ = OBJECTID_UNKNOWN;
    137141
    138142//        this->getScene()->getRootSceneNode()->addChild(object->node_);
  • code/trunk/src/orxonox/objects/worldentities/WorldEntity.h

    r2087 r2171  
    4242namespace orxonox
    4343{
    44     class _OrxonoxExport WorldEntity : public BaseObject, public network::Synchronisable
     44    class _OrxonoxExport WorldEntity : public BaseObject, public Synchronisable
    4545    {
    4646        public:
  • code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.cc

    r2106 r2171  
    8080    void Pawn::registerVariables()
    8181    {
    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);
    8484    }
    8585
  • code/trunk/src/orxonox/objects/worldentities/pawns/SpaceShip.cc

    r2087 r2171  
    8282    void SpaceShip::registerVariables()
    8383    {
    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);
    9090    }
    9191
  • code/trunk/src/orxonox/objects/worldentities/pawns/Spectator.cc

    r2087 r2171  
    6262        this->greetingFlare_ = new BillboardSet();
    6363        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());
    6566        this->greetingFlare_->setVisible(false);
    6667        this->bGreetingFlareVisible_ = false;
     
    7677            if (this->greetingFlare_)
    7778            {
    78                 this->getNode()->detachObject(this->greetingFlare_->getBillboardSet());
     79                if (this->greetingFlare_->getBillboardSet())
     80                    this->getNode()->detachObject(this->greetingFlare_->getBillboardSet());
    7981                delete this->greetingFlare_;
    8082            }
     
    8486    void Spectator::registerVariables()
    8587    {
    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);
    8991    }
    9092
     
    129131        ControllableEntity::setPlayer(player);
    130132
    131 //        this->setObjectMode(network::direction::toclient);
     133//        this->setObjectMode(direction::toclient);
    132134    }
    133135
     
    203205                {
    204206                    if (this->getGametype()->isStartCountdownRunning())
    205                         this->hudmode_ = 2 + 10*ceil(this->getGametype()->getStartCountdown());
     207                        this->hudmode_ = 2 + 10*(int)ceil(this->getGametype()->getStartCountdown());
    206208                    else
    207209                        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

    r2103 r2171  
    6969      this->debugBillboard_.setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1);
    7070      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
    7476    this->setObjectMode(0x0);
    7577  }
     
    310312  void Trigger::setBillboardColour(const ColourValue& colour)
    311313  {
    312     this->debugBillboard_.getBillboardSet()->getBillboard(0)->setColour(colour);
     314    this->debugBillboard_.setColour(colour);
    313315  }
    314316
  • 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  
    4040#include <OgrePanelOverlayElement.h>
    4141#include "util/Convert.h"
     42#include "util/Exception.h"
    4243#include "util/String.h"
     44#include "core/Core.h"
    4345#include "core/CoreIncludes.h"
    4446#include "core/XMLPort.h"
     
    5860    {
    5961        RegisterObject(OrxonoxOverlay);
     62
     63        if (!Core::showsGraphics())
     64            ThrowException(NoGraphics, "Can't create OrxonoxOverlay, graphics engine not initialized");
    6065
    6166        // add this overlay to the static map of OrxonoxOverlays
  • code/trunk/src/orxonox/overlays/hud/ChatOverlay.cc

    r2087 r2171  
    3838#include "network/ClientInformation.h"
    3939
    40 #include "LevelManager.h"
     40#include "PlayerManager.h"
    4141#include "objects/infos/PlayerInfo.h"
    4242#include "overlays/console/InGameConsole.h"
     
    7272        std::string text;
    7373
    74         if (senderID != network::CLIENTID_UNKNOWN)
     74        if (senderID != CLIENTID_UNKNOWN)
    7575        {
    7676            std::string name = "unknown";
    7777
    78             PlayerInfo* player = LevelManager::getInstance().getClient(senderID);
     78            PlayerInfo* player = PlayerManager::getInstance().getClient(senderID);
    7979            if (player)
    8080                name = player->getName();
  • code/trunk/src/orxonox/overlays/hud/ChatOverlay.h

    r2087 r2171  
    3939namespace orxonox
    4040{
    41     class _OrxonoxExport ChatOverlay : public OverlayText, public network::ChatListener
     41    class _OrxonoxExport ChatOverlay : public OverlayText, public ChatListener
    4242    {
    4343        public:
  • code/trunk/src/orxonox/tools/BillboardSet.cc

    r2087 r2171  
    3636#include <OgreBillboard.h>
    3737
     38#include "core/Core.h"
    3839#include "util/Convert.h"
    3940#include "util/String.h"
     
    7071        try
    7172        {
    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            }
    7579        }
    7680        catch (...)
    7781        {
    7882            COUT(1) << "Error: Couln't load billboard \"" << file << "\"" << std::endl;
     83            this->billboardSet_ = 0;
    7984        }
    8085
     
    8994        try
    9095        {
    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            }
    94102        }
    95103        catch (...)
    96104        {
    97105            COUT(1) << "Error: Couln't load billboard \"" << file << "\"" << std::endl;
     106            this->billboardSet_ = 0;
    98107        }
    99108
     
    105114        if (this->billboardSet_ && this->scenemanager_)
    106115            this->scenemanager_->destroyBillboardSet(this->billboardSet_);
     116        this->billboardSet_ = 0;
    107117    }
    108118
  • code/trunk/src/orxonox/tools/Mesh.cc

    r2087 r2171  
    7373            {
    7474                COUT(1) << "Error: Couln't load mesh \"" << meshsource << "\"" << std::endl;
     75                this->entity_ = 0;
    7576            }
    7677        }
  • code/trunk/src/orxonox/tools/ParticleInterface.cc

    r2087 r2171  
    2828
    2929/**
    30 * @file ParticleInterface.cc
     30* @file
    3131* @brief class to control praticle effects
    3232*/
     
    4141
    4242#include "GraphicsEngine.h"
     43#include "core/Core.h"
    4344#include "core/CoreIncludes.h"
    4445#include "util/Convert.h"
     
    5758        this->scenemanager_ = scenemanager;
    5859        this->sceneNode_ = 0;
     60        this->particleSystem_ = 0;
    5961
    6062        this->bEnabled_ = true;
     
    6264        this->bAllowedByLOD_ = true;
    6365
    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        }
    6780
    6881        this->setDetailLevel((unsigned int)detaillevel);
     
    7184    ParticleInterface::~ParticleInterface()
    7285    {
    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        }
    7692    }
    7793
     
    8197            this->detachFromSceneNode();
    8298
    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        }
    85104    }
    86105
     
    89108        if (this->sceneNode_)
    90109        {
    91             this->sceneNode_->detachObject(this->particleSystem_);
     110            if (this->particleSystem_)
     111                this->sceneNode_->detachObject(this->particleSystem_);
    92112            this->sceneNode_ = 0;
    93113        }
     
    96116    Ogre::ParticleEmitter* ParticleInterface::createNewEmitter()
    97117    {
    98         if (this->particleSystem_->getNumEmitters() > 0)
     118        if (this->particleSystem_ && this->particleSystem_->getNumEmitters() > 0)
    99119        {
    100120            Ogre::ParticleEmitter* newemitter = this->particleSystem_->addEmitter(this->particleSystem_->getEmitter(0)->getType());
     
    107127    Ogre::ParticleEmitter* ParticleInterface::getEmitter(unsigned int emitterNr) const
    108128    {
    109         if (emitterNr < this->particleSystem_->getNumEmitters())
     129        if (this->particleSystem_ && (emitterNr < this->particleSystem_->getNumEmitters()))
    110130            return this->particleSystem_->getEmitter(emitterNr);
    111131        else
     
    114134    void ParticleInterface::removeEmitter(unsigned int emitterNr)
    115135    {
    116         if (emitterNr < this->particleSystem_->getNumEmitters())
     136        if (this->particleSystem_ && (emitterNr < this->particleSystem_->getNumEmitters()))
    117137            this->particleSystem_->removeEmitter(emitterNr);
    118138    }
    119139    void ParticleInterface::removeAllEmitters()
    120140    {
    121         this->particleSystem_->removeAllEmitters();
     141        if (this->particleSystem_)
     142            this->particleSystem_->removeAllEmitters();
    122143    }
    123144    unsigned int ParticleInterface::getNumEmitters() const
    124145    {
    125         return this->particleSystem_->getNumEmitters();
     146        if (this->particleSystem_)
     147            return this->particleSystem_->getNumEmitters();
     148        else
     149            return 0;
    126150    }
    127151
    128152    Ogre::ParticleAffector* ParticleInterface::addAffector(const std::string& name)
    129153    {
    130         return this->particleSystem_->addAffector(name);
     154        if (this->particleSystem_)
     155            return this->particleSystem_->addAffector(name);
     156        else
     157            return 0;
    131158    }
    132159    Ogre::ParticleAffector* ParticleInterface::getAffector(unsigned int affectorNr) const
    133160    {
    134         if (affectorNr < this->particleSystem_->getNumAffectors())
     161        if (this->particleSystem_ && (affectorNr < this->particleSystem_->getNumAffectors()))
    135162            return this->particleSystem_->getAffector(affectorNr);
    136163        else
     
    139166    void ParticleInterface::removeAffector(unsigned int affectorNr)
    140167    {
    141         if (affectorNr < this->particleSystem_->getNumAffectors())
     168        if (this->particleSystem_ && (affectorNr < this->particleSystem_->getNumAffectors()))
    142169            this->particleSystem_->removeAffector(affectorNr);
    143170    }
    144171    void ParticleInterface::removeAllAffectors()
    145172    {
    146         this->particleSystem_->removeAllAffectors();
     173        if (this->particleSystem_)
     174            this->particleSystem_->removeAllAffectors();
    147175    }
    148176    unsigned int ParticleInterface::getNumAffectors() const
    149177    {
    150         return this->particleSystem_->getNumAffectors();
     178        if (this->particleSystem_)
     179            return this->particleSystem_->getNumAffectors();
     180        else
     181            return 0;
    151182    }
    152183
     
    155186        this->bEnabled_ = enable;
    156187
    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_);
    159191    }
    160192
     
    163195        this->bVisible_ = visible;
    164196
    165         this->particleSystem_->setVisible(this->bVisible_ && this->bAllowedByLOD_);
     197        if (this->particleSystem_)
     198            this->particleSystem_->setVisible(this->bVisible_ && this->bAllowedByLOD_);
    166199    }
    167200
     
    169202    {
    170203        this->detaillevel_ = level;
    171         this->detailLevelChanged(GraphicsEngine::getInstance().getDetailLevelParticle());
     204        if (GraphicsEngine::getInstancePtr())
     205            this->detailLevelChanged(GraphicsEngine::getInstance().getDetailLevelParticle());
    172206    }
    173207
     
    190224    void ParticleInterface::setSpeedFactor(float factor)
    191225    {
    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        }
    194231    }
    195232    float ParticleInterface::getSpeedFactor() const
    196233    {
    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;
    199241    }
    200242
    201243    bool ParticleInterface::getKeepParticlesInLocalSpace() const
    202244    {
    203         return this->particleSystem_->getKeepParticlesInLocalSpace();
     245        if (this->particleSystem_)
     246            return this->particleSystem_->getKeepParticlesInLocalSpace();
     247        else
     248            return false;
    204249    }
    205250    void ParticleInterface::setKeepParticlesInLocalSpace(bool keep)
    206251    {
    207         this->particleSystem_->setKeepParticlesInLocalSpace(keep);
     252        if (this->particleSystem_)
     253            this->particleSystem_->setKeepParticlesInLocalSpace(keep);
    208254    }
    209255}
  • code/trunk/src/orxonox/tools/Timer.h

    r2087 r2171  
    2828
    2929/*!
    30     @file Timer.h
     30    @file
    3131    @brief Definition and Implementation of the Timer class.
    3232
  • code/trunk/src/tolua/tolua-5.1.pkg

    • Property svn:mergeinfo changed (with no actual effect on merging)
  • code/trunk/src/util

  • code/trunk/src/util/CRC32.cc

    r1791 r2171  
    2929#include "CRC32.h"
    3030
     31namespace 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      }
    3141
    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}
    3459
    35     hbit=(crc32 & 0x80000000) ? 1 : 0;
    36     if (hbit != bit)
    37       crc32=(crc32<<1) ^ UTIL_CRC32POLY;
    38     else
    39       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 bit
    46       calcCRCBit(crc32, (data[i]&0x2)>>1); // 2nd bit
    47       calcCRCBit(crc32, (data[i]&0x3)>>2); // 3rd bit
    48       calcCRCBit(crc32, (data[i]&0x4)>>3); // 4th bit
    49       calcCRCBit(crc32, (data[i]&0x5)>>4); // 5th bit
    50       calcCRCBit(crc32, (data[i]&0x6)>>5); // 6th bit
    51       calcCRCBit(crc32, (data[i]&0x7)>>6); // 7th bit
    52       calcCRCBit(crc32, (data[i]&0x8)>>7); // 8th bit
    53     }
    54     return crc32;
    55   }
    56 
  • code/trunk/src/util/CRC32.h

    r1791 r2171  
    3434#include "Integers.h"
    3535
    36 const unsigned int UTIL_CRC32POLY = 0x04C11DB7; /* CRC-32 Polynom */
     36namespace orxonox
     37{
     38    const unsigned int UTIL_CRC32POLY = 0x04C11DB7; /* CRC-32 Polynom */
    3739
    38 _UtilExport void calcCRCBit(uint32_t &crc32, int bit);
     40    _UtilExport void calcCRCBit(uint32_t &crc32, int bit);
    3941
    40 _UtilExport uint32_t calcCRC(unsigned char *data, unsigned int dataLength);
    41 
     42    _UtilExport uint32_t calcCRC(unsigned char *data, unsigned int dataLength);
     43}
    4244
    4345#endif /* _Util_CRC_H__ */
  • code/trunk/src/util/Clipboard.cc

    r1791 r2171  
    3030
    3131/**
    32     @file Clipboard.cc
     32    @file
    3333    @brief OS-specific implementations of the clipboard functions.
    3434*/
     
    3737
    3838#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
     47namespace orxonox
     48{
    4449
    4550    /**
     
    97102        return "";
    98103    }
    99 #else
    100     /////////////
    101     // Default //
    102     /////////////
     104}
    103105
     106#else /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */
     107
     108/////////////
     109// Default //
     110/////////////
     111
     112namespace orxonox
     113{
    104114    std::string clipboard = ""; //!< Keeps the text of our internal clipboard
    105115
     
    123133        return clipboard;
    124134    }
    125 #endif
     135}
     136
     137#endif /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */
  • code/trunk/src/util/Clipboard.h

    r1791 r2171  
    2828
    2929/**
    30     @file Clipboard.h
     30    @file
    3131    @brief Some functions to exchange text between the OS clipboard and Orxonox.
    3232
     
    4646#include <string>
    4747
    48 
    49 _UtilExport bool toClipboard(const std::string& text);
    50 _UtilExport std::string fromClipboard();
    51 
     48namespace orxonox
     49{
     50    _UtilExport bool toClipboard(const std::string& text);
     51    _UtilExport std::string fromClipboard();
     52}
    5253
    5354#endif /* _Clipboard_H__ */
  • code/trunk/src/util/Convert.h

    r2087 r2171  
    6868#endif
    6969
    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 };
     70namespace 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}
    8689
    8790#if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC
     
    118121*/
    119122
    120 namespace
    121 {
    122     //! Little template that maps integers to entire types (Alexandrescu 2001)
    123     template <int I>
    124     struct Int2Type { };
     123namespace 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    };
    125165}
    126 
    127 
    128 ///////////////////
    129 // No Conversion //
    130 ///////////////////
    131 
    132 // Default template. No conversion available at all.
    133 template <class FromType, class ToType>
    134 struct ConverterFallback
    135 {
    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         else
    157             return false;
    158     }
    159 };
    160166
    161167
     
    170176    static bool convert(ToType* output, const FromType& input)
    171177    {
    172         return ConverterFallback<FromType, ToType>::convert(output, input);
     178        return orxonox::ConverterFallback<FromType, ToType>::convert(output, input);
    173179    }
    174180};
     
    185191    {
    186192        std::string temp;
    187         if (ConverterFallback<FromType, std::string>::convert(&temp, input))
     193        if (orxonox::ConverterFallback<FromType, std::string>::convert(&temp, input))
    188194        {
    189195            std::operator <<(outstream, temp);
     
    224230    inline bool operator >>(std::istream& instream, ToType& output)
    225231    {
    226         return ConverterFallback<std::string, ToType>
     232        return orxonox::ConverterFallback<std::string, ToType>
    227233            ::convert(&output, static_cast<std::istringstream&>(instream).str());
    228234    }
     
    247253};
    248254
    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);
     255namespace 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    };
    259491}
    260492
    261 // We can cast implicitely
    262 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 available
    275 template <class FromType, class ToType>
    276 struct ConverterExplicit
    277 {
    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 compile
    281         // We therefore have to out source it into another template function
    282         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 @brief
    294     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 section
    297     '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 ConvertValue
    306 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 @brief
    316     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 section
    319     'Actual conversion sequence' in this file above.
    320     If the conversion doesn't succeed, 'fallback' is written to '*output'.
    321 @param fallback
    322     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     else
    330     {
    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 Shortcut
    372 template <class FromType>
    373 inline std::string convertToString(FromType value)
    374 {
    375   return getConvertedValue<FromType, std::string>(value);
    376 }
    377 
    378 // convert from string Shortcut
    379 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::string
    390 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 stringstream
    400 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         else
    426             *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         else
    438             *output = '\0';
    439         return true;
    440     }
    441 };
    442 
    443 
    444 // bool to std::string
    445 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         else
    453           *output = "false";
    454         return false;
    455     }
    456 };
    457 
    458 // std::string to bool
    459 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         else
    480             return false;
    481     }
    482 };
    483 
    484493#endif /* _Convert_H__ */
  • code/trunk/src/util/Debug.h

    r2087 r2171  
    2828
    2929/**
    30     @file Debug.h
     30    @file
    3131    @brief Handles different output-levels of errors, warnings, infos and debug informations.
    3232
     
    6767#include "OutputHandler.h"
    6868
    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 level
    73 */
    74 static inline int getSoftDebugLevel()
    75 {
    76     return orxonox::OutputHandler::getSoftDebugLevel();
    77 }
    78 
    7969namespace orxonox
    8070{
     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
    8180    using std::endl;
    8281}
     
    115114  #if ORX_HARD_DEBUG_LEVEL >= ORX_NONE
    116115   #define COUT0 \
    117     (getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : COUT_EXEC(0)
     116   (orxonox::getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : COUT_EXEC(0)
    118117  #else
    119118   #define COUT0 \
     
    123122  #if ORX_HARD_DEBUG_LEVEL >= ORX_ERROR
    124123   #define COUT1 \
    125     (getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : COUT_EXEC(1)
     124    (orxonox::getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : COUT_EXEC(1)
    126125  #else
    127126   #define COUT1 \
     
    131130  #if ORX_HARD_DEBUG_LEVEL >= ORX_WARNING
    132131   #define COUT2 \
    133     (getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : COUT_EXEC(2)
     132    (orxonox::getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : COUT_EXEC(2)
    134133  #else
    135134   #define COUT2 \
     
    139138  #if ORX_HARD_DEBUG_LEVEL >= ORX_INFO
    140139   #define COUT3 \
    141     (getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : COUT_EXEC(3)
     140    (orxonox::getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : COUT_EXEC(3)
    142141  #else
    143142   #define COUT3 \
     
    147146  #if ORX_HARD_DEBUG_LEVEL >= ORX_DEBUG
    148147   #define COUT4 \
    149     (getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : COUT_EXEC(4)
     148    (orxonox::getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : COUT_EXEC(4)
    150149  #else
    151150   #define COUT4 \
     
    155154  #if ORX_HARD_DEBUG_LEVEL >= ORX_VERBOSE
    156155   #define COUT5 \
    157     (getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : COUT_EXEC(5)
     156    (orxonox::getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : COUT_EXEC(5)
    158157  #else
    159158   #define COUT5 \
     
    163162  #if ORX_HARD_DEBUG_LEVEL >= ORX_ULTRA
    164163   #define COUT6 \
    165     (getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : COUT_EXEC(6)
     164    (orxonox::getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : COUT_EXEC(6)
    166165  #else
    167166   #define COUT6 \
     
    199198  #if ORX_HARD_DEBUG_LEVEL >= ORX_NONE
    200199   #define CCOUT0 \
    201     (getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : CCOUT_EXEC(0)
     200    (orxonox::getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : CCOUT_EXEC(0)
    202201  #else
    203202   #define CCOUT0 \
     
    207206  #if ORX_HARD_DEBUG_LEVEL >= ORX_ERROR
    208207   #define CCOUT1 \
    209     (getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : CCOUT_EXEC(1)
     208    (orxonox::getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : CCOUT_EXEC(1)
    210209  #else
    211210   #define CCOUT1 \
     
    215214  #if ORX_HARD_DEBUG_LEVEL >= ORX_WARNING
    216215   #define CCOUT2 \
    217     (getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : CCOUT_EXEC(2)
     216    (orxonox::getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : CCOUT_EXEC(2)
    218217  #else
    219218   #define CCOUT2 \
     
    223222  #if ORX_HARD_DEBUG_LEVEL >= ORX_INFO
    224223   #define CCOUT3 \
    225     (getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : CCOUT_EXEC(3)
     224    (orxonox::getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : CCOUT_EXEC(3)
    226225  #else
    227226   #define CCOUT3 \
     
    231230  #if ORX_HARD_DEBUG_LEVEL >= ORX_DEBUG
    232231   #define CCOUT4 \
    233     (getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : CCOUT_EXEC(4)
     232    (orxonox::getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : CCOUT_EXEC(4)
    234233  #else
    235234   #define CCOUT4 \
     
    239238  #if ORX_HARD_DEBUG_LEVEL >= ORX_VERBOSE
    240239   #define CCOUT5 \
    241     (getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : CCOUT_EXEC(5)
     240    (orxonox::getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : CCOUT_EXEC(5)
    242241  #else
    243242   #define CCOUT5 \
     
    247246  #if ORX_HARD_DEBUG_LEVEL >= ORX_ULTRA
    248247   #define CCOUT6 \
    249     (getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : CCOUT_EXEC(6)
     248    (orxonox::getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : CCOUT_EXEC(6)
    250249  #else
    251250   #define CCOUT6 \
  • code/trunk/src/util/Exception.cc

    r2103 r2171  
    8181        return fullDescription_;
    8282    }
    83 
    84 
    8583}
  • code/trunk/src/util/Exception.h

    r2103 r2171  
    4343#include "Debug.h"
    4444
    45 // Define some ugly macros to make things more clear
    46 #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 
    5245namespace orxonox
    5346{
     
    5548    {
    5649    public:
    57         enum ExceptionType
    58         {
    59             General,
    60             FileNotFound,
    61             Argument,
    62             PluginsNotFound,
    63             InitialisationFailed,
    64             NotImplemented,
    65             GameState
    66         };
    6750
    6851        Exception(const std::string& description, int lineNumber,
     
    7457
    7558        virtual const std::string& getFullDescription() const;
    76         virtual ExceptionType      getType()            const = 0;
    7759        virtual std::string        getTypeName()        const = 0;
    7860        virtual const std::string& getDescription()     const { return this->description_; }
     
    9375
    9476
    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; }                  \
    13398    };
    13499
    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.
    136102    CREATE_ORXONOX_EXCEPTION(General);
    137103    CREATE_ORXONOX_EXCEPTION(FileNotFound);
     
    141107    CREATE_ORXONOX_EXCEPTION(NotImplemented);
    142108    CREATE_ORXONOX_EXCEPTION(GameState);
     109    CREATE_ORXONOX_EXCEPTION(NoGraphics);
     110    CREATE_ORXONOX_EXCEPTION(AbortLoading);
     111}
    143112
    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__)
    146115
    147116    // define an assert macro that can display a message
    148117#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)
    152121#else
    153122#define OrxAssert(condition, errorMessage)  ((void)0)
    154123#endif
    155124
    156 }
    157 
    158125#endif /* _Exception_H__ */
  • code/trunk/src/util/ExprParser.cc

    r1894 r2171  
    4545#define PARSE_BLANKS while (*reading_stream == ' ') ++reading_stream
    4646
    47 ExprParser::ExprParser(const std::string& str)
     47namespace orxonox
    4848{
    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        }
    60452    }
    61453}
    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     else
    74     {
    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     else
    89     {
    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 string
    244         this->failed_ = true;
    245         return 0;
    246     }
    247     else if (*reading_stream > 47 && *reading_stream < 59 || *reading_stream == 46)
    248     {  // number
    249         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 function
    253         char* word = new char[256];
    254         parse_word(word);
    255         PARSE_BLANKS;
    256         if (*reading_stream == '(')
    257         {
    258             ++reading_stream;
    259 #define SWITCH word
    260             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_ELSE
    335             {
    336                 this->failed_ = true;
    337                 delete[] word;
    338                 return 0;
    339             }
    340         }
    341         else
    342         {
    343 #define SWITCH word
    344             CASE_1("pi")
    345                 value = 3.1415926535897932;
    346             CASE("e")
    347                 value = 2.7182818284590452;
    348             CASE_ELSE
    349             {
    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 paranthesis
    359         ++reading_stream;
    360         value = parse_last_argument();
    361     }
    362     else
    363     {
    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         else
    425         {
    426             --reading_stream;
    427             return undef;
    428         }
    429     }
    430     else
    431         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  
    3838#include <string>
    3939
    40 class _UtilExport ExprParser
     40namespace orxonox
    4141{
    42 public:
    43     enum binary_operator
     42    class _UtilExport ExprParser
    4443    {
    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
    61100    };
    62101
    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}
    106109
    107110#endif /* _FloatParser_H__ */
  • code/trunk/src/util/Math.cc

    r2087 r2171  
    3838#include "SubString.h"
    3939
    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
     43namespace orxonox
    4444{
    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    }
    47339}
    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 position
    84     @param mydirection My viewing direction
    85     @param otherposition The position of the other object
    86     @return The angle
    87 
    88     @example
    89     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     else
    100         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 position
    106     @param mydirection My viewing direction
    107     @param myorthonormal My orthonormalvector (pointing upwards through my head)
    108     @param otherposition The position of the other object
    109     @return The viewing direction
    110 
    111     @example
    112     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 plane
    123     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     else
    132         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 position
    138     @param mydirection My viewing direction
    139     @param myorthonormal My orthonormalvector (pointing upwards through my head)
    140     @param otherposition The position of the other object
    141     @return The viewing direction
    142 
    143     @example
    144     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 plane
    155     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     else
    168         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 position
    174     @param projectilespeed The speed of my projectile
    175     @param targetposition The position of my target
    176     @param targetvelocity The velocity of my target
    177     @return The predicted position
    178 
    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 Vector2
    210 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     else
    216         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 Vector3
    233 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     else
    239         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 Vector4
    258 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     else
    264         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 Quaternion
    285 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 ColourValue
    308 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         else
    328             output->a = 1.0;
    329 
    330         return true;
    331     }
    332     return false;
    333 }
  • code/trunk/src/util/Math.h

    r2087 r2171  
    2828
    2929/**
    30     @file Math.h
     30    @file
    3131    @brief Declaration and implementation of several math-functions, typedefs of some Ogre::Math classes to the orxonox namespace.
    3232*/
     
    3939#include <ostream>
    4040#include <string>
     41#include <cmath>
    4142#include <boost/static_assert.hpp>
    4243
     
    4950#include <OgreQuaternion.h>
    5051#include <OgreColourValue.h>
    51 
    52 namespace orxonox
    53 {
    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);
    7452
    7553//Get around Windows hackery
     
    8361#endif
    8462
    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)
     63namespace orxonox
    9264{
    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    };
    94277}
    95278
    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 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 value
    181     @param max The operand
    182 */
    183 template <typename T>
    184 inline int mod(T x, int max)
    185 {
    186     if (x >= 0)
    187         return (x % max);
    188     else
    189         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 = 0
    227     @param end The value at time = 1
    228     @return The interpolation at a given time
    229 */
    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 = 0
    240     @param end The value at time = 1
    241     @return The smoothed interpolation at a given time
    242 */
    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 maximum
    260 */
    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 minimum
    269     @param max The maximum
    270 */
    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 IntVector2
    279 {
    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 IntVector3
    288 {
    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 
    297279#endif /* _Util_Math_H__ */
  • code/trunk/src/util/MathConvert.h

    r2087 r2171  
    4040#include "Convert.h"
    4141
    42 
    43 ////////////////////
    44 // Math to string //
    45 ////////////////////
    46 
    47 // Vector2 to std::string
    48 template <>
    49 struct ConverterExplicit<orxonox::Vector2, std::string>
     42namespace orxonox
    5043{
    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}
    206208
    207209#endif /* _MathConvert_H__ */
  • code/trunk/src/util/MultiType.cc

    r2087 r2171  
    2828
    2929/**
    30     @file MultiType.cc
     30    @file
    3131    @brief Implementation of the MultiType.
    3232*/
     
    3535#include "MultiTypeValue.h"
    3636
    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)
     37namespace orxonox
    4238{
    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)
    4444    {
    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. */
    94206}
    95 
    96 /**
    97     @brief Returns the name of the current type.
    98     @return The name
    99 */
    100 std::string MultiType::getTypename() const
    101 {
    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  
    2828
    2929/**
    30     @file MultiType.h
     30    @file
    3131    @brief Declaration of the MultiType and some helper constructs.
    3232
     
    7373#include "Math.h"
    7474
    75 /**
    76     @brief Enum of all possible types of a MultiType.
    77 */
    78 enum MT_Type
     75namespace orxonox
    7976{
    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_degree
    104 };
    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 primitves
    111      - all pointers
    112      - string
    113      - Vector2, Vector3, Vector4
    114      - Quaternion
    115      - ColourValue
    116      - Radian, Degree
    117 
    118     The internal type of a MultiType is determined by the first assigned value, but can be
    119     changed by using setType<T>(), convert<T>() or setValue<T>(value). If a value gets assigned
    120     the normal way (operator=, setValue(value)), the value gets converted to the current internal
    121     type of the MultiType.
    122 */
    123 class _UtilExport MultiType
    124 {
    125     _UtilExport friend std::ostream& operator<<(std::ostream& outstream, const MultiType& mt);
    126     template <typename T> friend struct MT_Value;
    127 
    12877    /**
    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.
    13179    */
    132     struct _UtilExport MT_ValueBase
     80    enum MT_Type
    13381    {
    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
    224106    };
    225107
     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
    226130    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}
    524529
    525530#endif /* _MultiType_H__ */
  • code/trunk/src/util/MultiTypeValue.h

    r2087 r2171  
    2828
    2929/**
    30     @file MultiTypeValue.h
     30    @file
    3131    @brief Declaration and Implementation of the MT_Value<T> class.
    3232
     
    4141#include "MultiType.h"
    4242
    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
     43namespace orxonox
    4844{
    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) {}
    5154
    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_); }
    5457
    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; }
    5760
    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)
    6263        {
    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            }
    6473        }
    65         else
    66         {
    67             this->value_ = zeroise<T>();
    68             return !(bHasDefaultValue_ = true);
    69         }
    70     }
    7174
    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. */
    9598
    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. */
    119122
    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. */
    143146
    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_; }
    146149
    147     T value_; //!< The stored value
    148 };
     150        T value_; //!< The stored value
     151    };
     152}
    149153
    150154#endif /* _MultiTypeValue_H__ */
  • code/trunk/src/util/OutputBuffer.cc

    r1791 r2171  
    2828
    2929/**
    30     @file OutputBuffer.cc
     30    @file
    3131    @brief Implementation of the OutputBuffer.
    3232*/
  • code/trunk/src/util/OutputBuffer.h

    r1854 r2171  
    2828
    2929/**
    30     @file OutputBuffer.h
     30    @file
    3131    @brief Declaration of the OutputBuffer class.
    3232
     
    5858        an OutputBuffer and this buffer changes.
    5959    */
    60     class _UtilExport OutputBufferListener
     60    class OutputBufferListener
    6161    {
    6262        friend class OutputBuffer;
  • code/trunk/src/util/OutputHandler.cc

    r2087 r2171  
    2828
    2929/**
    30     @file OutputHandler.cc
     30    @file
    3131    @brief Implementation of the OutputHandler class.
    3232*/
  • code/trunk/src/util/OutputHandler.h

    r1791 r2171  
    2828
    2929/**
    30     @file OutputHandler.h
     30    @file
    3131    @brief Definition of the OutputHandler class.
    3232
  • code/trunk/src/util/SignalHandler.cc

    r2103 r2171  
    4040#include <cstring>
    4141
    42 SignalHandler * SignalHandler::singletonRef = NULL;
     42namespace orxonox
     43{
     44    SignalHandler * SignalHandler::singletonRef = NULL;
     45}
    4346
    4447#if ORXONOX_PLATFORM != ORXONOX_PLATFORM_WIN32
     
    4952#include <X11/keysym.h>
    5053
    51 bool SignalHandler::bXAutoKeyRepeatOn_ = false;
    52 
    53 SignalHandler::SignalHandler()
     54namespace orxonox
    5455{
     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    }
    55358}
    56359
    57 /**
    58  * register signal handlers for SIGSEGV and SIGABRT
    59  * @param appName path to executable eg argv[0]
    60  * @param filename filename to append backtrace to
    61  */
    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 XAutoKeyRepeat
    68   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     else
    76       bXAutoKeyRepeatOn_ = false;
    77     XCloseDisplay(display);
    78   }
    79   else
    80   {
    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 dontCatch
    87   assert( sigRecList.size() == 0 );
    88 
    89   catchSignal( SIGSEGV );
    90   catchSignal( SIGABRT );
    91   catchSignal( SIGILL );
    92 }
    93 
    94 /**
    95  * restore previous signal handlers
    96  */
    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 sig
    109  * @param sig signal to catch
    110  */
    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 signals
    126  * @param sig
    127  */
    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 process
    179   if ( sigPid == 0 )
    180   {
    181     getInstance()->dontCatch();
    182     // wait for message from parent when it has attached gdb
    183     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 gdb
    209 
    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 gdb
    221 
    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     else
    252       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     else
    289       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 
    354360#endif /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */
  • code/trunk/src/util/SignalHandler.h

    r2103 r2171  
    4040#include <string>
    4141
    42 typedef int (*SignalCallback)( void * someData );
     42namespace orxonox
     43{
     44    typedef int (*SignalCallback)( void * someData );
     45}
    4346
    4447#if ORXONOX_PLATFORM != ORXONOX_PLATFORM_WIN32
    4548#include <signal.h>
    4649
    47 struct SignalRec
     50namespace orxonox
    4851{
    49   int signal;
    50   sig_t handler;
    51 };
     52    struct SignalRec
     53    {
     54        int signal;
     55        sig_t handler;
     56    };
    5257
    53 struct SignalCallbackRec
    54 {
    55   SignalCallback cb;
    56   void * someData;
    57 };
     58    struct SignalCallbackRec
     59    {
     60        SignalCallback cb;
     61        void * someData;
     62    };
    5863
    5964
    60 typedef std::list<SignalRec> SignalRecList;
    61 typedef std::list<SignalCallbackRec> SignalCallbackList;
     65    typedef std::list<SignalRec> SignalRecList;
     66    typedef std::list<SignalCallbackRec> SignalCallbackList;
    6267
    63 class SignalHandler
    64 {
    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; }
    7075
    71     void registerCallback( SignalCallback cb, void * someData );
     76        void registerCallback( SignalCallback cb, void * someData );
    7277
    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();
    7580
    76   private:
    77     static void sigHandler( int sig );
     81    private:
     82        static void sigHandler( int sig );
    7883
    79     void catchSignal( int sig );
    80     SignalRecList sigRecList;
     84        void catchSignal( int sig );
     85        SignalRecList sigRecList;
    8186
    82     SignalCallbackList callbackList;
     87        SignalCallbackList callbackList;
    8388
    84     static SignalHandler * singletonRef;
     89        static SignalHandler * singletonRef;
    8590
    86     std::string appName;
    87     std::string filename;
     91        std::string appName;
     92        std::string filename;
    8893
    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}
    9298
    9399#else /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */
    94100
    95 class _UtilExport SignalHandler
     101namespace orxonox
    96102{
    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 ) {};
    102110
    103   private:
    104     static SignalHandler * singletonRef;
    105 };
     111    private:
     112        static SignalHandler * singletonRef;
     113    };
     114}
    106115
    107116#endif /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */
  • code/trunk/src/util/Sleep.h

    r1841 r2171  
    4141#include <winbase.h>
    4242
    43 inline void usleep(DWORD dwMicroseconds)
     43namespace orxonox
    4444{
    45   Sleep(dwMicroseconds / 1000);
    46 }
     45    inline void usleep(DWORD dwMicroseconds)
     46    {
     47        Sleep(dwMicroseconds / 1000);
     48    }
    4749
    48 inline void msleep(DWORD dwMilliseconds)
    49 {
    50   Sleep(dwMilliseconds);
    51 }
     50    inline void msleep(DWORD dwMilliseconds)
     51    {
     52        Sleep(dwMilliseconds);
     53    }
    5254
    53 inline void sleep(DWORD dwSeconds)
    54 {
    55   Sleep(dwSeconds * 1000);
     55    inline void sleep(DWORD dwSeconds)
     56    {
     57        Sleep(dwSeconds * 1000);
     58    }
    5659}
    5760
     
    6063#include <unistd.h>
    6164
    62 inline void msleep(unsigned long msec)
     65namespace orxonox
    6366{
    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    }
    6579}
    6680
  • code/trunk/src/util/String.cc

    r2087 r2171  
    2828
    2929/**
    30     @file String.cc
     30    @file
    3131    @brief Implementation of several string manipulation functions.
    3232*/
     
    4040#include "Math.h"
    4141
    42 std::string BLANKSTRING("");
    43 
    44 std::string getUniqueNumberString()
     42namespace orxonox
    4543{
    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    }
    47494}
    48 
    49 /**
    50     @brief Removes all whitespaces from a string.
    51     @param str The string to strip
    52 */
    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 strip
    67     @return The stripped line
    68 */
    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 string
    79     @return The modified copy
    80 */
    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 string
    93     @param start The startposition
    94     @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 string
    118     @param pos The position to check
    119     @return True if pos is between two quotes
    120 */
    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 string
    144     @return True if there is something between quotes
    145 */
    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 string
    156     @param The string between the quotes
    157 */
    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     else
    165         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 strip
    171     @return The string with removed quotes
    172 */
    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     else
    205         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 strip
    211     @return The striped string
    212 */
    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 check
    226     @return True = it's a comment
    227 
    228     A comment is defined by a leading '#', '%', ';' or '//'.
    229 */
    230 bool isComment(const std::string& str)
    231 {
    232     // Strip the line, whitespaces are disturbing
    233     std::string teststring = getStripped(str);
    234 
    235     // There are four possible comment-symbols:
    236     //  1) #comment in script-language style
    237     //  2) %comment in matlab style
    238     //  3) ;comment in unreal tournament config-file style
    239     //  4) //comment in code style
    240     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 check
    257     @return True = it's empty
    258 */
    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 check
    268     @return True = it's a number
    269 */
    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             else
    281                 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 manipulate
    291     @return The string with added slashes
    292 */
    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 manipulate
    314     @return The string with removed slashes
    315 */
    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 convert
    349 */
    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 string
    361     @return The copy
    362 */
    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 convert
    373 */
    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 string
    385     @return The copy
    386 */
    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 string
    397     @param s2 Second string
    398 */
    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 reached
    405     while ( (it1!=s1.end()) && (it2!=s2.end()) )
    406     {
    407         if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
    408             // return -1 to indicate smaller than, 1 otherwise
    409             return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
    410         //proceed to the next character in each string
    411         ++it1;
    412         ++it2;
    413     }
    414     size_t size1=s1.size(), size2=s2.size();// cache lengths
    415     //return -1,0 or 1 according to strings' lengths
    416     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 string
    425     @param s2 Second string
    426     @param len Maximal number of chars to compare
    427 */
    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 reached
    436     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 otherwise
    440             return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
    441         //proceed to the next character in each string
    442         ++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 string
    451     @return True if the string contains a comment
    452 */
    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 string
    461     @return The comment
    462 */
    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 string
    471     @return The position
    472 */
    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 string
    481     @param start The startposition
    482     @return The position
    483 */
    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  
    2828
    2929/**
    30     @file String.h
     30    @file
    3131    @brief Declaration of several string manipulation functions, used in many parts of the game.
    3232*/
     
    4040#include <sstream>
    4141
    42 extern _UtilExport std::string BLANKSTRING;
    43 _UtilExport std::string getUniqueNumberString();
     42namespace orxonox
     43{
     44    extern _UtilExport std::string BLANKSTRING;
     45    _UtilExport std::string getUniqueNumberString();
    4446
    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);
    4749
    48 _UtilExport std::string removeTrailingWhitespaces(const std::string& str);
     50    _UtilExport std::string removeTrailingWhitespaces(const std::string& str);
    4951
    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);
    5254
    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);
    5557
    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);
    5860
    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);
    6264
    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);
    6567
    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);
    6870
    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);
    7173
    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);
    7476
    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}
    7982
    8083#endif /* _Util_String_H__ */
  • code/trunk/src/util/SubString.cc

    r1791 r2171  
    4040#include "SubString.h"
    4141
    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)
     42namespace orxonox
    5543{
    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)
    390541            token = token.substr(0, token.size() - fallBackNeighbours);
    391           /// FINISH
    392           if(emptyEntries || token.size() > 0)
    393           {
     542        if(emptyEntries || token.size() > 0)
     543        {
    394544            ret.push_back(token);
    395545            token.clear();
    396546            bInSafemode.push_back(inSafemode);
    397547            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    }
    548563}
    549 
    550 
    551 /**
    552  * @brief Some nice debug information about this SubString
    553  */
    554 void SubString::debug() const
    555 {
    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  
    3838
    3939 /*!
    40  * @file substring.h
     40 * @file
    4141 * @brief a small class to get the parts of a string separated by commas
    4242 *
     
    6464#include <string>
    6565
    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
     66namespace orxonox
    7267{
    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;
    8486
    8587
    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();
    99101
    100   // operate on the SubString
    101   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); };
    109111
    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        ////////////////////////////////////////
    119121
    120   // retrieve a SubSet from the String
    121   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;
    123125
    124   // retrieve Information from within
    125   /** @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(); };
    143145
    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;
    162164
    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;
    167169
    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}
    172175
    173176#endif /* __SubString_H__ */
  • code/trunk/src/util/UtilPrereqs.h

    r1747 r2171  
    6060// Forward declarations
    6161//-----------------------------------------------------------------------
    62 class ArgReader;
    63 class Convert;
    64 class ExprParser;
    65 class MultiType;
    66 class SubString;
    6762namespace orxonox
    6863{
     64    class Exception;
     65    class ExprParser;
     66    class IntVector2;
     67    class IntVector3;
     68    class MultiType;
    6969    class OutputBuffer;
    7070    class OutputBufferListener;
    71     class Error;
    7271    class OutputHandler;
     72    class SignalHandler;
     73    class SubString;
    7374}
    7475
  • 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

  • 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  
    167167                        </File>
    168168                        <File
     169                                RelativePath="..\..\src\orxonox\PlayerManager.cc"
     170                                >
     171                        </File>
     172                        <File
    169173                                RelativePath="..\..\src\orxonox\PrecompiledHeaderFiles.cc"
    170174                                >
     
    206210                                </File>
    207211                                <File
     212                                        RelativePath="..\..\src\orxonox\objects\Level.cc"
     213                                        >
     214                                </File>
     215                                <File
    208216                                        RelativePath="..\..\src\orxonox\objects\Radar.cc"
    209217                                        >
     
    358366                                        <File
    359367                                                RelativePath="..\..\src\orxonox\objects\infos\Info.cc"
    360                                                 >
    361                                         </File>
    362                                         <File
    363                                                 RelativePath="..\..\src\orxonox\objects\infos\Level.cc"
    364368                                                >
    365369                                        </File>
     
    827831                        </File>
    828832                        <File
     833                                RelativePath="..\..\src\orxonox\PlayerManager.h"
     834                                >
     835                        </File>
     836                        <File
    829837                                RelativePath="..\..\src\orxonox\Settings.h"
    830838                                >
     
    846854                                </File>
    847855                                <File
     856                                        RelativePath="..\..\src\orxonox\objects\Level.h"
     857                                        >
     858                                </File>
     859                                <File
    848860                                        RelativePath="..\..\src\orxonox\objects\Radar.h"
    849861                                        >
     
    978990                                        <File
    979991                                                RelativePath="..\..\src\orxonox\objects\infos\Info.h"
    980                                                 >
    981                                         </File>
    982                                         <File
    983                                                 RelativePath="..\..\src\orxonox\objects\infos\Level.h"
    984992                                                >
    985993                                        </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  
    235235                        </File>
    236236                        <File
     237                                RelativePath="..\..\src\util\mbool.h"
     238                                >
     239                        </File>
     240                        <File
    237241                                RelativePath="..\..\src\util\MultiType.h"
    238242                                >
  • 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.