| [230] | 1 | // | 
|---|
|  | 2 | // C++ Implementation: synchronisable | 
|---|
|  | 3 | // | 
|---|
| [285] | 4 | // Description: | 
|---|
| [230] | 5 | // | 
|---|
|  | 6 | // | 
|---|
| [247] | 7 | // Author:  Dumeni, Oliver Scheuss, (C) 2007 | 
|---|
| [230] | 8 | // | 
|---|
|  | 9 | // Copyright: See COPYING file that comes with this distribution | 
|---|
|  | 10 | // | 
|---|
| [238] | 11 |  | 
|---|
| [777] | 12 | #include <string> | 
|---|
|  | 13 | #include <iostream> | 
|---|
|  | 14 |  | 
|---|
| [285] | 15 | #include "Synchronisable.h" | 
|---|
| [230] | 16 |  | 
|---|
| [777] | 17 | namespace network | 
|---|
| [230] | 18 | { | 
|---|
| [777] | 19 | /** | 
|---|
|  | 20 | * Constructor: | 
|---|
|  | 21 | * calls registarAllVariables, that has to be implemented by the inheriting classID | 
|---|
|  | 22 | */ | 
|---|
|  | 23 | Synchronisable::Synchronisable(){ | 
|---|
|  | 24 | RegisterRootObject(Synchronisable); | 
|---|
|  | 25 | static int idCounter=0; | 
|---|
|  | 26 | datasize=0; | 
|---|
|  | 27 | objectID=idCounter++; | 
|---|
|  | 28 | //registerAllVariables(); | 
|---|
|  | 29 | } | 
|---|
| [230] | 30 |  | 
|---|
| [777] | 31 | Synchronisable::~Synchronisable(){ | 
|---|
|  | 32 | } | 
|---|
| [230] | 33 |  | 
|---|
| [777] | 34 | /** | 
|---|
|  | 35 | * This function is used to register a variable to be synchronized | 
|---|
|  | 36 | * also counts the total datasize needed to save the variables | 
|---|
|  | 37 | * @param var pointer to the variable | 
|---|
|  | 38 | * @param size size of the datatype the variable consists of | 
|---|
|  | 39 | */ | 
|---|
|  | 40 | void Synchronisable::registerVar(const void *var, int size, variableType t){ | 
|---|
|  | 41 | // create temporary synch.Var struct | 
|---|
|  | 42 | synchronisableVariable temp={size, var, t}; | 
|---|
|  | 43 | // increase datasize | 
|---|
|  | 44 | datasize+=sizeof(int)+size; | 
|---|
|  | 45 | // push temp to syncList (at the bottom) | 
|---|
|  | 46 | syncList.push_back(temp); | 
|---|
|  | 47 | } | 
|---|
| [285] | 48 |  | 
|---|
| [777] | 49 | /** | 
|---|
|  | 50 | * note: only use this function for debug use, because it's inefficient (in order to produce a gamestate, you have to copy the whole data again to another memory location after this process) | 
|---|
|  | 51 | * This function takes all SynchronisableVariables out of the Synchronisable and saves it into a syncData struct | 
|---|
|  | 52 | * structure of the bitstream: | 
|---|
|  | 53 | * (var1_size,var1,var2_size,var2,...) | 
|---|
|  | 54 | * varx_size: size = sizeof(int) | 
|---|
|  | 55 | * varx: size = varx_size | 
|---|
|  | 56 | * @return data containing all variables and their sizes | 
|---|
|  | 57 | */ | 
|---|
|  | 58 | // syncData Synchronisable::getData(){ | 
|---|
|  | 59 | //   std::list<synchronisableVariable>::iterator i; | 
|---|
|  | 60 | //   int totalsize=0; | 
|---|
|  | 61 | //   //figure out size of data to be allocated | 
|---|
|  | 62 | //   for(i=syncList.begin(); i!=syncList.end(); i++){ | 
|---|
|  | 63 | //     // increase size (size of variable and size of size of variable ;) | 
|---|
|  | 64 | //     if(i->type == STRING) | 
|---|
|  | 65 | //       totalsize+=sizeof(int)+((std::string *)i->var)->length()+1; | 
|---|
|  | 66 | //     else | 
|---|
|  | 67 | //       totalsize+=sizeof(int)+i->size; | 
|---|
|  | 68 | //   } | 
|---|
|  | 69 | //   syncData retVal; | 
|---|
|  | 70 | //   retVal.objectID=this->objectID; | 
|---|
|  | 71 | //   retVal.classID=this->classID; | 
|---|
|  | 72 | //   retVal.length=totalsize; | 
|---|
|  | 73 | //   // allocate memory | 
|---|
|  | 74 | //   retVal.data = (unsigned char *)malloc(totalsize); | 
|---|
|  | 75 | //   // copy to location | 
|---|
|  | 76 | //   //CHANGED: REMOVED DECLARATION int n=0 FROM LOOP | 
|---|
|  | 77 | //   int n=0; | 
|---|
|  | 78 | //   for(i=syncList.begin(); n<totalsize && i!=syncList.end(); i++){ | 
|---|
|  | 79 | //     std::memcpy(retVal.data+n, (const void*)(i->size), sizeof(int)); | 
|---|
|  | 80 | //     n+=sizeof(int); | 
|---|
|  | 81 | //     switch(i->type){ | 
|---|
|  | 82 | //     case STRING: | 
|---|
|  | 83 | //       std::memcpy(retVal.data+n, (const void *)(((std::string *)i->var)->c_str()), ((std::string *)i->var)->length()+1); | 
|---|
|  | 84 | //       n+=((std::string *)i->var)->length()+1; | 
|---|
|  | 85 | //       break; | 
|---|
|  | 86 | //     case DATA: | 
|---|
|  | 87 | //       std::memcpy(retVal.data+n, ((const void*)i->var), i->size); | 
|---|
|  | 88 | //       n+=i->size; | 
|---|
|  | 89 | //       break; | 
|---|
|  | 90 | //     } | 
|---|
|  | 91 | //   } | 
|---|
|  | 92 | //   return retVal; | 
|---|
|  | 93 | // } | 
|---|
|  | 94 | /** | 
|---|
|  | 95 | * This function takes all SynchronisableVariables out of the Synchronisable and saves it into a syncData struct | 
|---|
|  | 96 | * Difference to the above function: | 
|---|
|  | 97 | * takes a pointer to already allocated memory (must have at least getSize bytes length) | 
|---|
|  | 98 | * structure of the bitstream: | 
|---|
|  | 99 | * (var1_size,var1,var2_size,var2,...) | 
|---|
|  | 100 | * varx_size: size = sizeof(int) | 
|---|
|  | 101 | * varx: size = varx_size | 
|---|
|  | 102 | * @return data containing all variables and their sizes | 
|---|
|  | 103 | */ | 
|---|
|  | 104 | syncData Synchronisable::getData(unsigned char *mem){ | 
|---|
|  | 105 | std::list<synchronisableVariable>::iterator i; | 
|---|
|  | 106 | syncData retVal; | 
|---|
|  | 107 | retVal.objectID=this->objectID; | 
|---|
|  | 108 | retVal.classID=this->classID; | 
|---|
|  | 109 | retVal.length=getSize(); | 
|---|
|  | 110 | retVal.data=mem; | 
|---|
|  | 111 | // copy to location | 
|---|
|  | 112 | int n=0; | 
|---|
|  | 113 | for(i=syncList.begin(); n<datasize && i!=syncList.end(); ++i){ | 
|---|
|  | 114 | //COUT(2) << "size of variable: " << i->size << std::endl; | 
|---|
|  | 115 | //(std::memcpy(retVal.data+n, (const void*)(&(i->size)), sizeof(int)); | 
|---|
|  | 116 | memcpy( (void *)(retVal.data+n), (const void*)&(i->size), sizeof(int) ); | 
|---|
|  | 117 | n+=sizeof(int); | 
|---|
|  | 118 | switch(i->type){ | 
|---|
| [565] | 119 | case DATA: | 
|---|
| [656] | 120 | std::memcpy( (void *)(retVal.data+n), (const void*)(i->var), i->size); | 
|---|
| [565] | 121 | n+=i->size; | 
|---|
|  | 122 | break; | 
|---|
|  | 123 | case STRING: | 
|---|
| [571] | 124 | std::memcpy( retVal.data+n, (const void*)( ( (std::string *) i->var)->c_str()), ( (std::string *)i->var )->length()+1); | 
|---|
| [565] | 125 | n+=((std::string *) i->var)->length()+1; | 
|---|
|  | 126 | break; | 
|---|
| [777] | 127 | } | 
|---|
| [565] | 128 | } | 
|---|
| [777] | 129 | return retVal; | 
|---|
| [247] | 130 | } | 
|---|
|  | 131 |  | 
|---|
| [777] | 132 | /** | 
|---|
|  | 133 | * This function takes a syncData struct and takes it to update the variables | 
|---|
|  | 134 | * @param vars data of the variables | 
|---|
|  | 135 | * @return true/false | 
|---|
|  | 136 | */ | 
|---|
|  | 137 | bool Synchronisable::updateData(syncData vars){ | 
|---|
|  | 138 | unsigned char *data=vars.data; | 
|---|
|  | 139 | std::list<synchronisableVariable>::iterator i; | 
|---|
|  | 140 | for(i=syncList.begin(); i!=syncList.end(); i++){ | 
|---|
|  | 141 | if((int)*data==i->size || i->type==STRING){ | 
|---|
|  | 142 | switch(i->type){ | 
|---|
| [565] | 143 | case DATA: | 
|---|
|  | 144 | data+=sizeof(int); | 
|---|
|  | 145 | memcpy((void*)i->var, data, i->size); | 
|---|
|  | 146 | data+=i->size; | 
|---|
|  | 147 | break; | 
|---|
|  | 148 | case STRING: | 
|---|
|  | 149 | i->size = (int)*data; | 
|---|
|  | 150 | data+=sizeof(int); | 
|---|
|  | 151 | *((std::string *)i->var) = std::string((const char*)data); | 
|---|
|  | 152 | data += i->size; | 
|---|
|  | 153 | break; | 
|---|
| [777] | 154 | } | 
|---|
|  | 155 | } else | 
|---|
|  | 156 | return false; //there was some problem with registerVar | 
|---|
|  | 157 | } | 
|---|
|  | 158 | return true; | 
|---|
| [237] | 159 | } | 
|---|
| [230] | 160 |  | 
|---|
| [777] | 161 | /** | 
|---|
|  | 162 | * This function returns the total amount of bytes needed by getData to save the whole content of the variables | 
|---|
|  | 163 | * @return amount of bytes | 
|---|
|  | 164 | */ | 
|---|
|  | 165 | int Synchronisable::getSize(){ | 
|---|
|  | 166 | int tsize=0; | 
|---|
|  | 167 | std::list<synchronisableVariable>::iterator i; | 
|---|
|  | 168 | for(i=syncList.begin(); i!=syncList.end(); i++){ | 
|---|
|  | 169 | switch(i->type){ | 
|---|
| [565] | 170 | case DATA: | 
|---|
| [656] | 171 | tsize+=sizeof(int); | 
|---|
| [565] | 172 | tsize+=i->size; | 
|---|
|  | 173 | break; | 
|---|
|  | 174 | case STRING: | 
|---|
| [656] | 175 | tsize+=sizeof(int); | 
|---|
| [565] | 176 | tsize+=((std::string *)i->var)->length()+1; | 
|---|
|  | 177 | break; | 
|---|
| [777] | 178 | } | 
|---|
| [565] | 179 | } | 
|---|
| [777] | 180 | return tsize; | 
|---|
| [565] | 181 | } | 
|---|
| [247] | 182 |  | 
|---|
|  | 183 | } | 
|---|