Variable.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "EditorDefs.h"
  9. #include "Variable.h"
  10. #include "UsedResources.h" // for CUsedResources
  11. //////////////////////////////////////////////////////////////////////////
  12. CVarBlock* CVarBlock::Clone(bool bRecursive) const
  13. {
  14. CVarBlock* vb = new CVarBlock;
  15. for (Variables::const_iterator it = m_vars.begin(); it != m_vars.end(); ++it)
  16. {
  17. IVariable* var = *it;
  18. vb->AddVariable(var->Clone(bRecursive));
  19. }
  20. return vb;
  21. }
  22. //////////////////////////////////////////////////////////////////////////
  23. void CVarBlock::CopyValues(const CVarBlock* fromVarBlock)
  24. {
  25. // Copy all variables.
  26. int numSrc = fromVarBlock->GetNumVariables();
  27. int numTrg = GetNumVariables();
  28. for (int i = 0; i < numSrc && i < numTrg; i++)
  29. {
  30. GetVariable(i)->CopyValue(fromVarBlock->GetVariable(i));
  31. }
  32. }
  33. //////////////////////////////////////////////////////////////////////////
  34. void CVarBlock::CopyValuesByName(CVarBlock* fromVarBlock)
  35. {
  36. // Copy values using saving and loading to/from xml.
  37. XmlNodeRef node = XmlHelpers::CreateXmlNode("Temp");
  38. fromVarBlock->Serialize(node, false);
  39. Serialize(node, true);
  40. }
  41. //////////////////////////////////////////////////////////////////////////
  42. void CVarBlock::OnSetValues()
  43. {
  44. for (Variables::iterator it = m_vars.begin(); it != m_vars.end(); ++it)
  45. {
  46. IVariable* var = *it;
  47. var->OnSetValue(true);
  48. }
  49. }
  50. //////////////////////////////////////////////////////////////////////////
  51. void CVarBlock::SetRecreateSplines()
  52. {
  53. for (Variables::iterator it = m_vars.begin(); it != m_vars.end(); ++it)
  54. {
  55. IVariable* var = *it;
  56. var->SetFlagRecursive(IVariable::UI_CREATE_SPLINE);
  57. }
  58. }
  59. //////////////////////////////////////////////////////////////////////////
  60. void CVarBlock::AddVariable(IVariable* var)
  61. {
  62. //assert( !strstr(var->GetName(), " ") ); // spaces not allowed because of serialization
  63. m_vars.push_back(var);
  64. }
  65. //////////////////////////////////////////////////////////////////////////
  66. void CVarBlock::AddVariable(IVariable* pVar, const char* varName, unsigned char dataType)
  67. {
  68. if (varName)
  69. {
  70. pVar->SetName(varName);
  71. }
  72. pVar->SetDataType(dataType);
  73. AddVariable(pVar);
  74. }
  75. //////////////////////////////////////////////////////////////////////////
  76. void CVarBlock::AddVariable(CVariableBase& var, const char* varName, unsigned char dataType)
  77. {
  78. if (varName)
  79. {
  80. var.SetName(varName);
  81. }
  82. var.SetDataType(dataType);
  83. AddVariable(&var);
  84. }
  85. //////////////////////////////////////////////////////////////////////////
  86. bool CVarBlock::DeleteVariable(IVariable* var, bool bRecursive)
  87. {
  88. bool found = stl::find_and_erase(m_vars, var);
  89. if (!found && bRecursive)
  90. {
  91. for (Variables::iterator it = m_vars.begin(); it != m_vars.end(); ++it)
  92. {
  93. if ((*it)->DeleteVariable(var, bRecursive))
  94. {
  95. return true;
  96. }
  97. }
  98. }
  99. return found;
  100. }
  101. //////////////////////////////////////////////////////////////////////////
  102. bool CVarBlock::IsContainsVariable(IVariable* pVar, bool bRecursive) const
  103. {
  104. for (Variables::const_iterator it = m_vars.begin(); it != m_vars.end(); ++it)
  105. {
  106. if (*it == pVar)
  107. {
  108. return true;
  109. }
  110. }
  111. // If not found search childs.
  112. if (bRecursive)
  113. {
  114. // Search all top level variables.
  115. for (Variables::const_iterator it = m_vars.begin(); it != m_vars.end(); ++it)
  116. {
  117. if ((*it)->IsContainsVariable(pVar))
  118. {
  119. return true;
  120. }
  121. }
  122. }
  123. return false;
  124. }
  125. namespace
  126. {
  127. IVariable* FindVariable(const char* name, bool bRecursive, bool bHumanName, const std::vector<IVariablePtr>& vars)
  128. {
  129. // Search all top level variables.
  130. for (std::vector<IVariablePtr>::const_iterator it = vars.begin(); it != vars.end(); ++it)
  131. {
  132. IVariable* var = *it;
  133. if (bHumanName && QString::compare(var->GetHumanName(), name, Qt::CaseInsensitive) == 0)
  134. {
  135. return var;
  136. }
  137. else if (!bHumanName && QString::compare(var->GetName(), name) == 0)
  138. {
  139. return var;
  140. }
  141. }
  142. // If not found search childs.
  143. if (bRecursive)
  144. {
  145. // Search all top level variables.
  146. for (std::vector<IVariablePtr>::const_iterator it = vars.begin(); it != vars.end(); ++it)
  147. {
  148. IVariable* var = *it;
  149. IVariable* found = var->FindVariable(name, bRecursive, bHumanName);
  150. if (found)
  151. {
  152. return found;
  153. }
  154. }
  155. }
  156. return nullptr;
  157. }
  158. }
  159. //////////////////////////////////////////////////////////////////////////
  160. IVariable* CVarBlock::FindVariable(const char* name, bool bRecursive, bool bHumanName) const
  161. {
  162. return ::FindVariable(name, bRecursive, bHumanName, m_vars);
  163. }
  164. //////////////////////////////////////////////////////////////////////////
  165. IVariable* CVariableArray::FindVariable(const char* name, bool bRecursive, bool bHumanName) const
  166. {
  167. return ::FindVariable(name, bRecursive, bHumanName, m_vars);
  168. }
  169. //////////////////////////////////////////////////////////////////////////
  170. void CVarBlock::Serialize(XmlNodeRef vbNode, bool load)
  171. {
  172. if (load)
  173. {
  174. // Loading.
  175. QString name;
  176. for (Variables::iterator it = m_vars.begin(); it != m_vars.end(); ++it)
  177. {
  178. IVariable* var = *it;
  179. if (var->GetNumVariables())
  180. {
  181. XmlNodeRef child = vbNode->findChild(var->GetName().toUtf8().data());
  182. if (child)
  183. {
  184. var->Serialize(child, load);
  185. }
  186. }
  187. else
  188. {
  189. var->Serialize(vbNode, load);
  190. }
  191. }
  192. }
  193. else
  194. {
  195. // Saving.
  196. for (Variables::iterator it = m_vars.begin(); it != m_vars.end(); ++it)
  197. {
  198. IVariable* var = *it;
  199. if (var->GetNumVariables())
  200. {
  201. XmlNodeRef child = vbNode->newChild(var->GetName().toUtf8().data());
  202. var->Serialize(child, load);
  203. }
  204. else
  205. {
  206. var->Serialize(vbNode, load);
  207. }
  208. }
  209. }
  210. }
  211. //////////////////////////////////////////////////////////////////////////
  212. void CVarBlock::ReserveNumVariables(int numVars)
  213. {
  214. m_vars.reserve(numVars);
  215. }
  216. //////////////////////////////////////////////////////////////////////////
  217. void CVarBlock::WireVar(IVariable* src, IVariable* trg, bool bWire)
  218. {
  219. if (bWire)
  220. {
  221. src->Wire(trg);
  222. }
  223. else
  224. {
  225. src->Unwire(trg);
  226. }
  227. int numSrcVars = src->GetNumVariables();
  228. if (numSrcVars > 0)
  229. {
  230. int numTrgVars = trg->GetNumVariables();
  231. for (int i = 0; i < numSrcVars && i < numTrgVars; i++)
  232. {
  233. WireVar(src->GetVariable(i), trg->GetVariable(i), bWire);
  234. }
  235. }
  236. }
  237. //////////////////////////////////////////////////////////////////////////
  238. void CVarBlock::Wire(CVarBlock* toVarBlock)
  239. {
  240. Variables::iterator tit = toVarBlock->m_vars.begin();
  241. Variables::iterator sit = m_vars.begin();
  242. for (; sit != m_vars.end() && tit != toVarBlock->m_vars.end(); ++sit, ++tit)
  243. {
  244. IVariable* src = *sit;
  245. IVariable* trg = *tit;
  246. WireVar(src, trg, true);
  247. }
  248. }
  249. //////////////////////////////////////////////////////////////////////////
  250. void CVarBlock::Unwire(CVarBlock* toVarBlock)
  251. {
  252. Variables::iterator tit = toVarBlock->m_vars.begin();
  253. Variables::iterator sit = m_vars.begin();
  254. for (; sit != m_vars.end() && tit != toVarBlock->m_vars.end(); ++sit, ++tit)
  255. {
  256. IVariable* src = *sit;
  257. IVariable* trg = *tit;
  258. WireVar(src, trg, false);
  259. }
  260. }
  261. //////////////////////////////////////////////////////////////////////////
  262. void CVarBlock::AddOnSetCallback(IVariable::OnSetCallback* func)
  263. {
  264. for (Variables::iterator it = m_vars.begin(); it != m_vars.end(); ++it)
  265. {
  266. IVariable* var = *it;
  267. SetCallbackToVar(func, var, true);
  268. }
  269. }
  270. //////////////////////////////////////////////////////////////////////////
  271. void CVarBlock::RemoveOnSetCallback(IVariable::OnSetCallback* func)
  272. {
  273. for (Variables::iterator it = m_vars.begin(); it != m_vars.end(); ++it)
  274. {
  275. IVariable* var = *it;
  276. SetCallbackToVar(func, var, false);
  277. }
  278. }
  279. //////////////////////////////////////////////////////////////////////////
  280. void CVarBlock::SetCallbackToVar(IVariable::OnSetCallback* func, IVariable* pVar, bool bAdd)
  281. {
  282. if (bAdd)
  283. {
  284. pVar->AddOnSetCallback(func);
  285. }
  286. else
  287. {
  288. pVar->RemoveOnSetCallback(func);
  289. }
  290. int numVars = pVar->GetNumVariables();
  291. if (numVars > 0)
  292. {
  293. for (int i = 0; i < numVars; i++)
  294. {
  295. SetCallbackToVar(func, pVar->GetVariable(i), bAdd);
  296. }
  297. }
  298. }
  299. //////////////////////////////////////////////////////////////////////////
  300. void CVarBlock::GatherUsedResources(CUsedResources& resources)
  301. {
  302. for (int i = 0; i < GetNumVariables(); i++)
  303. {
  304. IVariable* pVar = GetVariable(i);
  305. GatherUsedResourcesInVar(pVar, resources);
  306. }
  307. }
  308. //////////////////////////////////////////////////////////////////////////
  309. void CVarBlock::EnableUpdateCallbacks(bool boEnable)
  310. {
  311. for (int i = 0; i < GetNumVariables(); i++)
  312. {
  313. IVariable* pVar = GetVariable(i);
  314. pVar->EnableUpdateCallbacks(boEnable);
  315. }
  316. }
  317. //////////////////////////////////////////////////////////////////////////
  318. void CVarBlock::GatherUsedResourcesInVar(IVariable* pVar, CUsedResources& resources)
  319. {
  320. int type = pVar->GetDataType();
  321. if (type == IVariable::DT_TEXTURE)
  322. {
  323. // this is file.
  324. QString filename;
  325. pVar->Get(filename);
  326. if (!filename.isEmpty())
  327. {
  328. resources.Add(filename.toUtf8().data());
  329. }
  330. }
  331. for (int i = 0; i < pVar->GetNumVariables(); i++)
  332. {
  333. GatherUsedResourcesInVar(pVar->GetVariable(i), resources);
  334. }
  335. }
  336. //////////////////////////////////////////////////////////////////////////
  337. inline bool CompareNames(const IVariable* pVar1, const IVariable* pVar2)
  338. {
  339. return (QString::compare(pVar1->GetHumanName(), pVar2->GetHumanName(), Qt::CaseInsensitive) < 0);
  340. }
  341. //////////////////////////////////////////////////////////////////////////
  342. void CVarBlock::Sort()
  343. {
  344. std::sort(m_vars.begin(), m_vars.end(), CompareNames);
  345. }
  346. //////////////////////////////////////////////////////////////////////////
  347. CVarObject::CVarObject()
  348. {}
  349. //////////////////////////////////////////////////////////////////////////
  350. CVarObject::~CVarObject()
  351. {}
  352. //////////////////////////////////////////////////////////////////////////
  353. void CVarObject::AddVariable(CVariableBase& var, const QString& varName, VarOnSetCallback* cb, unsigned char dataType)
  354. {
  355. if (!m_vars)
  356. {
  357. m_vars = new CVarBlock;
  358. }
  359. var.AddRef(); // Variables are local and must not be released by CVarBlock.
  360. var.SetName(varName);
  361. var.SetDataType(dataType);
  362. if (cb)
  363. {
  364. var.AddOnSetCallback(cb);
  365. }
  366. m_vars->AddVariable(&var);
  367. }
  368. //////////////////////////////////////////////////////////////////////////
  369. void CVarObject::AddVariable(CVariableBase& var, const QString& varName, const QString& varHumanName, VarOnSetCallback* cb, unsigned char dataType)
  370. {
  371. if (!m_vars)
  372. {
  373. m_vars = new CVarBlock;
  374. }
  375. var.AddRef(); // Variables are local and must not be released by CVarBlock.
  376. var.SetName(varName);
  377. var.SetHumanName(varHumanName);
  378. var.SetDataType(dataType);
  379. if (cb)
  380. {
  381. var.AddOnSetCallback(cb);
  382. }
  383. m_vars->AddVariable(&var);
  384. }
  385. //////////////////////////////////////////////////////////////////////////
  386. void CVarObject::AddVariable(CVariableArray& table, CVariableBase& var, const QString& varName, const QString& varHumanName, VarOnSetCallback* cb, unsigned char dataType)
  387. {
  388. if (!m_vars)
  389. {
  390. m_vars = new CVarBlock;
  391. }
  392. var.AddRef(); // Variables are local and must not be released by CVarBlock.
  393. var.SetName(varName);
  394. var.SetHumanName(varHumanName);
  395. var.SetDataType(dataType);
  396. if (cb)
  397. {
  398. var.AddOnSetCallback(cb);
  399. }
  400. table.AddVariable(&var);
  401. }
  402. //////////////////////////////////////////////////////////////////////////
  403. void CVarObject::RemoveVariable(IVariable* var)
  404. {
  405. if (m_vars != nullptr)
  406. {
  407. m_vars->DeleteVariable(var);
  408. }
  409. }
  410. //////////////////////////////////////////////////////////////////////////
  411. void CVarObject::EnableUpdateCallbacks(bool boEnable)
  412. {
  413. if (m_vars != nullptr)
  414. {
  415. m_vars->EnableUpdateCallbacks(boEnable);
  416. }
  417. }
  418. //////////////////////////////////////////////////////////////////////////
  419. void CVarObject::OnSetValues()
  420. {
  421. if (m_vars != nullptr)
  422. {
  423. m_vars->OnSetValues();
  424. }
  425. }
  426. //////////////////////////////////////////////////////////////////////////
  427. void CVarObject::ReserveNumVariables(int numVars)
  428. {
  429. if (m_vars != nullptr)
  430. {
  431. m_vars->ReserveNumVariables(numVars);
  432. }
  433. }
  434. //////////////////////////////////////////////////////////////////////////
  435. void CVarObject::CopyVariableValues(CVarObject* sourceObject)
  436. {
  437. // Check if compatible types.
  438. assert(metaObject() == sourceObject->metaObject());
  439. if (m_vars != nullptr && sourceObject->m_vars != nullptr)
  440. {
  441. m_vars->CopyValues(sourceObject->m_vars);
  442. }
  443. }
  444. //////////////////////////////////////////////////////////////////////////
  445. void CVarObject::Serialize(XmlNodeRef node, bool load)
  446. {
  447. if (m_vars)
  448. {
  449. m_vars->Serialize(node, load);
  450. }
  451. }