From a1e6867d15e06701d73e365c4aac3c096edbe4f6 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 9 Feb 2007 17:56:52 +0000 Subject: [PATCH] prevent leaks from loading characters --- panda/src/char/characterJointEffect.I | 9 ++++-- panda/src/char/characterJointEffect.cxx | 38 +++++++++++++++++++++++-- panda/src/char/characterJointEffect.h | 3 +- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/panda/src/char/characterJointEffect.I b/panda/src/char/characterJointEffect.I index e8d94d6f91..9830252245 100644 --- a/panda/src/char/characterJointEffect.I +++ b/panda/src/char/characterJointEffect.I @@ -31,9 +31,14 @@ CharacterJointEffect() { // Function: CharacterJointEffect::get_character // Access: Published // Description: Returns the Character that will get update() called -// on it when this node's relative transform is queried. +// on it when this node's relative transform is queried, +// or NULL if there is no such character. //////////////////////////////////////////////////////////////////// INLINE Character *CharacterJointEffect:: get_character() const { - return _character; + if (_character.is_valid_pointer()) { + return _character; + } else { + return NULL; + } } diff --git a/panda/src/char/characterJointEffect.cxx b/panda/src/char/characterJointEffect.cxx index a245f80df3..a2087ee170 100644 --- a/panda/src/char/characterJointEffect.cxx +++ b/panda/src/char/characterJointEffect.cxx @@ -41,7 +41,32 @@ CPT(RenderEffect) CharacterJointEffect:: make(Character *character) { CharacterJointEffect *effect = new CharacterJointEffect; effect->_character = character; - return return_new(effect); + + CPT(RenderEffect) new_effect_raw = return_new(effect); + const CharacterJointEffect *new_effect; + DCAST_INTO_R(new_effect, new_effect_raw, new_effect_raw); + + // It is possible that the CharacterJointEffect we have now is a + // different CharacterJointEffect to a different Character which has + // since been deleted, but which had the same memory address of our + // current character. If this happened, we have to force-update the + // CharacterJointEffect to tell its weak pointer that it is no + // longer invalid (and that it now points to this once-again-live + // Character object). + + // This is a little weird, because it means any nodes that used to + // be pointing to a deleted Character object (and knew they were + // pointing to a deleted Character object) will suddenly be pointing + // to a new, non-deleted Character object--and the wrong Character + // object, no less. But there's no other way to handle this, since + // we can't make the CharacterJointEffect's compare function base + // itself on whether its pointer is valid or not. + + if (!new_effect->_character.is_valid_pointer()) { + ((CharacterJointEffect *)new_effect)->_character = character; + } + + return new_effect_raw; } //////////////////////////////////////////////////////////////////// @@ -148,7 +173,9 @@ void CharacterJointEffect:: adjust_transform(CPT(TransformState) &net_transform, CPT(TransformState) &node_transform, PandaNode *node) const { - _character->update(); + if (_character.is_valid_pointer()) { + _character->update(); + } node_transform = node->get_transform(); } @@ -176,6 +203,13 @@ compare_to_impl(const RenderEffect *other) const { if (_character != ta->_character) { return _character < ta->_character ? -1 : 1; } + + // As tempting as it is to include the sense of whether the + // character pointer is valid in this sorting, we can't, because + // that property might change without warning--which would + // invalidate the CharacterJointEffect's position in any maps if we + // used it to determine its sort. + return 0; } diff --git a/panda/src/char/characterJointEffect.h b/panda/src/char/characterJointEffect.h index b50541c366..fdc326623f 100644 --- a/panda/src/char/characterJointEffect.h +++ b/panda/src/char/characterJointEffect.h @@ -25,6 +25,7 @@ #include "luse.h" #include "nodePath.h" #include "character.h" +#include "weakPointerTo.h" //////////////////////////////////////////////////////////////////// // Class : CharacterJointEffect @@ -65,7 +66,7 @@ protected: virtual int compare_to_impl(const RenderEffect *other) const; private: - PT(Character) _character; + WPT(Character) _character; public: static void register_with_read_factory();