Fix race condition when manipulating node transform in thread (LP #1417715)

This commit is contained in:
rdb 2015-02-04 00:06:14 +01:00
parent 6b10409890
commit 7c14d1872a
3 changed files with 63 additions and 63 deletions

View File

@ -1714,21 +1714,21 @@ set_hpr(const NodePath &other, const LVecBase3 &hpr) {
CPT(TransformState) rel_transform = get_transform(other);
nassertv(rel_transform->has_hpr());
CPT(TransformState) orig_transform = get_transform();
if (orig_transform->has_components()) {
CPT(TransformState) transform = get_transform();
if (transform->has_components()) {
// If we had a componentwise transform before we started, we
// should be careful to preserve the other three components. We
// wouldn't need to do this, except for the possibility of
// numerical error or decompose ambiguity.
const LVecBase3 &orig_pos = orig_transform->get_pos();
const LVecBase3 &orig_scale = orig_transform->get_scale();
const LVecBase3 &orig_shear = orig_transform->get_shear();
const LVecBase3 &orig_pos = transform->get_pos();
const LVecBase3 &orig_scale = transform->get_scale();
const LVecBase3 &orig_shear = transform->get_shear();
set_transform(other, rel_transform->set_hpr(hpr));
const TransformState *new_transform = get_transform();
if (new_transform->has_components()) {
transform = get_transform();
if (transform->has_components()) {
set_transform(TransformState::make_pos_hpr_scale_shear
(orig_pos, new_transform->get_hpr(), orig_scale, orig_shear));
(orig_pos, transform->get_hpr(), orig_scale, orig_shear));
}
} else {
@ -1787,21 +1787,21 @@ set_quat(const NodePath &other, const LQuaternion &quat) {
nassertv_always(!is_empty());
CPT(TransformState) rel_transform = get_transform(other);
CPT(TransformState) orig_transform = get_transform();
if (orig_transform->has_components()) {
CPT(TransformState) transform = get_transform();
if (transform->has_components()) {
// If we had a componentwise transform before we started, we
// should be careful to preserve the other three components. We
// wouldn't need to do this, except for the possibility of
// numerical error or decompose ambiguity.
const LVecBase3 &orig_pos = orig_transform->get_pos();
const LVecBase3 &orig_scale = orig_transform->get_scale();
const LVecBase3 &orig_shear = orig_transform->get_shear();
const LVecBase3 &orig_pos = transform->get_pos();
const LVecBase3 &orig_scale = transform->get_scale();
const LVecBase3 &orig_shear = transform->get_shear();
set_transform(other, rel_transform->set_quat(quat));
const TransformState *new_transform = get_transform();
if (new_transform->has_components()) {
transform = get_transform();
if (transform->has_components()) {
set_transform(TransformState::make_pos_quat_scale_shear
(orig_pos, new_transform->get_quat(), orig_scale, orig_shear));
(orig_pos, transform->get_quat(), orig_scale, orig_shear));
}
} else {
@ -1835,21 +1835,21 @@ set_scale(const NodePath &other, const LVecBase3 &scale) {
nassertv_always(!is_empty());
CPT(TransformState) rel_transform = get_transform(other);
CPT(TransformState) orig_transform = get_transform();
if (orig_transform->has_components()) {
CPT(TransformState) transform = get_transform();
if (transform->has_components()) {
// If we had a componentwise transform before we started, we
// should be careful to preserve the other three components. We
// wouldn't need to do this, except for the possibility of
// numerical error or decompose ambiguity.
const LVecBase3 &orig_pos = orig_transform->get_pos();
const LVecBase3 &orig_hpr = orig_transform->get_hpr();
const LVecBase3 &orig_shear = orig_transform->get_shear();
const LVecBase3 &orig_pos = transform->get_pos();
const LVecBase3 &orig_hpr = transform->get_hpr();
const LVecBase3 &orig_shear = transform->get_shear();
set_transform(other, rel_transform->set_scale(scale));
const TransformState *new_transform = get_transform();
if (new_transform->has_components()) {
transform = get_transform();
if (transform->has_components()) {
set_transform(TransformState::make_pos_hpr_scale_shear
(orig_pos, orig_hpr, new_transform->get_scale(), orig_shear));
(orig_pos, orig_hpr, transform->get_scale(), orig_shear));
}
} else {
@ -1907,21 +1907,21 @@ set_shear(const NodePath &other, const LVecBase3 &shear) {
nassertv_always(!is_empty());
CPT(TransformState) rel_transform = get_transform(other);
CPT(TransformState) orig_transform = get_transform();
if (orig_transform->has_components()) {
CPT(TransformState) transform = get_transform();
if (transform->has_components()) {
// If we had a componentwise transform before we started, we
// should be careful to preserve the other three components. We
// wouldn't need to do this, except for the possibility of
// numerical error or decompose ambiguity.
const LVecBase3 &orig_pos = orig_transform->get_pos();
const LVecBase3 &orig_hpr = orig_transform->get_hpr();
const LVecBase3 &orig_scale = orig_transform->get_scale();
const LVecBase3 &orig_pos = transform->get_pos();
const LVecBase3 &orig_hpr = transform->get_hpr();
const LVecBase3 &orig_scale = transform->get_scale();
set_transform(other, rel_transform->set_shear(shear));
const TransformState *new_transform = get_transform();
if (new_transform->has_components()) {
transform = get_transform();
if (transform->has_components()) {
set_transform(TransformState::make_pos_hpr_scale_shear
(orig_pos, orig_hpr, orig_scale, new_transform->get_shear()));
(orig_pos, orig_hpr, orig_scale, transform->get_shear()));
}
} else {
@ -1980,20 +1980,20 @@ set_pos_hpr(const NodePath &other, const LVecBase3 &pos,
nassertv_always(!is_empty());
CPT(TransformState) rel_transform = get_transform(other);
CPT(TransformState) orig_transform = get_transform();
if (orig_transform->has_components()) {
CPT(TransformState) transform = get_transform();
if (transform->has_components()) {
// If we had a componentwise transform before we started, we
// should be careful to preserve the other two components. We
// wouldn't need to do this, except for the possibility of
// numerical error or decompose ambiguity.
const LVecBase3 &orig_scale = orig_transform->get_scale();
const LVecBase3 &orig_shear = orig_transform->get_shear();
const LVecBase3 &orig_scale = transform->get_scale();
const LVecBase3 &orig_shear = transform->get_shear();
set_transform(other, TransformState::make_pos_hpr_scale_shear
(pos, hpr, rel_transform->get_scale(), rel_transform->get_shear()));
const TransformState *new_transform = get_transform();
if (new_transform->has_components()) {
set_pos_hpr_scale_shear(new_transform->get_pos(), new_transform->get_hpr(),
transform = get_transform();
if (transform->has_components()) {
set_pos_hpr_scale_shear(transform->get_pos(), transform->get_hpr(),
orig_scale, orig_shear);
}
@ -2018,20 +2018,20 @@ set_pos_quat(const NodePath &other, const LVecBase3 &pos,
nassertv_always(!is_empty());
CPT(TransformState) rel_transform = get_transform(other);
CPT(TransformState) orig_transform = get_transform();
if (orig_transform->has_components()) {
CPT(TransformState) transform = get_transform();
if (transform->has_components()) {
// If we had a componentwise transform before we started, we
// should be careful to preserve the other two components. We
// wouldn't need to do this, except for the possibility of
// numerical error or decompose ambiguity.
const LVecBase3 &orig_scale = orig_transform->get_scale();
const LVecBase3 &orig_shear = orig_transform->get_shear();
const LVecBase3 &orig_scale = transform->get_scale();
const LVecBase3 &orig_shear = transform->get_shear();
set_transform(other, TransformState::make_pos_quat_scale_shear
(pos, quat, rel_transform->get_scale(), rel_transform->get_shear()));
const TransformState *new_transform = get_transform();
if (new_transform->has_components()) {
set_pos_quat_scale_shear(new_transform->get_pos(), new_transform->get_quat(),
transform = get_transform();
if (transform->has_components()) {
set_pos_quat_scale_shear(transform->get_pos(), transform->get_quat(),
orig_scale, orig_shear);
}

View File

@ -231,7 +231,7 @@ find_stashed(PandaNode *node, Thread *current_thread) const {
// level, and has nothing to do with what render
// attributes may be inherited from parent nodes.
////////////////////////////////////////////////////////////////////
INLINE const RenderAttrib *PandaNode::
INLINE CPT(RenderAttrib) PandaNode::
get_attrib(TypeHandle type) const {
CDReader cdata(_cycler);
return cdata->_state->get_attrib(type);
@ -246,7 +246,7 @@ get_attrib(TypeHandle type) const {
// level, and has nothing to do with what render
// attributes may be inherited from parent nodes.
////////////////////////////////////////////////////////////////////
INLINE const RenderAttrib *PandaNode::
INLINE CPT(RenderAttrib) PandaNode::
get_attrib(int slot) const {
CDReader cdata(_cycler);
return cdata->_state->get_attrib(slot);
@ -299,7 +299,7 @@ clear_attrib(TypeHandle type) {
// Description: Returns the render effect of the indicated type,
// if it is defined on the node, or NULL if it is not.
////////////////////////////////////////////////////////////////////
INLINE const RenderEffect *PandaNode::
INLINE CPT(RenderEffect) PandaNode::
get_effect(TypeHandle type) const {
CDReader cdata(_cycler);
int index = cdata->_effects->find_effect(type);
@ -332,10 +332,10 @@ has_effect(TypeHandle type) const {
// particular node, and has nothing to do with state
// that might be inherited from above.
////////////////////////////////////////////////////////////////////
INLINE const RenderState *PandaNode::
INLINE CPT(RenderState) PandaNode::
get_state(Thread *current_thread) const {
CDReader cdata(_cycler, current_thread);
return cdata->_state;
return cdata->_state.p();
}
////////////////////////////////////////////////////////////////////
@ -357,7 +357,7 @@ clear_state(Thread *current_thread) {
// Description: Returns the complete RenderEffects that will be
// applied to this node.
////////////////////////////////////////////////////////////////////
INLINE const RenderEffects *PandaNode::
INLINE CPT(RenderEffects) PandaNode::
get_effects(Thread *current_thread) const {
CDReader cdata(_cycler, current_thread);
return cdata->_effects;
@ -381,10 +381,10 @@ clear_effects(Thread *current_thread) {
// the root, but simply the transform on this particular
// node.
////////////////////////////////////////////////////////////////////
INLINE const TransformState *PandaNode::
INLINE CPT(TransformState) PandaNode::
get_transform(Thread *current_thread) const {
CDReader cdata(_cycler, current_thread);
return cdata->_transform;
return cdata->_transform.p();
}
////////////////////////////////////////////////////////////////////
@ -405,10 +405,10 @@ clear_transform(Thread *current_thread) {
// node's "previous" position. See
// set_prev_transform().
////////////////////////////////////////////////////////////////////
const TransformState *PandaNode::
INLINE CPT(TransformState) PandaNode::
get_prev_transform(Thread *current_thread) const {
CDReader cdata(_cycler, current_thread);
return cdata->_prev_transform;
return cdata->_prev_transform.p();
}
////////////////////////////////////////////////////////////////////

View File

@ -163,32 +163,32 @@ PUBLISHED:
void copy_children(PandaNode *other, Thread *current_thread = Thread::get_current_thread());
void set_attrib(const RenderAttrib *attrib, int override = 0);
INLINE const RenderAttrib *get_attrib(TypeHandle type) const;
INLINE const RenderAttrib *get_attrib(int slot) const;
INLINE CPT(RenderAttrib) get_attrib(TypeHandle type) const;
INLINE CPT(RenderAttrib) get_attrib(int slot) const;
INLINE bool has_attrib(TypeHandle type) const;
INLINE bool has_attrib(int slot) const;
INLINE void clear_attrib(TypeHandle type);
void clear_attrib(int slot);
void set_effect(const RenderEffect *effect);
INLINE const RenderEffect *get_effect(TypeHandle type) const;
INLINE CPT(RenderEffect) get_effect(TypeHandle type) const;
INLINE bool has_effect(TypeHandle type) const;
void clear_effect(TypeHandle type);
void set_state(const RenderState *state, Thread *current_thread = Thread::get_current_thread());
INLINE const RenderState *get_state(Thread *current_thread = Thread::get_current_thread()) const;
INLINE CPT(RenderState) get_state(Thread *current_thread = Thread::get_current_thread()) const;
INLINE void clear_state(Thread *current_thread = Thread::get_current_thread());
void set_effects(const RenderEffects *effects, Thread *current_thread = Thread::get_current_thread());
INLINE const RenderEffects *get_effects(Thread *current_thread = Thread::get_current_thread()) const;
INLINE CPT(RenderEffects) get_effects(Thread *current_thread = Thread::get_current_thread()) const;
INLINE void clear_effects(Thread *current_thread = Thread::get_current_thread());
void set_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread());
INLINE const TransformState *get_transform(Thread *current_thread = Thread::get_current_thread()) const;
INLINE CPT(TransformState) get_transform(Thread *current_thread = Thread::get_current_thread()) const;
INLINE void clear_transform(Thread *current_thread = Thread::get_current_thread());
void set_prev_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread());
INLINE const TransformState *get_prev_transform(Thread *current_thread = Thread::get_current_thread()) const;
INLINE CPT(TransformState) get_prev_transform(Thread *current_thread = Thread::get_current_thread()) const;
void reset_prev_transform(Thread *current_thread = Thread::get_current_thread());
INLINE bool has_dirty_prev_transform() const;
static void reset_all_prev_transform(Thread *current_thread = Thread::get_current_thread());