diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index 18ca7726a4..d9bc374869 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -3174,11 +3174,10 @@ get_bin_draw_order() const { // Description: Adds the indicated texture to the list of textures // that will be rendered on the default texture stage. // -// This is the deprecated single-texture variant of this -// method; it is now superceded by set_texture() that -// accepts a stage and texture. However, this method -// may be used in the presence of multitexture if you -// just want to adjust the default stage. +// This is the convenience single-texture variant of +// this method; it is now superceded by set_texture() +// that accepts a stage and texture. You may use this +// method if you just want to adjust the default stage. //////////////////////////////////////////////////////////////////// void NodePath:: set_texture(Texture *tex, int priority) { diff --git a/panda/src/pgraph/transformState.I b/panda/src/pgraph/transformState.I index f08ddd8a44..851118779e 100644 --- a/panda/src/pgraph/transformState.I +++ b/panda/src/pgraph/transformState.I @@ -810,7 +810,7 @@ get_invert_composition_cache_num_entries() const { // get_composition_cache_source() or result(). // // This has no practical value other than for examining -// the cache for performacne analysis. +// the cache for performance analysis. //////////////////////////////////////////////////////////////////// INLINE int TransformState:: get_composition_cache_size() const { @@ -827,7 +827,7 @@ get_composition_cache_size() const { // See get_composition_cache_result(). // // This has no practical value other than for examining -// the cache for performacne analysis. +// the cache for performance analysis. //////////////////////////////////////////////////////////////////// INLINE const TransformState *TransformState:: get_composition_cache_source(int n) const { @@ -850,7 +850,7 @@ get_composition_cache_source(int n) const { // a->get_composition_cache_result(n). // // This has no practical value other than for examining -// the cache for performacne analysis. +// the cache for performance analysis. //////////////////////////////////////////////////////////////////// INLINE const TransformState *TransformState:: get_composition_cache_result(int n) const { @@ -871,7 +871,7 @@ get_composition_cache_result(int n) const { // get_invert_composition_cache_source() or result(). // // This has no practical value other than for examining -// the cache for performacne analysis. +// the cache for performance analysis. //////////////////////////////////////////////////////////////////// INLINE int TransformState:: get_invert_composition_cache_size() const { @@ -883,12 +883,12 @@ get_invert_composition_cache_size() const { // Function: TransformState::get_invert_composition_cache_source // Access: Published // Description: Returns the source TransformState of the nth element -// in the composition cache. Returns NULL if there -// doesn't happen to be an entry in the nth element. -// See get_invert_composition_cache_result(). +// in the invert composition cache. Returns NULL if +// there doesn't happen to be an entry in the nth +// element. See get_invert_composition_cache_result(). // // This has no practical value other than for examining -// the cache for performacne analysis. +// the cache for performance analysis. //////////////////////////////////////////////////////////////////// INLINE const TransformState *TransformState:: get_invert_composition_cache_source(int n) const { @@ -903,15 +903,16 @@ get_invert_composition_cache_source(int n) const { // Function: TransformState::get_invert_composition_cache_result // Access: Published // Description: Returns the result TransformState of the nth element -// in the composition cache. Returns NULL if there -// doesn't happen to be an entry in the nth element. +// in the invert composition cache. Returns NULL if +// there doesn't happen to be an entry in the nth +// element. // // In general, -// a->compose(a->get_invert_composition_cache_source(n)) == -// a->get_invert_composition_cache_result(n). +// a->invert_compose(a->get_invert_composition_cache_source(n)) +// == a->get_invert_composition_cache_result(n). // // This has no practical value other than for examining -// the cache for performacne analysis. +// the cache for performance analysis. //////////////////////////////////////////////////////////////////// INLINE const TransformState *TransformState:: get_invert_composition_cache_result(int n) const { diff --git a/panda/src/pgraph/transformState.cxx b/panda/src/pgraph/transformState.cxx index e0607f02e8..ca1b2061ec 100644 --- a/panda/src/pgraph/transformState.cxx +++ b/panda/src/pgraph/transformState.cxx @@ -24,6 +24,7 @@ #include "lightReMutexHolder.h" #include "lightMutexHolder.h" #include "thread.h" +#include "py_panda.h" LightReMutex *TransformState::_states_lock = NULL; TransformState::States *TransformState::_states = NULL; @@ -824,9 +825,129 @@ unref() const { return false; } +#ifdef HAVE_PYTHON +//////////////////////////////////////////////////////////////////// +// Function: TransformState::get_composition_cache +// Access: Published +// Description: Returns a list of 2-tuples that represents the +// composition cache. For each tuple in the list, the +// first element is the source transform, and the second +// is the result transform. If both are None, there is +// no entry in the cache at that slot. +// +// In general, a->compose(source) == result. +// +// This has no practical value other than for examining +// the cache for performance analysis. +//////////////////////////////////////////////////////////////////// +PyObject *TransformState:: +get_composition_cache() const { + IMPORT_THIS struct Dtool_PyTypedObject Dtool_TransformState; + 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) { + PyObject *tuple = PyTuple_New(2); + PyObject *a, *b; + if (!_composition_cache.has_element(i)) { + a = Py_None; + Py_INCREF(a); + b = Py_None; + Py_INCREF(b); + } else { + const TransformState *source = _composition_cache.get_key(i); + if (source == (TransformState *)NULL) { + a = Py_None; + 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, 1, b); + + PyList_SET_ITEM(list, i, tuple); + } + + return list; +} +#endif // HAVE_PYTHON + +#ifdef HAVE_PYTHON +//////////////////////////////////////////////////////////////////// +// Function: TransformState::get_invert_composition_cache +// Access: Published +// Description: Returns a list of 2-tuples that represents the +// invert_composition cache. For each tuple in the list, the +// first element is the source transform, and the second +// is the result transform. If both are None, there is +// no entry in the cache at that slot. +// +// In general, a->invert_compose(source) == result. +// +// This has no practical value other than for examining +// the cache for performance analysis. +//////////////////////////////////////////////////////////////////// +PyObject *TransformState:: +get_invert_composition_cache() const { + IMPORT_THIS struct Dtool_PyTypedObject Dtool_TransformState; + 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) { + PyObject *tuple = PyTuple_New(2); + PyObject *a, *b; + if (!_invert_composition_cache.has_element(i)) { + a = Py_None; + Py_INCREF(a); + b = Py_None; + Py_INCREF(b); + } else { + const TransformState *source = _invert_composition_cache.get_key(i); + if (source == (TransformState *)NULL) { + a = Py_None; + 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, 1, b); + + PyList_SET_ITEM(list, i, tuple); + } + + return list; +} +#endif // HAVE_PYTHON + //////////////////////////////////////////////////////////////////// // Function: TransformState::output -// Access: Published, Virtual +// Access: Published // Description: //////////////////////////////////////////////////////////////////// void TransformState:: @@ -916,17 +1037,28 @@ output(ostream &out) const { } } - //////////////////////////////////////////////////////////////////// // Function: TransformState::write -// Access: Published, Virtual +// Access: Published // Description: //////////////////////////////////////////////////////////////////// void TransformState:: write(ostream &out, int indent_level) const { indent(out, indent_level) << *this << "\n"; - // indent(out, indent_level + 2) << _composition_cache << "\n"; - // indent(out, indent_level + 2) << _invert_composition_cache << "\n"; +} + +//////////////////////////////////////////////////////////////////// +// Function: TransformState::write_composition_cache +// Access: Published +// Description: Writes a brief description of the composition cache +// and invert composition cache to the indicated +// ostream. This is not useful except for performance +// analysis, to examine the cache structure. +//////////////////////////////////////////////////////////////////// +void TransformState:: +write_composition_cache(ostream &out, int indent_level) const { + indent(out, indent_level + 2) << _composition_cache << "\n"; + indent(out, indent_level + 2) << _invert_composition_cache << "\n"; } //////////////////////////////////////////////////////////////////// @@ -1268,6 +1400,40 @@ validate_states() { return true; } +#ifdef HAVE_PYTHON +//////////////////////////////////////////////////////////////////// +// Function: TransformState::get_states +// Access: Published, Static +// Description: Returns a list of all of the TransformState objects +// in the state cache. The order of elements in this +// cache is arbitrary. +//////////////////////////////////////////////////////////////////// +PyObject *TransformState:: +get_states() { + IMPORT_THIS struct Dtool_PyTypedObject Dtool_TransformState; + if (_states == (States *)NULL) { + return PyList_New(0); + } + LightReMutexHolder holder(*_states_lock); + + size_t num_states = _states->size(); + PyObject *list = PyList_New(num_states); + States::const_iterator si; + size_t i; + for (si = _states->begin(), i = 0; si != _states->end(); ++si, ++i) { + nassertr(i < num_states, list); + const TransformState *state = (*si); + state->ref(); + PyObject *a = + DTool_CreatePyInstanceTyped((void *)state, Dtool_TransformState, + true, true, state->get_type_index()); + PyList_SET_ITEM(list, i, a); + } + nassertr(i == num_states, list); + return list; +} +#endif // HAVE_PYTHON + //////////////////////////////////////////////////////////////////// // Function: TransformState::init_states // Access: Public, Static diff --git a/panda/src/pgraph/transformState.h b/panda/src/pgraph/transformState.h index 993e00175d..77ceae2ea6 100644 --- a/panda/src/pgraph/transformState.h +++ b/panda/src/pgraph/transformState.h @@ -188,9 +188,14 @@ PUBLISHED: 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_result(int n) const; +#ifdef HAVE_PYTHON + PyObject *get_composition_cache() const; + PyObject *get_invert_composition_cache() const; +#endif // HAVE_PYTHON void output(ostream &out) const; void write(ostream &out, int indent_level) const; + void write_composition_cache(ostream &out, int indent_level) const; static int get_num_states(); static int get_num_unused_states(); @@ -198,6 +203,10 @@ PUBLISHED: static void list_cycles(ostream &out); static void list_states(ostream &out); static bool validate_states(); +#ifdef HAVE_PYTHON + static PyObject *get_states(); +#endif // HAVE_PYTHON + public: static void init_states();