ArrayAttr.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. #include "arrayattr.h"
  2. #include "..\strutil.h"
  3. #include "..\bool\BoolAttr.h"
  4. #include "..\long\LongAttr.h"
  5. #include "..\float\FloatAttr.h"
  6. #include "..\position\positionAttr.h"
  7. #include "..\Rotation\RotationAttr.h"
  8. #include "..\String\StringAttr.h"
  9. #include "..\Color\ColorAttr.h"
  10. #include "..\Enumerate\EnumAttr.h"
  11. #include "..\attrcreator.h"
  12. #include "..\..\missioneditor.h"
  13. #include "..\..\forms\globalParams.h"
  14. extern IGUIManager* igui;
  15. extern MissionEditor* sMission;
  16. ArrayAttribute & ArrayAttribute::operator = (ArrayAttribute & source)
  17. {
  18. CleanUp ();
  19. int e_count = source.GetElementsCount();
  20. /* Копируем элементы массива */
  21. for (int n = 0; n < e_count; n++)
  22. {
  23. BaseAttribute* element = source.GetElement(n);
  24. BaseAttribute* copy = CreateAttributeCopy (element);
  25. AddElement(copy);
  26. }
  27. /* Установить макс/мин значения */
  28. SetMaxElementCount(source.GetMaxElementCount());
  29. SetMinElementCount(source.GetMinElementCount());
  30. /* Копируем значения массива */
  31. int val_count = source.GetValuesCount();
  32. for (int i = 0; i < val_count; i++)
  33. {
  34. ArrayElement* element = source.GetValue(i);
  35. ArrayElement newElement;
  36. Copy (newElement, *element);
  37. ArrayValues.Add(newElement);
  38. newElement.elements.DelAll();
  39. }
  40. /* копируем базовые аттрибуты */
  41. BaseAttribute::Copy(*this, source);
  42. return *this;
  43. }
  44. ArrayAttribute & ArrayAttribute::operator = (const IMOParams::Array& source)
  45. {
  46. CleanUp ();
  47. SetName (source.name);
  48. SetIsLimit (source.isLimit);
  49. int count = source.element.Size();
  50. for (int n = 0; n < count; n++)
  51. {
  52. IMOParams::Param* c_param = source.element[n];
  53. BaseAttribute* base_attr = CreateFromMissionParam (c_param);
  54. if (base_attr) AddElement(base_attr);
  55. }
  56. SetMaxElementCount(source.max);
  57. SetMinElementCount(source.min);
  58. Resize (min);
  59. return *this;
  60. }
  61. ArrayAttribute::ArrayAttribute () : ArrayValues (_FL_, 128)
  62. {
  63. RootNode = NULL;
  64. RootExpanded = false;
  65. sysDelete = false;
  66. Type = IMOParams::t_array;
  67. min = -1;
  68. max = -1;
  69. }
  70. ArrayAttribute::~ArrayAttribute ()
  71. {
  72. CleanUp ();
  73. }
  74. BaseAttribute* ArrayAttribute::GetElement (int index)
  75. {
  76. return defaultelement.elements[index];
  77. }
  78. void ArrayAttribute::AddElement (BaseAttribute* value)
  79. {
  80. defaultelement.elements.Add(value);
  81. }
  82. int ArrayAttribute::GetElementsCount ()
  83. {
  84. return defaultelement.elements.Size();
  85. }
  86. int ArrayAttribute::GetMinElementCount ()
  87. {
  88. return min;
  89. }
  90. int ArrayAttribute::GetMaxElementCount ()
  91. {
  92. return max;
  93. }
  94. void ArrayAttribute::SetMinElementCount (int min)
  95. {
  96. this->min = min;
  97. }
  98. void ArrayAttribute::SetMaxElementCount (int max)
  99. {
  100. this->max = max;
  101. }
  102. void ArrayAttribute::UpdateTree(GUITreeNode * node, string * v)
  103. {
  104. tmpText = GetName ();
  105. tmpText += " #c808080";
  106. tmpText += IntToStr(ArrayValues.Size());
  107. tmpText += " items";
  108. node->Image->Load("meditor\\array");
  109. node->Tag = TAG_ATTRIBUTE;
  110. node->Expanded = RootExpanded;
  111. node->CanDrag = false;
  112. node->CanDrop = false;
  113. node->CanCopy = false;
  114. node->Data = this;
  115. node->SetText(tmpText);
  116. }
  117. void ArrayAttribute::Add2Tree (GUITreeNodes* nodes, TreeNodesPool* nodesPool, string * v)
  118. {
  119. GUITreeNode* nNode = nodesPool->CreateNode();
  120. RootNode = nNode;
  121. UpdateTree(nNode);
  122. nodes->Add(nNode);
  123. string t;
  124. int ArrayValuesSize = ArrayValues.Size ();
  125. for (int n = 0; n < ArrayValuesSize; n++)
  126. {
  127. int el_num = ArrayValues[n].elements.Size();
  128. ArrayValues[n].info.array = this;
  129. ArrayValues[n].info.element = &ArrayValues[n];
  130. ArrayValues[n].itemNode = nodesPool->CreateNode();
  131. ArrayValues[n].itemNode->Tag = TAG_ARRAYITEM;
  132. ArrayValues[n].itemNode->Expanded = ArrayValues[n].Expanded;
  133. ArrayValues[n].itemNode->CanDrag = false;
  134. ArrayValues[n].itemNode->CanDrop = false;
  135. ArrayValues[n].itemNode->CanCopy = false;
  136. ArrayValues[n].itemNode->Data = &ArrayValues[n].info;
  137. t = "";
  138. for (int i = 0; i < el_num; i++)
  139. {
  140. BaseAttribute* attr = ArrayValues[n].elements[i];
  141. attr->Add2Tree(&ArrayValues[n].itemNode->Childs, nodesPool, &t);
  142. }
  143. if (t.IsEmpty())
  144. {
  145. gp->__tmpText.Format("item %d", n);
  146. } else
  147. {
  148. gp->__tmpText.Format("item %d (%s)", n, t.c_str());
  149. if (gp->__tmpText.Len() >= (TREE_VIEW_ITEM_LEN-10))
  150. {
  151. gp->__tmpText.Delete((TREE_VIEW_ITEM_LEN-10), gp->__tmpText.Size()- (TREE_VIEW_ITEM_LEN-10));
  152. gp->__tmpText += "...";
  153. }
  154. }
  155. ArrayValues[n].itemNode->SetText(gp->__tmpText.c_str());
  156. nNode->Childs.Add(ArrayValues[n].itemNode);
  157. }
  158. }
  159. void ArrayAttribute::PopupEdit (int pX, int pY)
  160. {
  161. Form = NEW TArrayEdit (0, 0);
  162. Form->SetPosition (pX, pY);
  163. Form->MasterAttrib = this;
  164. Form->eValue->Text = IntToStr (ArrayValues.Size());
  165. Form->eValue->Hint = GetName ();
  166. Form->eValue->Hint += "\n----------------------";
  167. Form->eValue->Hint += string ("\nmin :") + IntToStr (min);
  168. Form->eValue->Hint += string ("\nmax :") + IntToStr (max);
  169. Form->eValue->Hint += "\n----------------------";
  170. for (int n = 0; n < defaultelement.elements; n++)
  171. {
  172. IMOParams::Type type = defaultelement.elements[n]->GetType();
  173. string text = "undefined";
  174. switch (type)
  175. {
  176. case IMOParams::t_bool:
  177. text = "bool";
  178. break;
  179. case IMOParams::t_long:
  180. text = "long";
  181. break;
  182. case IMOParams::t_float:
  183. text = "float";
  184. break;
  185. case IMOParams::t_string:
  186. text = "string";
  187. break;
  188. case IMOParams::t_locstring:
  189. text = "locstring";
  190. break;
  191. case IMOParams::t_position:
  192. text = "position";
  193. break;
  194. case IMOParams::t_angles:
  195. text = "angles";
  196. break;
  197. case IMOParams::t_color:
  198. text = "color";
  199. break;
  200. case IMOParams::t_array:
  201. text = "array";
  202. break;
  203. case IMOParams::t_enum:
  204. text = "enum";
  205. break;
  206. }
  207. text += string (" ");
  208. text += defaultelement.elements[n]->GetName ();
  209. Form->eValue->Hint += string ("\n") + text;
  210. }
  211. igui->ShowModal (Form);
  212. // Обязательно нужно сделать...
  213. pForm = Form;
  214. }
  215. void ArrayAttribute::Copy (ArrayElement &to, ArrayElement &from)
  216. {
  217. for (DWORD n = 0; n < from.elements.Size(); n++)
  218. {
  219. BaseAttribute* added_attr = NULL;
  220. added_attr = CreateAttributeCopy (from.elements[n]);
  221. to.elements.Add(added_attr);
  222. }
  223. to.info.array = from.info.array;
  224. to.info.element = &to;
  225. }
  226. void ArrayAttribute::Resize (int NewSize)
  227. {
  228. if (!sysDelete)
  229. {
  230. if (NewSize < min) NewSize = min;
  231. if (NewSize > max) NewSize = max;
  232. }
  233. if (NewSize < 0) return;
  234. if ((int)ArrayValues.Size() == NewSize) return;
  235. int OldSize = ArrayValues.Size();
  236. // Надо убить массив...
  237. if (NewSize == 0)
  238. {
  239. int arraySize = ArrayValues.Size();
  240. for (int n = 0; n < arraySize; n++)
  241. {
  242. int el_num = ArrayValues[0].elements.Size();
  243. for (int i = 0; i < el_num; i++)
  244. {
  245. BaseAttribute* attr = ArrayValues[0].elements[i];
  246. DeleteAttribute(attr);
  247. //delete ();
  248. }
  249. ArrayValues.ExtractNoShift(0);
  250. }
  251. SetMasterData (MasterData);
  252. return;
  253. }
  254. // Уменьшить кол-во элементов
  255. if (OldSize > NewSize)
  256. {
  257. int DelCount = OldSize-NewSize;
  258. for (int n = 0; n < DelCount; n++)
  259. {
  260. int last = ArrayValues.Size() - 1;
  261. int el_num = ArrayValues[last].elements.Size();
  262. for (int i = 0; i < el_num; i++)
  263. {
  264. DeleteAttribute(ArrayValues[last].elements[i]);
  265. }
  266. ArrayValues.DelIndex(last);
  267. }
  268. SetMasterData (MasterData);
  269. return;
  270. }
  271. // Если нужно увеличить кол-во элементов
  272. if (OldSize < NewSize)
  273. {
  274. int AddElements = (NewSize - OldSize);
  275. ArrayElement NewElement;
  276. for (int n = 0; n < AddElements; n++)
  277. {
  278. Copy (NewElement, defaultelement);
  279. ArrayValues.Add(NewElement);
  280. NewElement.elements.DelAll();
  281. }
  282. SetMasterData (MasterData);
  283. return;
  284. }
  285. }
  286. void ArrayAttribute::BeforeDelete ()
  287. {
  288. for (int n = 0; n < ArrayValues; n++)
  289. {
  290. GUITreeNode* node = ArrayValues[n].itemNode;
  291. if (node)
  292. {
  293. ArrayValues[n].Expanded = node->Expanded;
  294. ArrayValues[n].itemNode = NULL;
  295. }
  296. int sz = ArrayValues[n].elements.Size();
  297. for (int j = 0; j < sz; j++)
  298. {
  299. ArrayValues[n].elements[j]->BeforeDelete();
  300. }
  301. }
  302. if (RootNode)
  303. {
  304. RootExpanded = RootNode->Expanded;
  305. RootNode = NULL;
  306. }
  307. }
  308. void ArrayAttribute::CleanUp ()
  309. {
  310. sysDelete = true;
  311. Resize (0);
  312. sysDelete = false;
  313. for (int n = 0; n < defaultelement.elements; n++)
  314. {
  315. //delete ;
  316. DeleteAttribute(defaultelement.elements[n]);
  317. }
  318. defaultelement.elements.DelAll ();
  319. }
  320. int ArrayAttribute::GetValuesCount ()
  321. {
  322. return ArrayValues.Size();
  323. }
  324. ArrayAttribute::ArrayElement* ArrayAttribute::GetValue (int index)
  325. {
  326. return &ArrayValues[index];
  327. }
  328. void ArrayAttribute::SetMasterData (void* data)
  329. {
  330. for (int n = 0; n < ArrayValues; n++)
  331. {
  332. int el_count = ArrayValues[n].elements.Size();
  333. for (int i = 0; i < el_count; i++)
  334. {
  335. ArrayValues[n].elements[i]->SetMasterData(data);
  336. }
  337. }
  338. BaseAttribute::SetMasterData (data);
  339. }
  340. void ArrayAttribute::AddToWriter (MOPWriter& wrt)
  341. {
  342. wrt.AddArray(ArrayValues.Size());
  343. for (int n = 0; n < ArrayValues; n++)
  344. {
  345. int el_count = ArrayValues[n].elements.Size();
  346. for (int i = 0; i < el_count; i++)
  347. {
  348. BaseAttribute* base = ArrayValues[n].elements[i];
  349. base->AddToWriter(wrt);
  350. }
  351. }
  352. }
  353. void ArrayAttribute::WriteToFile (IFile* pFile)
  354. {
  355. DWORD written = 0;
  356. DWORD slen = strlen (GetName ());
  357. written = pFile->Write(&slen, sizeof (DWORD));
  358. Assert (written == sizeof (DWORD));
  359. written = pFile->Write(GetName (), slen);
  360. Assert (written == slen);
  361. /* Записываем общее кол-во элементов */
  362. DWORD save_val = ArrayValues.Size();
  363. written = pFile->Write(&save_val, sizeof (DWORD));
  364. Assert (written == sizeof (DWORD));
  365. for (int n = 0; n < ArrayValues; n++)
  366. {
  367. int el_count = ArrayValues[n].elements.Size();
  368. /* Записываем кол-во элементов в структуре */
  369. DWORD save_val2 = el_count;
  370. written = pFile->Write(&save_val2, sizeof (DWORD));
  371. Assert (written == sizeof (DWORD));
  372. /* Записываем структуру */
  373. for (int i = 0; i < el_count; i++)
  374. {
  375. BaseAttribute* base = ArrayValues[n].elements[i];
  376. //base
  377. IMOParams::Type t = base->GetType ();
  378. DWORD dwType = (DWORD)t;
  379. written = pFile->Write(&dwType, sizeof (DWORD));
  380. Assert (written == sizeof (DWORD));
  381. base->WriteToFile(pFile);
  382. }
  383. }
  384. }
  385. void ArrayAttribute::LoadFromFile (IFile* pFile, const char* ClassName)
  386. {
  387. DWORD loaded = 0;
  388. DWORD slen = 0;
  389. loaded = pFile->Read(&slen, sizeof (DWORD));
  390. Assert (loaded == sizeof (DWORD));
  391. char* ldName = NEW char[slen+1];
  392. ldName[slen] = 0;
  393. loaded = pFile->Read(ldName, slen);
  394. Assert (loaded == slen);
  395. SetName (ldName);
  396. delete ldName;
  397. DWORD array_size = 0;
  398. loaded = pFile->Read(&array_size, sizeof (DWORD));
  399. Assert (loaded == sizeof (DWORD));
  400. for (DWORD i = 0; i < array_size; i++)
  401. {
  402. DWORD elements_count = 0;
  403. loaded = pFile->Read(&elements_count, sizeof (DWORD));
  404. Assert (loaded == sizeof (DWORD));
  405. ArrayElement newElement;
  406. for (DWORD j = 0; j < elements_count; j++)
  407. {
  408. DWORD dwType = 0;
  409. loaded = pFile->Read(&dwType, sizeof (DWORD));
  410. Assert (loaded == sizeof (DWORD));
  411. BaseAttribute* nAttr = CreateEmptyAttribute ((IMOParams::Type)dwType);
  412. nAttr->LoadFromFile(pFile, ClassName);
  413. BaseAttribute* added_attr = CreateAttributeCopy (nAttr);
  414. newElement.elements.Add(added_attr);
  415. DeleteAttribute(nAttr);
  416. }
  417. ArrayValues.Add(newElement);
  418. newElement.elements.DelAll();
  419. }
  420. int availCount = sMission->AvailableMO.Size ();
  421. for (int n = 0; n< availCount; n++)
  422. {
  423. MissionEditor::tAvailableMO* pMissionObject = &sMission->AvailableMO[n];
  424. // Если нашли нужный класс
  425. if (strcmp (pMissionObject->ClassName, ClassName) == 0)
  426. {
  427. BaseAttribute* pEthalonArray = pMissionObject->AttrList->FindInAttrList(Name, Type);
  428. if (pEthalonArray)
  429. {
  430. ArrayAttribute* EthalonArrayAttr = (ArrayAttribute*)pEthalonArray;
  431. //AfterLoad(EthalonArrayAttr, pMissionObject->AttrList);
  432. }
  433. }
  434. }
  435. }
  436. ArrayAttribute::ArrayElement& ArrayAttribute::GetDefaultElement ()
  437. {
  438. return defaultelement;
  439. }
  440. void ArrayAttribute::AfterLoad (BaseAttribute* baseattr, AttributeList* OriginalAttrList , const char* szClassName)
  441. {
  442. if (baseattr->GetType() != IMOParams::t_array) return;
  443. //api->Trace("array - %s\n", baseattr->GetName());
  444. ArrayAttribute* ArrayAttr = (ArrayAttribute*)baseattr;
  445. //SetMinElementCount(ArrayAttr->GetMinElementCount());
  446. //SetMaxElementCount(ArrayAttr->GetMaxElementCount());
  447. int availCount = sMission->AvailableMO.Size ();
  448. for (int n = 0; n< availCount; n++)
  449. {
  450. MissionEditor::tAvailableMO* pMissionObject = &sMission->AvailableMO[n];
  451. // Если нашли нужный класс
  452. if (strcmp (pMissionObject->ClassName, szClassName) == 0)
  453. {
  454. BaseAttribute* pEthalonArray = pMissionObject->AttrList->FindInAttrList(Name, Type);
  455. if (pEthalonArray)
  456. {
  457. ArrayAttribute* EthalonArrayAttr = (ArrayAttribute*)pEthalonArray;
  458. SetMinElementCount(EthalonArrayAttr->GetMinElementCount());
  459. SetMaxElementCount(EthalonArrayAttr->GetMaxElementCount());
  460. }
  461. }
  462. }
  463. Copy (defaultelement, ArrayAttr->GetDefaultElement());
  464. ArrayElement temp;
  465. for (int n = 0; n < ArrayValues; n++)
  466. {
  467. // Копируем в TEMP текущий элемент...
  468. Copy (temp, ArrayValues[n]);
  469. // Ощицаем текущую позицию в массиве...
  470. for (DWORD j = 0; j < ArrayValues[n].elements.Size(); j++)
  471. {
  472. //delete ArrayValues[n].elements[j];
  473. DeleteAttribute(ArrayValues[n].elements[j]);
  474. }
  475. ArrayValues[n].elements.DelAll();
  476. // Идем по атрибуту-эталону...
  477. for (DWORD i = 0; i < defaultelement.elements.Size(); i++)
  478. {
  479. BaseAttribute* etalon = defaultelement.elements[i];
  480. // Идем по загруженному аттрибуту...
  481. int found_index = -1;
  482. for (DWORD j = 0; j < temp.elements.Size(); j++)
  483. {
  484. BaseAttribute* loaded = temp.elements[j];
  485. // Они совпадают...
  486. if (crt_stricmp (loaded->GetName(), etalon->GetName()) == 0)
  487. {
  488. found_index = j;
  489. break;
  490. }
  491. } // Для всех элементов в загруженном аттрибуте...
  492. // found_index индекс нужного нам элемента
  493. if (found_index == -1)
  494. {
  495. BaseAttribute* AttrCopy = CreateAttributeCopy (etalon);
  496. ArrayValues[n].elements.Add(AttrCopy);
  497. } else
  498. {
  499. temp.elements[found_index]->AfterLoad(etalon, OriginalAttrList, szClassName);
  500. BaseAttribute* AttrCopy = CreateAttributeCopy (temp.elements[found_index]);
  501. ArrayValues[n].elements.Add(AttrCopy);
  502. }
  503. } // Для всех элементов в эталоне...
  504. for ( j = 0; j < temp.elements.Size(); j++)
  505. {
  506. DeleteAttribute(temp.elements[j]);
  507. //delete temp.elements[j];
  508. }
  509. temp.elements.DelAll();
  510. } // Для всего массива...
  511. //api->Trace("array max/min = %d / %d\n", max, min);
  512. }
  513. int ArrayAttribute::GetElementIndex (ArrayElement* element)
  514. {
  515. for (int n = 0; n < ArrayValues; n++)
  516. {
  517. if (&ArrayValues[n] == element) return n;
  518. }
  519. return -1;
  520. }
  521. void ArrayAttribute::RemoveValue (int index)
  522. {
  523. if ((int)ArrayValues.Size() <= min) return;
  524. // Убиваем аттрибуты...
  525. for (DWORD n =0; n < ArrayValues[index].elements.Size(); n++)
  526. {
  527. DeleteAttribute(ArrayValues[index].elements[n]);
  528. }
  529. // Удаляем кусочек...
  530. ArrayValues.DelIndex(index);
  531. SetMasterData (MasterData);
  532. }
  533. void ArrayAttribute::InsertValue (int index, ArrayAttribute::ArrayElement* copyfrom)
  534. {
  535. if ((int)ArrayValues.Size() >= max) return;
  536. ArrayElement NewElement;
  537. if (!copyfrom)
  538. Copy (NewElement, defaultelement);
  539. else
  540. Copy (NewElement, *copyfrom);
  541. ArrayValues.Insert(NewElement, index);
  542. NewElement.elements.DelAll();
  543. SetMasterData (MasterData);
  544. return;
  545. }
  546. void ArrayAttribute::DebugLog (int deep)
  547. {
  548. string mar;
  549. for (int q = 0; q <= deep; q++)
  550. {
  551. mar += " ";
  552. }
  553. for (dword j = 0; j < ArrayValues.Size(); j++)
  554. {
  555. for (dword n = 0 ; n < ArrayValues[j].elements.Size(); n++)
  556. {
  557. IMOParams::Type t = ArrayValues[j].elements[n]->GetType();
  558. api->Trace("%s[%d]%s - %s", mar.c_str(), j, ArrayValues[j].elements[n]->GetName(), AttributeList::GetTextType(t));
  559. if (t == IMOParams::t_array)
  560. {
  561. ArrayAttribute* pArray = (ArrayAttribute*)ArrayValues[j].elements[n];
  562. pArray->DebugLog (deep+1);
  563. }
  564. if (t == IMOParams::t_group)
  565. {
  566. GroupAttribute* pGroup = (GroupAttribute*)ArrayValues[j].elements[n];
  567. pGroup->DebugLog (deep+1);
  568. }
  569. }
  570. }
  571. }
  572. void ArrayAttribute::WriteToXML (TextFile &file, int level)
  573. {
  574. file.Write(level, "<array val = \"%s\">\n", GetName ());
  575. file.Write(level+1, "<items>\n");
  576. for (dword i = 0; i < ArrayValues.Size(); i++)
  577. {
  578. file.Write(level+2, "<item>\n");
  579. for (dword j = 0; j < ArrayValues[i].elements.Size(); j++)
  580. {
  581. BaseAttribute* base = ArrayValues[i].elements[j];
  582. base->WriteToXML(file, level+3);
  583. }
  584. file.Write(level+2, "</item>\n");
  585. }
  586. file.Write(level+1, "</items>\n");
  587. file.Write(level, "</array>\n");
  588. }
  589. void ArrayAttribute::ReadXML (TiXmlElement* Root, const char* szMasterClass)
  590. {
  591. const char* objectName = Root->Attribute("val");
  592. SetName(objectName);
  593. TiXmlElement* node = Root->FirstChildElement("items");
  594. if (node)
  595. {
  596. for(TiXmlElement* child = node->FirstChildElement(); child; child = child->NextSiblingElement())
  597. {
  598. ArrayElement newElement;
  599. const char* val = child->Value();
  600. if (crt_stricmp(val, "item") == 0)
  601. {
  602. //Нашли item массива
  603. //внутри может быть много разнотипных элементов итерируемся по ним...
  604. for(TiXmlElement* item_child = child->FirstChildElement(); item_child; item_child = item_child->NextSiblingElement())
  605. {
  606. IMOParams::Type type = AttributeList::GetTypeFromXML(item_child);
  607. BaseAttribute* nAttr = CreateEmptyAttribute (type);
  608. nAttr->ReadXML(item_child, szMasterClass);
  609. BaseAttribute* added_attr = CreateAttributeCopy (nAttr);
  610. newElement.elements.Add(added_attr);
  611. DeleteAttribute(nAttr);
  612. //delete nAttr;
  613. }
  614. }
  615. ArrayValues.Add(newElement);
  616. newElement.elements.DelAll();
  617. }
  618. }
  619. }