AppEasy Core SDK  1.5.0
Cross platform mobile and desktop app and game development SDK - The easy way to make apps
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines
CzXomlVariables.h
Go to the documentation of this file.
00001 // 
00002 //
00003 // AppEasy SDK - Cross Platform Multi-purpose Game and App Engine
00004 //
00005 // Developed by Matthew Hopwood of Pocketeers Limited - www.pocketeers.co.uk
00006 //
00007 // For updates, tutorials and more details check out www.appeasymobile.com
00008 //
00009 // This code is provided free of charge and without any warranty whatsoever. You must ensure that this whole notice is present in all files and derivatives, so the reader knows its origin.
00010 // If you use this SDK in your product then please ensure that you credit AppEasy's usage appropriately. Please see www.appeasymobile.com for licensing details and support
00011 //
00012 //
00013 
00014 #if !defined(_CZ_XOML_VARIABLES_H_)
00015 #define _CZ_XOML_VARIABLES_H_
00016 
00017 #include "CzString.h"
00018 #include "CzXoml.h"
00019 #include "CzSlotArray.h"
00020 #include "CzVec2.h"
00021 #include "CzIVec2.h"
00022 #include "CzVec3.h"
00023 #include "CzVec4.h"
00024 #include "CzRect.h"
00025 
00026 struct CzXomlVariable;
00027 class CzXomlVariableManager;
00028 
00029 
00030 //
00031 //
00032 //
00033 //
00034 //  CzXomlCondition - A condition represents the true or false state of a specific set of variables, operators and values
00035 //
00036 //
00037 //
00038 //
00039 enum eCzXomlConditionOperator
00040 {
00041     CO_None, 
00042     CO_Equal, 
00043     CO_NotEqual, 
00044     CO_Greater, 
00045     CO_GreaterEqual, 
00046     CO_Less, 
00047     CO_LessEqual, 
00048     CO_And, 
00049 };
00050 enum eCzXomlConditionJoinOp
00051 {
00052     CJO_None, 
00053     CJO_And, 
00054     CJO_Or, 
00055 };
00056 struct CzXomlCondition
00057 {
00058     CzXomlVariable*             Variable;           // The variable to check
00059     CzXomlVariable*             Variable2;          // The variable to check against
00060     eCzXomlConditionOperator    Operator;           // Determines how the variable and its value should be checked
00061     eCzXomlConditionJoinOp      Join;               // Join specifies the operator that should be applied to the next condition in a list of conditions
00062     CzString                    Value;              // Value to compare variable against
00063 
00064     CzXomlCondition() : Operator(CO_None), Join(CJO_None), Variable(NULL), Variable2(NULL)  {}
00065 };
00066 
00067 typedef CzList<CzXomlCondition*> CzXomlConditions;
00068 
00069 
00070 // 
00071 // 
00072 //
00073 //
00074 // CzXomlVariable - A basic XOML variable
00075 //
00076 //
00077 //
00078 //
00079 enum eCzXomlVariableType
00080 {
00081     VT_String, 
00082     VT_Bool, 
00083     VT_Float, 
00084     VT_Int, 
00085     VT_Vec2, 
00086     VT_Vec3, 
00087     VT_Vec4, 
00088     VT_ArrayString, 
00089     VT_ArrayBool, 
00090     VT_ArrayFloat, 
00091     VT_ArrayInt, 
00092     VT_Condition, 
00093     VT_XML, 
00094 };
00095 
00096 struct CzXomlVariable
00097 {
00098     // Properties
00099 protected:
00100     bool                        Persist;            ///< if true then this variable will persist when the app is closed down and restarted
00101     bool                        InstantSave;        ///< if true then this variable will saved as soon as it is changed otherwise it will be saved when it is destroyed
00102     CzString                    Value;              ///< Value of variable
00103     bool                        Changed;            ///< Internal changed status
00104 public:
00105     void                        setPersistent(bool persist)     { Persist = persist; }
00106     bool                        isPersistent() const            { return Persist; }
00107     void                        setInstantSave(bool instant)    { InstantSave = instant; }
00108     bool                        isInstantSave() const           { return InstantSave; }
00109     void                        setValueText(const char* value) { Value = value; Changed = true; }
00110     virtual void                setValue(const char* value, int count = -1)
00111     {
00112         if (count < 0)
00113             Value = value;
00114         else
00115             Value.setString(value, count);
00116         Changed = true;
00117     }
00118     virtual void                addValue(const char* value, const char* limit = NULL)   
00119     {
00120         Value += value; Changed = true;
00121     }
00122     CzString&                   getValue()                      { return Value; }
00123     virtual bool                isTrue()                        { return !Value.isEmpty(); }
00124     virtual bool                checkCondition(eCzXomlConditionOperator condition, const CzString& val);
00125     // Properties end
00126     CzXomlVariableManager*      Parent;             ///< Parent manager
00127     CzString                    Name;               ///< Name of variable
00128     eCzXomlVariableType         Type;               ///< Type of variable
00129     bool                        Modified;           ///< Modified since last read flag
00130 
00131     CzXomlVariable() : Type(VT_String), Modified(false), Changed(true), Persist(false), InstantSave(false) {}
00132     virtual ~CzXomlVariable() { Save(); }
00133 
00134     virtual void                Update()
00135     {
00136         if (Changed)
00137         {
00138             Modified = true;
00139             Changed = false;
00140             if (InstantSave)
00141                 Save();
00142         }
00143         else
00144             Modified = false;
00145     }
00146 
00147     bool                        isArray() const         { return Type >= VT_ArrayString && Type <= VT_ArrayInt; }
00148     bool                        isXML() const           { return Type == VT_XML; }
00149 
00150     virtual bool                Save();
00151     virtual bool                Load();
00152 
00153     // Utility
00154     static CzXomlVariable* GetVariable(const CzString& value, IzXomlResource* parent);
00155 
00156 };
00157 
00158 struct CzXomlVariableBool : CzXomlVariable
00159 {
00160     bool                        NativeValue;        ///< Native value of the variable
00161     CzXomlVariableBool() : CzXomlVariable() { Type = VT_Bool; }
00162     void                        setValue(const char* value, int count = -1)
00163     {
00164         CzXomlVariable::setValue(value, count);
00165         NativeValue = Value.getAsBool();
00166     }
00167     void                    addValue(const char* value, const char* limit = NULL)
00168     {
00169         NativeValue = !NativeValue;
00170         if (NativeValue)
00171             Value = "true";
00172         else
00173             Value = "false";
00174         Changed = true;
00175     }
00176     bool                    isTrue()            { return NativeValue; }
00177     bool                    checkCondition(eCzXomlConditionOperator condition, const CzString& val);
00178 };
00179 
00180 
00181 struct CzXomlVariableFloat : CzXomlVariable
00182 {
00183     float                       NativeValue;        ///< Native value of the variable
00184     CzXomlVariableFloat() : CzXomlVariable()  { Type = VT_Float; }
00185     void                        setValue(const char* value, int count = -1)
00186     {
00187         CzXomlVariable::setValue(value, count);
00188         NativeValue = Value.getAsFloat();
00189         Changed = true;
00190     }
00191     void                        addValue(const char* value, const char* limit = NULL)
00192     {
00193         if (limit != NULL)
00194         {
00195             float val = CzString(value).getAsFloat();
00196             if (val == 0)
00197                 return;
00198             float lim = CzString(limit).getAsFloat();
00199     
00200             NativeValue += val;
00201             if (val < 0)
00202             {
00203                 if (NativeValue < lim)
00204                     NativeValue = lim;
00205             }
00206             else
00207             if (val > 0)
00208             {
00209                 if (NativeValue > lim)
00210                     NativeValue = lim;
00211             }
00212         }
00213         else
00214             NativeValue += CzString(value).getAsFloat();
00215         Value = NativeValue;
00216         Changed = true;
00217     }
00218     bool                        isTrue()            { return NativeValue != 0; }
00219     bool                        checkCondition(eCzXomlConditionOperator condition, const CzString& val);
00220 };
00221 
00222 struct CzXomlVariableInt : CzXomlVariable
00223 {
00224     int                         NativeValue;        ///< Native value of the variable
00225     CzXomlVariableInt() : CzXomlVariable()  { Type = VT_Int; }
00226     void                        setValue(const char* value, int count = -1)
00227     {
00228         CzXomlVariable::setValue(value, count);
00229         NativeValue = Value.getAsInt();
00230         Changed = true;
00231     }
00232     void                        addValue(const char* value, const char* limit = NULL)
00233     {
00234         if (limit != NULL)
00235     {
00236             int val = CzString(value).getAsInt();
00237             int lim = CzString(limit).getAsInt();
00238         NativeValue += val;
00239         if (val < 0)
00240         {
00241             if (NativeValue < lim)
00242                 NativeValue = lim;
00243         }
00244         else
00245         if (val > 0)
00246         {
00247             if (NativeValue > lim)
00248                 NativeValue = lim;
00249         }
00250         }
00251         else
00252             NativeValue += CzString(value).getAsInt();
00253         Value = NativeValue;
00254         Changed = true;
00255     }
00256     bool                        isTrue()            { return NativeValue != 0; }
00257     bool                        checkCondition(eCzXomlConditionOperator condition, const CzString& val);
00258 };
00259 
00260 struct CzXomlVariableVec2 : CzXomlVariable
00261 {
00262     CzVec2                      NativeValue;        ///< Native value of the variable
00263     CzXomlVariableVec2() : CzXomlVariable()  { Type = VT_Vec2; }
00264     void                        setValue(const char* value, int count = -1)
00265     {
00266         CzXomlVariable::setValue(value, count);
00267         float components[8];
00268         if (Value.getAsListOfFloat(components) == 2)
00269         {
00270             NativeValue.x = components[0];
00271             NativeValue.y = components[1];
00272             Changed = true;
00273         }
00274     }
00275     void                        addValue(const char* value, const char* limit = NULL)
00276     {
00277         CzString add = value;
00278         float components[8];
00279         if (add.getAsListOfFloat(components) == 2)
00280         {
00281             NativeValue.x += components[0];
00282             NativeValue.y += components[1];
00283             Changed = true;
00284             Value = NativeValue.x;
00285             Value += ",";
00286             Value += NativeValue.y;
00287         }
00288     }
00289     bool                        isTrue()            { return NativeValue.x != 0 && NativeValue.y != 0; }
00290     bool                        checkCondition(eCzXomlConditionOperator condition, const CzString& val);
00291 };
00292 
00293 struct CzXomlVariableVec3 : CzXomlVariable
00294 {
00295     CzVec3                      NativeValue;        ///< Native value of the variable
00296     CzXomlVariableVec3() : CzXomlVariable()  { Type = VT_Vec3; }
00297     void                        setValue(const char* value, int count = -1)
00298     {
00299         CzXomlVariable::setValue(value, count);
00300         float components[8];
00301         if (Value.getAsListOfFloat(components) == 3)
00302         {
00303             NativeValue.x = components[0];
00304             NativeValue.y = components[1];
00305             NativeValue.z = components[2];
00306             Changed = true;
00307         }
00308     }
00309     void                        addValue(const char* value, const char* limit = NULL)
00310     {
00311         CzString add = value;
00312         float components[8];
00313         if (add.getAsListOfFloat(components) == 3)
00314         {
00315             NativeValue.x += components[0];
00316             NativeValue.y += components[1];
00317             NativeValue.z += components[2];
00318             Changed = true;
00319             Value = NativeValue.x;
00320             Value += ",";
00321             Value += NativeValue.y;
00322             Value += ",";
00323             Value += NativeValue.z;
00324         }
00325     }
00326     bool                        isTrue()            { return NativeValue.x != 0 && NativeValue.y != 0 && NativeValue.z != 0; }
00327     bool                        checkCondition(eCzXomlConditionOperator condition, const CzString& val);
00328 };
00329 
00330 struct CzXomlVariableVec4 : CzXomlVariable
00331 {
00332     CzVec4                      NativeValue;        ///< Native value of the variable
00333     CzXomlVariableVec4() : CzXomlVariable()  { Type = VT_Vec4; }
00334     void                        setValue(const char* value, int count = -1)
00335     {
00336         CzXomlVariable::setValue(value, count);
00337         float components[8];
00338         if (Value.getAsListOfFloat(components) == 4)
00339         {
00340             NativeValue.x = components[0];
00341             NativeValue.y = components[1];
00342             NativeValue.z = components[2];
00343             NativeValue.w = components[3];
00344             Changed = true;
00345         }
00346     }
00347     void                        addValue(const char* value, const char* limit = NULL)
00348     {
00349         CzString add = value;
00350         float components[8];
00351         if (add.getAsListOfFloat(components) == 4)
00352         {
00353             NativeValue.x += components[0];
00354             NativeValue.y += components[1];
00355             NativeValue.z += components[2];
00356             NativeValue.w += components[3];
00357             Changed = true;
00358             Value = NativeValue.x;
00359             Value += ",";
00360             Value += NativeValue.y;
00361             Value += ",";
00362             Value += NativeValue.z;
00363             Value += ",";
00364             Value += NativeValue.w;
00365         }
00366     }
00367     bool                        isTrue()            { return NativeValue.x != 0 && NativeValue.y != 0 && NativeValue.z != 0 && NativeValue.w != 0; }
00368     bool                        checkCondition(eCzXomlConditionOperator condition, const CzString& val);
00369 };
00370 
00371 struct CzXomlVariableXML : CzXomlVariable
00372 {
00373     // Properties
00374 protected:
00375     CzXmlParser*    Parser;
00376     CzXmlNode*      Root;                   ///< Root node
00377 public:
00378     CzXmlNode*      getRoot()       { return Root; }
00379     // Properties end
00380 public:
00381     CzXomlVariableXML() : CzXomlVariable(), Root(NULL), Parser(NULL) { Type = VT_XML; }
00382     virtual ~CzXomlVariableXML()
00383     {
00384         SAFE_DELETE(Parser);
00385     }
00386     void                        setValue(const char* value, int count = -1);
00387 };
00388 
00389 struct CzXomlVariableCondition : CzXomlVariable
00390 {
00391     bool                        NativeValue;        ///< Native value of a condition is boolean
00392     CzXomlConditions            Conditions;         ///< Conditions that should be checked to determine true or false
00393     CzXomlVariableCondition() : CzXomlVariable()  { Type = VT_Condition; }
00394     virtual ~CzXomlVariableCondition()
00395     {
00396         for (CzXomlConditions::iterator it = Conditions.begin(); it != Conditions.end(); ++it)
00397             delete *it;
00398     }
00399     void                        setValue(const char* value, int count = -1);
00400     void                        addValue(const char* value, const char* limit = NULL)   { }
00401     bool                        isTrue();
00402 };
00403 
00404 struct CzXomlVariableArray : public CzXomlVariable
00405 {
00406     // Properties
00407 protected:
00408     CzSlotArray<CzXomlVariable*>    Values;                     ///< Array of values
00409     CzXomlVariableXML*              XmlVar;                     ///< XML variable to copy attributes from
00410     unsigned int                    XmlTagNameHash;             ///< XML Tag name hash
00411     unsigned int                    XmlAttribNameHash;          ///< XML Attribute name hash
00412 #if defined(_DEBUG)
00413     CzString                        XmlTagName;
00414     CzString                        XmlAttribName;
00415 #endif
00416 protected:
00417     void                        UpdateFromXML();
00418 public:
00419     CzXomlVariable*             getElement(int index)                   { return Values.element_at(index); }
00420     void                        addElement(CzXomlVariable* var)         { Values.add(var); }
00421     int                         getSize() const                         { return Values.getSize(); }
00422     int                         getCount() const                        { return Values.count(); }
00423     void                        setValue(const char* value, int count = -1);
00424     virtual void                setValue(int index, const char* value)
00425     {
00426         if (index < 0 || index >= Values.getSize())
00427         {
00428 #if defined(_DEBUG)
00429             CzDebug::Log(CZ_DEBUG_CHANNEL_ERROR, "Array index out of bounds - ", Name.c_str());
00430 #endif  // _DEBUG
00431             return;
00432         }
00433         Changed = true;
00434 
00435         Values.element_at(index)->setValue(value);
00436     }
00437     CzXomlVariableXML*          getXmlVar()                             { return XmlVar; }
00438     void                        setXmlTagName(const char* name)
00439     {
00440 #if defined(_DEBUG)
00441         XmlTagName = name;
00442 #endif
00443         XmlTagNameHash = CZ_HASH(name);
00444     }
00445     void                        setXmlAttribName(const char* name)
00446     {
00447 #if defined(_DEBUG)
00448         XmlAttribName = name;
00449 #endif
00450         XmlAttribNameHash = CZ_HASH(name);
00451     }
00452     void                        BindXML(const char* binding);
00453     // Properties end
00454 
00455     CzXomlVariableArray()
00456     {
00457         XmlVar = NULL;
00458         Type = VT_ArrayString;
00459         Modified = false;
00460         Changed = false;
00461         XmlTagNameHash = 0;
00462         XmlAttribNameHash = 0;
00463     }
00464     virtual ~CzXomlVariableArray()
00465     {
00466         Save();
00467         for (int t = 0; t < Values.getSize(); t++)
00468         {
00469             if (Values.element_at(t) != NULL)
00470                 delete Values.element_at(t);
00471         }
00472     }
00473 
00474     virtual void    Init(int size)
00475     {
00476         Values.resize(size);
00477 
00478         for (int t = 0; t < size; t++)
00479         {
00480             if (Values.element_at(t) == NULL)
00481                 Values.set(t, new CzXomlVariable());
00482         }
00483     }
00484 
00485     void            Update();
00486 
00487     bool            Save();
00488     bool            Load();
00489     bool            checkCondition(eCzXomlConditionOperator condition, const CzString& val);
00490 
00491 };
00492 
00493 struct CzXomlVariableArrayBool : public CzXomlVariableArray
00494 {
00495     // Properties
00496 protected:
00497 public:
00498     // Properties end
00499 
00500     CzXomlVariableArrayBool()
00501     {
00502         Type = VT_ArrayBool;
00503         Modified = false;
00504         Changed = false;
00505     }
00506 
00507     virtual void Init(int size)
00508     {
00509         Values.resize(size);
00510 
00511         for (int t = 0; t < Values.getSize(); t++)
00512             Values.set(t, new CzXomlVariableBool());
00513     }
00514     bool            checkCondition(eCzXomlConditionOperator condition, const CzString& val);
00515 };
00516 
00517 struct CzXomlVariableArrayFloat : public CzXomlVariableArray
00518 {
00519     // Properties
00520 protected:
00521 public:
00522     // Properties end
00523 
00524     CzXomlVariableArrayFloat()
00525     {
00526         Type = VT_ArrayFloat;
00527         Modified = false;
00528         Changed = false;
00529     }
00530 
00531     virtual void Init(int size)
00532     {
00533         Values.resize(size);
00534 
00535         for (int t = 0; t < Values.getSize(); t++)
00536             Values.set(t, new CzXomlVariableFloat());
00537     }
00538     bool            checkCondition(eCzXomlConditionOperator condition, const CzString& val);
00539 };
00540 
00541 struct CzXomlVariableArrayInt : public CzXomlVariableArray
00542 {
00543     // Properties
00544 protected:
00545 public:
00546     // Properties end
00547 
00548     CzXomlVariableArrayInt()
00549     {
00550         Type = VT_ArrayInt;
00551         Modified = false;
00552         Changed = false;
00553     }
00554 
00555     virtual void Init(int size)
00556     {
00557         Values.resize(size);
00558 
00559         for (int t = 0; t < Values.getSize(); t++)
00560             Values.set(t, new CzXomlVariableInt());
00561     }
00562     bool            checkCondition(eCzXomlConditionOperator condition, const CzString& val);
00563 };
00564 
00565 
00566 // 
00567 // 
00568 //
00569 //
00570 // CzXomlVariableManager - Manages a collection of XOML variables
00571 //
00572 //
00573 //
00574 //
00575 class CzXomlVariableManager
00576 {
00577 public:
00578     // Public access to iteration
00579     typedef CzList<CzXomlVariable*>::iterator _Iterator;
00580     _Iterator               begin()     { return Variables.begin(); }
00581     _Iterator               end()       { return Variables.end(); }
00582 
00583 protected:
00584     // Properties
00585     CzList<CzXomlVariable*> Variables;          ///< A collection of xoml variables
00586     IzXomlResource*         Parent;             ///< Parent container
00587 public:
00588     void                    addVariable(CzXomlVariable* variable);
00589     CzXomlVariable* addVariable(const char* name, eCzXomlVariableType type = VT_String);
00590     CzXomlVariable* addVariable(const char* name, eCzXomlVariableType type, const char* value, int size);
00591     void                    removeVariable(CzXomlVariable* var);
00592     void                    removeVariable(unsigned int name_hash);
00593     void                    setVariable(unsigned int name_hash, const char* value);
00594     void                    setVariable(const char* name, const char* value);
00595     CzXomlVariable* findVariable(unsigned int name_hash);
00596     CzXomlVariable* findVariable(const char* name);
00597     void                    clearVariables();
00598     void                    setParent(IzXomlResource* scene)        { Parent = scene; }
00599     IzXomlResource*         getParent()                             { return Parent; }
00600     // Properties end
00601 
00602 public:
00603     CzXomlVariableManager() : Parent(NULL) {}
00604     virtual ~CzXomlVariableManager() { clearVariables(); }
00605 
00606     CzXomlVariable* CreateVariable(const char* name, eCzXomlVariableType type = VT_String);
00607 
00608     void                    Update()
00609     {
00610         for (_Iterator it = begin(); it != end(); ++it)
00611         {
00612             (*it)->Update();
00613         }
00614     }
00615 
00616     // Utility
00617     static CzXomlVariable*  FindVariable(const char* name, IzXomlResource* container);
00618     static CzXomlVariable*  FindVariable(unsigned int name_hash, IzXomlResource* container);
00619 };
00620 
00621 //
00622 //
00623 //
00624 //
00625 // CzXomlAddVariable utility class to allow XOML files to add variables
00626 // 
00627 //
00628 // 
00629 //
00630 class CzXomlAddVariable : public IzXomlResource
00631 {
00632 public:
00633 protected:
00634     // Properties
00635 public:
00636     // Properties end
00637 public:
00638     CzXomlAddVariable() : IzXomlResource() { setClassType("variable"); }
00639     // Implementation of IzXomlClass interface
00640     int                 LoadFromXoml(IzXomlResource* parebt, bool load_children, CzXmlNode* node);
00641 };
00642 
00643 class CzXomlAddVariableCreator : public IzXomlClassCreator
00644 {
00645 public:
00646     CzXomlAddVariableCreator()
00647     {
00648         setClassName("variable");
00649     }
00650     IzXomlResource* CreateInstance(IzXomlResource* parent)  { return new CzXomlAddVariable(); }
00651 };
00652 
00653 
00654 #endif  // _CZ_XOML_VARIABLES_H_