Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

Diff Revisions 784 vs 794 for /trunk/Source Code/Graphs/SceneGraphNode.cpp

Diff revisions: vs.
  @@ -203,34 +203,36 @@
203 203 }
204 204
205 205 bool SceneGraphNode::removeNode(SceneGraphNode& node, bool recursive) {
206 + UpgradableReadLock ur_lock(_childLock);
207 +
206 208 U32 childCount = getChildCount();
207 -
208 - {
209 - for (U32 i = 0; i < childCount; ++i) {
210 - if (getChild(i, childCount).getGUID() == node.getGUID()) {
211 - {
212 - WriteLock w_lock(_childLock);
213 - _children[i].reset();
214 - _childCount = _childCount - 1;
215 - std::swap(_children[_childCount], _children[i]);
216 - }
217 - invalidateRelationshipCache();
218 - return true;
209 + for (U32 i = 0; i < childCount; ++i) {
210 + if (_children[i]->getGUID() == node.getGUID()) {
211 + {
212 + UpgradeToWriteLock w_lock(ur_lock);
213 + _children[i].reset();
214 + _childCount = _childCount - 1;
215 + std::swap(_children[_childCount], _children[i]);
219 216 }
217 + invalidateRelationshipCache();
218 + return true;
220 219 }
221 220 }
221 +
222 222
223 + bool success = false;
223 224 if (recursive) {
224 - for (U32 i = 0; i < childCount; ++i) {
225 - if (getChild(i, childCount).removeNode(node)) {
226 - return true;
227 - }
228 - }
225 + // If this didn't finish, it means that we found our node
226 + success = !forEachChildInterruptible([&node](SceneGraphNode& child) {
227 + if (child.removeNode(node)) {
228 + return false;
229 + }
230 + });
229 231 }
230 232
231 233 // Beware. Removing a node, does no delete it!
232 234 // Call delete on the SceneGraphNode's pointer to do that
233 - return false;
235 + return success;
234 236 }
235 237
236 238 void SceneGraphNode::postLoad() {
  @@ -278,8 +280,9 @@
278 280
279 281 SceneGraphNode_wptr SceneGraphNode::findChild(I64 GUID, bool recursive) {
280 282 U32 childCount = getChildCount();
283 + ReadLock r_lock(_childLock);
281 284 for (U32 i = 0; i < childCount; ++i) {
282 - SceneGraphNode& child = getChild(i, childCount);
285 + SceneGraphNode& child = *_children[i];
283 286 if (child.getGUID() == GUID) {
284 287 return child.shared_from_this();
285 288 } else {
  @@ -298,8 +301,9 @@
298 301
299 302 SceneGraphNode_wptr SceneGraphNode::findChild(const stringImpl& name, bool sceneNodeName, bool recursive) {
300 303 U32 childCount = getChildCount();
304 + ReadLock r_lock(_childLock);
301 305 for (U32 i = 0; i < childCount; ++i) {
302 - SceneGraphNode& child = getChild(i, childCount);
306 + SceneGraphNode& child = *_children[i];
303 307 if (sceneNodeName ? child.getNode()->getName().compare(name) == 0
304 308 : child.getName().compare(name) == 0)
305 309 {
  @@ -339,8 +343,9 @@
339 343
340 344 // The node we want isn't one of the children, so recursively check each of them
341 345 U32 childCount = getChildCount();
346 + ReadLock r_lock(_childLock);
342 347 for (U32 i = 0; i < childCount; ++i) {
343 - SceneGraphNode_wptr returnValue = getChild(i, childCount).findNode(name, sceneNodeName);
348 + SceneGraphNode_wptr returnValue = _children[i]->findNode(name, sceneNodeName);
344 349 // if it is not nullptr it is the node we are looking for so just pass it through
345 350 if (!returnValue.expired()) {
346 351 return returnValue;
  @@ -366,40 +371,36 @@
366 371 }
367 372
368 373 if (recursive) {
369 - U32 childCount = getChildCount();
370 - for (U32 i = 0; i < childCount; ++i) {
371 - getChild(i, childCount).intersect(ray, start, end, selectionHits);
372 - }
374 + forEachChild([&ray, start, end, &selectionHits](const SceneGraphNode& child) {
375 + child.intersect(ray, start, end, selectionHits);
376 + });
373 377 }
374 378 }
375 379
376 380 void SceneGraphNode::setSelectionFlag(SelectionFlag flag) {
377 381 if (_selectionFlag != flag) {
378 382 _selectionFlag = flag;
379 - U32 childCount = getChildCount();
380 - for (U32 i = 0; i < childCount; ++i) {
381 - getChild(i, childCount).setSelectionFlag(flag);
382 - }
383 + forEachChild([flag](SceneGraphNode& child) {
384 + child.setSelectionFlag(flag);
385 + });
383 386 }
384 387 }
385 388
386 389 void SceneGraphNode::setSelectable(const bool state) {
387 390 if (_isSelectable != state) {
388 391 _isSelectable = state;
389 - U32 childCount = getChildCount();
390 - for (U32 i = 0; i < childCount; ++i) {
391 - getChild(i, childCount).setSelectable(state);
392 - }
392 + forEachChild([state](SceneGraphNode& child) {
393 + child.setSelectable(state);
394 + });
393 395 }
394 396 }
395 397
396 398 void SceneGraphNode::lockVisibility(const bool state) {
397 399 if (_visibilityLocked != state) {
398 400 _visibilityLocked = state;
399 - U32 childCount = getChildCount();
400 - for (U32 i = 0; i < childCount; ++i) {
401 - getChild(i, childCount).lockVisibility(state);
402 - }
401 + forEachChild([state](SceneGraphNode& child) {
402 + child.lockVisibility(state);
403 + });
403 404 }
404 405 }
405 406
  @@ -412,19 +413,17 @@
412 413 }
413 414 }
414 415
415 - U32 childCount = getChildCount();
416 - for (U32 i = 0; i < childCount; ++i) {
417 - getChild(i, childCount).setActive(state);
418 - }
416 + forEachChild([state](SceneGraphNode& child) {
417 + child.setActive(state);
418 + });
419 419 }
420 420 }
421 421
422 422 void SceneGraphNode::getOrderedNodeList(vectorImpl<SceneGraphNode*>& nodeList) {
423 423 // Compute from leaf to root to ensure proper calculations
424 - U32 childCount = getChildCount();
425 - for (U32 i = 0; i < childCount; ++i) {
426 - getChild(i, childCount).getOrderedNodeList(nodeList);
427 - }
424 + forEachChild([&nodeList](SceneGraphNode& child) {
425 + child.getOrderedNodeList(nodeList);
426 + });
428 427
429 428 nodeList.push_back(this);
430 429 }
  @@ -461,10 +460,9 @@
461 460 }
462 461
463 462 void SceneGraphNode::onTransform() {
464 - U32 childCount = getChildCount();
465 - for (U32 i = 0; i < childCount; ++i) {
466 - getChild(i, childCount).onTransform();
467 - }
463 + forEachChild([](SceneGraphNode& child) {
464 + child.onTransform();
465 + });
468 466
469 467 PhysicsComponent* pComp = get<PhysicsComponent>();
470 468 BoundsComponent* bComp = get<BoundsComponent>();
  @@ -485,20 +483,18 @@
485 483 }
486 484
487 485 void SceneGraphNode::frameEnded() {
488 - U32 childCount = getChildCount();
489 - for (U32 i = 0; i < childCount; ++i) {
490 - getChild(i, childCount).frameEnded();
491 - }
486 + forEachChild([](SceneGraphNode& child) {
487 + child.frameEnded();
488 + });
492 489 }
493 490
494 491 void SceneGraphNode::onCameraUpdate(const I64 cameraGUID,
495 492 const vec3<F32>& posOffset,
496 493 const mat4<F32>& rotationOffset) {
497 494
498 - U32 childCount = getChildCount();
499 - for (U32 i = 0; i < childCount; ++i) {
500 - getChild(i, childCount).onCameraUpdate(cameraGUID, posOffset, rotationOffset);
501 - }
495 + forEachChild([cameraGUID, &posOffset, &rotationOffset](SceneGraphNode& child) {
496 + child.onCameraUpdate(cameraGUID, posOffset, rotationOffset);
497 + });
502 498
503 499 PhysicsComponent* pComp = get<PhysicsComponent>();
504 500 if (pComp && pComp->ignoreView(cameraGUID)) {
  @@ -566,10 +562,102 @@
566 562 SceneGraphNode_ptr parentPtr = _parent.lock();
567 563 if (parentPtr && parentPtr->getParent().lock()) {
568 564 parentPtr->invalidateRelationshipCache();
569 - U32 childCount = getChildCount();
570 - for (U32 i = 0; i < childCount; ++i) {
571 - getChild(i, childCount).invalidateRelationshipCache();
565 +
566 + forEachChild([](SceneGraphNode& child) {
567 + child.invalidateRelationshipCache();
568 + });
569 + }
570 + }
571 +
572 + void SceneGraphNode::forEachChild(const DELEGATE_CBK_PARAM<SceneGraphNode&>& callback) {
573 + ReadLock r_lock(_childLock);
574 + for (SceneGraphNode_ptr& child : _children) {
575 + if (child) {
576 + callback(*child);
577 + }
578 + }
579 + }
580 +
581 + void SceneGraphNode::forEachChild(const DELEGATE_CBK_PARAM<const SceneGraphNode&>& callback) const {
582 + ReadLock r_lock(_childLock);
583 + for (const SceneGraphNode_ptr& child : _children) {
584 + if (child) {
585 + callback(*child);
586 + }
587 + }
588 + }
589 +
590 + bool SceneGraphNode::forEachChildInterruptible(const DELEGATE_CBK_PARAM<SceneGraphNode&, bool>& callback) {
591 + ReadLock r_lock(_childLock);
592 + for (SceneGraphNode_ptr& child : _children) {
593 + if (child) {
594 + if (!callback(*child)) {
595 + return false;
596 + }
597 + }
598 + }
599 +
600 + return true;
601 + }
602 +
603 + bool SceneGraphNode::forEachChildInterruptible(const DELEGATE_CBK_PARAM<const SceneGraphNode&, bool>& callback) const {
604 + ReadLock r_lock(_childLock);
605 + for (const SceneGraphNode_ptr& child : _children) {
606 + if (child) {
607 + if (!callback(*child)) {
608 + return false;
609 + }
610 + }
611 + }
612 +
613 + return true;
614 + }
615 +
616 + void SceneGraphNode::forEachChild(const DELEGATE_CBK_PARAM_2<SceneGraphNode&, I32>& callback, U32 start, U32 end) {
617 + ReadLock r_lock(_childLock);
618 + for (U32 i = start; i < end; ++i) {
619 + SceneGraphNode_ptr& child = _children[i];
620 + if (child) {
621 + callback(*child, i);
572 622 }
573 623 }
574 624 }
625 +
626 + void SceneGraphNode::forEachChild(const DELEGATE_CBK_PARAM_2<const SceneGraphNode&, I32>& callback, U32 start, U32 end) const {
627 + ReadLock r_lock(_childLock);
628 + for (U32 i = start; i < end; ++i) {
629 + const SceneGraphNode_ptr& child = _children[i];
630 + if (child) {
631 + callback(*child, i);
632 + }
633 + }
634 + }
635 +
636 + bool SceneGraphNode::forEachChildInterruptible(const DELEGATE_CBK_PARAM_2<SceneGraphNode&, I32, bool>& callback, U32 start, U32 end) {
637 + ReadLock r_lock(_childLock);
638 + for (U32 i = start; i < end; ++i) {
639 + SceneGraphNode_ptr& child = _children[i];
640 + if (child) {
641 + if (!callback(*child, i)) {
642 + return false;
643 + }
644 + }
645 + }
646 +
647 + return true;
648 + }
649 +
650 + bool SceneGraphNode::forEachChildInterruptible(const DELEGATE_CBK_PARAM_2<const SceneGraphNode&, I32, bool>& callback, U32 start, U32 end) const {
651 + ReadLock r_lock(_childLock);
652 + for (U32 i = start; i < end; ++i) {
653 + const SceneGraphNode_ptr& child = _children[i];
654 + if (child) {
655 + if (!callback(*child, i)) {
656 + return false;
657 + }
658 + }
659 + }
660 +
661 + return true;
662 + }
575 663 };