better PandaNode::get_children(), introduce PandaNode::reset_all_prev_transform()
This commit is contained in:
parent
ab6492b17d
commit
160c848b68
|
|
@ -41,7 +41,6 @@
|
|||
#include "indent.h"
|
||||
|
||||
PStatCollector CollisionTraverser::_collisions_pcollector("App:Collisions");
|
||||
PStatCollector CollisionTraverser::_reset_prev_pcollector("App:Collisions:Reset");
|
||||
|
||||
PStatCollector CollisionTraverser::_cnode_volume_pcollector("Collision Volumes:CollisionNode");
|
||||
PStatCollector CollisionTraverser::_gnode_volume_pcollector("Collision Volumes:GeomNode");
|
||||
|
|
@ -313,16 +312,12 @@ traverse(const NodePath &root) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionTraverser::reset_prev_transform
|
||||
// Access: Published
|
||||
// Description: Once the collision traversal has finished, resets all
|
||||
// of the velocity deltas in the scene graph by setting
|
||||
// the "previous" transform to the current transform.
|
||||
// This must be called at least once per frame for
|
||||
// collisions to respect this velocity setting properly.
|
||||
// Description: This method is deprecated. Just call
|
||||
// PandaNode::reset_all_prev_transform() now.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CollisionTraverser::
|
||||
reset_prev_transform(const NodePath &root) {
|
||||
PStatTimer timer(_reset_prev_pcollector);
|
||||
r_reset_prev_transform(root.node());
|
||||
reset_prev_transform(const NodePath &) {
|
||||
PandaNode::reset_all_prev_transform();
|
||||
}
|
||||
|
||||
#ifdef DO_COLLISION_RECORDING
|
||||
|
|
@ -883,22 +878,6 @@ remove_handler(CollisionTraverser::Handlers::iterator hi) {
|
|||
return hi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionTraverser::r_reset_prev_transform
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CollisionTraverser::
|
||||
r_reset_prev_transform(PandaNode *node) {
|
||||
node->reset_prev_transform();
|
||||
|
||||
PandaNode::Children children = node->get_children();
|
||||
int num_children = children.get_num_children();
|
||||
for (int i = 0; i < num_children; ++i) {
|
||||
r_reset_prev_transform(children.get_child(i));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionTraverser::get_pass_collector
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -102,8 +102,6 @@ private:
|
|||
const GeometricBoundingVolume *from_node_gbv,
|
||||
const GeometricBoundingVolume *solid_gbv);
|
||||
|
||||
void r_reset_prev_transform(PandaNode *node);
|
||||
|
||||
PStatCollector &get_pass_collector(int pass);
|
||||
|
||||
private:
|
||||
|
|
@ -134,7 +132,6 @@ private:
|
|||
|
||||
// Statistics
|
||||
static PStatCollector _collisions_pcollector;
|
||||
static PStatCollector _reset_prev_pcollector;
|
||||
|
||||
static PStatCollector _cnode_volume_pcollector;
|
||||
static PStatCollector _gnode_volume_pcollector;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
nodePathComponent.I nodePathComponent.h \
|
||||
nodePathLerps.h \
|
||||
pandaNode.I pandaNode.h \
|
||||
pandaNodeChain.I pandaNodeChain.h \
|
||||
planeNode.I planeNode.h \
|
||||
pointLight.I pointLight.h \
|
||||
polylightNode.I polylightNode.h \
|
||||
|
|
@ -174,6 +175,7 @@
|
|||
nodePathComponent.cxx \
|
||||
nodePathLerps.cxx \
|
||||
pandaNode.cxx \
|
||||
pandaNodeChain.cxx \
|
||||
planeNode.cxx \
|
||||
pointLight.cxx \
|
||||
polylightNode.cxx \
|
||||
|
|
@ -272,6 +274,7 @@
|
|||
nodePathComponent.I nodePathComponent.h \
|
||||
nodePathLerps.h \
|
||||
pandaNode.I pandaNode.h \
|
||||
pandaNodeChain.I pandaNodeChain.h \
|
||||
planeNode.I planeNode.h \
|
||||
pointLight.I pointLight.h \
|
||||
polylightNode.I polylightNode.h \
|
||||
|
|
|
|||
|
|
@ -248,22 +248,20 @@ traverse_below(CullTraverserData &data) {
|
|||
#endif
|
||||
}
|
||||
|
||||
// Now visit all the node's children. We cannot use the
|
||||
// node->get_children() interface, because that will keep a read
|
||||
// pointer open, and we might end up changing this node during the
|
||||
// traversal.
|
||||
int num_children = node->get_num_children();
|
||||
// Now visit all the node's children.
|
||||
PandaNode::Children children = node->get_children();
|
||||
int num_children = children.get_num_children();
|
||||
if (node->has_selective_visibility()) {
|
||||
int i = node->get_first_visible_child();
|
||||
while (i < num_children) {
|
||||
CullTraverserData next_data(data, node->get_child(i));
|
||||
CullTraverserData next_data(data, children.get_child(i));
|
||||
traverse(next_data);
|
||||
i = node->get_next_visible_child(i);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
CullTraverserData next_data(data, node->get_child(i));
|
||||
CullTraverserData next_data(data, children.get_child(i));
|
||||
traverse(next_data);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,8 +191,9 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
|
|||
}
|
||||
}
|
||||
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler) {
|
||||
CDStageWriter cdata(_cycler, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
|
||||
CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
|
||||
Geoms::iterator gi;
|
||||
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
|
||||
GeomEntry &entry = (*gi);
|
||||
|
|
@ -409,8 +410,9 @@ add_geom(Geom *geom, const RenderState *state) {
|
|||
nassertv(geom->check_valid());
|
||||
nassertv(state != (RenderState *)NULL);
|
||||
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler) {
|
||||
CDStageWriter cdata(_cycler, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
|
||||
CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
|
||||
|
||||
cdata->_geoms.push_back(GeomEntry(geom, state));
|
||||
}
|
||||
|
|
@ -427,9 +429,10 @@ add_geom(Geom *geom, const RenderState *state) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomNode::
|
||||
add_geoms_from(const GeomNode *other) {
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler) {
|
||||
CDStageWriter cdata(_cycler, pipeline_stage);
|
||||
CDStageReader cdata_other(other->_cycler, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
|
||||
CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
|
||||
CDStageReader cdata_other(other->_cycler, pipeline_stage, current_thread);
|
||||
|
||||
Geoms::const_iterator gi;
|
||||
for (gi = cdata_other->_geoms.begin();
|
||||
|
|
@ -511,8 +514,9 @@ check_valid() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomNode::
|
||||
unify() {
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler) {
|
||||
CDStageWriter cdata(_cycler, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
|
||||
CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
|
||||
|
||||
Geoms new_geoms;
|
||||
|
||||
|
|
|
|||
|
|
@ -128,8 +128,9 @@ bool GeomTransformer::
|
|||
transform_vertices(GeomNode *node, const LMatrix4f &mat) {
|
||||
bool any_changed = false;
|
||||
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(node->_cycler) {
|
||||
GeomNode::CDStageWriter cdata(node->_cycler, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(node->_cycler, current_thread) {
|
||||
GeomNode::CDStageWriter cdata(node->_cycler, pipeline_stage, current_thread);
|
||||
GeomNode::Geoms::iterator gi;
|
||||
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
|
||||
GeomNode::GeomEntry &entry = (*gi);
|
||||
|
|
|
|||
|
|
@ -86,20 +86,23 @@ compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const {
|
|||
INLINE int PandaNode::
|
||||
get_num_parents() const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
return cdata->_up.size();
|
||||
return cdata->get_up()->size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_parent
|
||||
// Access: Published
|
||||
// Description: Returns the nth parent node of this node. See
|
||||
// get_num_parents().
|
||||
// get_num_parents(). Also see get_parents(), if your
|
||||
// intention is to iterate through the complete list of
|
||||
// parents; get_parents() is preferable in this case.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *PandaNode::
|
||||
get_parent(int n) const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
nassertr(n >= 0 && n < (int)cdata->_up.size(), NULL);
|
||||
return cdata->_up[n].get_parent();
|
||||
const Up &up = *cdata->get_up();
|
||||
nassertr(n >= 0 && n < (int)up.size(), NULL);
|
||||
return up[n].get_parent();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -125,20 +128,23 @@ find_parent(PandaNode *node) const {
|
|||
INLINE int PandaNode::
|
||||
get_num_children() const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
return cdata->_down.size();
|
||||
return cdata->get_down()->size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_child
|
||||
// Access: Published
|
||||
// Description: Returns the nth child node of this node. See
|
||||
// get_num_children().
|
||||
// get_num_children(). Also see get_children(), if your
|
||||
// intention is to iterate through the complete list of
|
||||
// children; get_children() is preferable in this case.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *PandaNode::
|
||||
get_child(int n) const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
nassertr(n >= 0 && n < (int)cdata->_down.size(), NULL);
|
||||
return cdata->_down[n].get_child();
|
||||
const Down &down = *cdata->get_down();
|
||||
nassertr(n >= 0 && n < (int)down.size(), NULL);
|
||||
return down[n].get_child();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -151,8 +157,9 @@ get_child(int n) const {
|
|||
INLINE int PandaNode::
|
||||
get_child_sort(int n) const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
nassertr(n >= 0 && n < (int)cdata->_down.size(), -1);
|
||||
return cdata->_down[n].get_sort();
|
||||
const Down &down = *cdata->get_down();
|
||||
nassertr(n >= 0 && n < (int)down.size(), -1);
|
||||
return down[n].get_sort();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -229,20 +236,24 @@ unstash_child(PandaNode *child_node) {
|
|||
INLINE int PandaNode::
|
||||
get_num_stashed() const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
return cdata->_stashed.size();
|
||||
return cdata->get_stashed()->size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_stashed
|
||||
// Access: Published
|
||||
// Description: Returns the nth stashed node of this node. See
|
||||
// get_num_stashed().
|
||||
// Description: Returns the nth stashed child of this node. See
|
||||
// get_num_stashed(). Also see get_stashed(), if your
|
||||
// intention is to iterate through the complete list of
|
||||
// stashed children; get_stashed() is preferable in this
|
||||
// case.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *PandaNode::
|
||||
get_stashed(int n) const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
nassertr(n >= 0 && n < (int)cdata->_stashed.size(), NULL);
|
||||
return cdata->_stashed[n].get_child();
|
||||
const Down &stashed = *cdata->get_stashed();
|
||||
nassertr(n >= 0 && n < (int)stashed.size(), NULL);
|
||||
return stashed[n].get_child();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -255,8 +266,9 @@ get_stashed(int n) const {
|
|||
INLINE int PandaNode::
|
||||
get_stashed_sort(int n) const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
nassertr(n >= 0 && n < (int)cdata->_stashed.size(), -1);
|
||||
return cdata->_stashed[n].get_sort();
|
||||
const Down &stashed = *cdata->get_stashed();
|
||||
nassertr(n >= 0 && n < (int)stashed.size(), -1);
|
||||
return stashed[n].get_sort();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -422,6 +434,20 @@ get_prev_transform() const {
|
|||
return cdata->_prev_transform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::has_dirty_prev_transform
|
||||
// Access: Published
|
||||
// Description: Returns true if this node has the
|
||||
// _dirty_prev_transform flag set, which indicates its
|
||||
// _prev_transform is different from its _transform
|
||||
// value (in pipeline stage 0). In this case, the node
|
||||
// will be visited by reset_prev_transform().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool PandaNode::
|
||||
has_dirty_prev_transform() const {
|
||||
return _dirty_prev_transform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_tag
|
||||
// Access: Published
|
||||
|
|
@ -690,22 +716,6 @@ mark_internal_bounds_stale(int pipeline_stage) {
|
|||
mark_bounds_stale(pipeline_stage);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_children_copy
|
||||
// Access: Public
|
||||
// Description: Returns an object that can be used to walk through
|
||||
// the list of children of the node. Unlike
|
||||
// get_children(), this function actually returns an
|
||||
// object that protects you from self-modifying loops,
|
||||
// because it makes and returns a copy of the complete
|
||||
// children list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::ChildrenCopy PandaNode::
|
||||
get_children_copy() const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
return ChildrenCopy(cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_children
|
||||
// Access: Public
|
||||
|
|
@ -713,74 +723,56 @@ get_children_copy() const {
|
|||
// the list of children of the node. When you intend to
|
||||
// visit multiple children, using this is slightly
|
||||
// faster than calling get_child() directly on the
|
||||
// PandaNode, since this object keeps the PipelineCycler
|
||||
// open the whole time.
|
||||
// PandaNode, since this object avoids reopening the
|
||||
// PipelineCycler each time.
|
||||
//
|
||||
// However, this object does not protect you from
|
||||
// self-modifying loops (e.g. adding or removing
|
||||
// children during traversal). Furthermore, if Panda is
|
||||
// compiled with pipelining enabled, this method is
|
||||
// compiled to behave exactly as get_children_copy(): it
|
||||
// returns a copy. This is intended to reduce the risk
|
||||
// of deadlocks.
|
||||
// This object also protects you from self-modifying
|
||||
// loops (e.g. adding or removing children during
|
||||
// traversal), since a virtual copy of the children is
|
||||
// made ahead of time. The virtual copy is fast--it is
|
||||
// a form of copy-on-write, so the list is not actually
|
||||
// copied unless it is modified during the traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Children PandaNode::
|
||||
get_children() const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
get_children(Thread *current_thread) const {
|
||||
CDLinksReader cdata(_cycler_links, current_thread);
|
||||
return Children(cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_stashed_copy
|
||||
// Access: Public
|
||||
// Description: Returns an object that can be used to walk through
|
||||
// the list of stashed children of the node. Unlike
|
||||
// get_stashed(), this function actually returns an
|
||||
// object that protects you from self-modifying loops,
|
||||
// because it makes and returns a copy of the complete
|
||||
// stashed list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::StashedCopy PandaNode::
|
||||
get_stashed_copy() const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
return StashedCopy(cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_stashed
|
||||
// Access: Public
|
||||
// Description: Returns an object that can be used to walk through
|
||||
// the list of stashed children of the node. When you
|
||||
// intend to visit multiple children, using this is
|
||||
// slightly faster than calling get_stashed() directly
|
||||
// on the PandaNode, since this object keeps the
|
||||
// PipelineCycler open the whole time.
|
||||
// the list of children of the node. When you intend to
|
||||
// visit multiple children, using this is slightly
|
||||
// faster than calling get_stashed() directly on the
|
||||
// PandaNode, since this object avoids reopening the
|
||||
// PipelineCycler each time.
|
||||
//
|
||||
// However, this object does not protect you from
|
||||
// self-modifying loops (e.g. adding or removing
|
||||
// stashed during traversal). Furthermore, if Panda is
|
||||
// compiled with pipelining enabled, this method is
|
||||
// compiled to behave exactly as get_stashed_copy(): it
|
||||
// returns a copy. This is intended to reduce the risk
|
||||
// of deadlocks.
|
||||
// This object also protects you from self-modifying
|
||||
// loops (e.g. adding or removing children during
|
||||
// traversal), since a virtual copy of the children is
|
||||
// made ahead of time. The virtual copy is fast--it is
|
||||
// a form of copy-on-write, so the list is not actually
|
||||
// copied unless it is modified during the traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Stashed PandaNode::
|
||||
get_stashed() const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
get_stashed(Thread *current_thread) const {
|
||||
CDLinksReader cdata(_cycler_links, current_thread);
|
||||
return Stashed(cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_parents_copy
|
||||
// Function: PandaNode::get_parents
|
||||
// Access: Public
|
||||
// Description: Returns an object that can be used to walk through
|
||||
// the list of parents of the node, similar to
|
||||
// get_children_copy()/
|
||||
// get_children() and get_stashed().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::ParentsCopy PandaNode::
|
||||
get_parents_copy() const {
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
return ParentsCopy(cdata);
|
||||
INLINE PandaNode::Parents PandaNode::
|
||||
get_parents(Thread *current_thread) const {
|
||||
CDLinksReader cdata(_cycler_links, current_thread);
|
||||
return Parents(cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -790,11 +782,46 @@ get_parents_copy() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PandaNode::
|
||||
do_find_parent(PandaNode *node, const CDataLinks *cdata) const {
|
||||
Up::const_iterator ui = cdata->_up.find(UpConnection(node));
|
||||
if (ui == cdata->_up.end()) {
|
||||
const Up &up = *cdata->get_up();
|
||||
Up::const_iterator ui = up.find(UpConnection(node));
|
||||
if (ui == up.end()) {
|
||||
return -1;
|
||||
}
|
||||
return ui - cdata->_up.begin();
|
||||
return ui - up.begin();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::set_dirty_prev_transform
|
||||
// Access: Private
|
||||
// Description: Sets the dirty_prev_transform flag, and adds the node
|
||||
// to the _dirty_prev_transforms chain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::
|
||||
set_dirty_prev_transform() {
|
||||
if (!_dirty_prev_transform) {
|
||||
MutexHolder holder(_dirty_prev_transforms._lock);
|
||||
if (!_dirty_prev_transform) {
|
||||
LinkedListNode::insert_before(&_dirty_prev_transforms);
|
||||
_dirty_prev_transform = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::clear_dirty_prev_transform
|
||||
// Access: Private
|
||||
// Description: Clears the dirty_prev_transform flag, and removes the node
|
||||
// from the _dirty_prev_transforms chain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::
|
||||
clear_dirty_prev_transform() {
|
||||
if (_dirty_prev_transform) {
|
||||
MutexHolder holder(_dirty_prev_transforms._lock);
|
||||
if (_dirty_prev_transform) {
|
||||
LinkedListNode::remove_from_list();
|
||||
_dirty_prev_transform = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -936,10 +963,85 @@ CDataBounds() {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::CDataLinks::
|
||||
CDataLinks() {
|
||||
CDataLinks() :
|
||||
_down(new PandaNode::Down),
|
||||
_stashed(new PandaNode::Down),
|
||||
_up(new PandaNode::Up)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::CDataLinks::get_down
|
||||
// Access: Public
|
||||
// Description: Returns a read-only pointer to the _down list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const PandaNode::Down *PandaNode::CDataLinks::
|
||||
get_down() const {
|
||||
return _down;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::CDataLinks::modify_down
|
||||
// Access: Public
|
||||
// Description: Returns a modifiable, unique pointer to the _down
|
||||
// list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Down *PandaNode::CDataLinks::
|
||||
modify_down() {
|
||||
if (_down->get_ref_count() > 1) {
|
||||
_down = new Down(*_down);
|
||||
}
|
||||
return _down;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::CDataLinks::get_stashed
|
||||
// Access: Public
|
||||
// Description: Returns a read-only pointer to the _stashed list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const PandaNode::Down *PandaNode::CDataLinks::
|
||||
get_stashed() const {
|
||||
return _stashed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::CDataLinks::modify_stashed
|
||||
// Access: Public
|
||||
// Description: Returns a modifiable, unique pointer to the _stashed
|
||||
// list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Down *PandaNode::CDataLinks::
|
||||
modify_stashed() {
|
||||
if (_stashed->get_ref_count() > 1) {
|
||||
_stashed = new Down(*_stashed);
|
||||
}
|
||||
return _stashed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::CDataLinks::get_up
|
||||
// Access: Public
|
||||
// Description: Returns a read-only pointer to the _up list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const PandaNode::Up *PandaNode::CDataLinks::
|
||||
get_up() const {
|
||||
return _up;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::CDataLinks::modify_up
|
||||
// Access: Public
|
||||
// Description: Returns a modifiable, unique pointer to the _up
|
||||
// list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Up *PandaNode::CDataLinks::
|
||||
modify_up() {
|
||||
if (_up->get_ref_count() > 1) {
|
||||
_up = new Up(*_up);
|
||||
}
|
||||
return _up;
|
||||
}
|
||||
|
||||
#ifndef DO_PIPELINING
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Children::Constructor
|
||||
// Access: Public
|
||||
|
|
@ -947,12 +1049,10 @@ CDataLinks() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Children::
|
||||
Children(const PandaNode::CDLinksReader &cdata) :
|
||||
_cdata(cdata)
|
||||
_down(cdata->get_down())
|
||||
{
|
||||
}
|
||||
#endif // DO_PIPELINING
|
||||
|
||||
#ifndef DO_PIPELINING
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Children::Copy Constructor
|
||||
// Access: Public
|
||||
|
|
@ -960,12 +1060,10 @@ Children(const PandaNode::CDLinksReader &cdata) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Children::
|
||||
Children(const PandaNode::Children ©) :
|
||||
_cdata(copy._cdata)
|
||||
_down(copy._down)
|
||||
{
|
||||
}
|
||||
#endif // DO_PIPELINING
|
||||
|
||||
#ifndef DO_PIPELINING
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Children::Copy Assignment Operator
|
||||
// Access: Public
|
||||
|
|
@ -973,11 +1071,9 @@ Children(const PandaNode::Children ©) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::Children::
|
||||
operator = (const PandaNode::Children ©) {
|
||||
_cdata = copy._cdata;
|
||||
_down = copy._down;
|
||||
}
|
||||
#endif // DO_PIPELINING
|
||||
|
||||
#ifndef DO_PIPELINING
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Children::get_num_children
|
||||
// Access: Public
|
||||
|
|
@ -985,11 +1081,9 @@ operator = (const PandaNode::Children ©) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PandaNode::Children::
|
||||
get_num_children() const {
|
||||
return _cdata->_down.size();
|
||||
return _down->size();
|
||||
}
|
||||
#endif // DO_PIPELINING
|
||||
|
||||
#ifndef DO_PIPELINING
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Children::get_child
|
||||
// Access: Public
|
||||
|
|
@ -997,54 +1091,10 @@ get_num_children() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *PandaNode::Children::
|
||||
get_child(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_cdata->_down.size(), NULL);
|
||||
return _cdata->_down[n].get_child();
|
||||
}
|
||||
#endif // DO_PIPELINING
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::ChildrenCopy::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::ChildrenCopy::
|
||||
ChildrenCopy(const PandaNode::ChildrenCopy ©) :
|
||||
_list(copy._list)
|
||||
{
|
||||
nassertr(n >= 0 && n < (int)_down->size(), NULL);
|
||||
return (*_down)[n].get_child();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::ChildrenCopy::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::ChildrenCopy::
|
||||
operator = (const PandaNode::ChildrenCopy ©) {
|
||||
_list = copy._list;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::ChildrenCopy::get_num_children
|
||||
// Access: Public
|
||||
// Description: Returns the number of children of the node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PandaNode::ChildrenCopy::
|
||||
get_num_children() const {
|
||||
return _list.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::ChildrenCopy::get_child
|
||||
// Access: Public
|
||||
// Description: Returns the nth child of the node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *PandaNode::ChildrenCopy::
|
||||
get_child(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_list.size(), NULL);
|
||||
return _list[n];
|
||||
}
|
||||
|
||||
#ifndef DO_PIPELINING
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Stashed::Constructor
|
||||
// Access: Public
|
||||
|
|
@ -1052,12 +1102,10 @@ get_child(int n) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Stashed::
|
||||
Stashed(const PandaNode::CDLinksReader &cdata) :
|
||||
_cdata(cdata)
|
||||
_stashed(cdata->get_stashed())
|
||||
{
|
||||
}
|
||||
#endif // DO_PIPELINING
|
||||
|
||||
#ifndef DO_PIPELINING
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Stashed::Copy Constructor
|
||||
// Access: Public
|
||||
|
|
@ -1065,12 +1113,10 @@ Stashed(const PandaNode::CDLinksReader &cdata) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::Stashed::
|
||||
Stashed(const PandaNode::Stashed ©) :
|
||||
_cdata(copy._cdata)
|
||||
_stashed(copy._stashed)
|
||||
{
|
||||
}
|
||||
#endif // DO_PIPELINING
|
||||
|
||||
#ifndef DO_PIPELINING
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Stashed::Copy Assignment Operator
|
||||
// Access: Public
|
||||
|
|
@ -1078,11 +1124,9 @@ Stashed(const PandaNode::Stashed ©) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::Stashed::
|
||||
operator = (const PandaNode::Stashed ©) {
|
||||
_cdata = copy._cdata;
|
||||
_stashed = copy._stashed;
|
||||
}
|
||||
#endif // DO_PIPELINING
|
||||
|
||||
#ifndef DO_PIPELINING
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Stashed::get_num_stashed
|
||||
// Access: Public
|
||||
|
|
@ -1090,11 +1134,9 @@ operator = (const PandaNode::Stashed ©) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PandaNode::Stashed::
|
||||
get_num_stashed() const {
|
||||
return _cdata->_stashed.size();
|
||||
return _stashed->size();
|
||||
}
|
||||
#endif // DO_PIPELINING
|
||||
|
||||
#ifndef DO_PIPELINING
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::Stashed::get_stashed
|
||||
// Access: Public
|
||||
|
|
@ -1102,91 +1144,59 @@ get_num_stashed() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *PandaNode::Stashed::
|
||||
get_stashed(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_cdata->_stashed.size(), NULL);
|
||||
return _cdata->_stashed[n].get_child();
|
||||
nassertr(n >= 0 && n < (int)_stashed->size(), NULL);
|
||||
return (*_stashed)[n].get_child();
|
||||
}
|
||||
#endif // DO_PIPELINING
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::StashedCopy::Copy Constructor
|
||||
// Function: PandaNode::Parents::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::StashedCopy::
|
||||
StashedCopy(const PandaNode::StashedCopy ©) :
|
||||
_list(copy._list)
|
||||
INLINE PandaNode::Parents::
|
||||
Parents(const PandaNode::CDLinksReader &cdata) :
|
||||
_up(cdata->get_up())
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::StashedCopy::Copy Assignment Operator
|
||||
// Function: PandaNode::Parents::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::StashedCopy::
|
||||
operator = (const PandaNode::StashedCopy ©) {
|
||||
_list = copy._list;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::StashedCopy::get_num_stashed
|
||||
// Access: Public
|
||||
// Description: Returns the number of stashed children of the node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PandaNode::StashedCopy::
|
||||
get_num_stashed() const {
|
||||
return _list.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::StashedCopy::get_stashed
|
||||
// Access: Public
|
||||
// Description: Returns the nth stashed child of the node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *PandaNode::StashedCopy::
|
||||
get_stashed(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_list.size(), NULL);
|
||||
return _list[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::ParentsCopy::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode::ParentsCopy::
|
||||
ParentsCopy(const PandaNode::ParentsCopy ©) :
|
||||
_list(copy._list)
|
||||
INLINE PandaNode::Parents::
|
||||
Parents(const PandaNode::Parents ©) :
|
||||
_up(copy._up)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::ParentsCopy::Copy Assignment Operator
|
||||
// Function: PandaNode::Parents::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::ParentsCopy::
|
||||
operator = (const PandaNode::ParentsCopy ©) {
|
||||
_list = copy._list;
|
||||
INLINE void PandaNode::Parents::
|
||||
operator = (const PandaNode::Parents ©) {
|
||||
_up = copy._up;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::ParentsCopy::get_num_parents
|
||||
// Function: PandaNode::Parents::get_num_parents
|
||||
// Access: Public
|
||||
// Description: Returns the number of parents of the node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PandaNode::ParentsCopy::
|
||||
INLINE int PandaNode::Parents::
|
||||
get_num_parents() const {
|
||||
return _list.size();
|
||||
return _up->size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::ParentsCopy::get_parent
|
||||
// Function: PandaNode::Parents::get_parent
|
||||
// Access: Public
|
||||
// Description: Returns the nth parent of the node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *PandaNode::ParentsCopy::
|
||||
INLINE PandaNode *PandaNode::Parents::
|
||||
get_parent(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_list.size(), NULL);
|
||||
return _list[n];
|
||||
nassertr(n >= 0 && n < (int)_up->size(), NULL);
|
||||
return (*_up)[n].get_parent();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,12 +27,17 @@
|
|||
#include "accumulatedAttribs.h"
|
||||
#include "clipPlaneAttrib.h"
|
||||
#include "boundingSphere.h"
|
||||
#include "pStatTimer.h"
|
||||
|
||||
// This category is just temporary for debugging convenience.
|
||||
NotifyCategoryDecl(drawmask, EXPCL_PANDA, EXPTP_PANDA);
|
||||
NotifyCategoryDef(drawmask, "");
|
||||
|
||||
PandaNodeChain PandaNode::_dirty_prev_transforms;
|
||||
DrawMask PandaNode::_overall_bit = DrawMask::bit(31);
|
||||
|
||||
PStatCollector PandaNode::_reset_prev_pcollector("App:Collisions:Reset");
|
||||
|
||||
TypeHandle PandaNode::_type_handle;
|
||||
|
||||
//
|
||||
|
|
@ -68,7 +73,8 @@ TypeHandle PandaNode::_type_handle;
|
|||
PandaNode::
|
||||
PandaNode(const string &name) :
|
||||
Namable(name),
|
||||
_paths_lock("PandaNode::_paths_lock")
|
||||
_paths_lock("PandaNode::_paths_lock"),
|
||||
_dirty_prev_transform(false)
|
||||
{
|
||||
if (pgraph_cat.is_debug()) {
|
||||
pgraph_cat.debug()
|
||||
|
|
@ -90,13 +96,14 @@ PandaNode::
|
|||
pgraph_cat.debug()
|
||||
<< "Destructing " << (void *)this << ", " << get_name() << "\n";
|
||||
}
|
||||
clear_dirty_prev_transform();
|
||||
|
||||
// We shouldn't have any parents left by the time we destruct, or
|
||||
// there's a refcount fault somewhere.
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
CDLinksReader cdata(_cycler_links);
|
||||
nassertv(cdata->_up.empty());
|
||||
nassertv(cdata->get_up()->empty());
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
|
|
@ -115,7 +122,8 @@ PandaNode(const PandaNode ©) :
|
|||
ReferenceCount(copy),
|
||||
TypedWritable(copy),
|
||||
Namable(copy),
|
||||
_paths_lock("PandaNode::_paths_lock")
|
||||
_paths_lock("PandaNode::_paths_lock"),
|
||||
_dirty_prev_transform(false)
|
||||
{
|
||||
if (pgraph_cat.is_debug()) {
|
||||
pgraph_cat.debug()
|
||||
|
|
@ -129,14 +137,17 @@ PandaNode(const PandaNode ©) :
|
|||
// Copy the other node's state.
|
||||
{
|
||||
CDLightReader copy_cdata(copy._cycler_light);
|
||||
CDLightWriter cdata(_cycler_light);
|
||||
CDLightWriter cdata(_cycler_light, true);
|
||||
cdata->_state = copy_cdata->_state;
|
||||
cdata->_transform = copy_cdata->_transform;
|
||||
cdata->_prev_transform = copy_cdata->_prev_transform;
|
||||
if (cdata->_transform != cdata->_prev_transform) {
|
||||
set_dirty_prev_transform();
|
||||
}
|
||||
}
|
||||
{
|
||||
CDHeavyReader copy_cdata(copy._cycler_heavy);
|
||||
CDHeavyWriter cdata(_cycler_heavy);
|
||||
CDHeavyWriter cdata(_cycler_heavy, true);
|
||||
cdata->_effects = copy_cdata->_effects;
|
||||
cdata->_tag_data = copy_cdata->_tag_data;
|
||||
cdata->_draw_control_mask = copy_cdata->_draw_control_mask;
|
||||
|
|
@ -565,16 +576,17 @@ add_child(PandaNode *child_node, int sort) {
|
|||
|
||||
// Apply this operation to the current stage as well as to all
|
||||
// upstream stages.
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links) {
|
||||
CDLinksStageWriter cdata(_cycler_links, pipeline_stage);
|
||||
CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links, current_thread) {
|
||||
CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread);
|
||||
CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, current_thread);
|
||||
|
||||
cdata->_down.insert(DownConnection(child_node, sort));
|
||||
cdata_child->_up.insert(UpConnection(this));
|
||||
cdata->modify_down()->insert(DownConnection(child_node, sort));
|
||||
cdata_child->modify_up()->insert(UpConnection(this));
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links);
|
||||
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links) {
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) {
|
||||
new_connection(this, child_node, pipeline_stage);
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links);
|
||||
|
|
@ -595,13 +607,15 @@ remove_child(int child_index) {
|
|||
nassertv(pipeline_stage == 0);
|
||||
|
||||
CDLinksStageWriter cdata(_cycler_links, pipeline_stage);
|
||||
nassertv(child_index >= 0 && child_index < (int)cdata->_down.size());
|
||||
Down &down = *cdata->modify_down();
|
||||
nassertv(child_index >= 0 && child_index < (int)down.size());
|
||||
|
||||
PT(PandaNode) child_node = cdata->_down[child_index].get_child();
|
||||
PT(PandaNode) child_node = down[child_index].get_child();
|
||||
CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage);
|
||||
Up &up = *cdata_child->modify_up();
|
||||
|
||||
cdata->_down.erase(cdata->_down.begin() + child_index);
|
||||
int num_erased = cdata_child->_up.erase(UpConnection(this));
|
||||
down.erase(down.begin() + child_index);
|
||||
int num_erased = up.erase(UpConnection(this));
|
||||
nassertv(num_erased == 1);
|
||||
|
||||
sever_connection(this, child_node, pipeline_stage);
|
||||
|
|
@ -630,7 +644,8 @@ remove_child(PandaNode *child_node) {
|
|||
// We have to do this for each upstream pipeline stage.
|
||||
bool any_removed = false;
|
||||
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links) {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) {
|
||||
if (stage_remove_child(child_node, pipeline_stage)) {
|
||||
any_removed = true;
|
||||
|
||||
|
|
@ -674,7 +689,8 @@ replace_child(PandaNode *orig_child, PandaNode *new_child) {
|
|||
// We have to do this for each upstream pipeline stage.
|
||||
bool any_replaced = false;
|
||||
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links) {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links, current_thread) {
|
||||
if (stage_replace_child(orig_child, new_child, pipeline_stage)) {
|
||||
any_replaced = true;
|
||||
}
|
||||
|
|
@ -723,8 +739,8 @@ stash_child(int child_index) {
|
|||
CDLinksStageWriter cdata(_cycler_links, pipeline_stage);
|
||||
CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage);
|
||||
|
||||
cdata->_stashed.insert(DownConnection(child_node, sort));
|
||||
cdata_child->_up.insert(UpConnection(this));
|
||||
cdata->modify_stashed()->insert(DownConnection(child_node, sort));
|
||||
cdata_child->modify_up()->insert(UpConnection(this));
|
||||
}
|
||||
|
||||
new_connection(this, child_node, pipeline_stage);
|
||||
|
|
@ -767,9 +783,9 @@ unstash_child(int stashed_index) {
|
|||
{
|
||||
CDLinksWriter cdata(_cycler_links);
|
||||
CDLinksWriter cdata_child(child_node->_cycler_links);
|
||||
|
||||
cdata->_down.insert(DownConnection(child_node, sort));
|
||||
cdata_child->_up.insert(UpConnection(this));
|
||||
|
||||
cdata->modify_down()->insert(DownConnection(child_node, sort));
|
||||
cdata_child->modify_up()->insert(UpConnection(this));
|
||||
}
|
||||
|
||||
int pipeline_stage = Thread::get_current_pipeline_stage();
|
||||
|
|
@ -806,8 +822,8 @@ add_stashed(PandaNode *child_node, int sort) {
|
|||
CDLinksWriter cdata(_cycler_links);
|
||||
CDLinksWriter cdata_child(child_node->_cycler_links);
|
||||
|
||||
cdata->_stashed.insert(DownConnection(child_node, sort));
|
||||
cdata_child->_up.insert(UpConnection(this));
|
||||
cdata->modify_stashed()->insert(DownConnection(child_node, sort));
|
||||
cdata_child->modify_up()->insert(UpConnection(this));
|
||||
}
|
||||
|
||||
int pipeline_stage = Thread::get_current_pipeline_stage();
|
||||
|
|
@ -829,13 +845,14 @@ remove_stashed(int child_index) {
|
|||
nassertv(pipeline_stage == 0);
|
||||
|
||||
CDLinksStageWriter cdata(_cycler_links, pipeline_stage);
|
||||
nassertv(child_index >= 0 && child_index < (int)cdata->_stashed.size());
|
||||
Down &stashed = *cdata->modify_stashed();
|
||||
nassertv(child_index >= 0 && child_index < (int)stashed.size());
|
||||
|
||||
PT(PandaNode) child_node = cdata->_stashed[child_index].get_child();
|
||||
PT(PandaNode) child_node = stashed[child_index].get_child();
|
||||
CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage);
|
||||
|
||||
cdata->_stashed.erase(cdata->_stashed.begin() + child_index);
|
||||
int num_erased = cdata_child->_up.erase(UpConnection(this));
|
||||
stashed.erase(stashed.begin() + child_index);
|
||||
int num_erased = cdata_child->modify_up()->erase(UpConnection(this));
|
||||
nassertv(num_erased == 1);
|
||||
|
||||
sever_connection(this, child_node, pipeline_stage);
|
||||
|
|
@ -857,29 +874,33 @@ remove_stashed(int child_index) {
|
|||
void PandaNode::
|
||||
remove_all_children() {
|
||||
// We have to do this for each upstream pipeline stage.
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links) {
|
||||
CDLinksStageWriter cdata(_cycler_links, pipeline_stage);
|
||||
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links, current_thread) {
|
||||
CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread);
|
||||
Down &down = *cdata->modify_down();
|
||||
Down::iterator di;
|
||||
for (di = cdata->_down.begin(); di != cdata->_down.end(); ++di) {
|
||||
for (di = down.begin(); di != down.end(); ++di) {
|
||||
PT(PandaNode) child_node = (*di).get_child();
|
||||
CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage);
|
||||
cdata_child->_up.erase(UpConnection(this));
|
||||
CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage,
|
||||
current_thread);
|
||||
cdata_child->modify_up()->erase(UpConnection(this));
|
||||
|
||||
sever_connection(this, child_node, pipeline_stage);
|
||||
child_node->parents_changed();
|
||||
}
|
||||
cdata->_down.clear();
|
||||
down.clear();
|
||||
|
||||
for (di = cdata->_stashed.begin(); di != cdata->_stashed.end(); ++di) {
|
||||
Down &stashed = *cdata->modify_stashed();
|
||||
for (di = stashed.begin(); di != stashed.end(); ++di) {
|
||||
PT(PandaNode) child_node = (*di).get_child();
|
||||
CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage);
|
||||
cdata_child->_up.erase(UpConnection(this));
|
||||
CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage,
|
||||
current_thread);
|
||||
cdata_child->modify_up()->erase(UpConnection(this));
|
||||
|
||||
sever_connection(this, child_node, pipeline_stage);
|
||||
child_node->parents_changed();
|
||||
}
|
||||
cdata->_stashed.clear();
|
||||
stashed.clear();
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links);
|
||||
|
||||
|
|
@ -965,8 +986,9 @@ set_attrib(const RenderAttrib *attrib, int override) {
|
|||
// Apply this operation to the current stage as well as to all
|
||||
// upstream stages.
|
||||
bool any_changed = false;
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light) {
|
||||
CDLightStageWriter cdata(_cycler_light, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) {
|
||||
CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread);
|
||||
|
||||
CPT(RenderState) new_state = cdata->_state->add_attrib(attrib, override);
|
||||
if (cdata->_state != new_state) {
|
||||
|
|
@ -995,8 +1017,9 @@ void PandaNode::
|
|||
clear_attrib(TypeHandle type) {
|
||||
bool any_changed = false;
|
||||
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light) {
|
||||
CDLightStageWriter cdata(_cycler_light, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) {
|
||||
CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread);
|
||||
|
||||
CPT(RenderState) new_state = cdata->_state->remove_attrib(type);
|
||||
if (cdata->_state != new_state) {
|
||||
|
|
@ -1025,8 +1048,9 @@ void PandaNode::
|
|||
set_effect(const RenderEffect *effect) {
|
||||
// Apply this operation to the current stage as well as to all
|
||||
// upstream stages.
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread);
|
||||
cdata->_effects = cdata->_effects->add_effect(effect);
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy);
|
||||
|
|
@ -1040,8 +1064,9 @@ set_effect(const RenderEffect *effect) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
clear_effect(TypeHandle type) {
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread);
|
||||
cdata->_effects = cdata->_effects->remove_effect(type);
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy);
|
||||
|
|
@ -1062,8 +1087,9 @@ set_state(const RenderState *state) {
|
|||
// Apply this operation to the current stage as well as to all
|
||||
// upstream stages.
|
||||
bool any_changed = false;
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light) {
|
||||
CDLightStageWriter cdata(_cycler_light, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) {
|
||||
CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread);
|
||||
if (cdata->_state != state) {
|
||||
cdata->_state = state;
|
||||
any_changed = true;
|
||||
|
|
@ -1090,8 +1116,9 @@ void PandaNode::
|
|||
set_effects(const RenderEffects *effects) {
|
||||
// Apply this operation to the current stage as well as to all
|
||||
// upstream stages.
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread);
|
||||
cdata->_effects = effects;
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy);
|
||||
|
|
@ -1109,8 +1136,9 @@ set_transform(const TransformState *transform) {
|
|||
// Apply this operation to the current stage as well as to all
|
||||
// upstream stages.
|
||||
bool any_changed = false;
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light) {
|
||||
CDLightStageWriter cdata(_cycler_light, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) {
|
||||
CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread);
|
||||
if (cdata->_transform != transform) {
|
||||
cdata->_transform = transform;
|
||||
any_changed = true;
|
||||
|
|
@ -1136,9 +1164,17 @@ void PandaNode::
|
|||
set_prev_transform(const TransformState *transform) {
|
||||
// Apply this operation to the current stage as well as to all
|
||||
// upstream stages.
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light) {
|
||||
CDLightStageWriter cdata(_cycler_light, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) {
|
||||
CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread);
|
||||
cdata->_prev_transform = transform;
|
||||
if (pipeline_stage == 0) {
|
||||
if (cdata->_transform != cdata->_prev_transform) {
|
||||
set_dirty_prev_transform();
|
||||
} else {
|
||||
clear_dirty_prev_transform();
|
||||
}
|
||||
}
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light);
|
||||
}
|
||||
|
|
@ -1146,24 +1182,63 @@ set_prev_transform(const TransformState *transform) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::reset_prev_transform
|
||||
// Access: Published
|
||||
// Description: Resets the "previous" transform on this node to be
|
||||
// the same as the current transform. This is not the
|
||||
// same as clearing it to identity.
|
||||
// Description: Resets the transform that represents this node's
|
||||
// "previous" position to the same as the current
|
||||
// transform. This is not the same thing as clearing it
|
||||
// to identity.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
reset_prev_transform() {
|
||||
// Apply this operation to the current stage as well as to all
|
||||
// upstream stages.
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light) {
|
||||
CDLightStageReader cdata(_cycler_light, pipeline_stage);
|
||||
if (cdata->_prev_transform != cdata->_transform) {
|
||||
CDLightStageWriter cdataw(_cycler_light, pipeline_stage, cdata);
|
||||
cdataw->_prev_transform = cdataw->_transform;
|
||||
}
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
|
||||
clear_dirty_prev_transform();
|
||||
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) {
|
||||
CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread);
|
||||
cdata->_prev_transform = cdata->_transform;
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::reset_all_prev_transform
|
||||
// Access: Published, Static
|
||||
// Description: Visits all nodes in the world with the
|
||||
// _dirty_prev_transform flag--that is, all nodes whose
|
||||
// _prev_transform is different from the _transform in
|
||||
// pipeline stage 0--and resets the _prev_transform to
|
||||
// be the same as _transform.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
reset_all_prev_transform() {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
nassertv(current_thread->get_pipeline_stage() == 0);
|
||||
|
||||
PStatTimer timer(_reset_prev_pcollector);
|
||||
MutexHolder holder(_dirty_prev_transforms._lock);
|
||||
|
||||
LinkedListNode *list_node = _dirty_prev_transforms._next;
|
||||
while (list_node != &_dirty_prev_transforms) {
|
||||
PandaNode *panda_node = (PandaNode *)list_node;
|
||||
nassertv(panda_node->_dirty_prev_transform);
|
||||
panda_node->_dirty_prev_transform = false;
|
||||
|
||||
CDLightStageWriter cdata(panda_node->_cycler_light, 0, current_thread);
|
||||
cdata->_prev_transform = cdata->_transform;
|
||||
|
||||
list_node = panda_node->_next;
|
||||
#ifndef NDEBUG
|
||||
panda_node->_prev = NULL;
|
||||
panda_node->_next = NULL;
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
_dirty_prev_transforms._prev = &_dirty_prev_transforms;
|
||||
_dirty_prev_transforms._next = &_dirty_prev_transforms;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::set_tag
|
||||
// Access: Published
|
||||
|
|
@ -1181,8 +1256,9 @@ void PandaNode::
|
|||
set_tag(const string &key, const string &value) {
|
||||
// Apply this operation to the current stage as well as to all
|
||||
// upstream stages.
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread);
|
||||
cdata->_tag_data[key] = value;
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy);
|
||||
|
|
@ -1197,8 +1273,9 @@ set_tag(const string &key, const string &value) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
clear_tag(const string &key) {
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread);
|
||||
cdata->_tag_data.erase(key);
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy);
|
||||
|
|
@ -1322,9 +1399,11 @@ copy_tags(PandaNode *other) {
|
|||
|
||||
// Apply this operation to the current stage as well as to all
|
||||
// upstream stages.
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy) {
|
||||
CDHeavyStageWriter cdataw(_cycler_heavy, pipeline_stage);
|
||||
CDHeavyStageReader cdatar(other->_cycler_heavy, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) {
|
||||
CDHeavyStageWriter cdataw(_cycler_heavy, pipeline_stage, current_thread);
|
||||
CDHeavyStageReader cdatar(other->_cycler_heavy, pipeline_stage,
|
||||
current_thread);
|
||||
|
||||
TagData::const_iterator ti;
|
||||
for (ti = cdatar->_tag_data.begin();
|
||||
|
|
@ -1444,8 +1523,9 @@ void PandaNode::
|
|||
adjust_draw_mask(DrawMask show_mask, DrawMask hide_mask, DrawMask clear_mask) {
|
||||
bool any_changed = false;
|
||||
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread);
|
||||
|
||||
DrawMask draw_control_mask = (cdata->_draw_control_mask | show_mask | hide_mask) & ~clear_mask;
|
||||
DrawMask draw_show_mask = (cdata->_draw_show_mask | show_mask) & ~hide_mask;
|
||||
|
|
@ -1543,8 +1623,9 @@ set_into_collide_mask(CollideMask mask) {
|
|||
mask &= get_legal_collide_mask();
|
||||
|
||||
bool any_changed = false;
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread);
|
||||
if (cdata->_into_collide_mask != mask) {
|
||||
cdata->_into_collide_mask = mask;
|
||||
any_changed = true;
|
||||
|
|
@ -1686,8 +1767,9 @@ write(ostream &out, int indent_level) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
set_bounds(const BoundingVolume *volume) {
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) {
|
||||
CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread);
|
||||
if (volume == NULL) {
|
||||
cdata->_user_bounds = NULL;
|
||||
} else {
|
||||
|
|
@ -1756,7 +1838,8 @@ get_bounds() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
mark_bounds_stale() const {
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links) {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) {
|
||||
mark_bounds_stale(pipeline_stage);
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links);
|
||||
|
|
@ -1839,8 +1922,9 @@ get_internal_bounds(int pipeline_stage) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
set_internal_bounds(const BoundingVolume *volume) {
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy) {
|
||||
CDHeavyStageWriter cdataw(_cycler_heavy, pipeline_stage);
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy, current_thread) {
|
||||
CDHeavyStageWriter cdataw(_cycler_heavy, pipeline_stage, current_thread);
|
||||
cdataw->_internal_bounds = volume;
|
||||
cdataw->_internal_bounds_stale = false;
|
||||
}
|
||||
|
|
@ -1861,7 +1945,8 @@ set_internal_bounds(const BoundingVolume *volume) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
force_bounds_stale() {
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links) {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) {
|
||||
force_bounds_stale(pipeline_stage);
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links);
|
||||
|
|
@ -1888,7 +1973,7 @@ force_bounds_stale(int pipeline_stage) {
|
|||
// It is similarly important that we use get_parents() here to copy
|
||||
// the parents list, instead of keeping the lock open while we walk
|
||||
// through the parents list directly on the node.
|
||||
ParentsCopy parents = get_parents_copy();
|
||||
Parents parents = get_parents();
|
||||
int num_parents = parents.get_num_parents();
|
||||
for (int i = 0; i < num_parents; ++i) {
|
||||
PandaNode *parent = parents.get_parent(i);
|
||||
|
|
@ -1910,7 +1995,8 @@ force_bounds_stale(int pipeline_stage) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
mark_internal_bounds_stale() {
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links) {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) {
|
||||
mark_internal_bounds_stale(pipeline_stage);
|
||||
}
|
||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links);
|
||||
|
|
@ -2032,8 +2118,9 @@ r_copy_subgraph(PandaNode::InstanceMap &inst_map) const {
|
|||
void PandaNode::
|
||||
r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map) {
|
||||
CDLinksReader from_cdata(from->_cycler_links);
|
||||
const Down &from_down = *from_cdata->get_down();
|
||||
Down::const_iterator di;
|
||||
for (di = from_cdata->_down.begin(); di != from_cdata->_down.end(); ++di) {
|
||||
for (di = from_down.begin(); di != from_down.end(); ++di) {
|
||||
int sort = (*di).get_sort();
|
||||
PandaNode *source_child = (*di).get_child();
|
||||
PT(PandaNode) dest_child;
|
||||
|
|
@ -2066,10 +2153,11 @@ do_find_child(PandaNode *node, const CDataLinks *cdata) const {
|
|||
|
||||
// We have to search for the child by brute force, since we don't
|
||||
// know what sort index it was added as.
|
||||
const Down &down = *cdata->get_down();
|
||||
Down::const_iterator di;
|
||||
for (di = cdata->_down.begin(); di != cdata->_down.end(); ++di) {
|
||||
for (di = down.begin(); di != down.end(); ++di) {
|
||||
if ((*di).get_child() == node) {
|
||||
return di - cdata->_down.begin();
|
||||
return di - down.begin();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2087,10 +2175,11 @@ do_find_stashed(PandaNode *node, const CDataLinks *cdata) const {
|
|||
|
||||
// We have to search for the child by brute force, since we don't
|
||||
// know what sort index it was added as.
|
||||
const Down &stashed = *cdata->get_stashed();
|
||||
Down::const_iterator di;
|
||||
for (di = cdata->_stashed.begin(); di != cdata->_stashed.end(); ++di) {
|
||||
for (di = stashed.begin(); di != stashed.end(); ++di) {
|
||||
if ((*di).get_child() == node) {
|
||||
return di - cdata->_stashed.begin();
|
||||
return di - stashed.begin();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2120,8 +2209,9 @@ stage_remove_child(PandaNode *child_node, int pipeline_stage) {
|
|||
int child_index = do_find_child(child_node, cdata);
|
||||
if (child_index >= 0) {
|
||||
// The child exists; remove it.
|
||||
cdata->_down.erase(cdata->_down.begin() + child_index);
|
||||
int num_erased = cdata_child->_up.erase(UpConnection(this));
|
||||
Down &down = *cdata->modify_down();
|
||||
down.erase(down.begin() + child_index);
|
||||
int num_erased = cdata_child->modify_up()->erase(UpConnection(this));
|
||||
nassertr(num_erased == 1, false);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2129,8 +2219,9 @@ stage_remove_child(PandaNode *child_node, int pipeline_stage) {
|
|||
int stashed_index = do_find_stashed(child_node, cdata);
|
||||
if (stashed_index >= 0) {
|
||||
// The child has been stashed; remove it.
|
||||
cdata->_stashed.erase(cdata->_stashed.begin() + stashed_index);
|
||||
int num_erased = cdata_child->_up.erase(UpConnection(this));
|
||||
Down &stashed = *cdata->modify_down();
|
||||
stashed.erase(stashed.begin() + stashed_index);
|
||||
int num_erased = cdata_child->modify_up()->erase(UpConnection(this));
|
||||
nassertr(num_erased == 1, false);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2175,7 +2266,7 @@ stage_replace_child(PandaNode *orig_child, PandaNode *new_child,
|
|||
int child_index = do_find_child(orig_child, cdata);
|
||||
if (child_index >= 0) {
|
||||
// The child exists; replace it.
|
||||
DownConnection &down = cdata->_down[child_index];
|
||||
DownConnection &down = (*cdata->modify_down())[child_index];
|
||||
nassertr(down.get_child() == orig_child, false);
|
||||
down.set_child(new_child);
|
||||
|
||||
|
|
@ -2183,7 +2274,7 @@ stage_replace_child(PandaNode *orig_child, PandaNode *new_child,
|
|||
int stashed_index = do_find_stashed(orig_child, cdata);
|
||||
if (stashed_index >= 0) {
|
||||
// The child has been stashed; remove it.
|
||||
DownConnection &down = cdata->_stashed[stashed_index];
|
||||
DownConnection &down = (*cdata->modify_stashed())[stashed_index];
|
||||
nassertr(down.get_child() == orig_child, false);
|
||||
down.set_child(new_child);
|
||||
|
||||
|
|
@ -2197,8 +2288,8 @@ stage_replace_child(PandaNode *orig_child, PandaNode *new_child,
|
|||
}
|
||||
|
||||
// Now adjust the bookkeeping on both children.
|
||||
cdata_new_child->_up.insert(UpConnection(this));
|
||||
int num_erased = cdata_orig_child->_up.erase(UpConnection(this));
|
||||
cdata_new_child->modify_up()->insert(UpConnection(this));
|
||||
int num_erased = cdata_orig_child->modify_up()->erase(UpConnection(this));
|
||||
nassertr(num_erased == 1, false);
|
||||
}
|
||||
|
||||
|
|
@ -2300,7 +2391,7 @@ detach_one_stage(NodePathComponent *child, int pipeline_stage) {
|
|||
|
||||
// First, look for and remove the parent node from the child's up
|
||||
// list.
|
||||
int num_erased = cdata_child->_up.erase(UpConnection(parent_node));
|
||||
int num_erased = cdata_child->modify_up()->erase(UpConnection(parent_node));
|
||||
nassertv(num_erased == 1);
|
||||
|
||||
// Now, look for and remove the child node from the parent's down
|
||||
|
|
@ -2308,19 +2399,17 @@ detach_one_stage(NodePathComponent *child, int pipeline_stage) {
|
|||
// has been stashed.
|
||||
Down::iterator di;
|
||||
bool found = false;
|
||||
for (di = cdata_parent->_down.begin();
|
||||
di != cdata_parent->_down.end() && !found;
|
||||
++di) {
|
||||
Down &down = *cdata_parent->modify_down();
|
||||
for (di = down.begin(); di != down.end() && !found; ++di) {
|
||||
if ((*di).get_child() == child_node) {
|
||||
cdata_parent->_down.erase(di);
|
||||
down.erase(di);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
for (di = cdata_parent->_stashed.begin();
|
||||
di != cdata_parent->_stashed.end() && !found;
|
||||
++di) {
|
||||
Down &stashed = *cdata_parent->modify_stashed();
|
||||
for (di = stashed.begin(); di != stashed.end() && !found; ++di) {
|
||||
if ((*di).get_child() == child_node) {
|
||||
cdata_parent->_stashed.erase(di);
|
||||
stashed.erase(di);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -2417,11 +2506,11 @@ reparent_one_stage(NodePathComponent *new_parent, NodePathComponent *child,
|
|||
CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage);
|
||||
|
||||
if (as_stashed) {
|
||||
cdata_parent->_stashed.insert(DownConnection(child_node, sort));
|
||||
cdata_parent->modify_stashed()->insert(DownConnection(child_node, sort));
|
||||
} else {
|
||||
cdata_parent->_down.insert(DownConnection(child_node, sort));
|
||||
cdata_parent->modify_down()->insert(DownConnection(child_node, sort));
|
||||
}
|
||||
cdata_child->_up.insert(UpConnection(parent_node));
|
||||
cdata_child->modify_up()->insert(UpConnection(parent_node));
|
||||
|
||||
#ifndef NDEBUG
|
||||
// The NodePathComponent should already be in the set.
|
||||
|
|
@ -2569,7 +2658,7 @@ r_get_generic_component(bool accept_ambiguity, bool &ambiguity_detected,
|
|||
{
|
||||
CDLinksStageReader cdata(_cycler_links, pipeline_stage);
|
||||
|
||||
int num_parents = cdata->_up.size();
|
||||
int num_parents = cdata->get_up()->size();
|
||||
if (num_parents == 0) {
|
||||
// No parents; no ambiguity. This is the root.
|
||||
return get_top_component(this, true, pipeline_stage);
|
||||
|
|
@ -2590,7 +2679,8 @@ r_get_generic_component(bool accept_ambiguity, bool &ambiguity_detected,
|
|||
<< " parents; choosing arbitrary path to root.\n";
|
||||
}
|
||||
ambiguity_detected = true;
|
||||
parent_node = cdata->_up[0].get_parent();
|
||||
const Up &up = *cdata->get_up();
|
||||
parent_node = up[0].get_parent();
|
||||
}
|
||||
|
||||
// Now that the lock is released, it's safe to recurse.
|
||||
|
|
@ -3453,9 +3543,9 @@ make_copy() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::CDataLinks::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) const {
|
||||
write_up_list(_up, manager, dg);
|
||||
write_down_list(_down, manager, dg);
|
||||
write_down_list(_stashed, manager, dg);
|
||||
write_up_list(*get_up(), manager, dg);
|
||||
write_down_list(*get_down(), manager, dg);
|
||||
write_down_list(*get_stashed(), manager, dg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3470,9 +3560,9 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
|||
int pi = CycleData::complete_pointers(p_list, manager);
|
||||
|
||||
// Get the parent and child pointers.
|
||||
pi += complete_up_list(_up, p_list + pi, manager);
|
||||
pi += complete_down_list(_down, p_list + pi, manager);
|
||||
pi += complete_down_list(_stashed, p_list + pi, manager);
|
||||
pi += complete_up_list(*modify_up(), p_list + pi, manager);
|
||||
pi += complete_down_list(*modify_down(), p_list + pi, manager);
|
||||
pi += complete_down_list(*modify_stashed(), p_list + pi, manager);
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
|
@ -3486,9 +3576,9 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::CDataLinks::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
fillin_up_list(_up, scan, manager);
|
||||
fillin_down_list(_down, scan, manager);
|
||||
fillin_down_list(_stashed, scan, manager);
|
||||
fillin_up_list(*modify_up(), scan, manager);
|
||||
fillin_down_list(*modify_down(), scan, manager);
|
||||
fillin_down_list(*modify_stashed(), scan, manager);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3620,10 +3710,10 @@ fillin_up_list(PandaNode::Up &up_list,
|
|||
DatagramIterator &scan, BamReader *manager) {
|
||||
int num_parents = scan.get_uint16();
|
||||
// Read the list of parent nodes. Push back a NULL for each one.
|
||||
_up.reserve(num_parents);
|
||||
up_list.reserve(num_parents);
|
||||
for (int i = 0; i < num_parents; i++) {
|
||||
manager->read_pointer(scan);
|
||||
_up.push_back(UpConnection(NULL));
|
||||
up_list.push_back(UpConnection(NULL));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3646,51 +3736,3 @@ fillin_down_list(PandaNode::Down &down_list,
|
|||
down_list.push_back(DownConnection(NULL, sort));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::ChildrenCopy::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode::ChildrenCopy::
|
||||
ChildrenCopy(const PandaNode::CDLinksReader &cdata) {
|
||||
_list.reserve(cdata->_down.size());
|
||||
|
||||
Down::const_iterator di;
|
||||
for (di = cdata->_down.begin(); di != cdata->_down.end(); ++di) {
|
||||
PandaNode *child = (*di).get_child();
|
||||
_list.push_back(child);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::StashedCopy::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode::StashedCopy::
|
||||
StashedCopy(const PandaNode::CDLinksReader &cdata) {
|
||||
_list.reserve(cdata->_down.size());
|
||||
|
||||
Down::const_iterator di;
|
||||
for (di = cdata->_stashed.begin(); di != cdata->_stashed.end(); ++di) {
|
||||
PandaNode *child = (*di).get_child();
|
||||
_list.push_back(child);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::ParentsCopy::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode::ParentsCopy::
|
||||
ParentsCopy(const PandaNode::CDLinksReader &cdata) {
|
||||
_list.reserve(cdata->_up.size());
|
||||
|
||||
Up::const_iterator ui;
|
||||
for (ui = cdata->_up.begin(); ui != cdata->_up.end(); ++ui) {
|
||||
PandaNode *parent = (*ui).get_parent();
|
||||
_list.push_back(parent);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
#include "pnotify.h"
|
||||
#include "updateSeq.h"
|
||||
#include "deletedChain.h"
|
||||
#include "pandaNodeChain.h"
|
||||
#include "pStatCollector.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
|
|
@ -66,7 +68,8 @@ class GeomTransformer;
|
|||
// is the base class of all specialized nodes, and also
|
||||
// serves as a generic node with no special properties.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA PandaNode : public TypedWritable, public Namable,
|
||||
class EXPCL_PANDA PandaNode : public TypedWritable, public Namable,
|
||||
public LinkedListNode,
|
||||
virtual public ReferenceCount {
|
||||
PUBLISHED:
|
||||
PandaNode(const string &name);
|
||||
|
|
@ -169,6 +172,8 @@ PUBLISHED:
|
|||
void set_prev_transform(const TransformState *transform);
|
||||
INLINE const TransformState *get_prev_transform() const;
|
||||
void reset_prev_transform();
|
||||
INLINE bool has_dirty_prev_transform() const;
|
||||
static void reset_all_prev_transform();
|
||||
|
||||
void set_tag(const string &key, const string &value);
|
||||
INLINE string get_tag(const string &key) const;
|
||||
|
|
@ -303,6 +308,9 @@ private:
|
|||
void fix_path_lengths(int pipeline_stage);
|
||||
void r_list_descendants(ostream &out, int indent_level) const;
|
||||
|
||||
INLINE void set_dirty_prev_transform();
|
||||
INLINE void clear_dirty_prev_transform();
|
||||
|
||||
public:
|
||||
// This must be declared public so that VC6 will allow the nested
|
||||
// CData class to access it.
|
||||
|
|
@ -323,7 +331,7 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
typedef ov_multiset<DownConnection> Down;
|
||||
typedef RefCountObj< ov_multiset<DownConnection> > Down;
|
||||
|
||||
class EXPCL_PANDA UpConnection {
|
||||
public:
|
||||
|
|
@ -336,7 +344,7 @@ private:
|
|||
// children do not circularly reference each other.
|
||||
PandaNode *_parent;
|
||||
};
|
||||
typedef ov_set<UpConnection> Up;
|
||||
typedef RefCountObj< ov_set<UpConnection> > Up;
|
||||
|
||||
// We also maintain a set of NodePathComponents in the node. This
|
||||
// represents the set of instances of this node that we have
|
||||
|
|
@ -352,6 +360,9 @@ private:
|
|||
Paths _paths;
|
||||
Mutex _paths_lock;
|
||||
|
||||
bool _dirty_prev_transform;
|
||||
static PandaNodeChain _dirty_prev_transforms;
|
||||
|
||||
// This is used to maintain a table of keyed data on each node, for
|
||||
// the user's purposes.
|
||||
typedef phash_map<string, string, string_hash> TagData;
|
||||
|
|
@ -368,7 +379,7 @@ private:
|
|||
// are grouped into a different one.
|
||||
|
||||
// The CDataLight object stores the lightweight parts of the node
|
||||
// that are likely to change fairly often: transform and stage.
|
||||
// that are likely to change fairly often: transform and state.
|
||||
class EXPCL_PANDA CDataLight : public CycleData {
|
||||
public:
|
||||
INLINE CDataLight();
|
||||
|
|
@ -529,9 +540,19 @@ private:
|
|||
void fillin_down_list(Down &down_list,
|
||||
DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
Down _down;
|
||||
Down _stashed;
|
||||
Up _up;
|
||||
INLINE const Down *get_down() const;
|
||||
INLINE Down *modify_down();
|
||||
INLINE const Down *get_stashed() const;
|
||||
INLINE Down *modify_stashed();
|
||||
INLINE const Up *get_up() const;
|
||||
INLINE Up *modify_up();
|
||||
|
||||
private:
|
||||
// We store the child lists by reference, so we can copy them
|
||||
// quickly. We perform copy-on-write when necessary.
|
||||
PT(Down) _down;
|
||||
PT(Down) _stashed;
|
||||
PT(Up) _up;
|
||||
};
|
||||
|
||||
PipelineCycler<CDataLinks> _cycler_links;
|
||||
|
|
@ -545,37 +566,16 @@ private:
|
|||
|
||||
static DrawMask _overall_bit;
|
||||
|
||||
static PStatCollector _reset_prev_pcollector;
|
||||
|
||||
public:
|
||||
// This class is returned from get_children_copy(). Use it to walk
|
||||
// through the list of children, particularly with a self-modifying
|
||||
// loop, since the list of children is copied first and is thus safe
|
||||
// from self modification.
|
||||
class EXPCL_PANDA ChildrenCopy {
|
||||
public:
|
||||
ChildrenCopy(const CDLinksReader &cdata);
|
||||
INLINE ChildrenCopy(const ChildrenCopy ©);
|
||||
INLINE void operator = (const ChildrenCopy ©);
|
||||
|
||||
INLINE int get_num_children() const;
|
||||
INLINE PandaNode *get_child(int n) const;
|
||||
|
||||
private:
|
||||
typedef PTA(PT(PandaNode)) List;
|
||||
List _list;
|
||||
};
|
||||
|
||||
// This class is returned from get_children(). Use this interface
|
||||
// when you want to walk through the list of children with less
|
||||
// overhead than get_children_copy(); in single-threaded Panda, a
|
||||
// copy is not made first, so this interface is fast. However, this
|
||||
// does not protect you from self-modifying loops. Also, since the
|
||||
// lock is kept open the whole time, this is generally unsafe to use
|
||||
// in threaded code (which would then hold the lock on the root node
|
||||
// during an entire traversal), so when pipelining is enabled,
|
||||
// get_children() returns the same thing as get_children_copy().
|
||||
#ifdef DO_PIPELINING
|
||||
typedef ChildrenCopy Children;
|
||||
#else
|
||||
// This class is returned from get_children(). Use it to walk
|
||||
// through the list of children. This is faster, and safer, than
|
||||
// walking through the children one at a time via
|
||||
// get_num_children()/get_child(), since the list of children is
|
||||
// saved out ahead of time, rather than having to reacquire the lock
|
||||
// with each iteration, or to keep the lock held for the entire
|
||||
// pass.
|
||||
class EXPCL_PANDA Children {
|
||||
public:
|
||||
INLINE Children(const CDLinksReader &cdata);
|
||||
|
|
@ -586,28 +586,10 @@ public:
|
|||
INLINE PandaNode *get_child(int n) const;
|
||||
|
||||
private:
|
||||
CDLinksReader _cdata;
|
||||
CPT(Down) _down;
|
||||
};
|
||||
#endif // DO_PIPELINING
|
||||
|
||||
// Similarly for stashed children.
|
||||
class EXPCL_PANDA StashedCopy {
|
||||
public:
|
||||
StashedCopy(const CDLinksReader &cdata);
|
||||
INLINE StashedCopy(const StashedCopy ©);
|
||||
INLINE void operator = (const StashedCopy ©);
|
||||
|
||||
INLINE int get_num_stashed() const;
|
||||
INLINE PandaNode *get_stashed(int n) const;
|
||||
|
||||
private:
|
||||
typedef PTA(PT(PandaNode)) List;
|
||||
List _list;
|
||||
};
|
||||
|
||||
#ifdef DO_PIPELINING
|
||||
typedef StashedCopy Stashed;
|
||||
#else
|
||||
class EXPCL_PANDA Stashed {
|
||||
public:
|
||||
INLINE Stashed(const CDLinksReader &cdata);
|
||||
|
|
@ -618,30 +600,26 @@ public:
|
|||
INLINE PandaNode *get_stashed(int n) const;
|
||||
|
||||
private:
|
||||
CDLinksReader _cdata;
|
||||
CPT(Down) _stashed;
|
||||
};
|
||||
#endif // DO_PIPELINING
|
||||
|
||||
// This class is returned from get_parents_copy().
|
||||
class EXPCL_PANDA ParentsCopy {
|
||||
// This class is returned from get_parents().
|
||||
class EXPCL_PANDA Parents {
|
||||
public:
|
||||
ParentsCopy(const CDLinksReader &cdata);
|
||||
INLINE ParentsCopy(const ParentsCopy ©);
|
||||
INLINE void operator = (const ParentsCopy ©);
|
||||
INLINE Parents(const CDLinksReader &cdata);
|
||||
INLINE Parents(const Parents ©);
|
||||
INLINE void operator = (const Parents ©);
|
||||
|
||||
INLINE int get_num_parents() const;
|
||||
INLINE PandaNode *get_parent(int n) const;
|
||||
|
||||
private:
|
||||
typedef PTA(PT(PandaNode)) List;
|
||||
List _list;
|
||||
CPT(Up) _up;
|
||||
};
|
||||
|
||||
INLINE ChildrenCopy get_children_copy() const;
|
||||
INLINE Children get_children() const;
|
||||
INLINE StashedCopy get_stashed_copy() const;
|
||||
INLINE Stashed get_stashed() const;
|
||||
INLINE ParentsCopy get_parents_copy() const;
|
||||
INLINE Children get_children(Thread *current_thread = Thread::get_current_thread()) const;
|
||||
INLINE Stashed get_stashed(Thread *current_thread = Thread::get_current_thread()) const;
|
||||
INLINE Parents get_parents(Thread *current_thread = Thread::get_current_thread()) const;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "nodePathComponent.cxx"
|
||||
#include "nodePathLerps.cxx"
|
||||
#include "pandaNode.cxx"
|
||||
#include "pandaNodeChain.cxx"
|
||||
#include "planeNode.cxx"
|
||||
#include "pointLight.cxx"
|
||||
#include "polylightNode.cxx"
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ flatten(PandaNode *root, int combine_siblings_bits) {
|
|||
|
||||
// Get a copy of the children list, so we don't have to worry
|
||||
// about self-modifications.
|
||||
PandaNode::ChildrenCopy cr = root->get_children_copy();
|
||||
PandaNode::Children cr = root->get_children();
|
||||
|
||||
// Now visit each of the children in turn.
|
||||
int num_children = cr.get_num_children();
|
||||
|
|
@ -257,7 +257,7 @@ r_flatten(PandaNode *grandparent_node, PandaNode *parent_node,
|
|||
|
||||
// First, recurse on each of the children.
|
||||
{
|
||||
PandaNode::ChildrenCopy cr = parent_node->get_children_copy();
|
||||
PandaNode::Children cr = parent_node->get_children();
|
||||
int num_children = cr.get_num_children();
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
PandaNode *child_node = cr.get_child(i);
|
||||
|
|
|
|||
|
|
@ -95,10 +95,10 @@ private:
|
|||
|
||||
// Iterates through all of the pipeline stages upstream of the current
|
||||
// stage, but not including the current stage.
|
||||
#define OPEN_ITERATE_UPSTREAM_ONLY(cycler) { \
|
||||
#define OPEN_ITERATE_UPSTREAM_ONLY(cycler, current_thread) { \
|
||||
CyclerHolder cholder(cycler); \
|
||||
int pipeline_stage; \
|
||||
for (pipeline_stage = Thread::get_current_pipeline_stage() - 1; \
|
||||
for (pipeline_stage = current_thread->get_pipeline_stage() - 1; \
|
||||
pipeline_stage >= 0; \
|
||||
--pipeline_stage)
|
||||
|
||||
|
|
@ -107,10 +107,10 @@ private:
|
|||
|
||||
// Iterates through all of the pipeline stages upstream of the current
|
||||
// stage, and including the current stage.
|
||||
#define OPEN_ITERATE_CURRENT_AND_UPSTREAM(cycler) { \
|
||||
#define OPEN_ITERATE_CURRENT_AND_UPSTREAM(cycler, current_thread) { \
|
||||
CyclerHolder cholder(cycler); \
|
||||
int pipeline_stage; \
|
||||
for (pipeline_stage = Thread::get_current_pipeline_stage(); \
|
||||
for (pipeline_stage = current_thread->get_pipeline_stage(); \
|
||||
pipeline_stage >= 0; \
|
||||
--pipeline_stage)
|
||||
|
||||
|
|
@ -118,9 +118,9 @@ private:
|
|||
}
|
||||
|
||||
// As above, but without holding the cycler lock during the loop.
|
||||
#define OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(cycler) { \
|
||||
#define OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(cycler, current_thread) { \
|
||||
int pipeline_stage; \
|
||||
for (pipeline_stage = Thread::get_current_pipeline_stage(); \
|
||||
for (pipeline_stage = current_thread->get_pipeline_stage(); \
|
||||
pipeline_stage >= 0; \
|
||||
--pipeline_stage)
|
||||
|
||||
|
|
@ -142,20 +142,20 @@ private:
|
|||
// These are trivial implementations of the above macros, defined when
|
||||
// pipelining is not enabled, that simply operate on stage 0 without
|
||||
// bothering to create a for loop.
|
||||
#define OPEN_ITERATE_UPSTREAM_ONLY(cycler) \
|
||||
#define OPEN_ITERATE_UPSTREAM_ONLY(cycler, current_thread) \
|
||||
if (false) { \
|
||||
const int pipeline_stage = -1;
|
||||
|
||||
#define CLOSE_ITERATE_UPSTREAM_ONLY(cycler) \
|
||||
}
|
||||
|
||||
#define OPEN_ITERATE_CURRENT_AND_UPSTREAM(cycler) { \
|
||||
#define OPEN_ITERATE_CURRENT_AND_UPSTREAM(cycler, current_thread) { \
|
||||
const int pipeline_stage = 0; \
|
||||
|
||||
#define CLOSE_ITERATE_CURRENT_AND_UPSTREAM(cycler) \
|
||||
}
|
||||
|
||||
#define OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(cycler) { \
|
||||
#define OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(cycler, current_thread) { \
|
||||
const int pipeline_stage = 0; \
|
||||
|
||||
#define CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(cycler) \
|
||||
|
|
|
|||
Loading…
Reference in New Issue