/* 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 //!< The type of an INT #define l_INT_FUNC atoi //!< the function to call to parse INT #define l_INT_NAME "int" //!< the name of an INT #define l_LONG_TYPE long //!< The type of a LONG #define l_LONG_FUNC atol //!< The function to parse a LONG #define l_LONG_NAME "long" //!< The name of a LONG #define l_SHORT_TYPE short //!< The type of a SHORT #define l_SHORT_FUNC atoi //!< The function to parse a SHORT #define l_SHORT_NAME "short" //!< The name of a SHORT #define l_FLOAT_TYPE float //!< The type of a FLOAT #define l_FLOAT_FUNC atof //!< The function to parse a FLOAT #define l_FLOAT_NAME "float" //!< The name of a FLOAT #define l_STRING_TYPE const char* //!< The type fo a STRING #define l_STRING_FUNC //!< The function to parse a STRING #define l_STRING_NAME "string" //!< The name of a STRING // 1. TYPE /** \brief a Macro to easily implement many different Constructors for the LoadParam-Class with 1 argument \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(root, pt2Object, paramName, 1, type1##_NAME) \ { \ 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 /** \brief a Macro to easily implement many different Constructors for the LoadParam-Class with 2 arguments \param type1 The type of the first functionParameter \param type2 The type of the second functionParameter */ #define LoadParam2(type1, type2) \ LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE)) \ : BaseLoadParam(root, pt2Object, paramName, 2, type1##_NAME, type2##_NAME) \ { \ 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 /** \brief a Macro to easily implement many different Constructors for the LoadParam-Class with 3 arguments \param type1 The type of the first functionParameter \param type2 The type of the second functionParameter \param type3 The type of the third functionParameter */ #define LoadParam3(type1, type2, type3) \ LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE))\ : BaseLoadParam(root, pt2Object, paramName, 3, type1##_NAME, type2##_NAME, type3##_NAME) \ { \ 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 /** \brief a Macro to easily implement many different Constructors for the LoadParam-Class with 4 arguments \param type1 The type of the first functionParameter \param type2 The type of the second functionParameter \param type3 The type of the third functionParameter \param type4 The type of the forth functionParameter */ #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(root, pt2Object, paramName, 4, type1##_NAME, type2##_NAME, type3##_NAME, type2##_NAME, type4##_NAME) \ { \ 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 /** \brief a Macro to easily implement many different Constructors for the LoadParam-Class with 5 arguments \param type1 The type of the first functionParameter \param type2 The type of the second functionParameter \param type3 The type of the third functionParameter \param type4 The type of the forth functionParameter \param type5 The type of the fifth functionParameter */ #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(root, pt2Object, paramName, 5, type1##_NAME, type2##_NAME, type3##_NAME, type2##_NAME, type4##_NAME, type5##_NAME) \ { \ 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()); \ } //! A class that handles the description of loadable parameters 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; //!< The name of the parameter int paramCount; //!< The count of parameters char** types; //!< What kind of parameters does this function take ?? char* description; //!< A longer description about this function }; //! A class for descriptions of a loadable module 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(const char* fileName = NULL); private: static bool parametersDescription; //!< if parameter-description should be enabled. static tList* classList; //!< a list, that holds all the loadable classes. (after one instance has been loaded) char* className; //!< name of the class tList* paramList; //!< List of parameters this class knows. }; //! abstract Base class for a Loadable parameter class BaseLoadParam { public: BaseLoadParam* describe(const char* descriptionText); protected: BaseLoadParam(const TiXmlElement* root, BaseObject* object, const char* paramName, int paramCount, ...); protected: LoadClassDescription* classDesc; //!< The LoadClassDescription of this LoadParameter LoadParamDescription* paramDesc; //!< The LoadParameterDescription of this LoadParameter const char* loadString; //!< The string loaded by this LoadParam }; //! derived template class, so all the Classes can load something. template class LoadParam : public BaseLoadParam { public: //! makes functions with one string loadable LoadParam1(l_STRING); //! makes functions with two strings loadable LoadParam2(l_STRING, l_STRING); //! makes functions with three strings loadable LoadParam3(l_STRING, l_STRING, l_STRING); //! makes functions with four strings loadable LoadParam4(l_STRING, l_STRING, l_STRING, l_STRING); //! makes functions with one int loadable LoadParam1(l_INT); //! makes functions with two ints loadable LoadParam2(l_INT, l_INT); //! makes functions with three ints loadable LoadParam3(l_INT, l_INT, l_INT); //! makes functions with four ints loadable LoadParam4(l_INT, l_INT, l_INT, l_INT); //! makes functions with one float loadable LoadParam1(l_FLOAT); //! makes functions with two floats loadable LoadParam2(l_FLOAT, l_FLOAT); //! makes functions with three floats loadable LoadParam3(l_FLOAT, l_FLOAT, l_FLOAT); //! makes functions with four floats loadable LoadParam4(l_FLOAT, l_FLOAT, l_FLOAT, l_FLOAT); }; #endif /* _LOAD_PARAM_H */