mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00

The new implementation stores elements contiguously and keeps a separate sparse array of indices, similar to the new PyPy and CPython implementations. This vastly improves performance when iterating over the individual elements, such as when garbage collecting states, and decreases memory usage.
148 lines
4.6 KiB
C++
148 lines
4.6 KiB
C++
/**
|
|
* PANDA 3D SOFTWARE
|
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
*
|
|
* All use of this software is subject to the terms of the revised BSD
|
|
* license. You should have received a copy of this license along
|
|
* with this source code in a file named "LICENSE."
|
|
*
|
|
* @file renderState_ext.cxx
|
|
* @author CFSworks
|
|
* @date 2014-03-31
|
|
*/
|
|
|
|
#include "renderState_ext.h"
|
|
|
|
#ifdef HAVE_PYTHON
|
|
|
|
/**
|
|
* Returns a list of 2-tuples that represents the composition cache. For each
|
|
* tuple in the list, the first element is the source render, and the second
|
|
* is the result render. 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 *Extension<RenderState>::
|
|
get_composition_cache() const {
|
|
extern struct Dtool_PyTypedObject Dtool_RenderState;
|
|
LightReMutexHolder holder(*RenderState::_states_lock);
|
|
size_t cache_size = _this->_composition_cache.get_num_entries();
|
|
PyObject *list = PyList_New(cache_size);
|
|
|
|
for (size_t i = 0; i < cache_size; ++i) {
|
|
PyObject *tuple = PyTuple_New(2);
|
|
PyObject *a, *b;
|
|
const RenderState *source = _this->_composition_cache.get_key(i);
|
|
if (source == (RenderState *)NULL) {
|
|
a = Py_None;
|
|
Py_INCREF(a);
|
|
} else {
|
|
source->ref();
|
|
a = DTool_CreatePyInstanceTyped((void *)source, Dtool_RenderState,
|
|
true, true, source->get_type_index());
|
|
}
|
|
const RenderState *result = _this->_composition_cache.get_data(i)._result;
|
|
if (result == (RenderState *)NULL) {
|
|
b = Py_None;
|
|
Py_INCREF(b);
|
|
} else {
|
|
result->ref();
|
|
b = DTool_CreatePyInstanceTyped((void *)result, Dtool_RenderState,
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* Returns a list of 2-tuples that represents the invert_composition cache.
|
|
* For each tuple in the list, the first element is the source render, and the
|
|
* second is the result render. 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 *Extension<RenderState>::
|
|
get_invert_composition_cache() const {
|
|
extern struct Dtool_PyTypedObject Dtool_RenderState;
|
|
LightReMutexHolder holder(*RenderState::_states_lock);
|
|
size_t cache_size = _this->_invert_composition_cache.get_num_entries();
|
|
PyObject *list = PyList_New(cache_size);
|
|
|
|
for (size_t i = 0; i < cache_size; ++i) {
|
|
PyObject *tuple = PyTuple_New(2);
|
|
PyObject *a, *b;
|
|
const RenderState *source = _this->_invert_composition_cache.get_key(i);
|
|
if (source == (RenderState *)NULL) {
|
|
a = Py_None;
|
|
Py_INCREF(a);
|
|
} else {
|
|
source->ref();
|
|
a = DTool_CreatePyInstanceTyped((void *)source, Dtool_RenderState,
|
|
true, true, source->get_type_index());
|
|
}
|
|
const RenderState *result = _this->_invert_composition_cache.get_data(i)._result;
|
|
if (result == (RenderState *)NULL) {
|
|
b = Py_None;
|
|
Py_INCREF(b);
|
|
} else {
|
|
result->ref();
|
|
b = DTool_CreatePyInstanceTyped((void *)result, Dtool_RenderState,
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* Returns a list of all of the RenderState objects in the state cache. The
|
|
* order of elements in this cache is arbitrary.
|
|
*/
|
|
PyObject *Extension<RenderState>::
|
|
get_states() {
|
|
extern struct Dtool_PyTypedObject Dtool_RenderState;
|
|
if (RenderState::_states == (RenderState::States *)NULL) {
|
|
return PyList_New(0);
|
|
}
|
|
LightReMutexHolder holder(*RenderState::_states_lock);
|
|
|
|
size_t num_states = RenderState::_states->get_num_entries();
|
|
PyObject *list = PyList_New(num_states);
|
|
size_t i = 0;
|
|
|
|
size_t size = RenderState::_states->get_num_entries();
|
|
for (size_t si = 0; si < size; ++si) {
|
|
const RenderState *state = RenderState::_states->get_key(si);
|
|
state->ref();
|
|
PyObject *a =
|
|
DTool_CreatePyInstanceTyped((void *)state, Dtool_RenderState,
|
|
true, true, state->get_type_index());
|
|
nassertr(i < num_states, list);
|
|
PyList_SET_ITEM(list, i, a);
|
|
++i;
|
|
}
|
|
nassertr(i == num_states, list);
|
|
return list;
|
|
}
|
|
|
|
|
|
|
|
#endif // HAVE_PYTHON
|