Changes between Version 6 and Version 7 of documentation/tutorials/PythonEventSystem
- Timestamp:
- 01/09/08 14:05:57 (10 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
documentation/tutorials/PythonEventSystem
v6 v7 2 2 = Python Event Tutorial = 3 3 4 The Python interface to Rocket exposes a DOM API in a very similar way to Javascript. Python code can be attached to any event in the RML definition which i s turn can dynamically update any part of the document including open otherdocuments. Full source code to the final PyInvaders application can be found in the samples folder once the Python plugin has been installed.4 The Python interface to Rocket exposes a DOM API in a very similar way to Javascript. Python code can be attached to any event in the RML definition which in turn can dynamically update any part of the document, including opening new documents. Full source code to the final PyInvaders application can be found in the samples folder once the Python plugin has been installed. 5 5 6 6 == Step 1: Setting up the Python environment == 8 8 Make sure you've got the required Python support packages installed. For more information, see [wiki:documentation/PythonManual/Overview this page]. 9 9 10 The first thing we need to do is initialise python in our application, once we have done this we can start executing scripts. We're going to make a PythonInterface class that will hide all the python intricacies.10 The first thing we need to do is initialise Python in our application. Once we have done this we can start executing scripts. We're going to make a PythonInterface class that will hide all the Python intricacies. 11 11 12 12 {{{ 13 13 /** 14 Creates and maintains the python interface to Invaders.14 Creates and maintains the Python interface to Invaders. 15 15 */ 16 16 30 30 We then implement these methods. 31 31 32 ''NOTE: Its a good idea to forcibly import the rocket Python module, this ensures all boost bindings have been done and that you can proceed to expose your own classes that rely on these bindings having taken place.''32 ''NOTE: Its a good idea to forcibly import the libRocket Python module. This ensures all Boost bindings have been done and that you can proceed to expose your own classes that rely on these bindings having taken place.'' 33 33 34 34 ''NOTE: For more information Python initialisation and shutdown please see the Python documentation at [http://docs.python.org]'' 40 40 Py_Initialize(); 41 41 42 // Pull in the rocket python module.42 // Pull in the Rocket Python module. 43 43 Py_XDECREF(PyImport_ImportModule("rocket")); 44 44 return true; 51 51 }}} 52 52 53 PythonInterface::Initialise should be called before rocket is initialised, this ensures the Python bindings are available when rocket starts up.54 55 PythonInterface::Shutdown should be called after you've released all contexts but before you call Rocket::Shutdown(). This ensures all python objects are released before rocket does its final cleanup.53 PythonInterface::Initialise should be called before Rocket is initialised. This ensures the Python bindings are available when Rocket starts up. 54 55 PythonInterface::Shutdown should be called after you've released all contexts but before you call Rocket::Shutdown(). This ensures all Python objects are released before Rocket does its final cleanup. 56 56 57 57 At this point you'll need to add the relevant Python and Boost::Python build paths to your project and then compile and link your project. 59 59 == Step 2: Replacing the Event System == 60 60 61 We can now completely remove the exiting event system from ''RocketInvaders'' as the Python bindings will do all the EventManagement for us. Remove all source and header files that begin with Event. You'll also need to comment out some code in GameElement.cpp and Game.cpp that call the EventManager directly. We'll get back to those later.61 We can now completely remove the exiting event system from ''RocketInvaders'' as the Python bindings will do all the event management for us. Remove all source and header files that begin with Event. You'll also need to comment out some code in GameElement.cpp and Game.cpp that call the EventManager directly. We'll get back to those later. 62 62 63 63 Also remove all the EventManager initialisation from main.cpp as we'll replace it with a new Python script. I suggest you name it ''autoexec.py'' and place it in a ''python'' subfolder. It should look something like this: 94 94 At this point the ''RocketInvaders'' will now run, however you'll get a script import error because ''autoexec'' cannot be found. To fix this we'll need to add the ''python'' folder to our Python search path. 95 95 96 ''NOTE: On Windows this error will go to stdout, which will not be visible. I suggest you grab a copy of DoAllocConsole() from the pyinvaders sample and drop it into your project. Call DoAllocConsole() at the start of your main function and you'll get a console for reading python error messages.''96 ''NOTE: On Windows this error will go to stdout, which will not be visible. I suggest you grab a copy of DoAllocConsole() from the pyinvaders sample and drop it into your project. Call DoAllocConsole() at the start of your main function and you'll get a console for reading Python error messages.'' 97 97 98 98 My PythonInterface::Initialise now looks like this: 118 118 }}} 119 119 120 This will get us further, you should see the main menu load, however you'll notice a python error on your console when Python attempts to execute the old ''onload'' event in mainmenu.rml. Update the ''onload'' and ''onunload'' events to use Python script which will correctly display and hide the logo.120 This will get us further, you should see the main menu load, however you'll notice a Python error on your console when Python attempts to execute the old ''onload'' event in mainmenu.rml. Update the ''onload'' and ''onunload'' events to use Python script which will correctly display and hide the logo. 121 121 {{{ 122 122 <body template="window" onload="document.context.LoadDocument('data/logo.rml').Show()" onunload="document.context.logo.Close()"> 160 160 PySys_SetPath(buffer); 161 161 162 // Import rocket162 // Import Rocket 163 163 if (!Import("rocket")) 164 164 return false; 195 195 } 196 196 }}} 197 197 198 == Step 4: Custom Elements == 198 199 199 200 The next problem we'll hit when converting ''RocketInvaders'' is the ElementGame does not have a Python interface. Thus we can't give it focus when we start the game which means the defender cannot be moved until the user clicks the game with the mouse. To fix this, we need to define ElementGame to Python and register the Python instancer with Rocket::Factory instead of the C++ instancer. 200 201 201 Let s define a static method on ElementGame to do this and call it from our game modules initialisation.202 Let's define a static method on ElementGame to do this and call it from our game module's initialisation. 202 203 203 204 {{{ 217 218 == Step 5: Key and end game bindings == 218 219 219 We can now get into the game, however the game will never finish as there s no key bindings for processing the ESCAPE key and nothing will make the game exit when the game is over. Fixing the key binding is easy, simply drop in a OnKeyDownhandler and make it launch the pause menu.220 221 OnGameOver is a bit more tricky, as the old Invaders would call EventManager::LoadWindow directly from C++. We're going to have to add a game_over flag to game and make the GameElement check this state every update and fire a custom OnGameOverevent.220 We can now get into the game, however the game will never finish as there's no key bindings for processing the ESCAPE key and nothing will make the game exit when the game is over. Fixing the key binding is easy, simply drop in a 'onkeydown' handler and make it launch the pause menu. 221 222 The game over event is a bit more tricky, as the old Invaders would call EventManager::LoadWindow directly from C++. We're going to have to add a game_over flag to game and make the GameElement check this state every update and fire a custom 'gameover' event. 222 223 223 224 {{{ 234 235 == Step 6: Python Data Formatters == 235 236 236 We're still using C++ data formatters for the high scores, these can be moved into python for simplicity.237 We're still using C++ data formatters for the high scores, these can be moved into Python for simplicity. 237 238 238 239 Here's my name formatter: 259 260 }}} 260 261 261 A lot more code could be moved from C++ into Python, for example the HighScore system. Its just a matter of taking the principles you have learnthere and applying them.262 A lot more code could be moved from C++ into Python, for example the HighScore system. Its just a matter of taking the principles described here and applying them.