Skip to content

Commit 3d49986

Browse files
committed
char: fix crash during Character destructor (regression)
This was a regression in 0bb81a4 which was not keeping an edge case in mind if a weak pointer is locked during object destruction. This issue was fixed by 525a05ea2b1d00a1db901f883f1755943aeff33c, but that is not enough since it causes CharacterJointEffect::get_character() to return null now, so we need a separate method to check if a CharacterJointEffect belongs to a given character. This is more efficient, too. Fixes panda3d#330
1 parent f2d429b commit 3d49986

File tree

3 files changed

+18
-6
lines changed

3 files changed

+18
-6
lines changed

panda/src/char/characterJoint.cxx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ bool CharacterJoint::
214214
remove_net_transform(PandaNode *node) {
215215
CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
216216
if (effect != (RenderEffect *)NULL &&
217-
DCAST(CharacterJointEffect, effect)->get_character() == _character) {
217+
DCAST(CharacterJointEffect, effect)->matches_character(_character)) {
218218
node->clear_effect(CharacterJointEffect::get_class_type());
219219
}
220220

@@ -244,7 +244,7 @@ clear_net_transforms() {
244244

245245
CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
246246
if (effect != (RenderEffect *)NULL &&
247-
DCAST(CharacterJointEffect, effect)->get_character() == _character) {
247+
DCAST(CharacterJointEffect, effect)->matches_character(_character)) {
248248
node->clear_effect(CharacterJointEffect::get_class_type());
249249
}
250250
}
@@ -306,7 +306,7 @@ bool CharacterJoint::
306306
remove_local_transform(PandaNode *node) {
307307
CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
308308
if (effect != (RenderEffect *)NULL &&
309-
DCAST(CharacterJointEffect, effect)->get_character() == _character) {
309+
DCAST(CharacterJointEffect, effect)->matches_character(_character)) {
310310
node->clear_effect(CharacterJointEffect::get_class_type());
311311
}
312312

@@ -336,7 +336,7 @@ clear_local_transforms() {
336336

337337
CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
338338
if (effect != (RenderEffect *)NULL &&
339-
DCAST(CharacterJointEffect, effect)->get_character() == _character) {
339+
DCAST(CharacterJointEffect, effect)->matches_character(_character)) {
340340
node->clear_effect(CharacterJointEffect::get_class_type());
341341
}
342342
}
@@ -427,7 +427,7 @@ set_character(Character *character) {
427427

428428
CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
429429
if (effect != (RenderEffect *)NULL &&
430-
DCAST(CharacterJointEffect, effect)->get_character() == _character) {
430+
DCAST(CharacterJointEffect, effect)->matches_character(_character)) {
431431
node->clear_effect(CharacterJointEffect::get_class_type());
432432
}
433433
}
@@ -438,7 +438,7 @@ set_character(Character *character) {
438438

439439
CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
440440
if (effect != (RenderEffect *)NULL &&
441-
DCAST(CharacterJointEffect, effect)->get_character() == _character) {
441+
DCAST(CharacterJointEffect, effect)->matches_character(_character)) {
442442
node->clear_effect(CharacterJointEffect::get_class_type());
443443
}
444444
}

panda/src/char/characterJointEffect.I

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,13 @@ INLINE PT(Character) CharacterJointEffect::
2727
get_character() const {
2828
return _character.lock();
2929
}
30+
31+
/**
32+
* Returns true if this CharacterJointEffect contains the given Character.
33+
* This exists because it is faster to check than get_character() and can even
34+
* be called while the Character is destructing.
35+
*/
36+
INLINE bool CharacterJointEffect::
37+
matches_character(Character *character) const {
38+
return _character == character;
39+
}

panda/src/char/characterJointEffect.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class EXPCL_PANDA_CHAR CharacterJointEffect : public RenderEffect {
4141
INLINE PT(Character) get_character() const;
4242

4343
public:
44+
INLINE bool matches_character(Character *character) const;
45+
4446
virtual bool safe_to_transform() const;
4547
virtual bool safe_to_combine() const;
4648
virtual void output(ostream &out) const;

0 commit comments

Comments
 (0)