/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ /*! \file load_param.h \brief A Class and macro-functions, that makes our lives easy to load-in parameters */ #ifndef _LOAD_PARAM_H #define _LOAD_PARAM_H #include "factory.h" #include "debug.h" #include "substring.h" // Forward Declaration // template class tList; /** useable FunctionParameters are: l_INT: int l_LONG: long l_SHORT: short l_FLOAT: float l_STRING: const char* */ #define l_INT_TYPE int #define l_INT_FUNC atoi #define l_INT_NAME "int" #define l_LONG_TYPE long #define l_LONG_FUNC atol #define l_LONG_NAME "long" #define l_SHORT_TYPE short #define l_SHORT_FUNC atoi #define l_SHORT_NAME "short" #define l_FLOAT_TYPE float #define l_FLOAT_FUNC atof #define l_FLOAT_NAME "float" #define l_STRING_TYPE const char* #define l_STRING_FUNC #define l_STRING_NAME "string" /** \brief a Macro to easily implement many different Constructors for the LoadParam-Class \param type1 The type of the first functionParameter */ #define LoadParam1(type1) \ LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE)) \ : BaseLoadParam(pt2Object, paramName, 1, type1##_NAME) \ { \ const char* loadString = grabParameter(root, paramName); \ if (loadString != NULL && root != NULL) \ (*pt2Object.*function)(type1##_FUNC(loadString)); \ else \ PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \ } // 2. TYPES #define LoadParam2(type1, type2) \ LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE)) \ : BaseLoadParam(pt2Object, paramName, 2, type1##_NAME, type2##_NAME) \ { \ const char* loadString = grabParameter(root, paramName); \ if (loadString != NULL && root != NULL) \ { \ SubString subLoads(loadString); \ if (subLoads.getCount() == 2) \ (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0)), type2##_FUNC(subLoads.getString(1))); \ else \ PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \ paramName, pt2Object->getClassName(), 2, subLoads.getCount()); \ } \ else \ PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \ } // 3. TYPES #define LoadParam3(type1, type2, type3) \ LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE))\ : BaseLoadParam(pt2Object, paramName, 3, type1##_NAME, type2##_NAME, type3##_NAME) \ { \ const char* loadString = grabParameter(root, paramName); \ if (loadString != NULL && root != NULL) \ { \ SubString subLoads(loadString); \ if (subLoads.getCount() == 3) \ (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0)), type2##_FUNC(subLoads.getString(1)), type3##_FUNC(subLoads.getString(2))); \ else \ PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \ paramName, pt2Object->getClassName(), 3, subLoads.getCount()); \ } \ else \ PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \ } // 4. TYPES #define LoadParam4(type1, type2, type3, type4) \ LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE, type4##_TYPE)) \ : BaseLoadParam(pt2Object, paramName, 4, type1##_NAME, type2##_NAME, type3##_NAME, type2##_NAME, type4##_NAME) \ { \ const char* loadString = grabParameter(root, paramName); \ if (loadString != NULL && root != NULL) \ { \ SubString subLoads(loadString); \ if (subLoads.getCount() == 4) \ (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0)), type2##_FUNC(subLoads.getString(1)), type3##_FUNC(subLoads.getString(2)), type4##_FUNC(subLoads.getString(3))); \ else \ PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \ paramName, pt2Object->getClassName(), 4, subLoads.getCount()); \ } \ else \ PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \ } // 5. TYPES #define LoadParam5(type1, type2, type3, type4, type5) \ LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE, type4##_TYPE, type5##_TYPE)) \ : BaseLoadParam(pt2Object, paramName, 5, type1##_NAME, type2##_NAME, type3##_NAME, type2##_NAME, type4##_NAME, type5##_NAME) \ { \ const char* loadString = grabParameter(root, paramName); \ if (loadString != NULL && root != NULL) \ { \ SubString subLoads(loadString); \ if (subLoads.getCount() == 5) \ (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0)), type2##_FUNC(subLoads.getString(1)), type3##_FUNC(subLoads.getString(2)), type4##_FUNC(subLoads.getString(3)), type5##_FUNC(subLoads.getString(4))); \ else \ PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \ paramName, pt2Object->getClassName(), 5, subLoads.getCount()); \ } \ else \ PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \ } class LoadParamDescription { friend class BaseLoadParam; friend class LoadClassDescription; public: LoadParamDescription(const char* paramName); ~LoadParamDescription(void); void setDescription(const char* descriptionText); /** \returns the descriptionString */ const char* getDescription(void) { return this->description;}; void print(void) const; private: char* paramName; int paramCount; char** types; const char* description; }; class LoadClassDescription { friend class BaseLoadParam; public: LoadClassDescription(const char* className); ~LoadClassDescription(void); static LoadClassDescription* addClass(const char* className); LoadParamDescription* addParam(const char* paramName); static void printAll(void); static bool parametersDescription; static tList* classList; private: char* className; tList* paramList; }; // abstract Base class class BaseLoadParam { public: void describe(const char* descriptionText); protected: BaseLoadParam(BaseObject* object, const char* paramName, int paramCount, ...); protected: LoadClassDescription* classDesc; LoadParamDescription* paramDesc; }; // derived template class template class LoadParam : public BaseLoadParam { public: LoadParam1(l_STRING); LoadParam2(l_STRING, l_STRING); LoadParam3(l_STRING, l_STRING, l_STRING); LoadParam4(l_STRING, l_STRING, l_STRING, l_STRING); LoadParam1(l_INT); LoadParam2(l_INT, l_INT); LoadParam3(l_INT, l_INT, l_INT); LoadParam4(l_INT, l_INT, l_INT, l_INT); LoadParam1(l_FLOAT); LoadParam2(l_FLOAT, l_FLOAT); LoadParam3(l_FLOAT, l_FLOAT, l_FLOAT); LoadParam4(l_FLOAT, l_FLOAT, l_FLOAT, l_FLOAT); }; #endif /* _LOAD_PARAM_H */