00001
00010 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00011 #pragma once
00012 #endif
00013 #ifndef COMMON_TOKDOC_H_
00014 #define COMMON_TOKDOC_H_
00015
00016 #include "Math.hpp"
00017
00018 namespace common {
00019
00020 #ifdef WIN32
00021 struct GameTime;
00022 #endif
00023
00024 class Tokenizer;
00025 class TokenWriter;
00026
00031 namespace tokdoc {
00032
00034 class Node
00035 {
00036 public:
00037 tstring Name, Value;
00038
00039 Node();
00040 Node(const Node &src);
00041 Node(const tstring &value);
00042 Node(const tstring &name, const tstring &value);
00043 ~Node();
00044
00045 Node & operator = (const Node &src);
00046
00047 void CopyFrom(const Node &src);
00048 void CopyChildrenFrom(const Node &src);
00049 void MoveChildrenFrom(Node *src);
00050
00052 void LoadChildren(Tokenizer &tok);
00053 void SaveChildren(TokenWriter &tok) const;
00054
00055 Node * GetParent() const { return m_Parent; }
00056 Node * GetFirstChild() const { return m_FirstChild; }
00057 Node * GetLastChild() const { return m_LastChild; }
00058 Node * GetPrevSibling() const { return m_PrevSibling; }
00059 Node * GetNextSibling() const { return m_NextSibling; }
00060
00061 Node * FindFirstChild(const tstring &name) const;
00062 Node * FindLastChild(const tstring &name) const;
00063 Node * FindPrevSibling(const tstring &name) const;
00064 Node * FindNextSibling(const tstring &name) const;
00065 Node & MustFindFirstChild(const tstring &name) const;
00066
00067 size_t CalcChildCount() const;
00068 size_t CalcChildCount(const tstring &name) const;
00069 bool HasChildren() const { return m_FirstChild != NULL; }
00070
00071 void Clear();
00072 void DeleteAllChildren();
00073 void DeleteAllChildren(const tstring &name);
00074
00075 void InsertChildAtBegin(const Node &addThis);
00076 void InsertChildAtEnd(const Node &addThis);
00077 void InsertChildBefore(Node *beforeThis, const Node &addThis);
00078 void InsertChildAfter(Node *afterThis, const Node &addThis);
00079 void DeleteChild(Node *deleteThis);
00080
00081 void LinkChildAtBegin(Node *addThis);
00082 void LinkChildAtEnd(Node *addThis);
00083 void LinkChildBefore(Node *beforeThis, Node *addThis);
00084 void LinkChildAfter(Node *afterThis, Node *addThis);
00085 void UnlinkChild(Node *deleteThis);
00086
00087 private:
00088 Node *m_Parent;
00089 Node *m_FirstChild, *m_LastChild;
00090 Node *m_PrevSibling, *m_NextSibling;
00091 };
00092
00094 template <typename T>
00095 inline void NodeValueFromSth(Node &node, const T &val)
00096 {
00097 SthToStr<T>(&node.Value, val);
00098 }
00099
00101 template <typename T>
00102 inline bool NodeValueToSth(T &out, const Node &node, bool required)
00103 {
00104 if (required)
00105 MustStrToSth<T>(&out, node.Value);
00106 else
00107 {
00108 T tmpVal;
00109 if (StrToSth(&tmpVal, node.Value))
00110 out = tmpVal;
00111 else
00112 return false;
00113 }
00114 return true;
00115 }
00116
00118
00120 void NodeValueFromEnum(Node &node, uint val,
00121 const tchar * const *itemNames, const uint *itemValues, uint itemCount);
00123
00125 bool NodeValueToEnum(uint &out, const Node &node, bool required,
00126 const tchar * const *itemNames, const uint *itemValues, uint itemCount);
00127
00128 template <typename T>
00129 inline void NodeFromVector(Node &node, const std::vector<T> &vec)
00130 {
00131 node.DeleteAllChildren();
00132 node.Value.clear();
00133
00134 for (size_t i = 0; i < vec.size(); i++)
00135 {
00136 Node *childNode = new Node();
00137 node.LinkChildAtEnd(childNode);
00138 NodeFrom(*childNode, vec[i]);
00139 }
00140 }
00141
00142 template <typename T>
00143 inline bool NodeToVector(std::vector<T> &out, const Node &node, bool required)
00144 {
00145 out.clear();
00146 T tmpVal;
00147 for (Node *childNode = node.FindFirstChild(EMPTY_STRING); childNode; childNode = childNode->FindNextSibling(EMPTY_STRING))
00148 {
00149 if (!NodeTo(tmpVal, childNode->Value, required))
00150 return false;
00151 out.push_back(tmpVal);
00152 }
00153 return true;
00154 }
00155
00157 inline bool _StrIsUintWithBase(const tstring &s)
00158 {
00159 return s.length() > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X');
00160 }
00161
00163 template <typename T>
00164 inline bool NodeValueToUint(T &out, const Node &node, bool required)
00165 {
00166 if (_StrIsUintWithBase(node.Value))
00167 {
00168 tstring valStr = node.Value.substr(2);
00169 bool ok = StrToUint(&out, valStr, 16) == 0;
00170 if (required && !ok)
00171 throw Error(_T("Cannot parse TokDoc node \"") + node.Name + _T("\" = \"") + node.Value + _T("\" to unsigned integer."), __TFILE__, __LINE__);
00172 return ok;
00173 }
00174 else
00175 return NodeValueToSth(out, node, required);
00176 }
00177
00178 template <typename T, typename UT>
00179 inline bool NodeValueToInt(T &out, const Node &node, bool required)
00180 {
00181 if (_StrIsUintWithBase(node.Value))
00182 return NodeValueToUint((UT&)out, node, required);
00183 else
00184 return NodeValueToSth(out, node, required);
00185 }
00186
00187 inline void NodeFrom(Node &node, bool val) { NodeValueFromSth(node, val); }
00188 inline void NodeFrom(Node &node, tchar val) { node.DeleteAllChildren(); node.Value.resize(1); node.Value[0] = val; }
00189 inline void NodeFrom(Node &node, const tstring &val) { node.DeleteAllChildren(); node.Value = val; }
00190 inline void NodeFrom(Node &node, const tchar *val) { node.DeleteAllChildren(); node.Value = val; }
00191 inline void NodeFrom(Node &node, uint1 val) { node.DeleteAllChildren(); NodeValueFromSth(node, val); }
00192 inline void NodeFrom(Node &node, uint2 val) { node.DeleteAllChildren(); NodeValueFromSth(node, val); }
00193 inline void NodeFrom(Node &node, uint4 val) { node.DeleteAllChildren(); NodeValueFromSth(node, val); }
00194 inline void NodeFrom(Node &node, uint8 val) { node.DeleteAllChildren(); NodeValueFromSth(node, val); }
00195 inline void NodeFrom(Node &node, int2 val) { node.DeleteAllChildren(); NodeValueFromSth(node, val); }
00196 inline void NodeFrom(Node &node, int4 val) { node.DeleteAllChildren(); NodeValueFromSth(node, val); }
00197 inline void NodeFrom(Node &node, int8 val) { node.DeleteAllChildren(); NodeValueFromSth(node, val); }
00198 inline void NodeFrom(Node &node, unsigned long val) { node.DeleteAllChildren(); NodeValueFromSth(node, val); }
00199 inline void NodeFrom(Node &node, long val) {node.DeleteAllChildren(); NodeValueFromSth(node, val); }
00200 inline void NodeFrom(Node &node, float val) { node.DeleteAllChildren(); NodeValueFromSth(node, val); }
00201 inline void NodeFrom(Node &node, double val) { node.DeleteAllChildren(); NodeValueFromSth(node, val); }
00202
00203 inline bool NodeTo(bool &out, const Node &node, bool required) { return NodeValueToSth(out, node, required); }
00204 inline bool NodeTo(tchar &out, const Node &node, bool required) { return NodeValueToSth(out, node, required); }
00205 inline bool NodeTo(tstring &out, const Node &node, bool required) { out = node.Value; return true; }
00206 inline bool NodeTo(uint1 &out, const Node &node, bool required) { return NodeValueToUint(out, node, required); }
00207 inline bool NodeTo(uint2 &out, const Node &node, bool required) { return NodeValueToUint(out, node, required); }
00208 inline bool NodeTo(uint4 &out, const Node &node, bool required) { return NodeValueToUint(out, node, required); }
00209 inline bool NodeTo(uint8 &out, const Node &node, bool required) { return NodeValueToUint(out, node, required); }
00210 inline bool NodeTo(unsigned long &out, const Node &node, bool required) { return NodeValueToUint(out, node, required); }
00211 inline bool NodeTo(int2 &out, const Node &node, bool required) { return NodeValueToInt<int2, uint2>(out, node, required); }
00212 inline bool NodeTo(int4 &out, const Node &node, bool required) { return NodeValueToInt<int4, uint4>(out, node, required); }
00213 inline bool NodeTo(int8 &out, const Node &node, bool required) { return NodeValueToInt<int8, uint8>(out, node, required); }
00214 inline bool NodeTo(long &out, const Node &node, bool required) { return NodeValueToInt<long, unsigned long>(out, node, required); }
00215 inline bool NodeTo(float &out, const Node &node, bool required) { return NodeValueToSth(out, node, required); }
00216 inline bool NodeTo(double &out, const Node &node, bool required) { return NodeValueToSth(out, node, required); }
00217
00218
00219
00220 #ifdef WIN32
00221 void NodeFrom(Node &node, GameTime val);
00222 bool NodeTo(GameTime &out, const Node &node, bool required);
00223 #endif // #ifdef WIN32
00224
00225
00226
00227 void NodeFrom(Node &node, const POINT_ &val);
00228 void NodeFrom(Node &node, const RECTI &val);
00229 void NodeFrom(Node &node, const VEC2 &val);
00230 void NodeFrom(Node &node, const VEC3 &val);
00231 void NodeFrom(Node &node, const VEC4 &val);
00232 void NodeFrom(Node &node, COLOR val);
00233 void NodeFrom(Node &node, const COLORF &val);
00234 void NodeFrom(Node &node, const RECTF &val);
00235 void NodeFrom(Node &node, const BOX &val);
00236 void NodeFrom(Node &node, const QUATERNION &val);
00237 void NodeFrom(Node &node, const MATRIX &val);
00238 void NodeFrom(Node &node, const LINE2D &val);
00239 void NodeFrom(Node &node, const PLANE &val);
00240
00241 bool NodeTo(POINT_ &out, const Node &node, bool required);
00242 bool NodeTo(RECTI &out, const Node &node, bool required);
00243 bool NodeTo(VEC2 &out, const Node &node, bool required);
00244 bool NodeTo(VEC3 &out, const Node &node, bool required);
00245 bool NodeTo(VEC4 &out, const Node &node, bool required);
00246 bool NodeTo(COLOR &out, const Node &node, bool required);
00247 bool NodeTo(COLORF &out, const Node &node, bool required);
00248 bool NodeTo(RECTF &out, const Node &node, bool required);
00249 bool NodeTo(BOX &out, const Node &node, bool required);
00250 bool NodeTo(QUATERNION &out, const Node &node, bool required);
00251 bool NodeTo(MATRIX &out, const Node &node, bool required);
00252 bool NodeTo(LINE2D &out, const Node &node, bool required);
00253 bool NodeTo(PLANE &out, const Node &node, bool required);
00254
00255
00256 template <typename T>
00257 void SubnodeFrom(Node &node, const tstring &subnodeName, const T &val)
00258 {
00259 Node *subnode = node.FindFirstChild(subnodeName);
00260 if (subnode == NULL)
00261 node.LinkChildAtEnd(subnode = new Node(subnodeName, EMPTY_STRING));
00262 NodeFrom(*subnode, val);
00263 }
00264
00266 enum SUBNODE_COND
00267 {
00268 SUBNODE_OPTIONAL_CORRECT,
00269 SUBNODE_REQUIRED,
00270 SUBNODE_OPTIONAL,
00271 };
00272
00273 template <typename T>
00274 bool SubnodeTo(T &out, const Node &node, const tstring &subnodeName, SUBNODE_COND required)
00275 {
00276 Node *subnode = node.FindFirstChild(subnodeName);
00277 if (subnode == NULL)
00278 {
00279 if (required == SUBNODE_REQUIRED)
00280 throw Error(_T("TokDoc subnode \"") + subnodeName + _T("\" not found"), __TFILE__, __LINE__);
00281 return false;
00282 }
00283 return NodeTo(out, *subnode, required != SUBNODE_OPTIONAL);
00284 }
00285
00286
00288
00289 }
00290 }
00291
00292 #endif