Monkey Patch support + Robust callback tracking

McRogueFace needs to accept callable objects (properties on C++ objects)
and also support subclassing (getattr on user objects). Only direct
properties were supported previously, now shadowing a callback by name
will allow custom objects to "just work".
- Added CallbackCache struct and is_python_subclass flag to UIDrawable.h
- Created metaclass for tracking class-level callback changes
- Updated all UI type init functions to detect subclasses
- Modified PyScene.cpp event dispatch to try subclass methods
This commit is contained in:
John McCardle 2026-01-09 21:37:23 -05:00
commit a77ac6c501
14 changed files with 1003 additions and 25 deletions

View file

@ -679,7 +679,8 @@ UIDrawable* UIGrid::click_at(sf::Vector2f point)
}
// No entity handled it, check if grid itself has handler
if (click_callable) {
// #184: Also check for Python subclass (might have on_click method)
if (click_callable || is_python_subclass) {
// #142 - Fire on_cell_click if we have the callback and clicked on a valid cell
if (on_cell_click_callable) {
int cell_x = static_cast<int>(std::floor(grid_x));
@ -987,7 +988,14 @@ int UIGrid::init(PyUIGridObject* self, PyObject* args, PyObject* kwds) {
Py_DECREF(weakref); // Cache owns the reference now
}
}
// #184: Check if this is a Python subclass (for callback method support)
PyObject* grid_type = PyObject_GetAttrString(McRFPy_API::mcrf_module, "Grid");
if (grid_type) {
self->data->is_python_subclass = (PyObject*)Py_TYPE(self) != grid_type;
Py_DECREF(grid_type);
}
return 0; // Success
}