fix: prevent segfault when closing window via X button
- Add cleanup() method to GameEngine to clear Python references before destruction
- Clear timers and McRFPy_API references in proper order
- Call cleanup() at end of run loop and in destructor
- Ensure cleanup is only called once per GameEngine instance
Also includes:
- Fix audio ::stop() calls (already in place, OpenAL warning is benign)
- Add Caption support for x, y keywords (e.g. Caption("text", x=5, y=10))
- Refactor UIDrawable_methods.h into UIBase.h for better organization
- Move UIEntity-specific implementations to UIEntityPyMethods.h
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
ee6550bf63
commit
97067a104e
11 changed files with 247 additions and 224 deletions
48
src/UIEntityPyMethods.h
Normal file
48
src/UIEntityPyMethods.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
#include "UIEntity.h"
|
||||
#include "UIBase.h"
|
||||
|
||||
// UIEntity-specific property implementations
|
||||
// These delegate to the wrapped sprite member
|
||||
|
||||
// Visible property
|
||||
static PyObject* UIEntity_get_visible(PyUIEntityObject* self, void* closure)
|
||||
{
|
||||
return PyBool_FromLong(self->data->sprite.visible);
|
||||
}
|
||||
|
||||
static int UIEntity_set_visible(PyUIEntityObject* self, PyObject* value, void* closure)
|
||||
{
|
||||
if (!PyBool_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "visible must be a boolean");
|
||||
return -1;
|
||||
}
|
||||
self->data->sprite.visible = PyObject_IsTrue(value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Opacity property
|
||||
static PyObject* UIEntity_get_opacity(PyUIEntityObject* self, void* closure)
|
||||
{
|
||||
return PyFloat_FromDouble(self->data->sprite.opacity);
|
||||
}
|
||||
|
||||
static int UIEntity_set_opacity(PyUIEntityObject* self, PyObject* value, void* closure)
|
||||
{
|
||||
float opacity;
|
||||
if (PyFloat_Check(value)) {
|
||||
opacity = PyFloat_AsDouble(value);
|
||||
} else if (PyLong_Check(value)) {
|
||||
opacity = PyLong_AsDouble(value);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "opacity must be a number");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Clamp to valid range
|
||||
if (opacity < 0.0f) opacity = 0.0f;
|
||||
if (opacity > 1.0f) opacity = 1.0f;
|
||||
|
||||
self->data->sprite.opacity = opacity;
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue