/* Crystal Space Entity Layer Copyright (C) 2003 by Jorrit Tyberghein This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CEL_CELTOOL_PARAMS__ #define __CEL_CELTOOL_PARAMS__ #include "cstypes.h" #include "csutil/scf.h" #include "csutil/strhash.h" #include "csutil/util.h" #include "csutil/array.h" #include "csutil/stringarray.h" #include "behaviourlayer/behave.h" // The following macros will set 'var' to the required variable and // 'p_var' will be made to 0 if there is a failure. #define CEL_FETCH_STRING_PAR(var,params,id) \ const celData* p_##var = params ? params->GetParameter (id) : 0; \ const char* var = 0; \ if (p_##var && p_##var->type == CEL_DATA_STRING) { \ var = p_##var->value.s->GetData (); \ } else { p_##var = 0; } #define CEL_FETCH_VECTOR3_PAR(var,params,id) \ const celData* p_##var = params ? params->GetParameter (id) : 0; \ csVector3 var; \ if (p_##var && p_##var->type == CEL_DATA_VECTOR3) { \ var.Set (p_##var->value.v.x, p_##var->value.v.y, p_##var->value.v.z); \ } else { p_##var = 0; } #define CEL_FETCH_FLOAT_PAR(var,params,id) \ const celData* p_##var = params ? params->GetParameter (id) : 0; \ float var = 0.0f; \ if (p_##var) { \ if (p_##var->type == CEL_DATA_FLOAT) \ var = p_##var->value.f; \ else if (p_##var->type == CEL_DATA_LONG) \ var = float (p_##var->value.l); \ else p_##var = 0; \ } #define CEL_FETCH_LONG_PAR(var,params,id) \ const celData* p_##var = params ? params->GetParameter (id) : 0; \ long var = 0; \ if (p_##var) { \ if (p_##var->type == CEL_DATA_LONG) \ var = p_##var->value.l; \ else if (p_##var->type == CEL_DATA_FLOAT) \ var = long (p_##var->value.f); \ else p_##var = 0; \ } #define CEL_FETCH_BOOL_PAR(var,params,id) \ const celData* p_##var = params ? params->GetParameter (id) : 0; \ bool var = false; \ if (p_##var) { \ if (p_##var->type == CEL_DATA_BOOL) \ var = p_##var->value.bo; \ else if (p_##var->type == CEL_DATA_LONG) \ var = ((p_##var->value.l)? true : false); \ else p_##var = 0; \ } /** * Generic parameter block implementation. */ class celGenericParameterBlock : public iCelParameterBlock { private: size_t count; csStringID* ids; celData* data; char** names; public: celGenericParameterBlock (size_t count) { SCF_CONSTRUCT_IBASE (0); celGenericParameterBlock::count = count; ids = new csStringID[count]; data = new celData[count]; names = new char*[count]; memset (names, 0, sizeof (char*)*count); } virtual ~celGenericParameterBlock () { delete[] ids; delete[] data; size_t i; for (i = 0 ; i < count ; i++) delete[] names[i]; delete[] names; SCF_DESTRUCT_IBASE (); } void SetParameterDef (size_t idx, csStringID id, const char* parname) { ids[idx] = id; delete[] names[idx]; names[idx] = csStrNew (parname); } celData& GetParameter (size_t idx) { return data[idx]; } SCF_DECLARE_IBASE; virtual size_t GetParameterCount () const { return count; } virtual const char* GetParameter (size_t idx, csStringID& id, celDataType& t) const { if (/*idx < 0 || */idx >= count) { id = csInvalidStringID; t = CEL_DATA_NONE; return 0; } id = ids[idx]; t = data[idx].type; return names[idx]; } virtual const celData* GetParameter (csStringID id) const { size_t i; for (i = 0 ; i < count ; i++) if (id == ids[i]) return &data[i]; return 0; } virtual const celData* GetParameterByIndex (size_t idx) const { return (idx >= count) ? 0 : &data[idx]; } }; /** * Variable parameter block implementation. */ class celVariableParameterBlock : public iCelParameterBlock { private: csArray ids; csArray data; csStringArray names; public: celVariableParameterBlock () { SCF_CONSTRUCT_IBASE (0); } /** * Copy constructor. */ celVariableParameterBlock (iCelParameterBlock* other) { SCF_CONSTRUCT_IBASE (0); if (other != 0) { const char* name = 0; csStringID id; celDataType type; for (size_t idx = 0; idx < other->GetParameterCount (); idx++) { name = other->GetParameter (idx, id, type); SetParameterDef (idx, id, name); data.GetExtend (idx) = *other->GetParameter (id); } } } virtual ~celVariableParameterBlock () { SCF_DESTRUCT_IBASE (); } void SetParameterDef (size_t idx, csStringID id, const char* parname) { ids.GetExtend (idx) = id; if (idx >= names.Length ()) names.SetLength (idx+1); names.Put (idx, parname); } celData& GetParameter (size_t idx) { return data.GetExtend (idx); } SCF_DECLARE_IBASE; virtual size_t GetParameterCount () const { return data.Length (); } virtual const char* GetParameter (size_t idx, csStringID& id, celDataType& t) const { if (/*idx < 0 || */idx >= data.Length ()) { id = csInvalidStringID; t = CEL_DATA_NONE; return 0; } id = ids[idx]; t = data[idx].type; return names[idx]; } virtual const celData* GetParameter (csStringID id) const { size_t i; for (i = 0 ; i < data.Length () ; i++) if (id == ids[i]) return &data[i]; return 0; } virtual const celData* GetParameterByIndex (size_t idx) const { return (idx >= data.Length ()) ? 0 : &data[idx]; } }; /** * Parameter block implementation if only one parameter is desired. */ class celOneParameterBlock : public iCelParameterBlock { private: csStringID id; celData data; char* name; public: celOneParameterBlock () { SCF_CONSTRUCT_IBASE (0); name = 0; } virtual ~celOneParameterBlock () { delete[] name; SCF_DESTRUCT_IBASE (); } void SetParameterDef (csStringID id, const char* parname) { celOneParameterBlock::id = id; delete[] name; name = csStrNew (parname); } celData& GetParameter (int) { return data; } SCF_DECLARE_IBASE; virtual size_t GetParameterCount () const { return 1; } virtual const char* GetParameter (size_t idx, csStringID& id, celDataType& t) const { if (idx != 0) { id = csInvalidStringID; t = CEL_DATA_NONE; return 0; } id = celOneParameterBlock::id; t = data.type; return name; } virtual const celData* GetParameter (csStringID id) const { if (id != celOneParameterBlock::id) return 0; return &data; } virtual const celData* GetParameterByIndex (size_t idx) const { return (idx != 0) ? 0 : &data; } }; #endif // __CEL_CELTOOL_PARAMS__