RioEngine  0.1
My first attempt to create a 3D WYSIWYG Game Engine
cactionmanager.cpp
Go to the documentation of this file.
1 //--------------------------------------------------------------- @License begins
2 // cocos2d for iPhone: http://www.cocos2d-iphone.org
3 // -> This file was ported to C++ by Leopoldo Lomas Flores just for fun.
4 // I suggest you get the official C++ version of this file from:
5 // http://www.cocos2d-x.org/
6 //
7 // Copyright (c) 2008-2011 Ricardo Quesada
8 // Copyright (c) 2011 Zynga Inc.
9 // Copyright (c) 2013-2014 Cocos2D Authors
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //--------------------------------------------------------------- @License ends
29 
30 #include "misc/genericshelper.hpp"
31 #include "cengine/cgameobject.h"
32 #include "caction.h"
33 #include "cactionmanager.h"
34 
35 //-----------------------------------------------------------------------------
36 
38  m_currentTarget = m_targets = NULL;
39 }
40 
41 //-----------------------------------------------------------------------------
42 
43 void CActionManager::removeActionAtIndex(unsigned int index, tHashElement* element) {
44  CAction* action = element->actions.at(index);
45 
46  if ( action == element->currentAction && !element->currentActionSalvaged ) {
47  element->currentAction->retain();
48  element->currentActionSalvaged = true;
49  }
50 
52 
53  // update actionIndex in case we are in tick:, looping over the actions
54  if ( element->actionIndex >= index )
55  element->actionIndex--;
56 
57  if ( element->actions.size() == 0 ) {
58  if ( m_currentTarget == element )
59  m_currentTargetSalvaged = true;
60  else
61  deleteHashElement(element);
62  }
63 }
64 
65 //-----------------------------------------------------------------------------
66 
67 void CActionManager::deleteHashElement(tHashElement* element) {
68  HASH_DEL(m_targets, element);
69  SAFE_RELEASE(element->target);
70  SAFE_RELEASE(element);
71 }
72 
73 //-----------------------------------------------------------------------------
74 
76  tHashElement* element = NULL;
77  HASH_FIND_INT(m_targets, &target, element);
78  if (element)
79  element->paused = true;
80 }
81 
82 //-----------------------------------------------------------------------------
83 
85  tHashElement* element = NULL;
86  HASH_FIND_INT(m_targets, &target, element);
87  if (element)
88  element->paused = false;
89 }
90 
91 //-----------------------------------------------------------------------------
92 
93 // TODO
94 //CPointerArray<CGameObject>* CActionManager::pauseAllRunningActions() {
95 // std::vector<CGameObject*>* objects_paused = new std::vector<CGameObject*>();
96 
97 // for ( tHashElement *element=m_targets;
98 // element != NULL;
99 // element = (tHashElement*)element->hh.next ) {
100 // if ( !element->paused ) {
101 // element->paused = true;
102 // objects_paused->push_back(element->target);
103 // }
104 // }
105 // return CPointerArray<CGameObject>::fromStdVector( objects_paused );
106 //}
107 
108 //-----------------------------------------------------------------------------
109 
110 void CActionManager::addAction(CAction* action, CGameObject* target, bool paused) {
111  RE_ASSERT(action);
112  RE_ASSERT(target);
113 
114  SAFE_RETAIN(action);
115 
116  tHashElement *element = NULL;
117  HASH_FIND_INT(m_targets, &target, element);
118  if ( ! element ) {
119  element = new tHashElement;
120  element->paused = paused;
121  element->target = (CGameObject*)target->retain();
122  HASH_ADD_INT(m_targets, target, element);
123  }
124 
125  element->actions.push_back(action);
126  action->startWithTarget(target);
127 }
128 
129 //-----------------------------------------------------------------------------
130 
132  for (tHashElement *element=m_targets; element != NULL; ) {
133  CGameObject* target = element->target;
134  element = (tHashElement*)element->hh.next;
136  }
137 }
138 
139 //-----------------------------------------------------------------------------
140 
142  // explicit NULL handling
143  if ( target == NULL )
144  return;
145 
146  tHashElement *element = NULL;
147  HASH_FIND_INT(m_targets, &target, element);
148  if ( element ) {
149  //std::vector<CAction*> element_actions = element->actions;
150  if ( std::find(element->actions.begin(),
151  element->actions.end(),
152  element->currentAction) != element->actions.end() ) {
153  element->currentAction->retain();
154  m_currentTargetSalvaged = true;
155  }
156  for (std::vector<CAction*>::iterator it = element->actions.begin();
157  it != element->actions.end();
158  ++it) {
159  SAFE_RELEASE(*it);
160  }
161  if ( m_currentTarget == element)
162  m_currentTargetSalvaged = true;
163  else
164  deleteHashElement(element);
165  }
166 }
167 
168 //-----------------------------------------------------------------------------
169 
171  // explicit NULL handling
172  if (!action)
173  return;
174 
175  tHashElement* element = NULL;
176  CGameObject* target = action->getOriginalTarget();
177  HASH_FIND_INT(m_targets, &target, element);
178 
179  if ( element ) {
180  int index = GenericsHelper::getIndexOfObjectInVector<CAction>(&element->actions, action);
181  if ( index > -1 )
182  removeActionAtIndex(index, element);
183  }
184 }
185 
186 //-----------------------------------------------------------------------------
187 
188 void CActionManager::removeActionByTag(unsigned int tag, CGameObject* target) {
189  //RE_ASSERT( aTag != kCCActionTagInvalid, @"Invalid tag");
190  RE_ASSERT( target );
191 
192  tHashElement* element = NULL;
193  HASH_FIND_INT(m_targets, &target, element);
194 
195  if ( element ) {
196  CAction* a = NULL;
197  for (std::vector<CAction*>::iterator it = element->actions.begin();
198  it != element->actions.end();
199  ++it) {
200  a = *it;
201 
202  if ( a->tag == tag && a->getOriginalTarget() == target) {
203  removeActionAtIndex(std::distance(element->actions.begin(), it), element);
204  break;
205  }
206  }
207  }
208 }
209 
210 //-----------------------------------------------------------------------------
211 
213  //RE_ASSERT( aTag != kCCActionTagInvalid, @"Invalid tag");
214 
215  tHashElement* element = NULL;
216  HASH_FIND_INT(m_targets, &target, element);
217 
218  if ( element ) {
219  if ( element->actions.size() == 0 ) {
220  CAction* iterated_action = NULL;
221  for (std::vector<CAction*>::iterator it = element->actions.begin();
222  it != element->actions.end();
223  ++it) {
224  iterated_action = *it;
225  if ( iterated_action->tag == tag )
226  return iterated_action;
227  }
228  }
229  }
230  return NULL;
231 }
232 
233 //-----------------------------------------------------------------------------
234 
236  tHashElement* element = NULL;
237  HASH_FIND_INT(m_targets, &target, element);
238 
239  if ( element )
240  return ( element->actions.size() > 0 ? element->actions.size() : 0 );
241 
242  return 0;
243 }
244 
245 //-----------------------------------------------------------------------------
246 
247 void CActionManager::update(double dt) {
248  for ( tHashElement *elt = m_targets; elt != NULL; ) {
249  m_currentTarget = elt;
250  m_currentTargetSalvaged = false;
251 
252  if ( !m_currentTarget->paused ) {
253  // The 'actions' ccArray may change while inside this loop.
254  for ( m_currentTarget->actionIndex = 0;
255  m_currentTarget->actionIndex < m_currentTarget->actions.size();
256  m_currentTarget->actionIndex++) {
257  m_currentTarget->currentAction = m_currentTarget->actions.at(m_currentTarget->actionIndex);
258  m_currentTarget->currentActionSalvaged = false;
259 
260  m_currentTarget->currentAction->step(dt);
261 
262  if ( m_currentTarget->currentActionSalvaged ) {
263  // The currentAction told the node to remove it. To prevent the action from
264  // accidentally deallocating itself before finishing its step, we retained
265  // it. Now that step is done, it's safe to release it.
266  SAFE_RELEASE(m_currentTarget->currentAction);
267  } else if ( m_currentTarget->currentAction->isDone() )
268  {
269  m_currentTarget->currentAction->stop();
270 
271  CAction *a = m_currentTarget->currentAction;
272  // Make currentAction NULL to prevent removeAction from salvaging it.
273  m_currentTarget->currentAction = NULL;
274  removeAction(a);
275  }
276 
277  m_currentTarget->currentAction = NULL;
278  }
279  }
280  // elt, at this moment, is still valid
281  // so it is safe to ask this here (issue #490)
282  elt = (tHashElement*)elt->hh.next;
283 
284  // only delete currentTarget if no actions were scheduled during the cycle (issue #481)
285  if ( m_currentTargetSalvaged && m_currentTarget->actions.size() == 0 )
286  deleteHashElement(m_currentTarget);
287  }
288  // issue #635
289  m_currentTarget = NULL;
290 }
291 
292 //-----------------------------------------------------------------------------
293 
296 }
void removeAction(CAction *action)
void removeActionByTag(unsigned int tag, CGameObject *target)
CGameObject * getOriginalTarget() const
Definition: caction.cpp:39
#define HASH_ADD_INT(head, intfield, add)
Definition: uthash.h:235
bool currentActionSalvaged
virtual void step(float dt)
Definition: caction.cpp:63
virtual void stop()
Definition: caction.cpp:57
CAction * currentAction
#define HASH_FIND_INT(head, findint, out)
Definition: uthash.h:233
void resumeTarget(CGameObject *target)
unsigned int numberOfRunningActionsInTarget(CGameObject *target)
std::vector< CAction * > actions
#define HASH_DEL(head, delptr)
Definition: uthash.h:241
UT_hash_handle hh
virtual void startWithTarget(CGameObject *target)
Definition: caction.cpp:45
CAction * getActionByTag(unsigned int tag, CGameObject *game_object)
#define SAFE_RELEASE(x)
Definition: cobject.h:36
void * next
Definition: uthash.h:964
virtual bool isDone()
Definition: caction.cpp:51
void update(double dt)
#define SAFE_RETAIN(x)
Definition: cobject.h:35
void addAction(CAction *action, CGameObject *target, bool paused)
#define RE_ASSERT
Definition: macro.h:57
unsigned int tag
Definition: caction.h:45
void removeAllActionsFromTarget(CGameObject *target)
static bool deleteObjectFromVector(std::vector< T * > *vec, void *object_to_delete)
struct _hashElement tHashElement
void pauseTarget(CGameObject *target)
unsigned int actionIndex
CGameObject * target
CObject * retain()
Definition: cobject.cpp:66