Compare commits
No commits in common. "09fa4f4665f78086ab2b9ad0f51989741b7d6fe9" and "baa7ee354b1392f3540a761e4079483c8cc14bff" have entirely different histories.
09fa4f4665
...
baa7ee354b
5 changed files with 48 additions and 28 deletions
|
|
@ -421,7 +421,7 @@ void GameEngine::processEvent(const sf::Event& event)
|
||||||
updateViewport();
|
updateViewport();
|
||||||
|
|
||||||
// Notify Python scenes about the resize
|
// Notify Python scenes about the resize
|
||||||
McRFPy_API::triggerResize(sf::Vector2u(event.size.width, event.size.height));
|
McRFPy_API::triggerResize(event.size.width, event.size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (event.type == sf::Event::KeyPressed || event.type == sf::Event::MouseButtonPressed || event.type == sf::Event::MouseWheelScrolled) actionType = "start";
|
else if (event.type == sf::Event::KeyPressed || event.type == sf::Event::MouseButtonPressed || event.type == sf::Event::MouseWheelScrolled) actionType = "start";
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ public:
|
||||||
// Scene lifecycle management for Python Scene objects
|
// Scene lifecycle management for Python Scene objects
|
||||||
static void triggerSceneChange(const std::string& from_scene, const std::string& to_scene);
|
static void triggerSceneChange(const std::string& from_scene, const std::string& to_scene);
|
||||||
static void updatePythonScenes(float dt);
|
static void updatePythonScenes(float dt);
|
||||||
static void triggerResize(sf::Vector2u new_size);
|
static void triggerResize(int width, int height);
|
||||||
static void triggerKeyEvent(const std::string& key, const std::string& action);
|
static void triggerKeyEvent(const std::string& key, const std::string& action);
|
||||||
|
|
||||||
// #151: Module-level scene property accessors
|
// #151: Module-level scene property accessors
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// McRogueFace version string (#164)
|
// McRogueFace version string (#164)
|
||||||
#define MCRFPY_VERSION "0.2.2-prerelease-7drl2026"
|
#define MCRFPY_VERSION "0.2.1-prerelease-7drl2026"
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,35 @@ static PyObject* PySceneClass_get_children(PySceneObject* self, void* closure)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject* PySceneClass::register_keyboard(PySceneObject* self, PyObject* args)
|
||||||
|
{
|
||||||
|
PyObject* callable;
|
||||||
|
if (!PyArg_ParseTuple(args, "O", &callable)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PyCallable_Check(callable)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Argument must be callable");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the callable
|
||||||
|
Py_INCREF(callable);
|
||||||
|
|
||||||
|
// Get the current scene and set its key_callable
|
||||||
|
GameEngine* game = McRFPy_API::game;
|
||||||
|
if (game) {
|
||||||
|
// We need to be on the right scene first
|
||||||
|
std::string old_scene = game->scene;
|
||||||
|
game->scene = self->name;
|
||||||
|
game->currentScene()->key_callable = std::make_unique<PyKeyCallable>(callable);
|
||||||
|
game->scene = old_scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(callable);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
// on_key property getter
|
// on_key property getter
|
||||||
static PyObject* PySceneClass_get_on_key(PySceneObject* self, void* closure)
|
static PyObject* PySceneClass_get_on_key(PySceneObject* self, void* closure)
|
||||||
{
|
{
|
||||||
|
|
@ -429,30 +458,11 @@ void PySceneClass::call_update(PySceneObject* self, float dt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PySceneClass::call_on_resize(PySceneObject* self, sf::Vector2u new_size)
|
void PySceneClass::call_on_resize(PySceneObject* self, int width, int height)
|
||||||
{
|
{
|
||||||
PyObject* method = PyObject_GetAttrString((PyObject*)self, "on_resize");
|
PyObject* method = PyObject_GetAttrString((PyObject*)self, "on_resize");
|
||||||
if (method && PyCallable_Check(method)) {
|
if (method && PyCallable_Check(method)) {
|
||||||
// Create a Vector object to pass
|
PyObject* result = PyObject_CallFunction(method, "ii", width, height);
|
||||||
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Vector");
|
|
||||||
if (!type) {
|
|
||||||
PyErr_Print();
|
|
||||||
Py_DECREF(method);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PyObject* args = Py_BuildValue("(ff)", (float)new_size.x, (float)new_size.y);
|
|
||||||
PyObject* vector = PyObject_CallObject((PyObject*)type, args);
|
|
||||||
Py_DECREF(type);
|
|
||||||
Py_DECREF(args);
|
|
||||||
|
|
||||||
if (!vector) {
|
|
||||||
PyErr_Print();
|
|
||||||
Py_DECREF(method);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject* result = PyObject_CallFunctionObjArgs(method, vector, NULL);
|
|
||||||
Py_DECREF(vector);
|
|
||||||
if (result) {
|
if (result) {
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -526,6 +536,15 @@ PyMethodDef PySceneClass::methods[] = {
|
||||||
MCRF_RETURNS("None")
|
MCRF_RETURNS("None")
|
||||||
MCRF_NOTE("Deactivates the current scene and activates this one. Lifecycle callbacks (on_exit, on_enter) are triggered.")
|
MCRF_NOTE("Deactivates the current scene and activates this one. Lifecycle callbacks (on_exit, on_enter) are triggered.")
|
||||||
)},
|
)},
|
||||||
|
{"register_keyboard", (PyCFunction)register_keyboard, METH_VARARGS,
|
||||||
|
MCRF_METHOD(SceneClass, register_keyboard,
|
||||||
|
MCRF_SIG("(callback: callable)", "None"),
|
||||||
|
MCRF_DESC("Register a keyboard event handler function."),
|
||||||
|
MCRF_ARGS_START
|
||||||
|
MCRF_ARG("callback", "Function that receives (key: str, pressed: bool) when keyboard events occur")
|
||||||
|
MCRF_RETURNS("None")
|
||||||
|
MCRF_NOTE("Alternative to setting on_key property. Handler is called for both key press and release events.")
|
||||||
|
)},
|
||||||
{"realign", (PyCFunction)PySceneClass_realign, METH_NOARGS,
|
{"realign", (PyCFunction)PySceneClass_realign, METH_NOARGS,
|
||||||
MCRF_METHOD(SceneClass, realign,
|
MCRF_METHOD(SceneClass, realign,
|
||||||
MCRF_SIG("()", "None"),
|
MCRF_SIG("()", "None"),
|
||||||
|
|
@ -577,14 +596,14 @@ void McRFPy_API::updatePythonScenes(float dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to trigger resize events on Python scenes
|
// Helper function to trigger resize events on Python scenes
|
||||||
void McRFPy_API::triggerResize(sf::Vector2u new_size)
|
void McRFPy_API::triggerResize(int width, int height)
|
||||||
{
|
{
|
||||||
GameEngine* game = McRFPy_API::game;
|
GameEngine* game = McRFPy_API::game;
|
||||||
if (!game) return;
|
if (!game) return;
|
||||||
|
|
||||||
// Only notify the active scene
|
// Only notify the active scene
|
||||||
if (python_scenes.count(game->scene) > 0) {
|
if (python_scenes.count(game->scene) > 0) {
|
||||||
PySceneClass::call_on_resize(python_scenes[game->scene], new_size);
|
PySceneClass::call_on_resize(python_scenes[game->scene], width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ public:
|
||||||
|
|
||||||
// Scene methods
|
// Scene methods
|
||||||
static PyObject* activate(PySceneObject* self, PyObject* args, PyObject* kwds);
|
static PyObject* activate(PySceneObject* self, PyObject* args, PyObject* kwds);
|
||||||
|
static PyObject* register_keyboard(PySceneObject* self, PyObject* args);
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
static PyObject* get_name(PySceneObject* self, void* closure);
|
static PyObject* get_name(PySceneObject* self, void* closure);
|
||||||
|
|
@ -37,7 +38,7 @@ public:
|
||||||
static void call_on_exit(PySceneObject* self);
|
static void call_on_exit(PySceneObject* self);
|
||||||
static void call_on_key(PySceneObject* self, const std::string& key, const std::string& action);
|
static void call_on_key(PySceneObject* self, const std::string& key, const std::string& action);
|
||||||
static void call_update(PySceneObject* self, float dt);
|
static void call_update(PySceneObject* self, float dt);
|
||||||
static void call_on_resize(PySceneObject* self, sf::Vector2u new_size);
|
static void call_on_resize(PySceneObject* self, int width, int height);
|
||||||
|
|
||||||
// #183: Lookup scene by name (returns new reference or nullptr)
|
// #183: Lookup scene by name (returns new reference or nullptr)
|
||||||
static PyObject* get_scene_by_name(const std::string& name);
|
static PyObject* get_scene_by_name(const std::string& name);
|
||||||
|
|
@ -76,7 +77,7 @@ namespace mcrfpydef {
|
||||||
" on_exit(): Called when scene is deactivated (another scene activates).\n"
|
" on_exit(): Called when scene is deactivated (another scene activates).\n"
|
||||||
" on_key(key: str, action: str): Called for keyboard events (subclass method).\n"
|
" on_key(key: str, action: str): Called for keyboard events (subclass method).\n"
|
||||||
" update(dt: float): Called every frame with delta time in seconds.\n"
|
" update(dt: float): Called every frame with delta time in seconds.\n"
|
||||||
" on_resize(new_size: Vector): Called when window is resized.\n\n"
|
" on_resize(width: int, height: int): Called when window is resized.\n\n"
|
||||||
"Example:\n"
|
"Example:\n"
|
||||||
" # Basic usage (replacing module functions):\n"
|
" # Basic usage (replacing module functions):\n"
|
||||||
" scene = mcrfpy.Scene('main_menu')\n"
|
" scene = mcrfpy.Scene('main_menu')\n"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue