timer fixes: timers managed by engine can run in the background. Closes #180
This commit is contained in:
parent
2c20455003
commit
b0b17f4633
4 changed files with 57 additions and 22 deletions
|
|
@ -911,6 +911,32 @@ PyObject* McRFPy_API::_setScene(PyObject* self, PyObject* args) {
|
|||
return Py_None;
|
||||
}
|
||||
|
||||
// #180: Create a Python wrapper for an existing C++ Timer (for orphaned timers)
|
||||
static PyObject* createTimerWrapper(std::shared_ptr<Timer> timer)
|
||||
{
|
||||
// Allocate new PyTimerObject
|
||||
PyTypeObject* type = &mcrfpydef::PyTimerType;
|
||||
PyTimerObject* obj = (PyTimerObject*)type->tp_alloc(type, 0);
|
||||
if (!obj) return nullptr;
|
||||
|
||||
// Initialize - use placement new for std::string
|
||||
new(&obj->name) std::string(timer->name);
|
||||
obj->data = timer; // Share the existing C++ Timer
|
||||
obj->weakreflist = nullptr;
|
||||
|
||||
// Register in cache for future lookups
|
||||
if (timer->serial_number == 0) {
|
||||
timer->serial_number = PythonObjectCache::getInstance().assignSerial();
|
||||
}
|
||||
PyObject* weakref = PyWeakref_NewRef((PyObject*)obj, NULL);
|
||||
if (weakref) {
|
||||
PythonObjectCache::getInstance().registerObject(timer->serial_number, weakref);
|
||||
Py_DECREF(weakref);
|
||||
}
|
||||
|
||||
return (PyObject*)obj;
|
||||
}
|
||||
|
||||
// #173: Get all timers as a tuple of Python Timer objects
|
||||
PyObject* McRFPy_API::api_get_timers()
|
||||
{
|
||||
|
|
@ -918,15 +944,25 @@ PyObject* McRFPy_API::api_get_timers()
|
|||
return PyTuple_New(0);
|
||||
}
|
||||
|
||||
// Count timers that have Python wrappers
|
||||
std::vector<PyObject*> timer_objs;
|
||||
for (auto& pair : game->timers) {
|
||||
auto& timer = pair.second;
|
||||
if (timer && timer->serial_number != 0) {
|
||||
PyObject* timer_obj = PythonObjectCache::getInstance().lookup(timer->serial_number);
|
||||
if (timer_obj && timer_obj != Py_None) {
|
||||
timer_objs.push_back(timer_obj);
|
||||
}
|
||||
if (!timer) continue;
|
||||
|
||||
PyObject* timer_obj = nullptr;
|
||||
|
||||
// Try to find existing Python wrapper
|
||||
if (timer->serial_number != 0) {
|
||||
timer_obj = PythonObjectCache::getInstance().lookup(timer->serial_number);
|
||||
}
|
||||
|
||||
// #180: If no wrapper exists (orphaned timer), create a new one
|
||||
if (!timer_obj || timer_obj == Py_None) {
|
||||
timer_obj = createTimerWrapper(timer);
|
||||
}
|
||||
|
||||
if (timer_obj && timer_obj != Py_None) {
|
||||
timer_objs.push_back(timer_obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -934,7 +970,8 @@ PyObject* McRFPy_API::api_get_timers()
|
|||
if (!tuple) return NULL;
|
||||
|
||||
for (Py_ssize_t i = 0; i < static_cast<Py_ssize_t>(timer_objs.size()); i++) {
|
||||
Py_INCREF(timer_objs[i]);
|
||||
// timer_objs already has a reference from lookup() or createTimerWrapper()
|
||||
// PyTuple_SET_ITEM steals that reference, so no additional INCREF needed
|
||||
PyTuple_SET_ITEM(tuple, i, timer_objs[i]);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue