mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
further debugging in TransformState (and one important bugfix)
This commit is contained in:
parent
212ed1e510
commit
e552c230a0
@ -768,6 +768,66 @@ unref() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::validate_composition_cache
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if the composition cache and invert
|
||||||
|
// composition cache for this particular TransformState
|
||||||
|
// are self-consistent and valid, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool TransformState::
|
||||||
|
validate_composition_cache() const {
|
||||||
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
|
int size = _composition_cache.get_size();
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
if (!_composition_cache.has_element(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const TransformState *source = _composition_cache.get_key(i);
|
||||||
|
if (source != (TransformState *)NULL) {
|
||||||
|
// Check that the source also has a pointer back to this one. We
|
||||||
|
// always add entries to the composition cache in pairs.
|
||||||
|
int ri = source->_composition_cache.find(this);
|
||||||
|
if (ri == -1) {
|
||||||
|
// Failure! There is no back-pointer.
|
||||||
|
pgraph_cat.error()
|
||||||
|
<< "TransformState::composition cache is inconsistent!\n";
|
||||||
|
pgraph_cat.error(false)
|
||||||
|
<< *this << " compose " << *source << "\n";
|
||||||
|
pgraph_cat.error(false)
|
||||||
|
<< "but no reverse\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size = _invert_composition_cache.get_size();
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
if (!_invert_composition_cache.has_element(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const TransformState *source = _invert_composition_cache.get_key(i);
|
||||||
|
if (source != (TransformState *)NULL) {
|
||||||
|
// Check that the source also has a pointer back to this one. We
|
||||||
|
// always add entries to the composition cache in pairs.
|
||||||
|
int ri = source->_invert_composition_cache.find(this);
|
||||||
|
if (ri == -1) {
|
||||||
|
// Failure! There is no back-pointer.
|
||||||
|
pgraph_cat.error()
|
||||||
|
<< "TransformState::invert composition cache is inconsistent!\n";
|
||||||
|
pgraph_cat.error(false)
|
||||||
|
<< *this << " invert compose " << *source << "\n";
|
||||||
|
pgraph_cat.error(false)
|
||||||
|
<< "but no reverse\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PYTHON
|
#ifdef HAVE_PYTHON
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TransformState::get_composition_cache
|
// Function: TransformState::get_composition_cache
|
||||||
@ -787,43 +847,47 @@ PyObject *TransformState::
|
|||||||
get_composition_cache() const {
|
get_composition_cache() const {
|
||||||
IMPORT_THIS struct Dtool_PyTypedObject Dtool_TransformState;
|
IMPORT_THIS struct Dtool_PyTypedObject Dtool_TransformState;
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
size_t cache_size = _composition_cache.get_size();
|
|
||||||
PyObject *list = PyList_New(cache_size);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < cache_size; ++i) {
|
size_t num_states = _composition_cache.get_num_entries();
|
||||||
|
PyObject *list = PyList_New(num_states);
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
int size = _composition_cache.get_size();
|
||||||
|
for (int si = 0; si < size; ++si) {
|
||||||
|
if (!_composition_cache.has_element(si)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *tuple = PyTuple_New(2);
|
PyObject *tuple = PyTuple_New(2);
|
||||||
PyObject *a, *b;
|
PyObject *a, *b;
|
||||||
if (!_composition_cache.has_element(i)) {
|
|
||||||
|
const TransformState *source = _composition_cache.get_key(si);
|
||||||
|
if (source == (TransformState *)NULL) {
|
||||||
a = Py_None;
|
a = Py_None;
|
||||||
Py_INCREF(a);
|
Py_INCREF(a);
|
||||||
|
} else {
|
||||||
|
source->ref();
|
||||||
|
a = DTool_CreatePyInstanceTyped((void *)source, Dtool_TransformState,
|
||||||
|
true, true, source->get_type_index());
|
||||||
|
}
|
||||||
|
const TransformState *result = _composition_cache.get_data(si)._result;
|
||||||
|
if (result == (TransformState *)NULL) {
|
||||||
b = Py_None;
|
b = Py_None;
|
||||||
Py_INCREF(b);
|
Py_INCREF(b);
|
||||||
} else {
|
} else {
|
||||||
const TransformState *source = _composition_cache.get_key(i);
|
result->ref();
|
||||||
if (source == (TransformState *)NULL) {
|
b = DTool_CreatePyInstanceTyped((void *)result, Dtool_TransformState,
|
||||||
a = Py_None;
|
true, true, result->get_type_index());
|
||||||
Py_INCREF(a);
|
|
||||||
} else {
|
|
||||||
source->ref();
|
|
||||||
a = DTool_CreatePyInstanceTyped((void *)source, Dtool_TransformState,
|
|
||||||
true, true, source->get_type_index());
|
|
||||||
}
|
|
||||||
const TransformState *result = _composition_cache.get_data(i)._result;
|
|
||||||
if (result == (TransformState *)NULL) {
|
|
||||||
b = Py_None;
|
|
||||||
Py_INCREF(b);
|
|
||||||
} else {
|
|
||||||
result->ref();
|
|
||||||
b = DTool_CreatePyInstanceTyped((void *)result, Dtool_TransformState,
|
|
||||||
true, true, result->get_type_index());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyTuple_SET_ITEM(tuple, 0, a);
|
PyTuple_SET_ITEM(tuple, 0, a);
|
||||||
PyTuple_SET_ITEM(tuple, 1, b);
|
PyTuple_SET_ITEM(tuple, 1, b);
|
||||||
|
|
||||||
|
nassertr(i < num_states, list);
|
||||||
PyList_SET_ITEM(list, i, tuple);
|
PyList_SET_ITEM(list, i, tuple);
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
nassertr(i == num_states, list);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
#endif // HAVE_PYTHON
|
#endif // HAVE_PYTHON
|
||||||
@ -847,43 +911,47 @@ PyObject *TransformState::
|
|||||||
get_invert_composition_cache() const {
|
get_invert_composition_cache() const {
|
||||||
IMPORT_THIS struct Dtool_PyTypedObject Dtool_TransformState;
|
IMPORT_THIS struct Dtool_PyTypedObject Dtool_TransformState;
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
size_t cache_size = _invert_composition_cache.get_size();
|
|
||||||
PyObject *list = PyList_New(cache_size);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < cache_size; ++i) {
|
size_t num_states = _invert_composition_cache.get_num_entries();
|
||||||
|
PyObject *list = PyList_New(num_states);
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
int size = _invert_composition_cache.get_size();
|
||||||
|
for (int si = 0; si < size; ++si) {
|
||||||
|
if (!_invert_composition_cache.has_element(si)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *tuple = PyTuple_New(2);
|
PyObject *tuple = PyTuple_New(2);
|
||||||
PyObject *a, *b;
|
PyObject *a, *b;
|
||||||
if (!_invert_composition_cache.has_element(i)) {
|
|
||||||
|
const TransformState *source = _invert_composition_cache.get_key(si);
|
||||||
|
if (source == (TransformState *)NULL) {
|
||||||
a = Py_None;
|
a = Py_None;
|
||||||
Py_INCREF(a);
|
Py_INCREF(a);
|
||||||
|
} else {
|
||||||
|
source->ref();
|
||||||
|
a = DTool_CreatePyInstanceTyped((void *)source, Dtool_TransformState,
|
||||||
|
true, true, source->get_type_index());
|
||||||
|
}
|
||||||
|
const TransformState *result = _invert_composition_cache.get_data(si)._result;
|
||||||
|
if (result == (TransformState *)NULL) {
|
||||||
b = Py_None;
|
b = Py_None;
|
||||||
Py_INCREF(b);
|
Py_INCREF(b);
|
||||||
} else {
|
} else {
|
||||||
const TransformState *source = _invert_composition_cache.get_key(i);
|
result->ref();
|
||||||
if (source == (TransformState *)NULL) {
|
b = DTool_CreatePyInstanceTyped((void *)result, Dtool_TransformState,
|
||||||
a = Py_None;
|
true, true, result->get_type_index());
|
||||||
Py_INCREF(a);
|
|
||||||
} else {
|
|
||||||
source->ref();
|
|
||||||
a = DTool_CreatePyInstanceTyped((void *)source, Dtool_TransformState,
|
|
||||||
true, true, source->get_type_index());
|
|
||||||
}
|
|
||||||
const TransformState *result = _invert_composition_cache.get_data(i)._result;
|
|
||||||
if (result == (TransformState *)NULL) {
|
|
||||||
b = Py_None;
|
|
||||||
Py_INCREF(b);
|
|
||||||
} else {
|
|
||||||
result->ref();
|
|
||||||
b = DTool_CreatePyInstanceTyped((void *)result, Dtool_TransformState,
|
|
||||||
true, true, result->get_type_index());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyTuple_SET_ITEM(tuple, 0, a);
|
PyTuple_SET_ITEM(tuple, 0, a);
|
||||||
PyTuple_SET_ITEM(tuple, 1, b);
|
PyTuple_SET_ITEM(tuple, 1, b);
|
||||||
|
|
||||||
|
nassertr(i < num_states, list);
|
||||||
PyList_SET_ITEM(list, i, tuple);
|
PyList_SET_ITEM(list, i, tuple);
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
nassertr(i == num_states, list);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
#endif // HAVE_PYTHON
|
#endif // HAVE_PYTHON
|
||||||
@ -1441,6 +1509,9 @@ validate_states() {
|
|||||||
while (snext < size) {
|
while (snext < size) {
|
||||||
nassertr(_states->get_key(snext)->get_ref_count() >= 0, false);
|
nassertr(_states->get_key(snext)->get_ref_count() >= 0, false);
|
||||||
const TransformState *ssi = _states->get_key(si);
|
const TransformState *ssi = _states->get_key(si);
|
||||||
|
if (!ssi->validate_composition_cache()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const TransformState *ssnext = _states->get_key(snext);
|
const TransformState *ssnext = _states->get_key(snext);
|
||||||
int c = ssi->compare_to(*ssnext);
|
int c = ssi->compare_to(*ssnext);
|
||||||
int ci = ssnext->compare_to(*ssi);
|
int ci = ssnext->compare_to(*ssi);
|
||||||
@ -1506,6 +1577,42 @@ get_states() {
|
|||||||
}
|
}
|
||||||
#endif // HAVE_PYTHON
|
#endif // HAVE_PYTHON
|
||||||
|
|
||||||
|
#ifdef HAVE_PYTHON
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TransformState::get_unused_states
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Returns a list of all of the "unused" TransformState
|
||||||
|
// objects in the state cache. See
|
||||||
|
// get_num_unused_states().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PyObject *TransformState::
|
||||||
|
get_unused_states() {
|
||||||
|
IMPORT_THIS struct Dtool_PyTypedObject Dtool_TransformState;
|
||||||
|
if (_states == (States *)NULL) {
|
||||||
|
return PyList_New(0);
|
||||||
|
}
|
||||||
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
|
PyObject *list = PyList_New(0);
|
||||||
|
int size = _states->get_size();
|
||||||
|
for (int si = 0; si < size; ++si) {
|
||||||
|
if (!_states->has_element(si)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const TransformState *state = _states->get_key(si);
|
||||||
|
if (state->get_cache_ref_count() == state->get_ref_count()) {
|
||||||
|
state->ref();
|
||||||
|
PyObject *a =
|
||||||
|
DTool_CreatePyInstanceTyped((void *)state, Dtool_TransformState,
|
||||||
|
true, true, state->get_type_index());
|
||||||
|
PyList_Append(list, a);
|
||||||
|
Py_DECREF(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
#endif // HAVE_PYTHON
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TransformState::init_states
|
// Function: TransformState::init_states
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
@ -2322,8 +2429,7 @@ do_calc_hash() {
|
|||||||
// Only bother to put the rest of the stuff in the hash if the
|
// Only bother to put the rest of the stuff in the hash if the
|
||||||
// transform is not invalid or empty.
|
// transform is not invalid or empty.
|
||||||
|
|
||||||
if ((_flags & (F_components_given | F_hpr_given | F_quat_given)) ==
|
if ((_flags & F_components_given) != 0) {
|
||||||
(F_components_given | F_hpr_given | F_quat_given)) {
|
|
||||||
// If the transform was specified componentwise, hash it
|
// If the transform was specified componentwise, hash it
|
||||||
// componentwise.
|
// componentwise.
|
||||||
_hash = _pos.add_hash(_hash);
|
_hash = _pos.add_hash(_hash);
|
||||||
|
@ -189,6 +189,7 @@ PUBLISHED:
|
|||||||
INLINE int get_invert_composition_cache_size() const;
|
INLINE int get_invert_composition_cache_size() const;
|
||||||
INLINE const TransformState *get_invert_composition_cache_source(int n) const;
|
INLINE const TransformState *get_invert_composition_cache_source(int n) const;
|
||||||
INLINE const TransformState *get_invert_composition_cache_result(int n) const;
|
INLINE const TransformState *get_invert_composition_cache_result(int n) const;
|
||||||
|
bool validate_composition_cache() const;
|
||||||
#ifdef HAVE_PYTHON
|
#ifdef HAVE_PYTHON
|
||||||
PyObject *get_composition_cache() const;
|
PyObject *get_composition_cache() const;
|
||||||
PyObject *get_invert_composition_cache() const;
|
PyObject *get_invert_composition_cache() const;
|
||||||
@ -207,6 +208,7 @@ PUBLISHED:
|
|||||||
static bool validate_states();
|
static bool validate_states();
|
||||||
#ifdef HAVE_PYTHON
|
#ifdef HAVE_PYTHON
|
||||||
static PyObject *get_states();
|
static PyObject *get_states();
|
||||||
|
static PyObject *get_unused_states();
|
||||||
#endif // HAVE_PYTHON
|
#endif // HAVE_PYTHON
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user