SceneObjectSet.cc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "sim/simBase.h"
  24. #include "string/stringTable.h"
  25. #include "console/console.h"
  26. #include "io/fileStream.h"
  27. #include "input/actionMap.h"
  28. #include "io/resource/resourceManager.h"
  29. #include "io/fileObject.h"
  30. #include "console/consoleInternal.h"
  31. #include "debug/profiler.h"
  32. #include "console/ConsoleTypeValidators.h"
  33. #include "memory/frameAllocator.h"
  34. #include "2d/sceneobject/SceneObject.h"
  35. #include "2d/sceneobject/SceneObjectSet.h"
  36. // Script bindings.
  37. #include "2d/sceneobject/SceneObjectSet_ScriptBinding.h"
  38. //-----------------------------------------------------------------------------
  39. IMPLEMENT_CONOBJECT(SceneObjectSet);
  40. //-----------------------------------------------------------------------------
  41. void SceneObjectSet::addObject(SceneObject* obj)
  42. {
  43. if ( obj == NULL )
  44. return;
  45. mObjectList.pushBack(obj);
  46. deleteNotify((SimObject*)obj);
  47. }
  48. void SceneObjectSet::removeObject(SceneObject* obj)
  49. {
  50. if ( obj == NULL )
  51. return;
  52. mObjectList.remove(obj);
  53. clearNotify((SimObject*)obj);
  54. }
  55. void SceneObjectSet::pushObject(SceneObject* pObj)
  56. {
  57. mObjectList.pushBackForce(pObj);
  58. deleteNotify((SimObject*)pObj);
  59. }
  60. void SceneObjectSet::popObject()
  61. {
  62. MutexHandle handle;
  63. if (mObjectList.size() == 0)
  64. {
  65. AssertWarn(false, "Stack underflow in SceneObjectSet::popObject");
  66. return;
  67. }
  68. SceneObject* pObject = mObjectList[mObjectList.size() - 1];
  69. mObjectList.removeStable(pObject);
  70. clearNotify((SimObject*)pObject);
  71. }
  72. //-----------------------------------------------------------------------------
  73. void SceneObjectSet::addTamlChild( SimObject* pSimObject )
  74. {
  75. // Sanity!
  76. AssertFatal( pSimObject != NULL, "SceneObjectSet::addTamlChild() - Cannot add a NULL child object." );
  77. addObject( dynamic_cast<SceneObject*>(pSimObject) );
  78. }
  79. //-----------------------------------------------------------------------------
  80. void SceneObjectSet::callOnChildren( const char * method, S32 argc, const char *argv[], bool executeOnChildGroups )
  81. {
  82. // Prep the arguments for the console exec...
  83. // Make sure and leave args[1] empty.
  84. const char* args[21];
  85. args[0] = method;
  86. for (S32 i = 0; i < argc; i++)
  87. args[i + 2] = argv[i];
  88. for( iterator i = begin(); i != end(); i++ )
  89. {
  90. SceneObject *childObj = static_cast<SceneObject*>(*i);
  91. if ( childObj == NULL )
  92. continue;
  93. if( childObj->isMethod( method ) )
  94. Con::execute(childObj, argc + 2, args);
  95. if( executeOnChildGroups )
  96. {
  97. SceneObjectSet* childSet = dynamic_cast<SceneObjectSet*>(*i);
  98. if ( childSet )
  99. childSet->callOnChildren( method, argc, argv, executeOnChildGroups );
  100. }
  101. }
  102. }
  103. //-----------------------------------------------------------------------------
  104. bool SceneObjectSet::reOrder( SceneObject *obj, SceneObject *target )
  105. {
  106. iterator itrS, itrD;
  107. if ( (itrS = find(begin(),end(),obj)) == end() )
  108. {
  109. return false; // object must be in list
  110. }
  111. if ( obj == target )
  112. {
  113. return true; // don't reorder same object but don't indicate error
  114. }
  115. if ( !target ) // if no target, then put to back of list
  116. {
  117. if ( itrS != (end()-1) ) // don't move if already last object
  118. {
  119. mObjectList.erase(itrS); // remove object from its current location
  120. mObjectList.push_back(obj); // push it to the back of the list
  121. }
  122. }
  123. else // if target, insert object in front of target
  124. {
  125. if ( (itrD = find(begin(),end(),target)) == end() )
  126. return false; // target must be in list
  127. mObjectList.erase(itrS);
  128. //Tinman - once itrS has been erased, itrD won't be pointing at the same place anymore - re-find...
  129. itrD = find(begin(),end(),target);
  130. mObjectList.insert(itrD,obj);
  131. }
  132. return true;
  133. }
  134. //-----------------------------------------------------------------------------
  135. void SceneObjectSet::onDeleteNotify(SimObject *object)
  136. {
  137. removeObject(dynamic_cast<SceneObject*>(object));
  138. Parent::onDeleteNotify(object);
  139. }
  140. void SceneObjectSet::onRemove()
  141. {
  142. mObjectList.sortId();
  143. if (mObjectList.size())
  144. {
  145. // This backwards iterator loop doesn't work if the
  146. // list is empty, check the size first.
  147. for (SceneObjectList::iterator ptr = mObjectList.end() - 1;
  148. ptr >= mObjectList.begin(); ptr--)
  149. {
  150. clearNotify(*ptr);
  151. }
  152. }
  153. Parent::onRemove();
  154. }
  155. //-----------------------------------------------------------------------------
  156. void SceneObjectSet::deleteObjects( void )
  157. {
  158. while(size() > 0 )
  159. {
  160. mObjectList[0]->deleteObject();
  161. }
  162. }
  163. //-----------------------------------------------------------------------------
  164. void SceneObjectSet::clear()
  165. {
  166. while (size() > 0)
  167. removeObject(mObjectList.last());
  168. }
  169. //-----------------------------------------------------------------------------
  170. SimObject *SceneObjectSet::findObject(const char *namePath)
  171. {
  172. // find the end of the object name
  173. S32 len;
  174. for(len = 0; namePath[len] != 0 && namePath[len] != '/'; len++)
  175. ;
  176. StringTableEntry stName = StringTable->lookupn(namePath, len);
  177. if(!stName)
  178. return NULL;
  179. for(SceneObjectSet::iterator i = begin(); i != end(); i++)
  180. {
  181. if((*i)->getName() == stName)
  182. {
  183. if(namePath[len] == 0)
  184. return *i;
  185. return (*i)->findObject(namePath + len + 1);
  186. }
  187. }
  188. return NULL;
  189. }
  190. //-----------------------------------------------------------------------------
  191. SceneObject* SceneObjectSet::findObjectByInternalName(const char* internalName, bool searchChildren)
  192. {
  193. iterator i;
  194. for (i = begin(); i != end(); i++)
  195. {
  196. SceneObject *childObj = static_cast<SceneObject*>(*i);
  197. if(childObj->getInternalName() == internalName)
  198. return childObj;
  199. else if (searchChildren)
  200. {
  201. SceneObjectSet* childSet = dynamic_cast<SceneObjectSet*>(*i);
  202. if (childSet)
  203. {
  204. SceneObject* found = childSet->findObjectByInternalName(internalName, searchChildren);
  205. if (found) return found;
  206. }
  207. }
  208. }
  209. return NULL;
  210. }
  211. //-----------------------------------------------------------------------------
  212. inline void SceneObjectSetIterator::Stack::push_back(SceneObjectSet* set)
  213. {
  214. increment();
  215. last().set = set;
  216. last().itr = set->begin();
  217. }
  218. //-----------------------------------------------------------------------------
  219. SceneObjectSetIterator::SceneObjectSetIterator(SceneObjectSet* set)
  220. {
  221. VECTOR_SET_ASSOCIATION(stack);
  222. if (!set->empty())
  223. stack.push_back(set);
  224. }
  225. //-----------------------------------------------------------------------------
  226. SceneObject* SceneObjectSetIterator::operator++()
  227. {
  228. SceneObjectSet* set;
  229. if ((set = dynamic_cast<SceneObjectSet*>(*stack.last().itr)) != 0)
  230. {
  231. if (!set->empty())
  232. {
  233. stack.push_back(set);
  234. return *stack.last().itr;
  235. }
  236. }
  237. while (++stack.last().itr == stack.last().set->end())
  238. {
  239. stack.pop_back();
  240. if (stack.empty())
  241. return 0;
  242. }
  243. return *stack.last().itr;
  244. }