Implement Scene subclass on_key callback support
Scene subclasses can now define on_key(self, key, state) methods that
receive keyboard events, matching the existing on_enter, on_exit, and
update lifecycle callbacks.
Changes:
- Rename call_on_keypress to call_on_key (consistent naming with property)
- Add triggerKeyEvent helper in McRFPy_API
- Call triggerKeyEvent from GameEngine when key_callable is not set
- Fix condition to check key_callable.isNone() (not just pointer existence)
- Handle both bound methods and instance-assigned callables
Usage:
class GameScene(mcrfpy.Scene):
def on_key(self, key, state):
if key == "Escape" and state == "end":
quit_game()
Property assignment (scene.on_key = callable) still works and takes
precedence when key_callable is set via the property setter.
Includes comprehensive test: tests/unit/scene_subclass_on_key_test.py
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
b6eb70748a
commit
1d11b020b0
5 changed files with 118 additions and 10 deletions
84
tests/unit/scene_subclass_on_key_test.py
Normal file
84
tests/unit/scene_subclass_on_key_test.py
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
"""Test Scene subclass on_key method callback
|
||||
|
||||
Verifies that:
|
||||
1. Subclass on_key method is called for keyboard events
|
||||
2. Property assignment (scene.on_key = callable) still works
|
||||
3. Property assignment on subclass overrides the method
|
||||
"""
|
||||
import mcrfpy
|
||||
from mcrfpy import automation
|
||||
import sys
|
||||
|
||||
# Test state
|
||||
tests_passed = 0
|
||||
tests_failed = 0
|
||||
|
||||
def test_subclass_method():
|
||||
"""Test that subclass on_key method receives keyboard events"""
|
||||
global tests_passed, tests_failed
|
||||
events = []
|
||||
|
||||
class TestScene(mcrfpy.Scene):
|
||||
def on_key(self, key, state):
|
||||
events.append((key, state))
|
||||
|
||||
ts = TestScene('test_method')
|
||||
ts.activate()
|
||||
automation.keyDown('a')
|
||||
automation.keyUp('a')
|
||||
|
||||
if len(events) >= 2:
|
||||
print("PASS: test_subclass_method")
|
||||
tests_passed += 1
|
||||
else:
|
||||
print(f"FAIL: test_subclass_method - got {events}")
|
||||
tests_failed += 1
|
||||
|
||||
def test_property_handler():
|
||||
"""Test that property assignment works"""
|
||||
global tests_passed, tests_failed
|
||||
events = []
|
||||
|
||||
scene = mcrfpy.Scene('test_property')
|
||||
scene.on_key = lambda k, s: events.append((k, s))
|
||||
scene.activate()
|
||||
automation.keyDown('b')
|
||||
automation.keyUp('b')
|
||||
|
||||
if len(events) >= 2:
|
||||
print("PASS: test_property_handler")
|
||||
tests_passed += 1
|
||||
else:
|
||||
print(f"FAIL: test_property_handler - got {events}")
|
||||
tests_failed += 1
|
||||
|
||||
def test_property_overrides_method():
|
||||
"""Test that property assignment on subclass overrides the method"""
|
||||
global tests_passed, tests_failed
|
||||
method_events = []
|
||||
property_events = []
|
||||
|
||||
class TestScene(mcrfpy.Scene):
|
||||
def on_key(self, key, state):
|
||||
method_events.append((key, state))
|
||||
|
||||
ts = TestScene('test_override')
|
||||
ts.activate()
|
||||
ts.on_key = lambda k, s: property_events.append((k, s))
|
||||
automation.keyDown('c')
|
||||
automation.keyUp('c')
|
||||
|
||||
if len(property_events) >= 2 and len(method_events) == 0:
|
||||
print("PASS: test_property_overrides_method")
|
||||
tests_passed += 1
|
||||
else:
|
||||
print(f"FAIL: test_property_overrides_method - method={method_events}, property={property_events}")
|
||||
tests_failed += 1
|
||||
|
||||
# Run tests
|
||||
test_subclass_method()
|
||||
test_property_handler()
|
||||
test_property_overrides_method()
|
||||
|
||||
print(f"\nResults: {tests_passed} passed, {tests_failed} failed")
|
||||
sys.exit(0 if tests_failed == 0 else 1)
|
||||
Loading…
Add table
Add a link
Reference in a new issue