Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Aug 11, 2010, 8:55:13 AM (14 years ago)
Author:
dafrick
Message:

Merged presentation3 branch into trunk.

Location:
code/trunk
Files:
53 edited
24 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/core/BaseObject.cc

    r6800 r7163  
    7575            this->setScene(this->creator_->getScene(), this->creator_->getSceneID());
    7676            this->setGametype(this->creator_->getGametype());
     77            this->setLevel(this->creator_->getLevel());
    7778        }
    7879        else
     
    8384            this->sceneID_ = OBJECTID_UNKNOWN;
    8485            this->gametype_ = 0;
     86            this->level_ = 0;
    8587        }
    8688    }
     
    103105        }
    104106    }
    105    
     107
    106108    /** @brief Adds an object which listens to the events of this object. */
    107109    void BaseObject::registerEventListener(BaseObject* object)
     
    123125        XMLPortParam(BaseObject, "mainstate", setMainStateName, getMainStateName, xmlelement, mode);
    124126        XMLPortParamTemplate(BaseObject, "template", addTemplate, getSingleTemplate, xmlelement, mode, const std::string&);
    125        
     127
    126128        XMLPortObjectTemplate(BaseObject, Template, "templates", addTemplate, getTemplate, xmlelement, mode, Template*);
    127129        XMLPortObject(BaseObject, BaseObject, "eventlisteners", addEventListener, getEventListener, xmlelement, mode);
     
    194196    {
    195197        this->templates_.insert(temp);
     198        if( temp->isLink() )
     199        {
     200          this->networkTemplateNames_.insert(temp->getLink());
     201          assert( !Template::getTemplate(temp->getLink())->isLink() );
     202        }
     203        else
     204          this->networkTemplateNames_.insert(temp->getName());
    196205        temp->applyOn(this);
    197206    }
     
    363372    {
    364373        this->registerEventStates();
    365        
     374
    366375        COUT(4) << this->getIdentifier()->getName() << " (&" << this << ") processing event. originator: " << event.originator_->getIdentifier()->getName() << " (&" << event.originator_ << "), activate: " << event.activate_ << ", name: " << event.name_ << ", statename: " << event.statename_ << "." << std::endl;
    367376
  • code/trunk/src/libraries/core/BaseObject.h

    r6800 r7163  
    5151    class Scene;
    5252    class Gametype;
     53    class Level;
    5354
    5455    //! The BaseObject is the parent of all classes representing an instance in the game.
     
    154155            virtual void changedGametype() {}
    155156
     157            inline void setLevel(const SmartPtr<Level>& level)
     158            {
     159                if (level != this->level_)
     160                {
     161                    this->level_ = level;
     162                    this->changedLevel();
     163                }
     164            }
     165            inline const SmartPtr<Level>& getLevel() const { return this->level_; }
     166            virtual void changedLevel() {}
     167
    156168            void addEventSource(BaseObject* source, const std::string& state);
    157169            void removeEventSource(BaseObject* source);
     
    179191            EventState* getEventState(const std::string& name) const;
    180192
    181             std::string name_;                                 //!< The name of the object
    182             std::string oldName_;                              //!< The old name of the object
    183             mbool       bActive_;                              //!< True = the object is active
    184             mbool       bVisible_;                             //!< True = the object is visible
    185             std::string mainStateName_;
    186             Functor*    mainStateFunctor_;
     193            std::string             name_;                     //!< The name of the object
     194            std::string             oldName_;                  //!< The old name of the object
     195            mbool                   bActive_;                  //!< True = the object is active
     196            mbool                   bVisible_;                 //!< True = the object is visible
     197            std::string             mainStateName_;
     198            Functor*                mainStateFunctor_;
     199            std::set<std::string>   networkTemplateNames_;
    187200
    188201        private:
     
    209222            SmartPtr<Gametype>     gametype_;
    210223            Gametype*              oldGametype_;
     224            SmartPtr<Level>        level_;
    211225            std::set<Template*>    templates_;
    212226
  • code/trunk/src/libraries/core/CMakeLists.txt

    r6417 r7163  
    9696    input/KeyBinder.h
    9797    input/KeyBinderManager.h
    98   DEFINE_SYMBOL
    99     "CORE_SHARED_BUILD"
    10098  PCH_FILE
    10199    CorePrecompiledHeaders.h
     
    112110    ogreceguirenderer_orxonox
    113111    ois_orxonox
    114     tinyxml++_orxonox
    115     tolua++_orxonox
     112    tinyxml_orxonox
     113    tolua_orxonox
    116114    util
    117115  SOURCE_FILES
  • code/trunk/src/libraries/core/ConfigFileManager.cc

    r6536 r7163  
    3333#include "util/Convert.h"
    3434#include "util/Math.h"
     35#include "util/StringUtils.h"
    3536#include "ConsoleCommand.h"
    3637#include "ConfigValueContainer.h"
  • code/trunk/src/libraries/core/ConfigFileManager.h

    r6536 r7163  
    3939
    4040#include "util/Singleton.h"
    41 #include "util/StringUtils.h"
    4241
    4342namespace orxonox // tolua_export
  • code/trunk/src/libraries/core/Core.cc

    r6746 r7163  
    7979    SetCommandLineArgument(settingsFile, "orxonox.ini").information("THE configuration file");
    8080    SetCommandLineSwitch(noIOConsole).information("Use this if you don't want to use the IOConsole (for instance for Lua debugging)");
     81
    8182#ifdef ORXONOX_PLATFORM_WINDOWS
    8283    SetCommandLineArgument(limitToCPU, 1).information("Limits the program to one CPU/core (1, 2, 3, etc.). Default is the first core (faster than off)");
  • code/trunk/src/libraries/core/Event.cc

    r6859 r7163  
    6060
    6161        COUT(4) << "Processing event (EventState) : originator: " << event.originator_->getIdentifier()->getName() << " (&" << event.originator_ << "), activate: " << event.activate_ << ", name: " << event.name_ << ", statename: " << event.statename_ << ", object: " << object->getIdentifier()->getName() << " (&" << object << ")" << "." << std::endl;
    62        
     62
    6363        // check if the originator is an instance of the requested class
    6464        if (event.originator_->isA(this->subclass_))
  • code/trunk/src/libraries/core/EventIncludes.h

    r6800 r7163  
    5252    } \
    5353    XMLPortEventStateIntern(xmlportevent##function, classname, statename, xmlelement, mode)
    54    
     54
    5555#define XMLPortEventSink(classname, subclassname, statename, function, xmlelement, mode) \
    5656    orxonox::EventState* containername##function = this->getEventState(statename); \
  • code/trunk/src/libraries/core/Executor.cc

    r6417 r7163  
    3030#include "Executor.h"
    3131
     32#include <algorithm>
     33
    3234#include "util/Convert.h"
     35#include "util/Debug.h"
     36#include "util/StringUtils.h"
     37#include "util/SubString.h"
    3338#include "Language.h"
    3439
     
    6368    bool Executor::parse(const std::string& params, const std::string& delimiter) const
    6469    {
    65         EXECUTOR_PARSE(normal);
     70        unsigned int paramCount = this->functor_->getParamCount();
     71       
     72        if (paramCount == 0)
     73        {
     74            COUT(5) << "Calling Executor " << this->name_ << " through parser without parameters." << std::endl;
     75            (*this->functor_)();
     76        }
     77        else if (paramCount == 1)
     78        {
     79            const std::string& temp = getStripped(params);
     80            if (!temp.empty())
     81            {
     82                COUT(5) << "Calling Executor " << this->name_ << " through parser with one parameter, using whole string: " << params << std::endl;
     83                (*this->functor_)(MultiType(params));
     84            }
     85            else if (this->bAddedDefaultValue_[0])
     86            {
     87                COUT(5) << "Calling Executor " << this->name_ << " through parser with one parameter, using default value: " << this->defaultValue_[0] << std::endl;
     88                (*this->functor_)(this->defaultValue_[0]);
     89            }
     90            else
     91            {
     92                COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input: " << temp << ")." << std::endl;
     93                return false;
     94            }
     95        }
     96        else
     97        {
     98            SubString tokens(params, delimiter, SubString::WhiteSpaces, false, '\\', true, '"', true, '(', ')', true, '\0');
     99           
     100            for (unsigned int i = tokens.size(); i < this->functor_->getParamCount(); i++)
     101            {
     102                if (!this->bAddedDefaultValue_[i])
     103                {
     104                    COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input:" << params << ")." << std::endl;
     105                    return false;
     106                }
     107            }
     108           
     109            MultiType param[MAX_FUNCTOR_ARGUMENTS];
     110            COUT(5) << "Calling Executor " << this->name_ << " through parser with " << paramCount << " parameters, using " << tokens.size() << " tokens (";
     111            for (unsigned int i = 0; i < tokens.size() && i < MAX_FUNCTOR_ARGUMENTS; i++)
     112            {
     113                param[i] = tokens[i];
     114                if (i != 0)
     115                {
     116                    COUT(5) << ", ";
     117                }
     118                COUT(5) << tokens[i];
     119            }
     120            COUT(5) << ") and " << std::max((int)paramCount - (int)tokens.size(), 0) << " default values (";
     121            for (unsigned int i = tokens.size(); i < paramCount; i++)
     122            {
     123                param[i] = this->defaultValue_[i];
     124                if (i != 0)
     125                {
     126                    COUT(5) << ", ";
     127                }
     128                COUT(5) << this->defaultValue_[i];
     129            }
     130            COUT(5) << ")." << std::endl;
     131           
     132            if ((tokens.size() > paramCount) && (this->functor_->getTypenameParam(paramCount - 1) == "string"))
     133                param[paramCount - 1] = tokens.subSet(paramCount - 1).join();
     134           
     135            switch(paramCount)
     136            {
     137                case 2:
     138                    (*this->functor_)(param[0], param[1]);
     139                    break;
     140                case 3:
     141                    (*this->functor_)(param[0], param[1], param[2]);
     142                    break;
     143                case 4:
     144                    (*this->functor_)(param[0], param[1], param[2], param[3]);
     145                    break;
     146                case 5:
     147                    (*this->functor_)(param[0], param[1], param[2], param[3], param[4]);
     148                    break;
     149            }
     150        }
     151
     152        return true;
    66153    }
    67154
  • code/trunk/src/libraries/core/Executor.h

    r6417 r7163  
    3333#include "CorePrereqs.h"
    3434
    35 #include <algorithm>
    3635#include <string>
    37 
    38 #include "util/Debug.h"
    39 #include "util/Math.h"
    40 #include "util/StringUtils.h"
    41 #include "util/SubString.h"
     36#include "util/MultiType.h"
    4237#include "Functor.h"
    43 
    44 
    45 #define EXECUTOR_PARSE_FUNCTORCALL(mode) EXECUTOR_PARSE_FUNCTORCALL##mode
    46 #define EXECUTOR_PARSE_FUNCTORCALLnormal (*this->functor_)
    47 #define EXECUTOR_PARSE_FUNCTORCALLobject (*((FunctorMember<T>*)this->functor_))
    48 
    49 #define EXECUTOR_PARSE_OBJECT(mode, comma) EXECUTOR_PARSE_OBJECT##mode##comma
    50 #define EXECUTOR_PARSE_OBJECTnormal0
    51 #define EXECUTOR_PARSE_OBJECTnormal1
    52 #define EXECUTOR_PARSE_OBJECTobject0 object
    53 #define EXECUTOR_PARSE_OBJECTobject1 object,
    54 
    55 #define EXECUTOR_PARSE(mode) \
    56     unsigned int paramCount = this->functor_->getParamCount(); \
    57     \
    58     if (paramCount == 0) \
    59     { \
    60         COUT(5) << "Calling Executor " << this->name_ << " through parser without parameters." << std::endl; \
    61         EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 0)); \
    62     } \
    63     else if (paramCount == 1) \
    64     { \
    65         const std::string& temp = getStripped(params); \
    66         if (!temp.empty()) \
    67         { \
    68             COUT(5) << "Calling Executor " << this->name_ << " through parser with one parameter, using whole string: " << params << std::endl; \
    69             EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) MultiType(params)); \
    70         } \
    71         else if (this->bAddedDefaultValue_[0]) \
    72         { \
    73             COUT(5) << "Calling Executor " << this->name_ << " through parser with one parameter, using default value: " << this->defaultValue_[0] << std::endl; \
    74             EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) this->defaultValue_[0]); \
    75         } \
    76         else \
    77         { \
    78             COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input: " << temp << ")." << std::endl; \
    79             return false; \
    80         } \
    81     } \
    82     else \
    83     { \
    84         SubString tokens(params, delimiter, SubString::WhiteSpaces, false, '\\', true, '"', true, '(', ')', true, '\0'); \
    85         \
    86         for (unsigned int i = tokens.size(); i < this->functor_->getParamCount(); i++) \
    87         { \
    88             if (!this->bAddedDefaultValue_[i]) \
    89             { \
    90                 COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input:" << params << ")." << std::endl; \
    91                 return false; \
    92             } \
    93         } \
    94         \
    95         MultiType param[MAX_FUNCTOR_ARGUMENTS]; \
    96         COUT(5) << "Calling Executor " << this->name_ << " through parser with " << paramCount << " parameters, using " << tokens.size() << " tokens ("; \
    97         for (unsigned int i = 0; i < tokens.size() && i < MAX_FUNCTOR_ARGUMENTS; i++) \
    98         { \
    99             param[i] = tokens[i]; \
    100             if (i != 0) \
    101             { \
    102                 COUT(5) << ", "; \
    103             } \
    104             COUT(5) << tokens[i]; \
    105         } \
    106         COUT(5) << ") and " << std::max(static_cast<int>(paramCount) - static_cast<int>(tokens.size()), 0) << " default values ("; \
    107         for (unsigned int i = tokens.size(); i < paramCount; i++) \
    108         { \
    109             param[i] = this->defaultValue_[i]; \
    110             if (i != 0) \
    111             { \
    112                 COUT(5) << ", "; \
    113             } \
    114             COUT(5) << this->defaultValue_[i]; \
    115         } \
    116         COUT(5) << ")." << std::endl; \
    117         \
    118         if ((tokens.size() > paramCount) && (this->functor_->getTypenameParam(paramCount - 1) == "string")) \
    119             param[paramCount - 1] = tokens.subSet(paramCount - 1).join(); \
    120         \
    121         switch(paramCount) \
    122         { \
    123             case 2: \
    124                 EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) param[0], param[1]); \
    125                 break; \
    126             case 3: \
    127                 EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) param[0], param[1], param[2]); \
    128                 break; \
    129             case 4: \
    130                 EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) param[0], param[1], param[2], param[3]); \
    131                 break; \
    132             case 5: \
    133                 EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) param[0], param[1], param[2], param[3], param[4]); \
    134                 break; \
    135         } \
    136     } \
    137     \
    138     return true
    13938
    14039namespace orxonox
     
    284183            bool parse(T* object, const std::string& params, const std::string& delimiter = " ") const
    285184            {
    286                 EXECUTOR_PARSE(object);
     185                static_cast<FunctorMember<T>*>(this->functor_)->setObject(object);
     186                if (Executor::parse(params, delimiter))
     187                    return true;
     188                else
     189                {
     190                    static_cast<FunctorMember<T>*>(this->functor_)->setObject((T*)NULL);
     191                    return false;
     192                }
    287193            }
    288194
    289195            bool parse(const T* object, const std::string& params, const std::string& delimiter = " ") const
    290196            {
    291                 EXECUTOR_PARSE(object);
     197                static_cast<FunctorMember<T>*>(this->functor_)->setObject(object);
     198                if (Executor::parse(params, delimiter))
     199                    return true;
     200                else
     201                {
     202                    static_cast<FunctorMember<T>*>(this->functor_)->setObject((T*)NULL);
     203                    return false;
     204                }
    292205            }
    293206    };
  • code/trunk/src/libraries/core/GUIManager.cc

    r6763 r7163  
    321321    }
    322322
    323     void GUIManager::keyPressed(const KeyEvent& evt)
     323    void GUIManager::buttonPressed(const KeyEvent& evt)
    324324    {
    325325        this->protectedCall(boost::bind(&CEGUI::System::injectKeyDown, _1, evt.getKeyCode()));
     
    327327    }
    328328
    329     void GUIManager::keyReleased(const KeyEvent& evt)
     329    void GUIManager::buttonReleased(const KeyEvent& evt)
    330330    {
    331331        this->protectedCall(boost::bind(&CEGUI::System::injectKeyUp, _1, evt.getKeyCode()));
  • code/trunk/src/libraries/core/GUIManager.h

    r6749 r7163  
    8484        //! Creates a new InputState to be used with a GUI Sheet
    8585        const std::string& createInputState(const std::string& name, TriBool::Value showCursor = TriBool::True, TriBool::Value useKeyboard = TriBool::True, bool bBlockJoyStick = false); // tolua_export
     86        LuaState* getLuaState(void)
     87            { return this->luaState_.get(); }
    8688
    8789        //! Returns the root window for all menu sheets
     
    9597        inline void setPlayer(const std::string& guiname, PlayerInfo* player)
    9698            { this->players_[guiname] = player; }
    97         inline PlayerInfo* getPlayer(const std::string& guiname) const
    98             { std::map<std::string, PlayerInfo*>::const_iterator it = this->players_.find(guiname); return (it != this->players_.end()) ? it->second : 0; }
     99        inline orxonox::PlayerInfo* getPlayer(const std::string& guiname) const { std::map<std::string, PlayerInfo*>::const_iterator it = this->players_.find(guiname); return (it != this->players_.end()) ? it->second : 0; } // tolua_export
    99100
    100101        // TODO: Temporary hack because the tolua exported CEGUI method does not seem to work
     
    105106    private:
    106107        GUIManager(const GUIManager& instance); //!< private and undefined copy c'tor (this is a singleton class)
     108        void executeCode(const std::string& str);
    107109
    108         void executeCode(const std::string& str);
    109110        template <typename FunctionType>
    110111        bool protectedCall(FunctionType function);
    111112
    112113        // keyHandler functions
    113         void keyPressed (const KeyEvent& evt);
    114         void keyReleased(const KeyEvent& evt);
     114        void buttonPressed (const KeyEvent& evt);
     115        void buttonReleased(const KeyEvent& evt);
    115116
    116117        // mouseHandler functions
  • code/trunk/src/libraries/core/OrxonoxClass.h

    r6524 r7163  
    108108            bool isParentOf(const OrxonoxClass* object);
    109109            bool isDirectParentOf(const OrxonoxClass* object);
    110            
     110
    111111            virtual void clone(OrxonoxClass*& item) {}
    112112
     
    172172            std::vector<std::pair<unsigned int, void*> > objectPointers_;
    173173    };
    174    
    175     SUPER_FUNCTION(11, OrxonoxClass, clone, true);
    176    
     174
     175    SUPER_FUNCTION(11, OrxonoxClass, clone, false);
     176
    177177}
    178178
  • code/trunk/src/libraries/core/Super.h

    r6524 r7163  
    267267    #define SUPER_changedGametype(classname, functionname, ...) \
    268268        SUPER_NOARGS(classname, functionname)
    269        
     269
    270270    #define SUPER_changedUsed(classname, functionname, ...) \
    271271        SUPER_NOARGS(classname, functionname)
    272        
     272
    273273    #define SUPER_clone(classname, functionname, ...) \
    274274        SUPER_ARGS(classname, functionname, __VA_ARGS__)
    275        
     275
    276276    #define SUPER_changedCarrier(classname, functionname, ...) \
    277277        SUPER_NOARGS(classname, functionname)
    278        
     278
    279279    #define SUPER_changedPickedUp(classname, functionname, ...) \
    280280        SUPER_NOARGS(classname, functionname)
    281        
     281
    282282    // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
    283283
     
    530530            ()
    531531        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
    532        
     532
    533533        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(10, changedUsed, false)
    534534            ()
     
    538538            (item)
    539539        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
    540        
     540
    541541        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(12, changedCarrier, false)
    542542            ()
    543543        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
    544        
     544
    545545        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(13, changedPickedUp, false)
    546546            ()
  • code/trunk/src/libraries/core/Template.cc

    r6746 r7163  
    9999    }
    100100
    101     const TiXmlElement& Template::getXMLElement() const
     101    const TiXmlElement& Template::getXMLElement()
    102102    {
    103103        if (this->bIsLink_)
     
    106106            if (temp)
    107107            {
     108                this->bLoadDefaults_ = temp->bLoadDefaults_;
     109
    108110                if (!temp->bIsReturningXMLElement_)
    109111                {
  • code/trunk/src/libraries/core/Template.h

    r6417 r7163  
    5151            inline const std::string& getLink() const
    5252                { return this->link_; }
     53            inline bool isLink() const
     54                { return this->bIsLink_; }
    5355
    5456            inline void setLoadDefaults(bool bLoadDefaults)
     
    5860
    5961            void setXMLElement(const TiXmlElement& xmlelement);
    60             const TiXmlElement& getXMLElement() const;
     62            const TiXmlElement& getXMLElement();
    6163
    6264            void setBaseclass(const std::string& baseclass);
  • code/trunk/src/libraries/core/XMLPort.cc

    r5781 r7163  
    4141        return ((!this->bApplyLoaderMask_) || identifier->isA(ClassIdentifier<Namespace>::getIdentifier()) || Loader::currentMask_s.isIncluded(identifier));
    4242    }
     43
     44    XMLPortObjectContainer& XMLPortObjectContainer::port(BaseObject* object, Element& xmlelement, XMLPort::Mode mode)
     45    {
     46        if ((mode == XMLPort::LoadObject) || (mode == XMLPort::ExpandObject))
     47        {
     48            try
     49            {
     50                Element* xmlsubelement;
     51                if (!this->sectionname_.empty())
     52                    xmlsubelement = xmlelement.FirstChildElement(this->sectionname_, false);
     53                else
     54                    xmlsubelement = &xmlelement;
     55
     56                if (!xmlsubelement)
     57                    return (*this);
     58
     59                for (ticpp::Iterator<ticpp::Element> child = xmlsubelement->FirstChildElement(false); child != child.end(); child++)
     60                {
     61                    Identifier* identifier = Identifier::getIdentifierByString(child->Value());
     62                    if (!identifier)
     63                    {
     64                        if (!this->sectionname_.empty())
     65                        {
     66                            COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a valid classname." << std::endl;
     67                        }
     68                        else
     69                        {
     70                            // It's probably just another subsection
     71                        }
     72                        continue;
     73                    }
     74                    if (!identifier->isA(objectIdentifier_))
     75                    {
     76                        COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a '" << objectIdentifier_->getName() << "'." << std::endl;
     77                        continue;
     78                    }
     79                    if (!identifier->isLoadable())
     80                    {
     81                        COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not loadable." << std::endl;
     82                        continue;
     83                    }
     84                    if (!this->identifierIsIncludedInLoaderMask(identifier))
     85                        continue;
     86
     87                    try
     88                    {
     89                        COUT(4) << object->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl;
     90
     91                        BaseObject* newObject = identifier->fabricate(object);
     92                        newObject->setLoaderIndentation(object->getLoaderIndentation() + "  ");
     93
     94                        if (this->bLoadBefore_)
     95                        {
     96                            newObject->XMLPort(*child, XMLPort::LoadObject);
     97                            COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << static_cast<BaseObject*>(object)->getName() << ')' << std::endl;
     98                        }
     99                        else
     100                        {
     101                            COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << static_cast<BaseObject*>(object)->getName() << ')' << std::endl;
     102                        }
     103
     104                        COUT(5) << object->getLoaderIndentation();
     105
     106                        this->callLoadExecutor(object, newObject);
     107
     108                        if (!this->bLoadBefore_)
     109                            newObject->XMLPort(*child, XMLPort::LoadObject);
     110
     111                        COUT(5) << object->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl;
     112                    }
     113                    catch (AbortLoadingException& ex)
     114                    {
     115                        COUT(1) << "An error occurred while loading object, abort loading..." << std::endl;
     116                        throw ex;
     117                    }
     118                    catch (...)
     119                    {
     120                        COUT(1) << "An error occurred while loading object:" << std::endl;
     121                        COUT(1) << Exception::handleMessage() << std::endl;
     122                    }
     123                }
     124            }
     125            catch (ticpp::Exception& ex)
     126            {
     127                COUT(1) << std::endl;
     128                COUT(1) << "An error occurred in XMLPort.h while loading a '" << objectIdentifier_->getName() << "' in '" << this->sectionname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << object->getName() << ") in " << object->getFilename() << ':' << std::endl;
     129                COUT(1) << ex.what() << std::endl;
     130            }
     131        }
     132        else if (mode == XMLPort::SaveObject)
     133        {
     134        }
     135
     136        return (*this);
     137    }
    43138}
  • code/trunk/src/libraries/core/XMLPort.h

    r6417 r7163  
    197197    @param loadfunction The function to add a new object to the class
    198198    @param loadfunction The function to get all added objects from the class
    199     @param xmlelement The XMLElement (recieved through the XMLPort function)
     199    @param xmlelement The XMLElement (received through the XMLPort function)
    200200    @param mode The mode (load/save) (received through the XMLPort function)
    201201    @param bApplyLoaderMask If this is true, an added sub-object gets loaded only if it's class is included in the Loaders ClassTreeMask (this is usually false)
     
    495495            virtual ~XMLPortObjectContainer() {}
    496496
     497            XMLPortObjectContainer& port(BaseObject* object, Element& xmlelement, XMLPort::Mode mode);
     498
     499            virtual void callLoadExecutor(BaseObject* object, BaseObject* newObject) = 0;
     500
    497501            inline const std::string& getName() const
    498502                { return this->sectionname_; }
     
    508512            bool bLoadBefore_;
    509513            Identifier* identifier_;
     514            Identifier* objectIdentifier_;
    510515    };
    511516
     
    518523                this->sectionname_ = sectionname;
    519524                this->identifier_ = identifier;
     525                assert(identifier->isA(ClassIdentifier<T>::getIdentifier()));
     526                this->objectIdentifier_ = ClassIdentifier<O>::getIdentifier();
    520527                this->loadexecutor_ = loadexecutor;
    521528                this->saveexecutor_ = saveexecutor;
     
    532539            }
    533540
    534             XMLPortObjectContainer& port(T* object, Element& xmlelement, XMLPort::Mode mode)
    535             {
    536                 if ((mode == XMLPort::LoadObject) || (mode == XMLPort::ExpandObject))
    537                 {
    538                     try
    539                     {
    540                         Element* xmlsubelement;
    541                         if (!this->sectionname_.empty())
    542                             xmlsubelement = xmlelement.FirstChildElement(this->sectionname_, false);
    543                         else
    544                             xmlsubelement = &xmlelement;
    545 
    546                         if (xmlsubelement)
    547                         {
    548                             for (ticpp::Iterator<ticpp::Element> child = xmlsubelement->FirstChildElement(false); child != child.end(); child++)
    549                             {
    550                                 Identifier* identifier = Identifier::getIdentifierByString(child->Value());
    551                                 if (identifier)
    552                                 {
    553                                     if (identifier->isA(ClassIdentifier<O>::getIdentifier()))
    554                                     {
    555                                         if (identifier->isLoadable())
    556                                         {
    557                                             if (this->identifierIsIncludedInLoaderMask(identifier))
    558                                             {
    559                                                 try
    560                                                 {
    561                                                     COUT(4) << object->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl;
    562 
    563                                                     BaseObject* newObject = identifier->fabricate(static_cast<BaseObject*>(object));
    564                                                     assert(newObject);
    565                                                     newObject->setLoaderIndentation(object->getLoaderIndentation() + "  ");
    566 
    567                                                     O* castedObject = orxonox_cast<O*>(newObject);
    568                                                     assert(castedObject);
    569 
    570                                                     if (this->bLoadBefore_)
    571                                                     {
    572                                                         newObject->XMLPort(*child, XMLPort::LoadObject);
    573                                                         COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << static_cast<BaseObject*>(object)->getName() << ')' << std::endl;
    574                                                     }
    575                                                     else
    576                                                     {
    577                                                         COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << static_cast<BaseObject*>(object)->getName() << ')' << std::endl;
    578                                                     }
    579 
    580                                                     COUT(5) << object->getLoaderIndentation();
    581                                                     (*this->loadexecutor_)(object, castedObject);
    582 
    583                                                     if (!this->bLoadBefore_)
    584                                                         newObject->XMLPort(*child, XMLPort::LoadObject);
    585 
    586                                                     COUT(5) << object->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl;
    587                                                 }
    588                                                 catch (AbortLoadingException& ex)
    589                                                 {
    590                                                     COUT(1) << "An error occurred while loading object, abort loading..." << std::endl;
    591                                                     throw ex;
    592                                                 }
    593                                                 catch (...)
    594                                                 {
    595                                                     COUT(1) << "An error occurred while loading object:" << std::endl;
    596                                                     COUT(1) << Exception::handleMessage() << std::endl;
    597                                                 }
    598                                             }
    599                                         }
    600                                         else
    601                                         {
    602                                             COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not loadable." << std::endl;
    603                                         }
    604                                     }
    605                                     else
    606                                     {
    607                                         COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a '" << ClassIdentifier<O>::getIdentifier()->getName() << "'." << std::endl;
    608                                     }
    609                                 }
    610                                 else
    611                                 {
    612                                     if (!this->sectionname_.empty())
    613                                     {
    614                                         COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a valid classname." << std::endl;
    615                                     }
    616                                     else
    617                                     {
    618                                         // It's probably just another subsection
    619                                     }
    620                                 }
    621                             }
    622                         }
    623                     }
    624                     catch (ticpp::Exception& ex)
    625                     {
    626                         COUT(1) << std::endl;
    627                         COUT(1) << "An error occurred in XMLPort.h while loading a '" << ClassIdentifier<O>::getIdentifier()->getName() << "' in '" << this->sectionname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << object->getName() << ") in " << object->getFilename() << ':' << std::endl;
    628                         COUT(1) << ex.what() << std::endl;
    629                     }
    630                 }
    631                 else if (mode == XMLPort::SaveObject)
    632                 {
    633                 }
    634 
    635                 return (*this);
     541            void callLoadExecutor(BaseObject* object, BaseObject* newObject)
     542            {
     543                T* castedObject = orxonox_cast<T*>(object);
     544                assert(castedObject);
     545                O* castedNewObject = orxonox_cast<O*>(newObject);
     546                assert(castedNewObject);
     547
     548                (*this->loadexecutor_)(castedObject, castedNewObject);
    636549            }
    637550
  • code/trunk/src/libraries/network/CMakeLists.txt

    r5781 r7163  
    2929  GamestateClient.cc
    3030  GamestateHandler.cc
     31  LANDiscoverable.cc
     32  LANDiscovery.cc
    3133  NetworkFunction.cc
    3234  Host.cc
     
    4850  GamestateManager.h
    4951  Host.h
     52  LANDiscoverable.h
     53  LANDiscovery.h
    5054  NetworkFunction.h
    5155  NetworkPrecompiledHeaders.h
     
    6064
    6165ORXONOX_ADD_LIBRARY(network
    62   DEFINE_SYMBOL
    63     "NETWORK_SHARED_BUILD"
     66  TOLUA_FILES
     67    Client.h
     68    LANDiscovery.h
    6469  PCH_FILE
    6570    NetworkPrecompiledHeaders.h
  • code/trunk/src/libraries/network/ChatListener.cc

    r5781 r7163  
    3636        RegisterRootObject(ChatListener);
    3737    }
     38
     39    //void ChatListener::incomingChat( const std::string& message,
     40      //unsigned int senderID )
     41    //{
     42      //COUT(0) << "Chat: \"" << message << "\"\n";
     43
     44
     45    //}
     46
     47
    3848}
    3949
  • code/trunk/src/libraries/network/ChatListener.h

    r5781 r7163  
    3838    {
    3939        public:
     40            /* constructor, destructor */
    4041            ChatListener();
    4142            virtual ~ChatListener() {}
    4243
     44            /* What to do with incoming chat */
    4345            virtual void incomingChat(const std::string& message, unsigned int senderID) = 0;
    4446    };
  • code/trunk/src/libraries/network/Client.cc

    r6417 r7163  
    5050#include "FunctionCallManager.h"
    5151#include "core/CoreIncludes.h"
     52#include "core/CommandLineParser.h"
    5253#include "core/Game.h"
     54#include "core/ScopedSingletonManager.h"
    5355
    5456namespace orxonox
    5557{
    5658
     59  ManageScopedSingleton( Client, ScopeID::Root, true );
    5760
    5861  /**
     
    6164  */
    6265  Client::Client():
     66      gamestate(0),
    6367      isSynched_(false),
    6468      gameStateFailure_(false),
    6569      timeSinceLastUpdate_(0)
    6670  {
    67   }
    68 
    69   /**
    70   * Constructor for the Client class
    71   * @param address the server address
    72   * @param port port of the application on the server
    73   */
    74   Client::Client(const std::string& address, int port):
    75       isSynched_(false),
    76       gameStateFailure_(false),
    77       timeSinceLastUpdate_(0)
    78   {
    79       setPort( port );
    80       setServerAddress( address );
    81   }
    82 
    83   Client::~Client(){
     71    this->setDestination( CommandLineParser::getValue("dest").getString(), CommandLineParser::getValue("port") );
     72  }
     73
     74  Client::~Client()
     75  {
    8476    if ( ClientConnection::isConnected() )
    8577      closeConnection();
     
    9082  * @return true/false
    9183  */
    92   bool Client::establishConnection(){
     84  bool Client::establishConnection()
     85  {
    9386    Synchronisable::setClient(true);
    94     return ClientConnection::establishConnection();
     87    this->gamestate = new GamestateClient();
     88    if( ClientConnection::establishConnection() )
     89    {
     90      Host::setActive(true);
     91      return true;
     92    }
     93    else
     94      return false;
    9595  }
    9696
     
    9999  * @return true/false
    100100  */
    101   bool Client::closeConnection(){
     101  bool Client::closeConnection()
     102  {
     103    assert(this->gamestate);
     104    delete this->gamestate;
     105    this->gamestate = 0;
     106    Host::setActive(false);
    102107    return ClientConnection::closeConnection();
    103108  }
    104 
    105   bool Client::queuePacket(ENetPacket *packet, int clientID){
     109 
     110  void Client::setDestination(const std::string& serverAddress, unsigned int port)
     111  {
     112    ClientConnection::setServerAddress(serverAddress);
     113    ClientConnection::setPort(port);
     114  }
     115
     116  bool Client::queuePacket(ENetPacket *packet, int clientID)
     117  {
    106118    bool b = ClientConnection::addPacket(packet);
    107119    assert(b);
     
    109121  }
    110122
    111   bool Client::processChat(const std::string& message, unsigned int playerID){
     123  bool Client::processChat(const std::string& message, unsigned int playerID)
     124  {
    112125//    COUT(1) << "Player " << playerID << ": " << message << std::endl;
    113126    return true;
    114127  }
    115128
    116   void Client::printRTT(){
     129  void Client::printRTT()
     130  {
    117131    COUT(0) << "Round trip time to server is " << ClientConnection::getRTT() << " ms" << endl;
    118132  }
     
    123137   * @return result(true/false)
    124138   */
    125   bool Client::chat(const std::string& message){
     139  bool Client::chat(const std::string& message)
     140  {
    126141    packet::Chat *m = new packet::Chat(message, Host::getPlayerID());
    127142    return m->send();
     
    133148   * @param time
    134149   */
    135   void Client::update(const Clock& time){
     150  void Client::update(const Clock& time)
     151  {
    136152    //this steers our network frequency
    137153    timeSinceLastUpdate_+=time.getDeltaTime();
     
    143159      {
    144160        COUT(4) << "popping partial gamestate: " << std::endl;
    145         packet::Gamestate *gs = gamestate.getGamestate();
     161        packet::Gamestate *gs = gamestate->getGamestate();
    146162        //assert(gs); <--- there might be the case that no data has to be sent, so its commented out now
    147163        if(gs){
     
    157173
    158174    Connection::processQueue();
    159     if(gamestate.processGamestates())
     175    if(gamestate->processGamestates())
    160176    {
    161177      if(!isSynched_)
    162178        isSynched_=true;
    163179    }
    164     gamestate.cleanup();
     180    gamestate->cleanup();
    165181    Connection::sendPackets();
    166182
     
    184200  }
    185201
     202
     203
    186204}
  • code/trunk/src/libraries/network/Client.h

    r5961 r7163  
    4747
    4848#include "util/UtilPrereqs.h"
     49#include "util/Singleton.h"
    4950#include "ClientConnection.h"
    5051#include "GamestateClient.h"
    5152#include "Host.h"
     53#include "LANDiscovery.h"
     54#include "packet/ServerInformation.h"
    5255
     56// tolua_begin
    5357namespace orxonox
    5458{
     59// tolua_end
    5560  /**
    5661  Client *client;
     
    6065  *
    6166  */
    62   class _NetworkExport Client : public Host, public ClientConnection{
     67  class _NetworkExport Client // tolua_export
     68    : public Host, protected ClientConnection, public Singleton<Client>
     69  { // tolua_export
     70  friend class Singleton<Client>;
    6371  public:
    6472    Client();
    65     Client(const std::string& address, int port);
    6673    ~Client();
     74   
     75    static Client* getInstance(){ return singletonPtr_s; } // tolua_export
    6776
    6877    bool establishConnection();
     78    void setDestination( const std::string& serverAddress, unsigned int port ); // tolua_export
    6979    bool closeConnection();
    7080    bool queuePacket(ENetPacket *packet, int clientID);
     
    8191    virtual bool isServer_(){return false;}
    8292
    83     GamestateClient gamestate;
     93    static Client* singletonPtr_s;
     94    GamestateClient* gamestate;
    8495    bool isSynched_;
    8596
    8697    bool gameStateFailure_;
    8798    float timeSinceLastUpdate_;
    88   };
     99  }; // tolua_export
    89100
    90101
    91 }
     102} // tolua_export
    92103
    93104#endif /* _Client_H__ */
  • code/trunk/src/libraries/network/Connection.cc

    r6417 r7163  
    3636namespace orxonox
    3737{
    38   Connection *Connection::instance_=0;
     38//   Connection *Connection::instance_=0;
    3939
    4040  Connection::Connection():
    4141    host_(0)
    4242  {
    43     assert(instance_==0);
    44     Connection::instance_=this;
     43//     assert(instance_==0);
     44//     Connection::instance_=this;
    4545    enet_initialize();
    4646    atexit(enet_deinitialize);
     
    4848
    4949  Connection::~Connection(){
    50     Connection::instance_=0;
     50//     Connection::instance_=0;
    5151  }
    5252
     
    6767
    6868  bool Connection::sendPackets() {
    69     if ( !Connection::instance_ || this->host_==NULL )
     69    if ( /*!Connection::instance_ || */this->host_==NULL )
    7070      return false;
    7171    enet_host_flush(this->host_);
  • code/trunk/src/libraries/network/Connection.h

    r6417 r7163  
    6161  protected:
    6262    Connection();
    63     static Connection* getInstance(){ return Connection::instance_; }
     63//     static Connection* getInstance(){ return Connection::instance_; }
    6464
    6565    int service(ENetEvent* event);
     
    7575    ENetAddress *bindAddress_;
    7676
    77     static Connection *instance_;
     77//     static Connection *instance_;
    7878
    7979  };
  • code/trunk/src/libraries/network/GamestateClient.cc

    r6417 r7163  
    161161      assert(b);
    162162    }
    163     if(gs->isDiffed()){
    164       packet::Gamestate *base = gamestateMap_[gs->getBaseID()];
    165       if(!base){
    166         COUT(3) << "could not find base gamestate id: " << gs->getBaseID() << endl;
    167         delete gs;
    168         return 0;
    169       }
    170 //       assert(base); //TODO: fix this
    171       packet::Gamestate *undiffed = gs->undiff(base);
    172       delete gs;
    173       gs=undiffed;
    174       COUT(5) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;
     163    if(gs->isDiffed())
     164    {
     165      assert(0);
     166//       packet::Gamestate *base = gamestateMap_[gs->getBaseID()];
     167//       if(!base)
     168//       {
     169//         COUT(0) << "could not find base gamestate id: " << gs->getBaseID() << endl;
     170//         assert(0);
     171//         delete gs;
     172//         return 0;
     173//       }
     174//       packet::Gamestate *undiffed = gs->undiff(base);
     175//       delete gs;
     176//       gs=undiffed;
     177//       COUT(5) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;
    175178    }
    176179    if(gs->spreadData(0x2))
     
    178181    else
    179182    {
    180       COUT(3) << "could not spread gamestate" << endl;
     183      COUT(0) << "could not spread gamestate" << endl;
     184      assert(0);
    181185      return NULL;
    182186    }
  • code/trunk/src/libraries/network/GamestateManager.cc

    r6417 r7163  
    4343#include <cassert>
    4444#include <queue>
     45#include "util/Clock.h"
    4546// #include <boost/thread/mutex.hpp>
    4647
     
    158159
    159160      clientGamestates.push(0);
    160       finishGamestate( cid, &clientGamestates.back(), client, reference );
     161      finishGamestate( cid, clientGamestates.back(), client, reference );
    161162      //FunctorMember<GamestateManager>* functor =
    162163//       ExecutorMember<GamestateManager>* executor = createExecutor( createFunctor(&GamestateManager::finishGamestate, this) );
     
    180181
    181182
    182   void GamestateManager::finishGamestate( unsigned int clientID, packet::Gamestate** destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) {
     183  void GamestateManager::finishGamestate( unsigned int clientID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) {
    183184    //why are we searching the same client's gamestate id as we searched in
    184185    //Server::sendGameState?
     
    186187    //chose wheather the next gamestate is the first or not
    187188
    188     packet::Gamestate *gs = gamestate->doSelection(clientID, 20000);
    189 //     packet::Gamestate *gs = new packet::Gamestate(*gamestate);
     189//     packet::Gamestate *gs = gamestate->doSelection(clientID, 20000);
     190//       packet::Gamestate* gs = new packet::Gamestate(*gamestate);
     191//     packet::Gamestate* gs = gamestate;
     192    packet::Gamestate *gs = new packet::Gamestate(*gamestate); //TODO: is this neccessary ?
    190193//     packet::Gamestate *gs = new packet::Gamestate();
    191194//     gs->collectData( id_, 0x1 );
     
    193196    gamestateMap_[clientID][gamestate->getID()]=gs;
    194197//     this->threadMutex_->unlock();
     198      Clock clock;
     199      clock.capture();
    195200
    196201    if(base)
    197202    {
    198 
    199 //       COUT(3) << "diffing" << std::endl;
    200 //       packet::Gamestate* gs1  = gs;
    201       packet::Gamestate *diffed = gs->diff(base);
    202       //packet::Gamestate *gs2 = diffed->undiff(gs);
    203 //       assert(*gs == *gs2);
    204       gs = diffed;
    205 //       packet::Gamestate* gs2 = gs->undiff(client);
    206 //       gs = new packet::Gamestate(*gs);
    207 //       assert(*gs1==*gs2);
    208     }
    209     else{
     203      packet::Gamestate *diffed1 = gs->diffVariables(base);
     204      if( diffed1->getDataSize() == 0 )
     205      {
     206        delete diffed1;
     207        destgamestate = 0;
     208        return;
     209      }
     210      gs = diffed1;
     211    }
     212    else
     213    {
    210214      gs = new packet::Gamestate(*gs);
    211215    }
     
    214218    bool b = gs->compressData();
    215219    assert(b);
    216 //     COUT(4) << "sending gamestate with id " << gs->getID();
     220      clock.capture();
     221      COUT(0) << "diff time: " << clock.getDeltaTime() << endl;
     222//     COUT(5) << "sending gamestate with id " << gs->getID();
    217223//     if(gamestate->isDiffed())
    218 //     COUT(4) << " and baseid " << gs->getBaseID() << endl;
     224//       COUT(5) << " and baseid " << gs->getBaseID() << endl;
    219225//     else
    220 //     COUT(4) << endl;
     226//       COUT(5) << endl;
    221227    gs->setClientID(clientID);
    222     *destgamestate = gs;
     228    destgamestate = gs;
    223229  }
    224230
  • code/trunk/src/libraries/network/GamestateManager.h

    r5781 r7163  
    7676    void sendGamestates();
    7777//     packet::Gamestate *popGameState(unsigned int clientID);
    78     void finishGamestate( unsigned int clientID, packet::Gamestate** destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate );
     78    void finishGamestate( unsigned int clientID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate );
    7979
    8080    bool getSnapshot();
  • code/trunk/src/libraries/network/Host.cc

    r5961 r7163  
    3838namespace orxonox {
    3939
    40 SetConsoleCommandShortcut(Host, Chat);
     40  SetConsoleCommandShortcut(Host, Chat);
    4141
    42 Host *Host::instance_=0;
     42  // Host*               Host::instance_=0;
     43  uint32_t            Host::clientID_s=0;
     44  uint32_t            Host::shipID_s=-1;
     45  std::vector<Host*>  Host::instances_s;
    4346
    44 /**
    45  * @brief Constructor: assures that only one reference will be created and sets the pointer
    46  */
    47 Host::Host()
    48 {
    49   clientID_=0;
    50   assert(instance_==0);
    51   instance_=this;
    52   this->printRTTCC_ = createConsoleCommand( createFunctor(&Host::printRTT, this), "printRTT" );
    53   CommandExecutor::addConsoleCommandShortcut( this->printRTTCC_ );
    54 }
     47  /**
     48  * @brief Constructor: assures that only one reference will be created and sets the pointer
     49  */
     50  Host::Host()
     51  {
     52  //   assert(instance_==0);
     53    instances_s.push_back(this);
     54    this->printRTTCC_ = createConsoleCommand( createFunctor(&Host::printRTT, this), "printRTT" );
     55    CommandExecutor::addConsoleCommandShortcut( this->printRTTCC_ );
     56    this->bIsActive_ = false;
     57  }
    5558
    5659
    57 /**
    58  * @brief Destructor: resets the instance pointer to 0
    59  */
    60 Host::~Host()
    61 {
    62   instance_=0;
    63   if( this->printRTTCC_ )
    64     delete this->printRTTCC_;
    65 }
     60  /**
     61  * @brief Destructor: resets the instance pointer to 0
     62  */
     63  Host::~Host()
     64  {
     65    assert( std::find( instances_s.begin(), instances_s.end(), this )!=instances_s.end() );
     66    instances_s.erase(std::find( instances_s.begin(), instances_s.end(), this ));
     67    if( this->printRTTCC_ )
     68      delete this->printRTTCC_;
     69  }
    6670
    67 /**
    68  * This function is used to add an enetpacket to be sent to another peer
    69  * @param packet Packet to be added
    70  * @param clientID ID of the client the packet should be sent to
    71  * @return success?
    72  */
    73 bool Host::addPacket(ENetPacket *packet, int clientID){
    74   if(instance_)
    75     return instance_->queuePacket(packet, clientID);
    76   else
    77     return false;
    78 }
     71  /**
     72  * This function is used to add an enetpacket to be sent to another peer
     73  * @param packet Packet to be added
     74  * @param clientID ID of the client the packet should be sent to
     75  * @return success?
     76  */
     77  bool Host::addPacket(ENetPacket *packet, int clientID)
     78  {
     79    bool result = true;
     80    for( std::vector<Host*>::iterator it = instances_s.begin(); it!=instances_s.end(); ++it )
     81    {
     82      if( (*it)->isActive() )
     83      {
     84        if( !(*it)->queuePacket(packet, clientID) )
     85          result = false;
     86      }
     87    }
     88    return result;
     89  }
    7990
    80 /**
    81  * This function returns the ID of the player
    82  * @return playerID
    83  */
    84 unsigned int Host::getPlayerID(){
    85   if(!instance_)
    86     return 0;
    87   return instance_->clientID_;
    88 }
     91  bool Host::Chat(const std::string& message)
     92  {
     93    if(instances_s.size()==0)
     94    {
     95      for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
     96        it->incomingChat(message, 0);
     97      return true;
     98    }
     99    else
     100    {
     101      bool result = true;
     102      for( std::vector<Host*>::iterator it = instances_s.begin(); it!=instances_s.end(); ++it )
     103      {
     104        if( (*it)->isActive() )
     105        {
     106          if( !(*it)->chat(message) )
     107            result = false;
     108        }
     109      }
     110      return result;
     111    }
     112  }
    89113
    90 bool Host::Chat(const std::string& message){
    91   if(!instance_)
     114  bool Host::Broadcast(const std::string& message)
     115  {
     116    if(instances_s.size()==0)
     117    {
     118      for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
     119        it->incomingChat(message, CLIENTID_UNKNOWN);
     120      return true;
     121    }
     122    else
     123    {
     124      bool result = true;
     125      for( std::vector<Host*>::iterator it = instances_s.begin(); it!=instances_s.end(); ++it )
     126      {
     127        if( (*it)->isActive() )
     128        {
     129          if( !(*it)->broadcast(message) )
     130            result = false;
     131        }
     132      }
     133      return result;
     134    }
     135  }
     136
     137  bool Host::incomingChat(const std::string& message, unsigned int playerID)
    92138  {
    93139    for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
    94       it->incomingChat(message, 0);
    95     return true;
     140      it->incomingChat(message, playerID);
     141   
     142    bool result = true;
     143    for( std::vector<Host*>::iterator it = instances_s.begin(); it!=instances_s.end(); ++it )
     144    {
     145      if( (*it)->isActive() )
     146      {
     147        if( !(*it)->processChat(message, playerID) )
     148          result = false;
     149      }
     150    }
     151    return result;
    96152  }
    97   return instance_->chat(message);
    98 }
    99153
    100 bool Host::Broadcast(const std::string& message){
    101   if(!instance_)
     154  bool Host::isServer()
    102155  {
    103     for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
    104       it->incomingChat(message, CLIENTID_UNKNOWN);
    105     return true;
     156    for (std::vector<Host*>::iterator it=instances_s.begin(); it!=instances_s.end(); ++it )
     157    {
     158      if( (*it)->isServer_() )
     159        return true;
     160    }
     161    return false;
    106162  }
    107   else
    108     return instance_->broadcast(message);
    109 }
    110 
    111 bool Host::incomingChat(const std::string& message, unsigned int playerID){
    112   for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
    113     it->incomingChat(message, playerID);
    114 
    115   return instance_->processChat(message, playerID);
    116 }
    117163
    118164}//namespace orxonox
  • code/trunk/src/libraries/network/Host.h

    r6073 r7163  
    3333#include "core/CorePrereqs.h"
    3434
     35#include <vector>
     36
    3537namespace orxonox {
    3638
    3739  const unsigned int CLIENTID_SERVER = 0;
    38   const unsigned int NETWORK_FREQUENCY = 30;
     40  const unsigned int NETWORK_FREQUENCY = 25;
    3941  const float NETWORK_PERIOD = 1.0f/NETWORK_FREQUENCY;
    4042
     
    4951class _NetworkExport Host{
    5052  private:
    51     //TODO add theese functions or adequate
     53    //TODO add these functions or adequate
    5254    //virtual bool processChat(packet::Chat *message, unsigned int clientID)=0;
    5355    //virtual bool sendChat(packet::Chat *chat)=0;
     
    6365    Host();
    6466    virtual ~Host();
    65     static Host *instance_;
    66     unsigned int clientID_;
    67     unsigned int shipID_;
     67    void setActive( bool bActive ){ bIsActive_ = bActive; }
     68//     static Host *instance_;
    6869
    6970  public:
    70     static bool running(){return instance_!=0;}
     71//     static Host* getInstance(){ return instance_; }
     72    static bool running(){ return instances_s.size(); }
    7173    static bool addPacket(ENetPacket *packet, int clientID=0);
    7274    //static bool chat(std::string& message);
    7375//     static bool receiveChat(packet::Chat *message, unsigned int clientID);
    74     static unsigned int getPlayerID();
    75     static unsigned int getShipID(){return instance_->shipID_;}
    76     static void setClientID(unsigned int id){ instance_->clientID_ = id; }
    77     static void setShipID(unsigned int id){ instance_->shipID_ = id; }
    78     static bool isServer(){ return instance_->isServer_(); }
     76    static unsigned int getPlayerID(){ return clientID_s; }
     77    static unsigned int getShipID(){return shipID_s;}
     78    static void setClientID(unsigned int id){ clientID_s = id; }
     79    static void setShipID(unsigned int id){ shipID_s = id; }
     80    static bool isServer();
    7981    static bool Chat(const std::string& message);
    8082    static bool Broadcast(const std::string& message);
    8183    static bool incomingChat(const std::string& message, unsigned int playerID);
    8284    virtual void printRTT()=0;
     85    bool isActive(){ return bIsActive_; }
    8386  private:
    8487    ConsoleCommand* printRTTCC_;
     88    static uint32_t clientID_s;
     89    static uint32_t shipID_s;
     90    static std::vector<Host*> instances_s;
     91    bool bIsActive_;
    8592};
    8693
  • code/trunk/src/libraries/network/NetworkPrereqs.h

    r6417 r7163  
    6464namespace orxonox
    6565{
    66   static const unsigned int GAMESTATEID_INITIAL = static_cast<unsigned int>(-1);
    67   static const unsigned int CLIENTID_UNKNOWN    = static_cast<unsigned int>(-2);
     66  static const unsigned int GAMESTATEID_INITIAL     = static_cast<unsigned int>(-1);
     67  static const unsigned int CLIENTID_UNKNOWN        = static_cast<unsigned int>(-2);
     68  extern const char* LAN_DISCOVERY_MESSAGE;
     69  extern const char* LAN_DISCOVERY_ACK;
     70  static const unsigned int LAN_DISCOVERY_PORT      = 55557;
    6871}
    6972
  • code/trunk/src/libraries/network/Server.cc

    r6417 r7163  
    6969  *
    7070  */
    71   Server::Server() {
     71  Server::Server()
     72  {
    7273    this->timeSinceLastUpdate_=0;
    7374  }
    7475
    75   Server::Server(int port){
     76  Server::Server(int port)
     77  {
    7678    this->setPort( port );
    7779    this->timeSinceLastUpdate_=0;
     
    8385  * @param bindAddress Address to listen on
    8486  */
    85   Server::Server(int port, const std::string& bindAddress) {
     87  Server::Server(int port, const std::string& bindAddress)
     88  {
    8689    this->setPort( port );
    8790    this->setBindAddress( bindAddress );
     
    9295  * @brief Destructor
    9396  */
    94   Server::~Server(){
     97  Server::~Server()
     98  {
    9599  }
    96100
     
    98102  * This function opens the server by creating the listener thread
    99103  */
    100   void Server::open() {
     104  void Server::open()
     105  {
     106    Host::setActive(true);
    101107    COUT(4) << "opening server" << endl;
    102108    this->openListener();
     109    LANDiscoverable::setActivity(true);
    103110    return;
    104111  }
     
    107114  * This function closes the server
    108115  */
    109   void Server::close() {
     116  void Server::close()
     117  {
     118    Host::setActive(false);
    110119    COUT(4) << "closing server" << endl;
    111120    this->disconnectClients();
    112121    this->closeListener();
     122    LANDiscoverable::setActivity(false);
    113123    return;
    114124  }
    115125
    116   bool Server::processChat(const std::string& message, unsigned int playerID){
     126  bool Server::processChat(const std::string& message, unsigned int playerID)
     127  {
    117128    ClientInformation *temp = ClientInformation::getBegin();
    118129    packet::Chat *chat;
     
    134145  * @param time time since last tick
    135146  */
    136   void Server::update(const Clock& time) {
     147  void Server::update(const Clock& time)
     148  {
    137149    // receive incoming packets
    138150    Connection::processQueue();
     151    // receive and process incoming discovery packets
     152    LANDiscoverable::update();
    139153
    140154    if ( ClientInformation::hasClients() )
     
    157171  }
    158172
    159   bool Server::queuePacket(ENetPacket *packet, int clientID){
     173  bool Server::queuePacket(ENetPacket *packet, int clientID)
     174  {
    160175    return ServerConnection::addPacket(packet, clientID);
    161176  }
     
    164179   * @brief: returns ping time to client in milliseconds
    165180   */
    166   unsigned int Server::getRTT(unsigned int clientID){
     181  unsigned int Server::getRTT(unsigned int clientID)
     182  {
    167183    assert(ClientInformation::findClient(clientID));
    168184    return ClientInformation::findClient(clientID)->getRTT();
     
    178194   * @brief: return packet loss ratio to client (scales from 0 to 1)
    179195   */
    180   double Server::getPacketLoss(unsigned int clientID){
     196  double Server::getPacketLoss(unsigned int clientID)
     197  {
    181198    assert(ClientInformation::findClient(clientID));
    182199    return ClientInformation::findClient(clientID)->getPacketLoss();
     
    186203  * takes a new snapshot of the gamestate and sends it to the clients
    187204  */
    188   void Server::updateGamestate() {
     205  void Server::updateGamestate()
     206  {
    189207    if( ClientInformation::getBegin()==NULL )
    190208      //no client connected
     
    208226  * sends the gamestate
    209227  */
    210   bool Server::sendGameState() {
     228  bool Server::sendGameState()
     229  {
    211230//     COUT(5) << "Server: starting function sendGameState" << std::endl;
    212231//     ClientInformation *temp = ClientInformation::getBegin();
     
    244263  }
    245264
    246   bool Server::sendObjectDeletes(){
     265  bool Server::sendObjectDeletes()
     266  {
    247267    ClientInformation *temp = ClientInformation::getBegin();
    248268    if( temp == NULL )
     
    257277//     COUT(3) << "sending DeleteObjects" << std::endl;
    258278    while(temp != NULL){
    259       if( !(temp->getSynched()) ){
     279      if( !(temp->getSynched()) )
     280      {
    260281        COUT(5) << "Server: not sending gamestate" << std::endl;
    261282        temp=temp->next();
     
    276297
    277298
    278   void Server::addPeer(ENetEvent *event){
     299  void Server::addPeer(ENetEvent *event)
     300  {
    279301    static unsigned int newid=1;
    280302
    281303    COUT(2) << "Server: adding client" << std::endl;
    282304    ClientInformation *temp = ClientInformation::insertBack(new ClientInformation);
    283     if(!temp){
     305    if(!temp)
     306    {
    284307      COUT(2) << "Server: could not add client" << std::endl;
    285308    }
     
    310333  }
    311334
    312   bool Server::createClient(int clientID){
     335  bool Server::createClient(int clientID)
     336  {
    313337    ClientInformation *temp = ClientInformation::findClient(clientID);
    314     if(!temp){
     338    if(!temp)
     339    {
    315340      COUT(2) << "Conn.Man. could not create client with id: " << clientID << std::endl;
    316341      return false;
     
    345370  }
    346371
    347   void Server::disconnectClient( ClientInformation *client ){
     372  void Server::disconnectClient( ClientInformation *client )
     373  {
    348374    ServerConnection::disconnectClient( client );
    349375    GamestateManager::removeClient(client);
     
    352378  }
    353379
    354   bool Server::chat(const std::string& message){
     380  bool Server::chat(const std::string& message)
     381  {
    355382      return this->sendChat(message, Host::getPlayerID());
    356383  }
    357384
    358   bool Server::broadcast(const std::string& message){
     385  bool Server::broadcast(const std::string& message)
     386  {
    359387      return this->sendChat(message, CLIENTID_UNKNOWN);
    360388  }
    361389
    362   bool Server::sendChat(const std::string& message, unsigned int clientID){
     390  bool Server::sendChat(const std::string& message, unsigned int clientID)
     391  {
    363392    ClientInformation *temp = ClientInformation::getBegin();
    364393    packet::Chat *chat;
    365     while(temp){
     394    while(temp)
     395    {
    366396      chat = new packet::Chat(message, clientID);
    367397      chat->setClientID(temp->getID());
     
    377407  }
    378408
    379   void Server::syncClassid(unsigned int clientID) {
     409  void Server::syncClassid(unsigned int clientID)
     410  {
    380411    int failures=0;
    381412    packet::ClassID *classid = new packet::ClassID();
  • code/trunk/src/libraries/network/Server.h

    r6417 r7163  
    3737#include "GamestateManager.h"
    3838#include "ServerConnection.h"
     39#include "LANDiscoverable.h"
    3940
    4041namespace orxonox
     
    4546  * It implements all functions necessary for a Server
    4647  */
    47   class _NetworkExport Server : public Host, public ServerConnection, public GamestateManager{
     48  class _NetworkExport Server : public Host, public ServerConnection, public GamestateManager, public LANDiscoverable{
    4849  public:
    4950    Server();
  • code/trunk/src/libraries/network/ServerConnection.cc

    r6417 r7163  
    9494
    9595  bool ServerConnection::addPacketAll(ENetPacket *packet) {
    96     if ( !Connection::getInstance() )
    97       return false;
    98     enet_host_broadcast( Connection::getInstance()->getHost(), 0, packet);
     96//     if ( !Connection::getInstance() )
     97//       return false;
     98    enet_host_broadcast( Connection::getHost(), 0, packet);
    9999    return true;
    100100  }
  • code/trunk/src/libraries/network/ServerConnection.h

    r6417 r7163  
    5656    bool openListener();
    5757    bool closeListener();
    58     static bool addPacket(ENetPacket *packet, unsigned int ID);
    59     static bool addPacketAll(ENetPacket *packet);
     58    bool addPacket(ENetPacket *packet, unsigned int ID);
     59    bool addPacketAll(ENetPacket *packet);
    6060    virtual void disconnectClient(ClientInformation *client);
    6161    void disconnectClient(int clientID);
  • code/trunk/src/libraries/network/packet/CMakeLists.txt

    r5929 r7163  
    1111  Welcome.cc
    1212COMPILATION_END
     13  ServerInformation.cc
    1314)
    1415
     
    2324  Gamestate.h
    2425  Packet.h
     26  ServerInformation.h
    2527  Welcome.h
    2628)
  • code/trunk/src/libraries/network/packet/Chat.cc

    r6417 r7163  
    3737
    3838#define   PACKET_FLAGS_CHAT PacketFlag::Reliable
     39
     40/* Some lengths */
    3941#define   _PACKETID         0
    4042const int _PLAYERID     =   _PACKETID + sizeof(Type::Value);
     
    4547 : Packet()
    4648{
     49  /* Add chat flag to packet flags */
    4750  flags_ = flags_ | PACKET_FLAGS_CHAT;
     51
     52  /* set message length to length of input string + 1 */
    4853  messageLength_ = message.length()+1;
     54
     55  /* allocate memory for the data */
    4956  data_=new unsigned char[ getSize() ];
     57
    5058  *(Type::Value *)(data_ + _PACKETID ) = Type::Chat;
    5159  *(unsigned int *)(data_ + _PLAYERID ) = playerID;
    5260  *(unsigned int *)(data_ + _MESSAGELENGTH ) = messageLength_;
     61
     62  /* cast the hell out of the message string, and copy it into the
     63   * data buffer.
     64   */
    5365  memcpy( data_+_MESSAGE, static_cast<void*>(const_cast<char*>(message.c_str())), messageLength_ );
    5466}
  • code/trunk/src/libraries/network/packet/Chat.h

    r6073 r7163  
    4141{
    4242public:
     43  /* constructors */
    4344  Chat( const std::string& message, unsigned int playerID );
    4445  Chat( uint8_t* data, unsigned int clientID );
     46
     47  /* destructor */
    4548  ~Chat();
    4649
     50  /* get size of packet */
    4751  inline unsigned int getSize() const;
     52
     53  /* process chat message packet and remove it afterwards */
    4854  bool process();
    4955
     56  /* Get the length of the message (not the full size of the packet) */
    5057  unsigned int getMessageLength(){ return messageLength_; };
     58
     59  /* return message content */
    5160  unsigned char *getMessage();
     61
    5262private:
     63
     64  /* Message length */
    5365  uint32_t messageLength_;
     66
     67  /* Client ID (an integral value for identification) */
    5468  unsigned int clientID_;
    5569};
  • code/trunk/src/libraries/network/packet/ClassID.cc

    r6417 r7163  
    6565    tempQueue.push( std::pair<unsigned int, std::string>(network_id, classname) );
    6666    ++nrOfClasses;
    67     packetSize += (classname.size()+1)+sizeof(uint32_t)+sizeof(uint32_t);
     67    packetSize += (classname.size()+1)+sizeof(network_id)+sizeof(uint32_t);
    6868  }
    6969
     
    8080  // now save all classids and classnames
    8181  std::pair<uint32_t, std::string> tempPair;
     82  uint32_t tempsize = 2*sizeof(uint32_t); // packetid and nrOfClasses
    8283  while( !tempQueue.empty() ){
    8384    tempPair = tempQueue.front();
     
    8788    memcpy(temp+2*sizeof(uint32_t), tempPair.second.c_str(), tempPair.second.size()+1);
    8889    temp+=2*sizeof(uint32_t)+tempPair.second.size()+1;
     90    tempsize+=2*sizeof(uint32_t)+tempPair.second.size()+1;
    8991  }
     92  assert(tempsize==packetSize);
    9093
    9194  COUT(5) << "classid packetSize is " << packetSize << endl;
     
    111114  for(unsigned int i=0; i<nrOfClasses; i++){
    112115    totalsize += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t));
     116    temp += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t));
    113117  }
    114118  return totalsize;
     
    141145    COUT(3) << "processing classid: " << networkID << " name: " << classname << " id: " << id << std::endl;
    142146    if(id==NULL){
    143       COUT(0) << "Recieved a bad classname" << endl;
     147      COUT(0) << "Received a bad classname" << endl;
    144148      abort();
    145149    }
  • code/trunk/src/libraries/network/packet/Gamestate.cc

    r6417 r7163  
    4545#define PACKET_FLAG_GAMESTATE  PacketFlag::Reliable
    4646
    47 
    48 Gamestate::Gamestate()
     47inline bool memzero( uint8_t* data, uint32_t datalength)
     48{
     49  uint64_t* d = (uint64_t*)data;
     50
     51  for( unsigned int i=0; i<datalength/8; i++ )
     52  {
     53    if( *(d+i) != 0 )
     54      return false;
     55  }
     56  // now process the rest (when datalength isn't a multiple of 4)
     57  for( unsigned int j = 8*(datalength/8); j<datalength; j++ )
     58  {
     59    if( *(data+j) != 0 )
     60      return false;
     61  }
     62  return true;
     63}
     64
     65
     66Gamestate::Gamestate():
     67  header_(0)
    4968{
    5069  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
    51   header_ = 0;
    52 }
     70}
     71
    5372
    5473Gamestate::Gamestate(uint8_t *data, unsigned int clientID):
    55     Packet(data, clientID)
     74  Packet(data, clientID)
    5675{
    5776  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
     
    5978}
    6079
     80
    6181Gamestate::Gamestate(uint8_t *data)
    6282{
    6383  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
    64   data_=data;
     84  data_ = data;
    6585  header_ = new GamestateHeader(data_);
    6686}
    6787
     88
    6889Gamestate::Gamestate(const Gamestate& g) :
    69     Packet( *(Packet*)&g )
     90    Packet( *(Packet*)&g ), nrOfVariables_(0)
    7091{
    7192  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
    7293  header_ = new GamestateHeader(data_);
     94  sizes_ = g.sizes_;
    7395}
    7496
     
    79101    delete header_;
    80102}
     103
    81104
    82105bool Gamestate::collectData(int id, uint8_t mode)
     
    91114    return false;
    92115  data_ = new uint8_t[size + GamestateHeader::getSize()];
    93   if(!data_){
     116  if(!data_)
     117  {
    94118    COUT(2) << "GameStateManager: could not allocate memory" << std::endl;
    95119    return false;
     
    101125
    102126  //start collect data synchronisable by synchronisable
    103   uint8_t *mem=data_;
     127  uint8_t *mem = data_; // in this stream store all data of the variables and the headers of the synchronisable
    104128  mem += GamestateHeader::getSize();
    105129  ObjectList<Synchronisable>::iterator it;
    106   for(it = ObjectList<Synchronisable>::begin(); it; ++it){
     130  for(it = ObjectList<Synchronisable>::begin(); it; ++it)
     131  {
    107132
    108133//     tempsize=it->getSize(id, mode);
    109134
    110     tempsize = it->getData(mem, id, mode);
     135    tempsize = it->getData(mem, this->sizes_, id, mode);
    111136    if ( tempsize != 0 )
    112137      dataVector_.push_back( obj(it->getObjectID(), it->getCreatorID(), tempsize, mem-data_) );
    113138
    114139#ifndef NDEBUG
    115     if(currentsize+tempsize > size){
     140    if(currentsize+tempsize > size)
     141    {
    116142      assert(0); // if we don't use multithreading this part shouldn't be neccessary
    117143      // start allocate additional memory
     
    148174}
    149175
     176
    150177bool Gamestate::spreadData(uint8_t mode)
    151178{
     
    153180  assert(data_);
    154181  assert(!header_->isCompressed());
    155   assert(!header_->isDiffed());
    156182  uint8_t *mem=data_+GamestateHeader::getSize();
    157183  Synchronisable *s;
    158184
    159185  // update the data of the objects we received
    160   while(mem < data_+GamestateHeader::getSize()+header_->getDataSize()){
     186  while(mem < data_+GamestateHeader::getSize()+header_->getDataSize())
     187  {
    161188    SynchronisableHeader objectheader(mem);
    162189
     
    170197      else
    171198      {
    172         mem += objectheader.getDataSize();
     199        mem += objectheader.getDataSize() + ( objectheader.isDiffed() ? SynchronisableHeaderLight::getSize() : SynchronisableHeader::getSize() );
    173200      }
    174201    }
     
    181208   // In debug mode, check first, whether there are no duplicate objectIDs
    182209#ifndef NDEBUG
    183   if(this->getID()%1000==0){
     210  if(this->getID()%1000==1)
     211  {
    184212    std::list<uint32_t> v1;
    185213    ObjectList<Synchronisable>::iterator it;
    186     for (it = ObjectList<Synchronisable>::begin(); it != ObjectList<Synchronisable>::end(); ++it) {
    187       if (it->getObjectID() == OBJECTID_UNKNOWN) {
    188         if (it->objectMode_ != 0x0) {
     214    for (it = ObjectList<Synchronisable>::begin(); it != ObjectList<Synchronisable>::end(); ++it)
     215    {
     216      if (it->getObjectID() == OBJECTID_UNKNOWN)
     217      {
     218        if (it->objectMode_ != 0x0)
     219        {
    189220          COUT(0) << "Found object with OBJECTID_UNKNOWN on the client with objectMode != 0x0!" << std::endl;
    190221          COUT(0) << "Possible reason for this error: Client created a synchronized object without the Server's approval." << std::endl;
     
    193224        }
    194225      }
    195       else {
     226      else
     227      {
    196228        std::list<uint32_t>::iterator it2;
    197         for (it2 = v1.begin(); it2 != v1.end(); ++it2) {
    198           if (it->getObjectID() == *it2) {
     229        for (it2 = v1.begin(); it2 != v1.end(); ++it2)
     230        {
     231          if (it->getObjectID() == *it2)
     232          {
    199233            COUT(0) << "Found duplicate objectIDs on the client!" << std::endl
    200234                    << "Are you sure you don't create a Sychnronisable objcect with 'new' \
     
    211245}
    212246
     247
    213248uint32_t Gamestate::getSize() const
    214249{
     
    222257}
    223258
    224 bool Gamestate::operator==(packet::Gamestate gs){
     259
     260bool Gamestate::operator==(packet::Gamestate gs)
     261{
    225262  uint8_t *d1 = data_+GamestateHeader::getSize();
    226263  uint8_t *d2 = gs.data_+GamestateHeader::getSize();
     
    233270}
    234271
     272
    235273bool Gamestate::process()
    236274{
    237275  return GamestateHandler::addGamestate(this, getClientID());
    238276}
    239 
    240277
    241278
     
    253290  int retval;
    254291  retval = compress( dest, &buffer, source, (uLong)(header_->getDataSize()) );
    255   switch ( retval ) {
     292  switch ( retval )
     293  {
    256294    case Z_OK: COUT(5) << "G.St.Man: compress: successfully compressed" << std::endl; break;
    257295    case Z_MEM_ERROR: COUT(1) << "G.St.Man: compress: not enough memory available in gamestate.compress" << std::endl; return false;
     
    270308  header_->setCompSize( buffer );
    271309  header_->setCompressed( true );
    272   COUT(5) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl;
     310  COUT(0) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl;
    273311  return true;
    274312}
     313
     314
    275315bool Gamestate::decompressData()
    276316{
     
    289329  uLongf length=bufsize;
    290330  retval = uncompress( dest, &length, source, (uLong)compsize );
    291   switch ( retval ) {
     331  switch ( retval )
     332  {
    292333    case Z_OK: COUT(5) << "successfully decompressed" << std::endl; break;
    293334    case Z_MEM_ERROR: COUT(1) << "not enough memory available" << std::endl; return false;
     
    301342  delete temp;
    302343
    303   if (this->bDataENetAllocated_){
     344  if (this->bDataENetAllocated_)
     345  {
    304346    // Memory was allocated by ENet. --> We let it be since enet_packet_destroy will
    305347    // deallocated it anyway. So data and packet stay together.
    306348    this->bDataENetAllocated_ = false;
    307349  }
    308   else{
     350  else
     351  {
    309352    // We allocated the memory in the first place (unlikely). So we destroy the old data
    310353    // and overwrite it with the new decompressed data.
     
    320363}
    321364
    322 /*Gamestate *Gamestate::diff(Gamestate *base)
    323 {
    324   assert(data_);
    325   assert(!header_->isCompressed());
     365
     366Gamestate* Gamestate::diffVariables(Gamestate *base)
     367{
     368  assert(this && base); assert(data_ && base->data_);
     369  assert(!header_->isCompressed() && !base->header_->isCompressed());
    326370  assert(!header_->isDiffed());
    327   GamestateHeader diffHeader(base->data_);
    328   uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_);
    329   uint32_t of=0; // pointers offset
    330   uint32_t dest_length=0;
    331   dest_length=header_->getDataSize();
    332   if(dest_length==0)
    333     return NULL;
    334   uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
    335   uint8_t *dest = ndata + GamestateHeader::getSize();
    336   while(of < diffHeader.getDataSize() && of < header_->getDataSize()){
    337     *(dest+of)=*(basep+of)^*(gs+of); // do the xor
    338     ++of;
    339   }
    340   if(diffHeader.getDataSize()!=header_->getDataSize()){
    341     uint8_t n=0;
    342     if(diffHeader.getDataSize() < header_->getDataSize()){
    343       while(of<dest_length){
    344         *(dest+of)=n^*(gs+of);
    345         of++;
    346       }
    347     }
    348   }
    349 
    350   Gamestate *g = new Gamestate(ndata, getClientID());
     371
     372
     373  // *** first do a raw diff of the two gamestates
     374
     375  uint8_t *baseData = GAMESTATE_START(base->data_);
     376  uint8_t *origData = GAMESTATE_START(this->data_);
     377  uint32_t origLength = header_->getDataSize();
     378  uint32_t baseLength = base->header_->getDataSize();
     379
     380  assert( origLength && baseLength );
     381
     382  uint8_t *nData = new uint8_t[origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_]; // this is the maximum size needed in the worst case
     383  uint8_t *dest = GAMESTATE_START(nData);
     384
     385  uint32_t baseOffset = 0; //offset in the diffed stream
     386  uint32_t origOffset = 0; //offset in the new stream with removed 0's
     387  std::vector<uint32_t>::iterator sizes = this->sizes_.begin();
     388
     389  while( origOffset < origLength )
     390  {
     391    //iterate through all objects
     392
     393    SynchronisableHeader h(origData+origOffset);
     394
     395    // Find (if possible) the current object in the datastream of the old gamestate
     396    // Start at the current offset position
     397    if(baseOffset >= baseLength)
     398      baseOffset = 0;
     399    uint8_t* temp = baseData + baseOffset;
     400    uint32_t objectID = h.getObjectID();
     401    assert(temp < baseData+baseLength);
     402    assert(dest < nData + origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_);
     403    assert(sizes != this->sizes_.end());
     404    while ( temp < baseData+baseLength )
     405    {
     406      SynchronisableHeader htemp(temp);
     407      assert( htemp.getDataSize()!=0 );
     408      if ( htemp.getObjectID() == objectID )
     409      {
     410        assert( h.getClassID() == htemp.getClassID() );
     411        goto DODIFF;
     412      }
     413//       {
     414//         SynchronisableHeader htemp2(temp+htemp.getDataSize()+SynchronisableHeader::getSize());
     415//         if( temp+htemp.getDataSize()+SynchronisableHeader::getSize() < baseData+baseLength )
     416//         {
     417//           assert(htemp2.getClassID()<500);
     418//           assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
     419//           assert(htemp2.isDiffed()==false);
     420//         }
     421//       }
     422      temp += htemp.getDataSize()+SynchronisableHeader::getSize();
     423       
     424    }
     425    // If not found start looking at the beginning
     426    assert( temp==baseData+baseLength );
     427    temp = baseData;
     428//     {
     429//       SynchronisableHeader htemp2(temp);
     430//       if( temp < baseData+baseLength )
     431//       {
     432//         assert(htemp2.getClassID()<500);
     433//         assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
     434//         assert(htemp2.isDiffed()==false);
     435//       }
     436//     }
     437    while ( temp < baseData+baseOffset )
     438    {
     439      SynchronisableHeader htemp(temp);
     440      if ( htemp.getObjectID() == objectID )
     441      {
     442        assert( h.getClassID() == htemp.getClassID() );
     443        goto DODIFF;
     444      }
     445//       {
     446//         SynchronisableHeader htemp2(temp+htemp.getDataSize()+SynchronisableHeader::getSize());
     447//         if( temp+htemp.getDataSize()+SynchronisableHeader::getSize() < baseData+baseLength )
     448//         {
     449//           assert(htemp2.getClassID()<500);
     450//           assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
     451//           assert(htemp2.isDiffed()==false);
     452//         }
     453//       }
     454      temp += htemp.getDataSize()+SynchronisableHeader::getSize();
     455    }
     456    // Object is new, thus never transmitted -> just copy over
     457    goto DOCOPY;
     458
     459
     460DODIFF:
     461    {
     462//       COUT(4) << "dodiff" << endl;
     463//       if(baseOffset==0)
     464//       {
     465//         assert(origOffset==0);
     466//       }
     467      uint32_t objectOffset = SynchronisableHeader::getSize(); // offset inside the object in the origData and baseData
     468      // Check whether the whole object stayed the same
     469      if( memcmp( origData+origOffset+objectOffset, temp+objectOffset, h.getDataSize()) == 0 )
     470      {
     471//         COUT(4) << "skip object" << Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() << endl;
     472        origOffset += objectOffset+ h.getDataSize(); // skip the whole object
     473        baseOffset = temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData;
     474        sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables();
     475      }
     476      else
     477      {
     478//         if( Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() == "Bot" )
     479//           COUT(0) << "blub" << endl;
     480//         COUT(4) << "object diff: " << Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() << endl;
     481//         COUT(4) << "diff " << h.getObjectID() << ":";
     482        // Now start to diff the Object
     483        SynchronisableHeaderLight h2(dest);
     484        h2 = h; // copy over the objectheader
     485        VariableID variableID = 0;
     486        uint32_t newObjectOffset = SynchronisableHeaderLight::getSize();
     487        // iterate through all variables
     488        while( objectOffset < h.getDataSize()+SynchronisableHeader::getSize() )
     489        {
     490          // check whether variable changed and write id and copy over variable to the new stream
     491          // otherwise skip variable
     492          assert(sizes != this->sizes_.end());
     493          uint32_t varSize = *sizes;
     494          assert( varSize == Synchronisable::getSynchronisable(h.getObjectID())->getVarSize(variableID) );
     495          if ( varSize != 0 )
     496          {
     497            if ( memcmp(origData+origOffset+objectOffset, temp+objectOffset, varSize) != 0 )
     498            {
     499//               COUT(4) << "copy variable" << endl;
     500              *(VariableID*)(dest+newObjectOffset) = variableID; // copy over the variableID
     501              newObjectOffset += sizeof(VariableID);
     502              memcpy( dest+newObjectOffset, origData+origOffset+objectOffset, varSize );
     503              newObjectOffset += varSize;
     504              objectOffset += varSize;
     505            }
     506            else
     507            {
     508//               COUT(4) << "skip variable" << endl;
     509              objectOffset += varSize;
     510            }
     511          }
     512//           else
     513//             COUT(4) << "varsize 0" << endl;
     514
     515          ++variableID;
     516          ++sizes;
     517        }
     518       
     519        if( Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() != variableID )
     520          sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() - variableID;
     521//         COUT(4) << endl;
     522        h2.setDiffed(true);
     523        h2.setDataSize(newObjectOffset-SynchronisableHeaderLight::getSize());
     524        assert(objectOffset == h.getDataSize()+SynchronisableHeader::getSize());
     525        origOffset += objectOffset;
     526//         baseOffset += temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData;
     527        //baseOffset += objectOffset;
     528//         SynchronisableHeader htemp(temp);
     529//         baseOffset += SynchronisableHeader::getSize() + htemp.getDataSize();
     530//         {
     531//           SynchronisableHeader htemp2( baseData+(temp-baseData+objectOffset) );
     532//           if( baseData+(temp-baseData+objectOffset) < baseData+baseLength )
     533//           {
     534//             assert(htemp2.getClassID()<500);
     535//             assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
     536//             assert(htemp2.isDiffed()==false);
     537//           }
     538//         }
     539        baseOffset = temp-baseData + objectOffset;
     540        dest += newObjectOffset;
     541      }
     542
     543      continue;
     544    }
     545
     546DOCOPY:
     547    {
     548//       COUT(4) << "docopy" << endl;
     549      // Just copy over the whole Object
     550      memcpy( dest, origData+origOffset, h.getDataSize()+SynchronisableHeader::getSize() );
     551      dest += h.getDataSize()+SynchronisableHeader::getSize();
     552      origOffset += h.getDataSize()+SynchronisableHeader::getSize();
     553      assert( Synchronisable::getSynchronisable(h.getObjectID()) );
     554//       COUT(4) << "copy " << h.getObjectID() << endl;
     555//       COUT(4) << "copy " << h.getObjectID() << ":";
     556      //sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables();
     557      for( unsigned int i = 0; i < Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables(); ++i )
     558      {
     559//         COUT(4) << " " << *sizes;
     560        ++sizes;
     561      }
     562//       COUT(4) << endl;
     563      assert(sizes != this->sizes_.end() || origOffset>=origLength);
     564      continue;
     565    }
     566  }
     567
     568
     569  Gamestate *g = new Gamestate(nData, getClientID());
     570  assert(g->header_);
    351571  *(g->header_) = *header_;
    352   g->header_->setDiffed( true );
    353572  g->header_->setBaseID( base->getID() );
     573  g->header_->setDataSize(dest - nData - GamestateHeader::getSize());
    354574  g->flags_=flags_;
    355575  g->packetDirection_ = packetDirection_;
     576  assert(!g->isCompressed());
    356577  return g;
    357 }*/
    358 
    359 Gamestate *Gamestate::diff(Gamestate *base)
     578}
     579
     580
     581Gamestate* Gamestate::diffData(Gamestate *base)
    360582{
    361583  assert(this && base); assert(data_ && base->data_);
     
    393615}
    394616
    395 Gamestate *Gamestate::undiff(Gamestate *base)
     617
     618Gamestate* Gamestate::undiff(Gamestate *base)
    396619{
    397620  assert(this && base); assert(data_ && base->data_);
     
    423646
    424647
    425 // Gamestate *Gamestate::diff(Gamestate *base)
    426 // {
    427 //   assert(data_);
    428 //   assert(!header_->isCompressed());
    429 //   assert(!header_->isDiffed());
    430 //   GamestateHeader diffHeader(base->data_);
    431 //   uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_);
    432 //   uint32_t of=0; // pointers offset
    433 //   uint32_t dest_length=0;
    434 //   dest_length=header_->getDataSize();
    435 //   if(dest_length==0)
    436 //     return NULL;
    437 //   uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
    438 //   uint8_t *dest = ndata + GamestateHeader::getSize();
    439 //
    440 //
    441 //   // LOOP-UNROLLED DIFFING
    442 //   uint32_t *dest32 = (uint32_t*)dest, *base32 = (uint32_t*)basep, *gs32 = (uint32_t*)gs;
    443 //   // diff in 4-byte steps
    444 //   while( of < (uint32_t)(header_->getDataSize())/4 ){
    445 //     if( of < (uint32_t)(diffHeader.getDataSize())/4 )
    446 //     {
    447 //       *(dest32+of)=*(base32+of) ^ *(gs32+of); // do the xor
    448 //       ++of;
    449 //     }
    450 //     else
    451 //     {
    452 //       *(dest32+of)=*(gs32+of); // same as 0 ^ *(gs32+of)
    453 //       ++of;
    454 //     }
    455 //   }
    456 //   for( unsigned int of2 = 0; of2 < header_->getDataSize()%4; ++of2 )
    457 //   {
    458 //     if( of*4+of2 < diffHeader.getDataSize() )
    459 //     {
    460 //       *(dest+4*of+of2)=*(basep+4*of+of2) ^ *(gs+4*of+of2); // do the xor
    461 //     }
    462 //     else
    463 //     {
    464 //       *(dest+4*of+of2)=*(gs+4*of+of2); // same as 0 ^ *(gs32+of)
    465 //     }
    466 //   }
    467 //
    468 //   Gamestate *g = new Gamestate(ndata, getClientID());
    469 //   *(g->header_) = *header_;
    470 //   g->header_->setDiffed( true );
    471 //   g->header_->setBaseID( base->getID() );
    472 //   g->flags_=flags_;
    473 //   g->packetDirection_ = packetDirection_;
    474 //   return g;
    475 // }
    476 
    477 
    478648void Gamestate::rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength)
    479649{
     
    501671  assert(j==datalength);
    502672}
     673
    503674
    504675Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
     
    529700//   COUT(0) << "myvector contains:";
    530701//   for ( itt=dataVector_.begin() ; itt!=dataVector_.end(); itt++ )
    531 //     COUT(0) << ' ' << (*itt).objID;
     702//     COUT(0) << " " << (*itt).objID;
    532703//   COUT(0) << endl;
    533704  for(it=dataVector_.begin(); it!=dataVector_.end();){
    534705    SynchronisableHeader oldobjectheader(origdata);
    535706    SynchronisableHeader newobjectheader(newdata);
    536     if ( it->objSize == 0 )
     707    if ( (*it).objSize == 0 )
    537708    {
    538709      ++it;
    539710      continue;
    540711    }
    541     objectsize = oldobjectheader.getDataSize();
     712    objectsize = oldobjectheader.getDataSize()+SynchronisableHeader::getSize();
    542713    objectOffset=SynchronisableHeader::getSize(); //skip the size and the availableData variables in the objectheader
    543     if ( it->objID == oldobjectheader.getObjectID() ){
     714    if ( (*it).objID == oldobjectheader.getObjectID() ){
    544715      memcpy(newdata, origdata, objectsize);
    545       assert(newobjectheader.isDataAvailable()==true);
    546716      ++it;
    547717    }else{
    548718      newobjectheader = oldobjectheader;
    549       newobjectheader.setDataAvailable(false);
    550719      memset(newdata+objectOffset, 0, objectsize-objectOffset);
    551720    }
     
    559728  {
    560729    SynchronisableHeader oldobjectheader(origdata);
    561     objectsize = oldobjectheader.getDataSize();
     730    objectsize = oldobjectheader.getDataSize()+SynchronisableHeader::getSize();
    562731    origdata += objectsize;
    563732    origsize += objectsize;
     
    571740
    572741
    573 /*Gamestate *Gamestate::undiff(Gamestate *base)
    574 {
    575   assert(this && base);assert(data_);
    576   assert(header_->isDiffed());
    577   assert(!header_->isCompressed() && !base->header_->isCompressed());
    578   uint8_t *basep = GAMESTATE_START(base->data_);
    579   uint8_t *gs = GAMESTATE_START(this->data_);
    580   uint32_t of=0; // pointers offset
    581   uint32_t dest_length=0;
    582   dest_length=header_->getDataSize();
    583   if(dest_length==0)
    584     return NULL;
    585   uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
    586   uint8_t *dest = ndata + GamestateHeader::getSize();
    587   while(of < base->header_->getDataSize() && of < header_->getDataSize()){
    588     *(dest+of)=*(basep+of)^*(gs+of); // do the xor
    589     ++of;
    590   }
    591   if(base->header_->getDataSize()!=header_->getDataSize()){
    592     uint8_t n=0;
    593     if(base->header_->getDataSize() < header_->getDataSize()){
    594       while(of < dest_length){
    595         *(dest+of)=n^*(gs+of);
    596         of++;
    597       }
    598     }
    599   }
    600   Gamestate *g = new Gamestate(ndata, getClientID());
    601   assert(g->header_);
    602   *(g->header_) = *header_;
    603   g->header_->setDiffed( false );
    604   g->flags_=flags_;
    605   g->packetDirection_ = packetDirection_;
    606   assert(!g->isDiffed());
    607   assert(!g->isCompressed());
    608   return g;
    609 }*/
    610 
    611742uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode)
    612743{
    613   uint32_t size=0;
     744  uint32_t size = 0;
     745  uint32_t nrOfVariables = 0;
    614746    // get the start of the Synchronisable list
    615747  ObjectList<Synchronisable>::iterator it;
    616748    // get total size of gamestate
    617   for(it = ObjectList<Synchronisable>::begin(); it; ++it)
     749  for(it = ObjectList<Synchronisable>::begin(); it; ++it){
    618750    size+=it->getSize(id, mode); // size of the actual data of the synchronisable
     751    nrOfVariables += it->getNrOfVariables();
     752  }
     753//   COUT(0) << "allocating " << nrOfVariables << " ints" << endl;
     754  this->sizes_.reserve(nrOfVariables);
    619755  return size;
    620756}
     757
    621758
    622759} //namespace packet
  • code/trunk/src/libraries/network/packet/Gamestate.h

    r6073 r7163  
    3636#include <cstring>
    3737#include <list>
     38#include <vector>
    3839
    3940#include "util/CRC32.h"
     
    113114    inline bool isCompressed() const { return header_->isCompressed(); }
    114115    inline int32_t getBaseID() const { return header_->getBaseID(); }
    115     Gamestate *diff(Gamestate *base);
     116    inline uint32_t getDataSize() const { return header_->getDataSize(); }
     117    Gamestate* diffVariables(Gamestate *base);
     118    Gamestate* diffData(Gamestate *base);
    116119    Gamestate *undiff(Gamestate *base);
    117120    Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);
     
    123126  private:
    124127    void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength);
     128    inline uint32_t findObject( const SynchronisableHeader& header, uint8_t* mem, uint32_t dataLength, uint32_t startPosition = 0 );
    125129    virtual uint32_t getSize() const;
    126130    virtual inline bool process();
    127 
    128   private:
    129131    uint32_t calcGamestateSize(int32_t id, uint8_t mode=0x0);
    130     std::list<obj> dataVector_;
    131     GamestateHeader* header_;
     132   
     133    std::list<obj>          dataVector_;
     134    GamestateHeader*        header_;
     135    std::vector<uint32_t>   sizes_;
     136    uint32_t                nrOfVariables_;
    132137};
    133138
  • code/trunk/src/libraries/network/packet/Packet.cc

    r6417 r7163  
    6262std::map<size_t, Packet *> Packet::packetMap_;
    6363
    64 Packet::Packet(){
     64Packet::Packet()
     65{
    6566  flags_ = PACKET_FLAG_DEFAULT;
    6667  packetDirection_ = Direction::Outgoing;
     
    7172}
    7273
    73 void blub(ENetPacket *packet){
    74   COUT(4) << "blubb" << std::endl;
    75 }
    76 
    77 Packet::Packet(uint8_t *data, unsigned int clientID){
     74Packet::Packet(uint8_t *data, unsigned int clientID)
     75{
    7876  flags_ = PACKET_FLAG_DEFAULT;
    7977  packetDirection_ = Direction::Incoming;
  • code/trunk/src/libraries/network/synchronisable/Serialise.h

    r6417 r7163  
    3838#include "util/TypeTraits.h"
    3939#include "core/CorePrereqs.h"
     40#include "core/CoreIncludes.h"
     41#include "core/SmartPtr.h"
    4042
    4143namespace orxonox{
     
    7274            return *(uint32_t*)(mem) == variable->getObjectID();
    7375        else
     76            return variable == variable->getSynchronisable(*(uint32_t*)(mem));
     77    }
     78   
     79    // These functions implement loading / saving / etc. for SmartPtr<T>
     80   
     81    /** @brief returns the size of the objectID needed to synchronise the pointer */
     82    template <class T> inline uint32_t returnSize( const SmartPtr<T>& variable )
     83    {
     84        return sizeof(uint32_t);
     85    }
     86   
     87    /** @brief reads the objectID of a pointer out of the bytestream and increases the mem pointer */
     88    template <class T> inline void loadAndIncrease( const SmartPtr<T>& variable, uint8_t*& mem )
     89    {
     90//         *const_cast<typename Loki::TypeTraits<T*>::UnqualifiedType*>(&variable) = dynamic_cast<T*>(variable->getSynchronisable( *(uint32_t*)(mem) ));
     91        *const_cast<typename Loki::TypeTraits<SmartPtr<T> >::UnqualifiedType*>(&variable) = orxonox_cast<T*>(T::getSynchronisable(*(uint32_t*)(mem)));
     92        mem += returnSize( variable );
     93    }
     94   
     95    /** @brief saves the objectID of a pointer into the bytestream and increases the mem pointer */
     96    template <class T> inline void saveAndIncrease( const SmartPtr<T>& variable, uint8_t*& mem )
     97    {
     98        if ( variable.get() )
     99            *(uint32_t*)(mem) = static_cast<uint32_t>(variable->getObjectID());
     100        else
     101            *(uint32_t*)(mem) = OBJECTID_UNKNOWN;
     102        mem += returnSize( variable );
     103    }
     104   
     105    /** @brief checks whether the objectID of the variable is the same as in the bytestream */
     106    template <class T> inline  bool checkEquality( const SmartPtr<T>& variable, uint8_t* mem )
     107    {
     108        if ( variable.get() )
     109            return *(uint32_t*)(mem) == variable->getObjectID();
     110        else
     111            return *(uint32_t*)(mem) == OBJECTID_UNKNOWN;
     112    }
     113   
     114    // These functions implement loading / saving / etc. for WeakPtr<T>
     115   
     116    /** @brief returns the size of the objectID needed to synchronise the pointer */
     117    template <class T> inline uint32_t returnSize( const WeakPtr<T>& variable )
     118    {
     119        return sizeof(uint32_t);
     120    }
     121   
     122    /** @brief reads the objectID of a pointer out of the bytestream and increases the mem pointer */
     123    template <class T> inline void loadAndIncrease( const WeakPtr<T>& variable, uint8_t*& mem )
     124    {
     125        //         *const_cast<typename Loki::TypeTraits<T*>::UnqualifiedType*>(&variable) = dynamic_cast<T*>(variable->getSynchronisable( *(uint32_t*)(mem) ));
     126        *const_cast<typename Loki::TypeTraits<SmartPtr<T> >::UnqualifiedType*>(&variable) = orxonox_cast<T*>(T::getSynchronisable(*(uint32_t*)(mem)));
     127        mem += returnSize( variable );
     128    }
     129   
     130    /** @brief saves the objectID of a pointer into the bytestream and increases the mem pointer */
     131    template <class T> inline void saveAndIncrease( const WeakPtr<T>& variable, uint8_t*& mem )
     132    {
     133        if ( variable.get() )
     134            *(uint32_t*)(mem) = static_cast<uint32_t>(variable->getObjectID());
     135        else
     136            *(uint32_t*)(mem) = OBJECTID_UNKNOWN;
     137        mem += returnSize( variable );
     138    }
     139   
     140    /** @brief checks whether the objectID of the variable is the same as in the bytestream */
     141    template <class T> inline  bool checkEquality( const WeakPtr<T>& variable, uint8_t* mem )
     142    {
     143        if ( variable.get() )
     144            return *(uint32_t*)(mem) == variable->getObjectID();
     145        else
    74146            return *(uint32_t*)(mem) == OBJECTID_UNKNOWN;
    75147    }
  • code/trunk/src/libraries/network/synchronisable/Synchronisable.cc

    r6417 r7163  
    4949  * Initializes all Variables and sets the right objectID_
    5050  */
    51   Synchronisable::Synchronisable(BaseObject* creator ){
     51  Synchronisable::Synchronisable(BaseObject* creator )
     52  {
    5253    RegisterRootObject(Synchronisable);
    5354    static uint32_t idCounter=0;
    5455    objectMode_=0x1; // by default do not send data to server
    55     if ( GameMode::isMaster() || ( Host::running() && Host::isServer() ) )
     56    if ( GameMode::isMaster()/* || ( Host::running() && Host::isServer() )*/ )
    5657    {
    5758      this->setObjectID( idCounter++ );
     
    7374    else
    7475      this->creatorID_ = OBJECTID_UNKNOWN;
    75 
    76     /*searchcreatorID:
    77     if (creator)
    78     {
    79         Synchronisable* synchronisable_creator = orxonox_cast<Synchronisable*>(creator);
    80         if (synchronisable_creator && synchronisable_creator->objectMode_)
    81         {
    82             this->creatorID = synchronisable_creator->getScene()->getObjectID();
    83         }
    84         else if (creator != creator->getCreator())
    85         {
    86             creator = creator->getCreator();
    87             goto searchcreatorID;
    88         }
    89     }*/
    9076  }
    9177
     
    9480   * Delete all callback objects and remove objectID_ from the objectMap_
    9581   */
    96   Synchronisable::~Synchronisable(){
     82  Synchronisable::~Synchronisable()
     83  {
    9784    // delete callback function objects
    9885    if(!Identifier::isCreatingHierarchy()){
     
    10188        deletedObjects_.push(objectID_);
    10289    }
    103     // delete all Synchronisable Variables from syncList ( which are also in stringList )
    104     for(std::vector<SynchronisableVariableBase*>::iterator it = syncList.begin(); it!=syncList.end(); it++)
     90    // delete all Synchronisable Variables from syncList_ ( which are also in stringList_ )
     91    for(std::vector<SynchronisableVariableBase*>::iterator it = syncList_.begin(); it!=syncList_.end(); it++)
    10592      delete (*it);
    106     syncList.clear();
    107     stringList.clear();
     93    syncList_.clear();
     94    stringList_.clear();
    10895    std::map<uint32_t, Synchronisable*>::iterator it;
    10996    it = objectMap_.find(objectID_);
     
    118105   * @param b true if this object is located on a client or on a server
    119106   */
    120   void Synchronisable::setClient(bool b){
     107  void Synchronisable::setClient(bool b)
     108  {
    121109    if(b) // client
    122110      state_=0x2;
     
    135123  {
    136124    SynchronisableHeader header(mem);
    137 
    138     if(!header.isDataAvailable())
    139     {
    140       mem += header.getDataSize();
    141       return 0;
    142     }
     125    assert( !header.isDiffed() );
    143126
    144127    COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl;
     
    160143      if (!synchronisable_creator)
    161144      {
    162         mem += header.getDataSize(); //.TODO: this suckz.... remove size from header
     145        mem += header.getDataSize()+SynchronisableHeader::getSize(); //.TODO: this suckz.... remove size from header
    163146        assert(0); // TODO: uncomment this if we have a clean objecthierarchy (with destruction of children of objects) ^^
    164147        return 0;
     
    177160    no->setClassID(header.getClassID());
    178161    assert(no->creatorID_ == header.getCreatorID());
     162    if( creator )
     163      bo->setLevel(creator->getLevel());          // Note: this ensures that the level is known on the client for child objects of the scene (and the scene itself)
    179164    //assert(no->classID_ == header.getClassID());
    180165    COUT(4) << "fabricate objectID_: " << no->objectID_ << " classID_: " << no->classID_ << std::endl;
     
    196181   * @return true/false
    197182   */
    198   bool Synchronisable::deleteObject(uint32_t objectID_){
     183  bool Synchronisable::deleteObject(uint32_t objectID_)
     184  {
    199185    if(!getSynchronisable(objectID_))
    200186      return false;
     
    213199   * @return pointer to the Synchronisable with the objectID_
    214200   */
    215   Synchronisable* Synchronisable::getSynchronisable(uint32_t objectID_){
     201  Synchronisable* Synchronisable::getSynchronisable(uint32_t objectID_)
     202  {
    216203    std::map<uint32_t, Synchronisable*>::iterator it1;
    217204    it1 = objectMap_.find(objectID_);
    218205    if (it1 != objectMap_.end())
    219206      return it1->second;
    220 
    221 //     ObjectList<Synchronisable>::iterator it;
    222 //     for(it = ObjectList<Synchronisable>::begin(); it; ++it){
    223 //       if( it->getObjectID()==objectID_ ){
    224 //         objectMap_[objectID_] = *it;
    225 //         return *it;
    226 //       }
    227 //     }
    228207    // if the objects not in the map it should'nt exist at all anymore
    229208    return NULL;
     
    245224   * @return true: if !doSync or if everything was successfully saved
    246225   */
    247   uint32_t Synchronisable::getData(uint8_t*& mem, int32_t id, uint8_t mode){
     226  uint32_t Synchronisable::getData(uint8_t*& mem, std::vector<uint32_t>& sizes, int32_t id, uint8_t mode)
     227  {
     228    unsigned int test = 0;
    248229    if(mode==0x0)
    249230      mode=state_;
     
    253234    uint32_t tempsize = 0;
    254235#ifndef NDEBUG
     236    uint8_t* oldmem = mem;
    255237    if (this->classID_==0)
    256238      COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
     
    270252    // end copy header
    271253
    272 
    273     COUT(5) << "Synchronisable getting data from objectID_: " << objectID_ << " classID_: " << classID_ << std::endl;
     254    CCOUT(5) << "getting data from objectID_: " << objectID_ << ", classID_: " << classID_ << std::endl;
     255//     COUT(4) << "objectid: " << this->objectID_ << ":";
    274256    // copy to location
    275     for(i=syncList.begin(); i!=syncList.end(); ++i){
    276       tempsize += (*i)->getData( mem, mode );
     257    for(i=syncList_.begin(); i!=syncList_.end(); ++i)
     258    {
     259      uint32_t varsize = (*i)->getData( mem, mode );
     260//       COUT(4) << " " << varsize;
     261      tempsize += varsize;
     262      sizes.push_back(varsize);
     263      ++test;
    277264      //tempsize += (*i)->getSize( mode );
    278265    }
    279 
    280     tempsize += SynchronisableHeader::getSize();
     266//     COUT(4) << endl;
     267
    281268    header.setObjectID( this->objectID_ );
    282269    header.setCreatorID( this->creatorID_ );
    283270    header.setClassID( this->classID_ );
    284     header.setDataAvailable( true );
    285271    header.setDataSize( tempsize );
     272    assert( tempsize == mem-oldmem-SynchronisableHeader::getSize() );
     273    assert( test == this->getNrOfVariables() );
     274    header.setDiffed(false);
     275    tempsize += SynchronisableHeader::getSize();
    286276
    287277#ifndef NDEBUG
     
    300290   * @return true/false
    301291   */
    302   bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback){
     292  bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback)
     293  {
    303294    if(mode==0x0)
    304295      mode=state_;
    305     std::vector<SynchronisableVariableBase *>::iterator i;
    306     if(syncList.empty()){
     296    if(syncList_.empty())
     297    {
    307298      assert(0);
    308       COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl;
     299      COUT(2) << "Synchronisable::updateData syncList_ is empty" << std::endl;
    309300      return false;
    310301    }
     
    312303    uint8_t* data=mem;
    313304    // start extract header
    314     SynchronisableHeader syncHeader(mem);
    315     assert(syncHeader.getObjectID()==this->objectID_);
    316     assert(syncHeader.getCreatorID()==this->creatorID_);
    317     assert(syncHeader.getClassID()==this->classID_);
    318     if(syncHeader.isDataAvailable()==false){
    319       mem += syncHeader.getDataSize();
    320       return true;
    321     }
    322 
    323     mem += SynchronisableHeader::getSize();
    324     // stop extract header
     305    SynchronisableHeaderLight syncHeaderLight(mem);
     306    assert(syncHeaderLight.getObjectID()==this->getObjectID());
    325307
    326308    //COUT(5) << "Synchronisable: objectID_ " << syncHeader.getObjectID() << ", classID_ " << syncHeader.getClassID() << " size: " << syncHeader.getDataSize() << " synchronising data" << std::endl;
    327     for(i=syncList.begin(); i!=syncList.end(); i++)
    328     {
    329       assert( mem <= data+syncHeader.getDataSize() ); // always make sure we don't exceed the datasize in our stream
    330       (*i)->putData( mem, mode, forceCallback );
    331     }
    332     assert(mem == data+syncHeader.getDataSize());
     309    if( !syncHeaderLight.isDiffed() )
     310    {
     311      SynchronisableHeader syncHeader2(mem);
     312      assert( this->getClassID() == syncHeader2.getClassID() );
     313      assert( this->getCreatorID() == syncHeader2.getCreatorID() );
     314      mem += SynchronisableHeader::getSize();
     315      std::vector<SynchronisableVariableBase *>::iterator i;
     316      for(i=syncList_.begin(); i!=syncList_.end(); i++)
     317      {
     318        assert( mem <= data+syncHeader2.getDataSize()+SynchronisableHeader::getSize() ); // always make sure we don't exceed the datasize in our stream
     319        (*i)->putData( mem, mode, forceCallback );
     320      }
     321      assert(mem == data+syncHeaderLight.getDataSize()+SynchronisableHeader::getSize() );
     322    }
     323    else
     324    {
     325      mem += SynchronisableHeaderLight::getSize();
     326//       COUT(0) << "objectID: " << this->objectID_ << endl;
     327      while( mem < data+syncHeaderLight.getDataSize()+SynchronisableHeaderLight::getSize() )
     328      {
     329        VariableID varID = *(VariableID*)mem;
     330//         COUT(0) << "varID: " << varID << endl;
     331        assert( varID < syncList_.size() );
     332        mem += sizeof(VariableID);
     333        syncList_[varID]->putData( mem, mode, forceCallback );
     334      }
     335      assert(mem == data+syncHeaderLight.getDataSize()+SynchronisableHeaderLight::getSize() );
     336    }
    333337    return true;
    334338  }
     
    340344  * @return amount of bytes
    341345  */
    342   uint32_t Synchronisable::getSize(int32_t id, uint8_t mode){
    343     int tsize=SynchronisableHeader::getSize();
     346  uint32_t Synchronisable::getSize(int32_t id, uint8_t mode)
     347  {
     348    uint32_t tsize=SynchronisableHeader::getSize();
    344349    if (mode==0x0)
    345350      mode=state_;
     
    349354    tsize += this->dataSize_;
    350355    std::vector<SynchronisableVariableBase*>::iterator i;
    351     for(i=stringList.begin(); i!=stringList.end(); ++i){
     356    for(i=stringList_.begin(); i!=stringList_.end(); ++i)
     357    {
    352358      tsize += (*i)->getSize( mode );
    353359    }
     
    360366   * @return true/false
    361367   */
    362   bool Synchronisable::doSync(int32_t id, uint8_t mode){
     368  bool Synchronisable::doSync(int32_t id, uint8_t mode)
     369  {
    363370    if(mode==0x0)
    364371      mode=state_;
    365     return ( (this->objectMode_ & mode)!=0 && (!syncList.empty() ) );
    366   }
    367 
    368   /**
    369    * This function looks at the header located in the bytestream and checks wheter objectID_ and classID_ match with the Synchronisables ones
    370    * @param mem pointer to the bytestream
    371    */
    372   bool Synchronisable::isMyData(uint8_t* mem)
    373   {
    374     SynchronisableHeader header(mem);
    375     assert(header.getObjectID()==this->objectID_);
    376     return header.isDataAvailable();
     372    return ( (this->objectMode_ & mode)!=0 && (!syncList_.empty() ) );
    377373  }
    378374
     
    385381   * @param mode same as in registerVar
    386382   */
    387   void Synchronisable::setSyncMode(uint8_t mode){
     383  void Synchronisable::setSyncMode(uint8_t mode)
     384  {
    388385    assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3);
    389386    this->objectMode_=mode;
     
    397394    else
    398395      sv = new SynchronisableVariable<std::string>(variable, mode, cb);
    399     syncList.push_back(sv);
    400     stringList.push_back(sv);
     396    syncList_.push_back(sv);
     397    stringList_.push_back(sv);
     398  }
     399
     400template <> void Synchronisable::unregisterVariable( std::string& variable )
     401  {
     402    bool unregistered_nonexistent_variable = true;
     403    std::vector<SynchronisableVariableBase*>::iterator it = syncList_.begin();
     404    while(it!=syncList_.end())
     405    {
     406      if( ((*it)->getReference()) == &variable )
     407      {
     408        delete (*it);
     409        syncList_.erase(it);
     410        unregistered_nonexistent_variable = false;
     411        break;
     412      }
     413      else
     414        ++it;
     415    }
     416    assert(unregistered_nonexistent_variable == false);
     417   
     418    it = stringList_.begin();
     419    while(it!=stringList_.end())
     420    {
     421      if( ((*it)->getReference()) == &variable )
     422      {
     423        delete (*it);
     424        stringList_.erase(it);
     425        return;
     426      }
     427      else
     428        ++it;
     429    }
     430    unregistered_nonexistent_variable = true;
     431    assert(unregistered_nonexistent_variable == false); //if we reach this point something went wrong:
     432    // the variable has not been registered before
    401433  }
    402434
  • code/trunk/src/libraries/network/synchronisable/Synchronisable.h

    r6417 r7163  
    3737#include <map>
    3838#include <queue>
     39#include <set>
    3940
    4041#include "util/mbool.h"
     
    6465    };
    6566  }
     67 
     68  typedef uint8_t VariableID;
    6669
    6770  /**
     
    7174   * in an emulated bitset.
    7275   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
    73    * Bit 32 is a bool and defines whether the data is actually stored or is just filled up with 0
     76   * Bit 32 is a bool and defines whether the variables are stored in diff mode
    7477   * Byte 5 to 8: objectID_
    7578   * Byte 9 to 12: classID_
     
    7780   */
    7881  class _NetworkExport SynchronisableHeader{
     82    friend class SynchronisableHeaderLight;
    7983    private:
    80       uint8_t *data_;
     84      uint8_t* data_;
    8185    public:
    8286      SynchronisableHeader(uint8_t* data)
    8387        { data_ = data; }
    8488      inline static uint32_t getSize()
    85         { return 16; }
    86       inline uint32_t getDataSize() const
    87         { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
    88       inline void setDataSize(uint32_t size)
    89         { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
    90       inline bool isDataAvailable() const
    91         { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
    92       inline void setDataAvailable( bool b)
    93         { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
     89        { return 14; }
     90      inline uint16_t getDataSize() const
     91        { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 15 bits
     92      inline void setDataSize(uint16_t size)
     93        { *(uint16_t*)(data_) = (size & 0x7FFF) | (*(uint16_t*)(data_) & 0x8000 ); }
     94      inline bool isDiffed() const
     95        { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; }
     96      inline void setDiffed( bool b)
     97        { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); }
    9498      inline uint32_t getObjectID() const
    95         { return *(uint32_t*)(data_+4); }
     99        { return *(uint32_t*)(data_+2); }
    96100      inline void setObjectID(uint32_t objectID_)
    97         { *(uint32_t*)(data_+4) = objectID_; }
     101        { *(uint32_t*)(data_+2) = objectID_; }
    98102      inline uint32_t getClassID() const
    99         { return *(uint32_t*)(data_+8); }
     103        { return *(uint32_t*)(data_+6); }
    100104      inline void setClassID(uint32_t classID_)
    101         { *(uint32_t*)(data_+8) = classID_; }
     105        { *(uint32_t*)(data_+6) = classID_; }
    102106      inline uint32_t getCreatorID() const
    103         { return *(uint32_t*)(data_+12); }
     107        { return *(uint32_t*)(data_+10); }
    104108      inline void setCreatorID(uint32_t creatorID_)
    105         { *(uint32_t*)(data_+12) = creatorID_; }
     109        { *(uint32_t*)(data_+10) = creatorID_; }
    106110      inline void operator=(SynchronisableHeader& h)
    107111        { memcpy(data_, h.data_, getSize()); }
    108112  };
    109113
     114    /**
     115   * @brief: stores information about a Synchronisable (light version)
     116   *
     117   * This class stores the information about a Synchronisable (objectID_, dataSize)
     118   * in an emulated bitset.
     119   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
     120   * Bit 32 is a bool and defines whether the variables are stored in diff mode
     121   * Byte 5 to 8: objectID_
     122   */
     123  class _NetworkExport SynchronisableHeaderLight{
     124    private:
     125      uint8_t* data_;
     126    public:
     127      SynchronisableHeaderLight(uint8_t* data)
     128        { data_ = data; }
     129      inline static uint32_t getSize()
     130        { return 6; }
     131      inline uint16_t getDataSize() const
     132        { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 31 bits
     133      inline void setDataSize(uint16_t size)
     134        { *(uint16_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint16_t*)(data_) & 0x8000 ); }
     135      inline bool isDiffed() const
     136        { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; }
     137      inline void setDiffed( bool b)
     138        { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); }
     139      inline uint32_t getObjectID() const
     140        { return *(uint32_t*)(data_+2); }
     141      inline void setObjectID(uint32_t objectID_)
     142        { *(uint32_t*)(data_+2) = objectID_; }
     143      inline void operator=(SynchronisableHeader& h)
     144        { memcpy(data_, h.data_, getSize()); }
     145  };
    110146
    111147  /**
     
    134170
    135171    void setSyncMode(uint8_t mode);
     172   
     173    inline uint32_t getNrOfVariables(){ return this->syncList_.size(); }
     174    inline uint32_t getVarSize( VariableID ID )
     175    { return this->syncList_[ID]->getSize(state_); }
    136176
    137177  protected:
    138178    Synchronisable(BaseObject* creator);
    139179    template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
     180    template <class T> void registerVariable(std::set<T>& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
     181    template <class T> void unregisterVariable(T& var);
    140182
    141183    void setPriority(unsigned int freq){ objectFrequency_ = freq; }
     
    143185
    144186  private:
    145     uint32_t getData(uint8_t*& men, int32_t id, uint8_t mode=0x0);
     187    uint32_t getData(uint8_t*& mem, std::vector<uint32_t>& sizes, int32_t id, uint8_t mode);
    146188    uint32_t getSize(int32_t id, uint8_t mode=0x0);
    147189    bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
    148     bool isMyData(uint8_t* mem);
    149190    bool doSync(int32_t id, uint8_t mode=0x0);
    150191
     
    156197    uint32_t classID_;
    157198
    158     std::vector<SynchronisableVariableBase*> syncList;
    159     std::vector<SynchronisableVariableBase*> stringList;
     199    std::vector<SynchronisableVariableBase*> syncList_;
     200    std::vector<SynchronisableVariableBase*> stringList_;
    160201    uint32_t dataSize_; //size of all variables except strings
    161202    static uint8_t state_; // detemines wheter we are server (default) or client
     
    171212    if (bidirectional)
    172213    {
    173       syncList.push_back(new SynchronisableVariableBidirectional<T>(variable, mode, cb));
    174       this->dataSize_ += syncList.back()->getSize(state_);
     214      syncList_.push_back(new SynchronisableVariableBidirectional<T>(variable, mode, cb));
     215      this->dataSize_ += syncList_.back()->getSize(state_);
    175216    }
    176217    else
    177218    {
    178       syncList.push_back(new SynchronisableVariable<T>(variable, mode, cb));
     219      syncList_.push_back(new SynchronisableVariable<T>(variable, mode, cb));
    179220      if ( this->state_ == mode )
    180         this->dataSize_ += syncList.back()->getSize(state_);
     221        this->dataSize_ += syncList_.back()->getSize(state_);
    181222    }
    182223  }
     224 
     225  template <class T> void Synchronisable::unregisterVariable(T& variable){
     226    std::vector<SynchronisableVariableBase*>::iterator it = syncList_.begin();
     227    while(it!=syncList_.end()){
     228      if( ((*it)->getReference()) == &variable ){
     229        this->dataSize_ -= (*it)->getSize(Synchronisable::state_);
     230        delete (*it);
     231        syncList_.erase(it);
     232        return;
     233      }
     234      else
     235        it++;
     236    }
     237    bool unregistered_nonexistent_variable = false;
     238    assert(unregistered_nonexistent_variable); //if we reach this point something went wrong:
     239    // the variable has not been registered before
     240  }
     241
     242  template <class T> void Synchronisable::registerVariable( std::set<T>& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
     243  {
     244    SynchronisableVariableBase* sv;
     245    if (bidirectional)
     246      sv = new SynchronisableVariableBidirectional<std::set<T> >(variable, mode, cb);
     247    else
     248      sv = new SynchronisableVariable<std::set<T> >(variable, mode, cb);
     249    syncList_.push_back(sv);
     250    stringList_.push_back(sv);
     251  }
    183252
    184253  template <> _NetworkExport void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
     254//   template <class T> _NetworkExport void Synchronisable::registerVariable<std::set<T> >( std::set<T>& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
     255  template <> _NetworkExport void Synchronisable::unregisterVariable( std::string& variable );
    185256
    186257
  • code/trunk/src/libraries/tools/CMakeLists.txt

    r6417 r7163  
    1515COMPILATION_END
    1616)
     17#ADD_SUBDIRECTORY(bsp)
    1718ADD_SUBDIRECTORY(interfaces)
    1819
    1920ORXONOX_ADD_LIBRARY(tools
    2021  FIND_HEADER_FILES
    21   DEFINE_SYMBOL
    22     "TOOLS_SHARED_BUILD"
    2322  LINK_LIBRARIES
    2423    core
  • code/trunk/src/libraries/tools/ToolsPrereqs.h

    r5929 r7163  
    4242//-----------------------------------------------------------------------
    4343
    44 #if defined(ORXONOX_PLATFORM_WINDOWS) && !defined(ORXONOX_STATIC_BUILD)
     44#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined(TOOLS_STATIC_BUILD)
    4545#  ifdef TOOLS_SHARED_BUILD
    4646#    define _ToolsExport __declspec(dllexport)
  • code/trunk/src/libraries/util/CMakeLists.txt

    r6503 r7163  
    2727  Clipboard.cc
    2828  Clock.cc
     29  Convert.cc
    2930  CRC32.cc
    3031  ExprParser.cc
     
    4950ORXONOX_ADD_LIBRARY(util
    5051  FIND_HEADER_FILES
    51   DEFINE_SYMBOL
    52     "UTIL_SHARED_BUILD"
    5352  LINK_LIBRARIES
    5453    ${CEGUI_LIBRARY}
  • code/trunk/src/libraries/util/Convert.h

    r6417 r7163  
    6464
    6565    Defining your own functions:
    66     There are obviously 4 ways to specifiy a user defined conversion. What should I use?
     66    There are obviously 4 ways to specify a user defined conversion. What should you use?
    6767
    6868    Usually, ConverterFallback fits quite well. You won't have to deal with the conversion from
     
    7070
    7171    However if you want to overwrite an implicit conversion or an iostream operator, you really need to
    72     make use of ConverterExplicit.
     72    make use of ConverterExplicit. We have to do this for the Ogre classes for instance because they
     73    define stream operators we don't particulary like.
    7374*/
    7475
     
    388389    };
    389390
    390     // Declarations to avoid StringUtils.h include
    391     _UtilExport std::string removeTrailingWhitespaces(const std::string& str);
    392     _UtilExport std::string getLowercase(const std::string& str);
    393 
    394391    // std::string to bool
    395392    template <>
    396     struct ConverterExplicit<std::string, bool>
    397     {
    398         static bool convert(bool* output, const std::string& input)
    399         {
    400             const std::string& stripped = getLowercase(removeTrailingWhitespaces(input));
    401             if (stripped == "true" || stripped == "on" || stripped == "yes")
    402             {
    403                 *output = true;
    404                 return true;
    405             }
    406             else if (stripped == "false" || stripped == "off" || stripped == "no")
    407             {
    408                 *output = false;
    409                 return true;
    410             }
    411 
    412             std::istringstream iss(input);
    413             if (iss >> (*output))
    414                 return true;
    415             else
    416                 return false;
    417         }
     393    struct _UtilExport ConverterExplicit<std::string, bool>
     394    {
     395        static bool convert(bool* output, const std::string& input);
    418396    };
    419397}
  • code/trunk/src/libraries/util/Serialise.h

    r6746 r7163  
    3838
    3939#include <cstring>
     40#include <set>
    4041#include "Math.h"
    4142#include "mbool.h"
     
    5253    template <class T> inline bool checkEquality( const T& variable, uint8_t* mem );
    5354
     55 
     56  // =========== char*
     57   
     58  inline uint32_t returnSize( char*& variable )
     59  {
     60    return strlen(variable)+1;
     61  }
     62     
     63  inline void saveAndIncrease( char*& variable, uint8_t*& mem )
     64  {
     65    strcpy((char*)mem, variable);
     66    mem += returnSize(variable);
     67  }
     68       
     69  inline void loadAndIncrease( char*& variable, uint8_t*& mem )
     70  {
     71    if( variable )
     72      delete variable;
     73    uint32_t len = strlen((char*)mem)+1;
     74    variable = new char[len];
     75    strcpy((char*)variable, (char*)mem);
     76    mem += len;
     77  }
     78         
     79  inline bool checkEquality( char*& variable, uint8_t* mem )
     80  {
     81    return strcmp(variable, (char*)mem)==0;
     82  }
     83   
    5484// =================== Template specialisation stuff =============
    5585
     
    393423        return memcmp(&temp, mem, sizeof(uint64_t))==0;
    394424    }
    395 
     425       
    396426// =========== string
    397427
     
    635665        return checkEquality( (unsigned char&)((mbool&)variable).getMemory(), mem );
    636666    }
     667
     668    // =========== std::set
     669
     670    template <class T> inline uint32_t returnSize( const std::set<T>& variable )
     671    {
     672        uint32_t tempsize = sizeof(uint32_t); // for the number of entries
     673        for( typename std::set<T>::iterator it=((std::set<T>*)(&variable))->begin(); it!=((std::set<T>*)(&variable))->end(); ++it)
     674            tempsize += returnSize( *it );
     675        return tempsize;
     676    }
     677
     678    template <class T> inline void saveAndIncrease(  const std::set<T>& variable, uint8_t*& mem )
     679    {
     680        typename std::set<T>::const_iterator it = variable.begin();
     681        saveAndIncrease( (uint32_t)variable.size(), mem );
     682        for( ; it!=variable.end(); ++it )
     683            saveAndIncrease( *it, mem );
     684    }
     685
     686    template <class T> inline void loadAndIncrease( const std::set<T>& variable, uint8_t*& mem )
     687    {
     688        uint32_t nrOfElements = 0;
     689        loadAndIncrease( nrOfElements, mem );
     690        typename std::set<T>::const_iterator it = variable.begin();
     691        for( uint32_t i = 0; i<nrOfElements; ++i )
     692        {
     693            T temp;
     694            loadAndIncrease(temp, mem);
     695            while( it!=variable.end() && *it!=temp )
     696            {
     697                ((std::set<T>*)(&variable))->erase(it++);
     698                ++it;
     699            }
     700            if( it==variable.end() )
     701            {
     702                ((std::set<T>*)(&variable))->insert(temp);
     703            }
     704        }
     705    }
     706
     707    template <class T> inline bool checkEquality( const std::set<T>& variable, uint8_t* mem )
     708    {
     709        uint8_t* temp = mem;
     710        uint32_t nrOfElements;
     711        loadAndIncrease(nrOfElements, mem);
     712        if( variable.size() == nrOfElements )
     713        {
     714            T tempT;
     715            for( uint32_t i=0; i<nrOfElements; ++i )
     716            {
     717                loadAndIncrease(tempT, mem);
     718                if( variable.find(tempT) == variable.end() )
     719                {
     720                    mem = temp;
     721                    return false;
     722                }
     723            }
     724        }
     725        else
     726        {
     727            mem = temp;
     728            return false;
     729        }
     730        return true;
     731    }
    637732}
    638733
  • code/trunk/src/libraries/util/SignalHandler.cc

    r5738 r7163  
    124124      if( SignalHandler::singletonPtr_s == 0 )
    125125      {
    126         COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "can't write backtrace because SignalHandler already destroyed" << std::endl;
     126        COUT(0) << "received signal " << sigName.c_str() << std::endl << "can't write backtrace because SignalHandler already destroyed" << std::endl;
    127127        exit(EXIT_FAILURE);
    128128      }
     
    134134
    135135
    136       COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "try to write backtrace to file orxonox_crash.log" << std::endl;
     136      COUT(0) << "received signal " << sigName.c_str() << std::endl << "try to write backtrace to file orxonox_crash.log" << std::endl;
    137137
    138138      int sigPipe[2];
  • code/trunk/src/libraries/util/Singleton.h

    r6751 r7163  
    3131
    3232#include "UtilPrereqs.h"
     33
    3334#include <cassert>
     35#include <cstring>
    3436
    3537namespace orxonox
Note: See TracChangeset for help on using the changeset viewer.