|
|
@@ -40,7 +40,7 @@ TransformState() {
|
|
|
if (_states == (States *)NULL) {
|
|
|
// Make sure the global _states map is allocated. This only has
|
|
|
// to be done once. We could make this map static, but then we
|
|
|
- // run into problems if anyone creates a RenderState object at
|
|
|
+ // run into problems if anyone creates a TransformState object at
|
|
|
// static init time; it also seems to cause problems when the
|
|
|
// Panda shared library is unloaded at application exit time.
|
|
|
_states = new States;
|
|
|
@@ -652,6 +652,89 @@ write(ostream &out, int indent_level) const {
|
|
|
indent(out, indent_level) << *this << "\n";
|
|
|
}
|
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: TransformState::get_cache_size
|
|
|
+// Access: Published, Static
|
|
|
+// Description: Returns the total number of unique TransformState
|
|
|
+// objects allocated in the world. This will go up and
|
|
|
+// down during normal operations.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+int TransformState::
|
|
|
+get_cache_size() {
|
|
|
+ if (_states == (States *)NULL) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return _states->size();
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: TransformState::clear_cache
|
|
|
+// Access: Published, Static
|
|
|
+// Description: Empties the cache of composed TransformStates. This
|
|
|
+// makes every TransformState forget what results when
|
|
|
+// it is composed with other TransformStates.
|
|
|
+//
|
|
|
+// This will eliminate any TransformState objects that
|
|
|
+// have been allocated but have no references outside of
|
|
|
+// the internal TransformState map. It will not
|
|
|
+// eliminate TransformState objects that are still in
|
|
|
+// use.
|
|
|
+//
|
|
|
+// Normally, TransformState objects will remove
|
|
|
+// themselves from the interal map when their reference
|
|
|
+// counts go to 0, but since circular references are
|
|
|
+// possible there may be some cycles that cannot remove
|
|
|
+// themselves. Calling this function from time to time
|
|
|
+// will ensure there is no wasteful memory leakage, but
|
|
|
+// calling it too often may result in decreased
|
|
|
+// performance as the cache is forced to be recomputed.
|
|
|
+//
|
|
|
+// The return value is the number of TransformStates
|
|
|
+// freed by this operation.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+int TransformState::
|
|
|
+clear_cache() {
|
|
|
+ if (_states == (States *)NULL) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ int orig_size = _states->size();
|
|
|
+
|
|
|
+ // First, we need to copy the entire set of transforms to a
|
|
|
+ // temporary vector, reference-counting each object. That way we
|
|
|
+ // can walk through the copy, without fear of dereferencing (and
|
|
|
+ // deleting) the objects in the map as we go.
|
|
|
+ {
|
|
|
+ typedef pvector< CPT(TransformState) > TempStates;
|
|
|
+ TempStates temp_states;
|
|
|
+ temp_states.reserve(orig_size);
|
|
|
+
|
|
|
+ copy(_states->begin(), _states->end(),
|
|
|
+ back_inserter(temp_states));
|
|
|
+
|
|
|
+ // Now it's safe to walk through the list, destroying the cache
|
|
|
+ // within each object as we go. Nothing will be destructed till
|
|
|
+ // we're done.
|
|
|
+ TempStates::iterator ti;
|
|
|
+ for (ti = temp_states.begin(); ti != temp_states.end(); ++ti) {
|
|
|
+ TransformState *state = (TransformState *)(*ti).p();
|
|
|
+ state->_composition_cache.clear();
|
|
|
+ state->_invert_composition_cache.clear();
|
|
|
+ if (state->_self_compose != (TransformState *)NULL &&
|
|
|
+ state->_self_compose != state) {
|
|
|
+ unref_delete((TransformState *)state->_self_compose);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Once this block closes and the temp_states object goes away,
|
|
|
+ // all the destruction will begin. Anything whose reference was
|
|
|
+ // held only within the various objects' caches will go away.
|
|
|
+ }
|
|
|
+
|
|
|
+ int new_size = _states->size();
|
|
|
+ return orig_size - new_size;
|
|
|
+}
|
|
|
+
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: TransformState::return_new
|
|
|
// Access: Private, Static
|