Changeset 1052 for code/trunk/src/orxonox/core/XMLPort.h
- Timestamp:
- Apr 14, 2008, 3:42:49 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk/src/orxonox/core/XMLPort.h
r871 r1052 32 32 #include "util/MultiTypeMath.h" 33 33 #include "util/tinyxml/ticpp.h" 34 #include "util/SubString.h" 35 #include "Functor.h" 34 #include "Executor.h" 36 35 #include "Debug.h" 37 36 #include "CoreIncludes.h" … … 41 40 42 41 43 #define XMLPortParam(classname, paramname, loadfunction, savefunction, xmlelement, loading) \ 44 orxonox::XMLPortClassParamContainer<classname>* xmlcontainer##loadfunction##savefunction = (orxonox::XMLPortClassParamContainer<classname>*)(this->getIdentifier()->getXMLPortParamContainer(paramname)); \ 45 if (!xmlcontainer##loadfunction##savefunction) \ 42 #define XMLPortParam(classname, paramname, loadfunction, savefunction, xmlelement, mode) \ 43 XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, paramname, orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), #loadfunction), orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), #savefunction), xmlelement, mode) 44 #define XMLPortParam_Template(classname, paramname, loadtemplate, loadfunction, savetemplate, savefunction, xmlelement, mode) \ 45 XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, paramname, orxonox::createExecutor(orxonox::createFunctor loadtemplate (&classname::loadfunction), #loadfunction), orxonox::createExecutor(orxonox::createFunctor savetemplate (&classname::savefunction), #savefunction), xmlelement, mode) 46 47 #define XMLPortParamLoadOnly(classname, paramname, loadfunction, xmlelement, mode) \ 48 XMLPortParamGeneric(xmlcontainer##loadfunction##0, classname, paramname, orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), #loadfunction), 0, xmlelement, mode) 49 #define XMLPortParamLoadOnly_Template(classname, paramname, loadtemplate, loadfunction, xmlelement, mode) \ 50 XMLPortParamGeneric(xmlcontainer##loadfunction##0, classname, paramname, orxonox::createExecutor(orxonox::createFunctor loadtemplate (&classname::loadfunction), #loadfunction), 0, xmlelement, mode) 51 52 #define XMLPortParamGeneric(containername, classname, paramname, loadexecutor, saveexecutor, xmlelement, mode) \ 53 orxonox::XMLPortClassParamContainer<classname>* containername = (orxonox::XMLPortClassParamContainer<classname>*)(this->getIdentifier()->getXMLPortParamContainer(paramname)); \ 54 if (!containername) \ 46 55 { \ 47 xmlcontainer##loadfunction##savefunction = new orxonox::XMLPortClassParamContainer<classname>(this->getIdentifier()->getName(), std::string(paramname), createFunctor(&classname::loadfunction), createFunctor(&classname::savefunction)); \48 this->getIdentifier()->addXMLPortParamContainer(paramname, xmlcontainer##loadfunction##savefunction); \56 containername = new orxonox::XMLPortClassParamContainer<classname>(std::string(paramname), loadexecutor, saveexecutor); \ 57 this->getIdentifier()->addXMLPortParamContainer(paramname, containername); \ 49 58 } \ 50 xmlcontainer##loadfunction##savefunction->port(this, xmlelement, loading) 51 52 #define XMLPortParamLoadOnly(classname, paramname, loadfunction, xmlelement, loading) \ 53 orxonox::XMLPortClassParamContainer<classname>* xmlcontainer##loadfunction##savefunction = (orxonox::XMLPortClassParamContainer<classname>*)(this->getIdentifier()->getXMLPortParamContainer(paramname)); \ 54 if (!xmlcontainer##loadfunction##savefunction) \ 59 containername->port(this, xmlelement, mode) 60 61 62 #define XMLPortObject(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode, bApplyLoaderMask, bLoadBefore) \ 63 XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), #loadfunction), orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), #savefunction), xmlelement, mode, bApplyLoaderMask, bLoadBefore) 64 #define XMLPortObject_Template(classname, objectclass, sectionname, loadtemplate, loadfunction, savetemplate, savefunction, xmlelement, mode, bApplyLoaderMask, bLoadBefore) \ 65 XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, orxonox::createExecutor(orxonox::createFunctor loadtemplate (&classname::loadfunction), #loadfunction), orxonox::createExecutor(orxonox::createFunctor savetemplate (&classname::savefunction), #savefunction), xmlelement, mode, bApplyLoaderMask, bLoadBefore) 66 67 #define XMLPortObjectGeneric(containername, classname, objectclass, sectionname, loadexecutor, saveexecutor, xmlelement, mode, bApplyLoaderMask, bLoadBefore) \ 68 orxonox::XMLPortClassObjectContainer<classname, objectclass>* containername = (orxonox::XMLPortClassObjectContainer<classname, objectclass>*)(this->getIdentifier()->getXMLPortObjectContainer(sectionname)); \ 69 if (!containername) \ 55 70 { \ 56 xmlcontainer##loadfunction##savefunction = new orxonox::XMLPortClassParamContainer<classname>(this->getIdentifier()->getName(), std::string(paramname), createFunctor(&classname::loadfunction), 0); \57 this->getIdentifier()->addXMLPort ParamContainer(paramname, xmlcontainer##loadfunction##savefunction); \71 containername = new orxonox::XMLPortClassObjectContainer<classname, objectclass>(std::string(sectionname), loadexecutor, saveexecutor, bApplyLoaderMask, bLoadBefore); \ 72 this->getIdentifier()->addXMLPortObjectContainer(sectionname, containername); \ 58 73 } \ 59 xmlcontainer##loadfunction##savefunction->port(this, xmlelement, loading) 60 61 #define XMLPortObject(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, loading) \ 62 orxonox::XMLPortClassObjectContainer<classname, objectclass>* xmlcontainer##loadfunction##savefunction = (orxonox::XMLPortClassObjectContainer<classname, objectclass>*)(this->getIdentifier()->getXMLPortObjectContainer(sectionname)); \ 63 if (!xmlcontainer##loadfunction##savefunction) \ 64 { \ 65 xmlcontainer##loadfunction##savefunction = new orxonox::XMLPortClassObjectContainer<classname, objectclass>(this->getIdentifier()->getName(), std::string(sectionname), &classname::loadfunction, &classname::savefunction); \ 66 this->getIdentifier()->addXMLPortObjectContainer(sectionname, xmlcontainer##loadfunction##savefunction); \ 67 } \ 68 xmlcontainer##loadfunction##savefunction->port(this, xmlelement, loading) 74 containername->port(this, xmlelement, mode) 69 75 70 76 71 77 namespace orxonox 72 78 { 79 80 #ifndef _XMLPort_Mode__ 81 #define _XMLPort_Mode__ 82 namespace XMLPort 83 { 84 enum Mode 85 { 86 LoadObject, 87 SaveObject 88 }; 89 } 90 #endif 91 73 92 // ############################### 74 93 // ### XMLPortParamContainer ### … … 76 95 class _CoreExport XMLPortParamContainer 77 96 { 97 enum ParseResult 98 { 99 PR_not_started, 100 PR_finished, 101 PR_waiting_for_default_values 102 }; 103 78 104 public: 79 XMLPortParamContainer(); 105 XMLPortParamContainer() 106 { this->parseResult_ = PR_not_started; } 107 virtual ~XMLPortParamContainer() {} 80 108 81 109 inline const std::string& getName() const 82 110 { return this->paramname_; } 83 111 84 XMLPortParamContainer& description(const std::string description); 85 const std::string& getDescription(); 86 87 XMLPortParamContainer& defaultValues(const MultiTypeMath& param1 = MT_null, const MultiTypeMath& param2 = MT_null, const MultiTypeMath& param3 = MT_null, const MultiTypeMath& param4 = MT_null, const MultiTypeMath& param5 = MT_null) 88 { 89 this->defaultValues_[0] = param1; 90 this->defaultValues_[1] = param2; 91 this->defaultValues_[2] = param3; 92 this->defaultValues_[3] = param4; 93 this->defaultValues_[4] = param5; 94 95 return (*this); 96 } 112 virtual XMLPortParamContainer& description(const std::string description) = 0; 113 virtual const std::string& getDescription() = 0; 114 115 virtual XMLPortParamContainer& defaultValue(unsigned int index, const MultiTypeMath& param) = 0; 116 virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1) = 0; 117 virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2) = 0; 118 virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3) = 0; 119 virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3, const MultiTypeMath& param4) = 0; 120 virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3, const MultiTypeMath& param4, const MultiTypeMath& param5) = 0; 97 121 98 122 protected: 99 std::string classname_;100 123 std::string paramname_; 101 MultiTypeMath defaultValues_[5]; 102 103 private: 104 LanguageEntryLabel description_; 105 bool bAddedDescription_; 106 bool bAddedDefaultValues_; 124 ParseResult parseResult_; 125 107 126 }; 108 127 … … 110 129 class XMLPortClassParamContainer : public XMLPortParamContainer 111 130 { 131 struct ParseParams 132 { 133 T* object; 134 Element* xmlelement; 135 XMLPort::Mode mode; 136 }; 137 112 138 public: 113 XMLPortClassParamContainer(const std::string classname, const std::string paramname, FunctorMember<T>* loadfunction, FunctorMember<T>* savefunction) 114 { 115 this->classname_ = classname; 139 XMLPortClassParamContainer(const std::string paramname, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor) 140 { 116 141 this->paramname_ = paramname; 117 this->loadfunction_ = loadfunction; 118 this->savefunction_ = savefunction; 119 } 120 121 XMLPortParamContainer& port(T* object, Element& xmlelement, bool loading) 122 { 123 if (loading) 142 this->loadexecutor_ = loadexecutor; 143 this->saveexecutor_ = saveexecutor; 144 } 145 146 XMLPortParamContainer& port(T* object, Element& xmlelement, XMLPort::Mode mode) 147 { 148 this->parseParams_.object = object; 149 this->parseParams_.xmlelement = &xmlelement; 150 this->parseParams_.mode = mode; 151 152 if (mode == XMLPort::LoadObject) 124 153 { 125 154 try 126 155 { 127 156 std::string attribute = xmlelement.GetAttribute(this->paramname_); 128 if ( attribute.size() > 0)157 if ((attribute.size() > 0) || (this->loadexecutor_->allDefaultValuesSet())) 129 158 { 130 SubString tokens(attribute, ",", SubString::WhiteSpaces, false, '\\', '"', '(', ')', '\0'); 131 if ((unsigned int)tokens.size() >= (unsigned int)this->loadfunction_->getParamCount()) 132 { 133 COUT(5) << object->getLoaderIndentation() << "Loading parameter " << this->paramname_ << " in " << this->classname_ << " (objectname " << object->getName() << ") with "; 134 if (this->loadfunction_->getParamCount() == 1) 135 { 136 COUT(5) << "1 parameter (using whole string):" << std::endl; 137 COUT(5) << object->getLoaderIndentation() << " " << attribute << std::endl; 138 (*this->loadfunction_)(object, MultiTypeMath(attribute)); 139 } 140 else 141 { 142 COUT(5) << tokens.size() << " parameter (using MultiTypeMath)." << std::endl; 143 MultiTypeMath param1 = MT_null, param2 = MT_null, param3 = MT_null, param4 = MT_null, param5 = MT_null; 144 if (tokens.size() >= 1) param1 = tokens[0]; 145 if (tokens.size() >= 2) param2 = tokens[1]; 146 if (tokens.size() >= 3) param3 = tokens[2]; 147 if (tokens.size() >= 4) param4 = tokens[3]; 148 if (tokens.size() >= 5) param5 = tokens[4]; 149 COUT(5) << object->getLoaderIndentation() << " " << attribute << std::endl; 150 COUT(5) << object->getLoaderIndentation() << " " << param1 << ", " << param2 << ", " << param3 << ", " << param4 << ", " << param5 << std::endl; 151 152 (*this->loadfunction_)(object, param1, param2, param3, param4, param5); 153 } 154 } 159 COUT(5) << object->getLoaderIndentation() << "Loading parameter " << this->paramname_ << " in " << object->getIdentifier()->getName() << " (objectname " << object->getName() << ")." << std::endl << object->getLoaderIndentation(); 160 if (this->loadexecutor_->parse(object, attribute, ",")) 161 this->parseResult_ = PR_finished; 155 162 else 156 { 157 COUT(2) << object->getLoaderIndentation() << "Warning: Parameter \"" << this->paramname_ << "\" in \"" << this->classname_ << "\" (objectname: " << object->getName() << ") is incomplete and couln't be loaded." << std::endl; 158 } 163 this->parseResult_ = PR_waiting_for_default_values; 159 164 } 160 165 } … … 162 167 { 163 168 COUT(1) << std::endl; 164 COUT(1) << "An error occurred in XMLPort.h while loading attribute '" << this->paramname_ << "' of '" << this->classname_<< "' (objectname: " << object->getName() << ") in " << object->getLevelfile() << ":" << std::endl;169 COUT(1) << "An error occurred in XMLPort.h while loading attribute '" << this->paramname_ << "' of '" << object->getIdentifier()->getName() << "' (objectname: " << object->getName() << ") in " << object->getLevelfile() << ":" << std::endl; 165 170 COUT(1) << ex.what() << std::endl; 166 171 } … … 168 173 else 169 174 { 170 if (this->save function_)175 if (this->saveexecutor_) 171 176 { 172 177 // xmlelement.SetAttribute(this->paramname_, "..."); … … 177 182 } 178 183 184 XMLPortParamContainer& port(const ParseParams& parseParams) 185 { 186 return this->port(parseParams.object, *parseParams.xmlelement, parseParams.mode); 187 } 188 189 XMLPortParamContainer& portIfWaitingForDefaultValues(const ParseResult& result, const ParseParams& params) 190 { 191 if (result == PR_waiting_for_default_values) 192 return this->port(params); 193 else 194 return (*this); 195 } 196 197 virtual XMLPortParamContainer& description(const std::string description) 198 { this->loadexecutor_->setDescription(description); return (*this); } 199 virtual const std::string& getDescription() 200 { return this->loadexecutor_->getDescription(); } 201 202 virtual XMLPortParamContainer& defaultValue(unsigned int index, const MultiTypeMath& param) 203 { 204 if (!this->loadexecutor_->defaultValueSet(index)) 205 this->loadexecutor_->setDefaultValue(index, param); 206 return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_); 207 } 208 virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1) 209 { 210 if (!this->loadexecutor_->defaultValueSet(0)) 211 this->loadexecutor_->setDefaultValues(param1); 212 return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_); 213 } 214 virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2) 215 { 216 if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1))) 217 this->loadexecutor_->setDefaultValues(param1, param2); 218 return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_); 219 } 220 virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3) 221 { 222 if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2))) 223 this->loadexecutor_->setDefaultValues(param1, param2, param3); 224 return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_); 225 } 226 virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3, const MultiTypeMath& param4) 227 { 228 if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)) || (!this->loadexecutor_->defaultValueSet(3))) 229 this->loadexecutor_->setDefaultValues(param1, param2, param3, param4); 230 return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_); 231 } 232 virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3, const MultiTypeMath& param4, const MultiTypeMath& param5) 233 { 234 if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)) || (!this->loadexecutor_->defaultValueSet(3)) || (!this->loadexecutor_->defaultValueSet(4))) 235 this->loadexecutor_->setDefaultValues(param1, param2, param3, param4, param5); 236 return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_); 237 } 238 179 239 private: 180 FunctorMember<T>* loadfunction_; 181 FunctorMember<T>* savefunction_; 240 ExecutorMember<T>* loadexecutor_; 241 ExecutorMember<T>* saveexecutor_; 242 ParseParams parseParams_; 182 243 }; 183 244 … … 189 250 { 190 251 public: 191 XMLPortObjectContainer(); 252 XMLPortObjectContainer() 253 { this->bApplyLoaderMask_ = false; } 254 virtual ~XMLPortObjectContainer() {} 192 255 193 256 inline const std::string& getName() const 194 257 { return this->sectionname_; } 195 258 196 XMLPortObjectContainer& description(const std::string description); 197 const std::string& getDescription(); 198 static bool identifierIsIncludedInLoaderMask(const Identifier* identifier); 259 virtual XMLPortObjectContainer& description(const std::string description) = 0; 260 virtual const std::string& getDescription() = 0; 261 262 bool identifierIsIncludedInLoaderMask(const Identifier* identifier); 199 263 200 264 protected: 201 std::string classname_;202 265 std::string sectionname_; 203 204 private: 205 LanguageEntryLabel description_; 206 bool bAddedDescription_; 266 bool bApplyLoaderMask_; 267 bool bLoadBefore_; 207 268 }; 208 269 … … 211 272 { 212 273 public: 213 XMLPortClassObjectContainer(const std::string classname, const std::string sectionname, void (T::*loadfunction)(O*), const O* (T::*savefunction)(unsigned int)) 214 { 215 this->classname_ = classname; 274 XMLPortClassObjectContainer(const std::string sectionname, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor, bool bApplyLoaderMask, bool bLoadBefore) 275 { 216 276 this->sectionname_ = sectionname; 217 this->loadfunction_ = loadfunction; 218 this->savefunction_ = savefunction; 219 } 220 221 XMLPortObjectContainer& port(T* object, Element& xmlelement, bool loading) 222 { 223 if (loading) 277 this->loadexecutor_ = loadexecutor; 278 this->saveexecutor_ = saveexecutor; 279 this->bApplyLoaderMask_ = bApplyLoaderMask; 280 this->bLoadBefore_ = bLoadBefore; 281 } 282 283 XMLPortObjectContainer& port(T* object, Element& xmlelement, XMLPort::Mode mode) 284 { 285 if (mode == XMLPort::LoadObject) 224 286 { 225 287 try 226 288 { 227 Element* xmlsubelement = xmlelement.FirstChildElement(this->sectionname_, false); 289 Element* xmlsubelement; 290 if ((this->sectionname_ != "") && (this->sectionname_.size() > 0)) 291 xmlsubelement = xmlelement.FirstChildElement(this->sectionname_, false); 292 else 293 xmlsubelement = &xmlelement; 228 294 229 295 if (xmlsubelement) 230 296 { 231 for ( ticpp::Iterator<ticpp::Element> child = xmlsubelement->FirstChildElement(false); child != child.end(); child++)297 for (ticpp::Iterator<ticpp::Element> child = xmlsubelement->FirstChildElement(false); child != child.end(); child++) 232 298 { 233 299 Identifier* identifier = ID(child->Value()); … … 239 305 { 240 306 COUT(4) << object->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl; 307 241 308 O* newObject = (O*)identifier->fabricate(); 242 309 newObject->setLoaderIndentation(object->getLoaderIndentation() + " "); 243 310 newObject->setLevel(object->getLevel()); 244 newObject->XMLPort(*child, true); 245 COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->classname_ << " (objectname " << object->getName() << ")" << std::endl; 246 (*object.*this->loadfunction_)(newObject); 247 COUT(5) << " ...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl; 311 newObject->setNamespace(object->getNamespace()); 312 313 if (this->bLoadBefore_) 314 { 315 newObject->XMLPort(*child, XMLPort::LoadObject); 316 COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << object->getIdentifier()->getName() << " (objectname " << object->getName() << ")" << std::endl; 317 } 318 else 319 { 320 COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << object->getIdentifier()->getName() << " (objectname " << object->getName() << ")" << std::endl; 321 } 322 323 COUT(5) << object->getLoaderIndentation(); 324 (*this->loadexecutor_)(object, newObject); 325 326 if (!this->bLoadBefore_) 327 newObject->XMLPort(*child, XMLPort::LoadObject); 328 329 COUT(5) << object->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl; 248 330 } 249 331 } … … 263 345 { 264 346 COUT(1) << std::endl; 265 COUT(1) << "An error occurred in XMLPort.h while loading a '" << Class(O)->getName() << "' in '" << this->sectionname_ << "' of '" << this->classname_<< "' (objectname: " << object->getName() << ") in " << object->getLevelfile() << ":" << std::endl;347 COUT(1) << "An error occurred in XMLPort.h while loading a '" << Class(O)->getName() << "' in '" << this->sectionname_ << "' of '" << object->getIdentifier()->getName() << "' (objectname: " << object->getName() << ") in " << object->getLevelfile() << ":" << std::endl; 266 348 COUT(1) << ex.what() << std::endl; 267 349 } … … 274 356 } 275 357 358 virtual XMLPortObjectContainer& description(const std::string description) 359 { this->loadexecutor_->setDescription(description); return (*this); } 360 virtual const std::string& getDescription() 361 { return this->loadexecutor_->getDescription(); } 362 276 363 private: 277 void (T::*loadfunction_)(O*);278 const O* (T::*savefunction_)(unsigned int);364 ExecutorMember<T>* loadexecutor_; 365 ExecutorMember<T>* saveexecutor_; 279 366 }; 280 367 }
Note: See TracChangeset
for help on using the changeset viewer.