New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor the game event system to be based on Lua at the core #5663
Conversation
Unit tests proving out the different aspects of this functionality would be very beneficial. |
Adding doxygen doc comments to methods is also a good habit for us to all get into, I think. |
227269a
to
0805dfa
Compare
I think this addresses most of the concerns people mentioned. I still have a few things to finish though:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There still isn't enough documentation in this PR to enable the PR to be reviewed.
Change requested: add the documentation.
The documentation goes on the wiki though, right? It's not part of the PR. |
There's more than just API docs to add. I think docs should be written like the game Taboo - try to explain what it does without repeating the words in the class name, function name, argument types or argument names; that often acts as a design review. The The |
Does that help? |
I drafted up some documentation for the Lua API on the wiki. I realize it's perhaps a little tucked away in this PR, but does anyone have any comments on the Lua |
I'll do a review this evening, but was going to ask if you'd split this into a separate PR. |
Unlike the old wesnoth.game_events.on_event hook and the "convenient" on_event() wrapper for it, this new functionality supports all of the features of WML events, with the sole exception of serialization, since it's not possible to reliably serialize a Lua function. This commit also divorces menu items from the event that they trigger. The undocumented wesnoth.interface.set_menu_item function no longer adds an event for the menu item; the caller needs to separately register an event using the new functionality.
…t is registered from Lua.
* These functions take the full event data config as the final argument, rather than just the weapon info subconfigs. * The [fire_event] tag now supports a [data] tag that can add additional data to the event, for example damage_inflicted. The [primary_attack] and [secondary_attack] tags are still supported and are not deprecated. * wesnoth.current.event_context now has a data child which holds the full event data. It still duplicates common info (weapons and damage inflicted) in the same way as before.
- Don't try to serialize an event with a Lua filter (ie, add{filter = function() end}) - Write the serialization warning to in-game chat, but ONLY if the event was registered after preload
… a repeating event This is a somewhat controversial change! PROS: - This makes wesnoth.game_events.add a drop-in replacement for the on_event function - If you're registering events in preload, most of them WILL be repeating events CONS: - This makes the default depend on the call style; in positional style, it defaults to repeating, and in named-argument style, it defaults to non-repeating - This makes the default different from the WML default of non-repeating events
Basically this means each of the call modes of the old function is now a separate function. - add_repeating and add_menu take an ID and a function - add_wml takes variable substitution setting and a config - add takes the full options table
Since they're non-serializable, the code can't be shown, but the fact that unspecified Lua code is present will be shown.
These are taken as synonyms of the actual internal tag names, [first] and [second]. So, first is interchangeable with primary_attack and second is interchangeable with secondary_attack.
Although it's already possible to pass {formula = "whatever"}, this change allows mixing that with the simplified syntax, such as {formula = "whatever", side = {side = 3}}
This creates a filter that's read dynamically from the specified WML variable.
- Add default name for wesnoth.game_events.add when it's a menu item - Add error message when both ID and name are empty
0aad8dd
to
1edd0cb
Compare
Fixes wesnoth#6898. The issue is that non-WML events added through the new events API always disable undo with no equivalent of WML's `[allow_undo]`. The long-term fix is to add a way to do that; however until that's available then listeners for `moveto` need to use the old `on_event` API. The old `on_event` API can't be deprecated yet, and this is enforced by our unit tests (the build fails if there are unexpected deprecation warnings during the tests). Reverts most of 7e234f8. Does not revert files that only listen for non-undoable events such as `die` or `new turn`. Reverts the deprecation part of wesnoth#5663's 8cd1332.
Fixes wesnoth#6898. The issue is that non-WML events added through the new events API always disable undo with no equivalent of WML's `[allow_undo]`. The long-term fix is to add a way to do that; however until that's available then listeners for `moveto` need to use the old `on_event` API. The old `on_event` API can't be deprecated yet, and this is enforced by our unit tests (the build fails if there are unexpected deprecation warnings during the tests). Reverts most of 7e234f8. Does not revert files that only listen for non-undoable events such as `die` or `new turn`. Reverts the deprecation part of wesnoth#5663's 8cd1332.
Fixes #6898. The issue is that non-WML events added through the new events API always disable undo with no equivalent of WML's `[allow_undo]`. The long-term fix is to add a way to do that; however until that's available then listeners for `moveto` need to use the old `on_event` API. The old `on_event` API can't be deprecated yet, and this is enforced by our unit tests (the build fails if there are unexpected deprecation warnings during the tests). Reverts most of 7e234f8. Does not revert files that only listen for non-undoable events such as `die` or `new turn`. Reverts the deprecation part of #5663's 8cd1332.
Fixes wesnoth#6898. The issue is that non-WML events added through the new events API always disable undo with no equivalent of WML's `[allow_undo]`. The long-term fix is to add a way to do that; however until that's available then listeners for `moveto` need to use the old `on_event` API. The old `on_event` API can't be deprecated yet, and this is enforced by our unit tests (the build fails if there are unexpected deprecation warnings during the tests). Reverts most of 7e234f8. Does not revert files that only listen for non-undoable events such as `die` or `new turn`. Reverts the deprecation part of wesnoth#5663's 8cd1332.
All events are now just a Lua function and a package of arguments that are passed to the function. A typical event added via WML (ie, with the
[event]
tag) is the functionwesnoth.wml_actions.command
with the contained ActionWML tags passed as the argument, so they work just the same as before. However, you can now add events in two other ways:Instead of using ActionWML, you can write the entire event inline as Lua code using[event]code=
. Although this is similar to just using an event containing a single[lua]
tag, there are some differences. The code is compiled when the event is added, rather than when it is executed, and the argument passed to the event code is a copy of the[event]
tag with filter data and event name and ID stripped out.wesnoth.game_events.add
function, which supercedes theon_event()
system that World Conquest and a few other things depend on. Unlikeon_event()
, this interface supports everything that[event]
does, such asfirst_time_only=true
or giving the event an ID that will allow other events to remove it. It also supports some things that[event]
doesn't, such as using an arbitrary Lua function to handle the event (although if you do this, the event becomes unserializable, just the same as if you usedon_event()
) or marking the event as a menu item event (meaning it will be removed if the menu item with the same ID is removed).The other significant change in this PR is a refactor of the event filtering system, which would make it very easy to add a new type of filter if we wanted to in the future (although I'm not anticipating any new types). As part of that, two new ways of filtering in events have been added:
filter_formula
key in[event]
takes a WFL formula that determines whether the event should trigger. It can access all the event context info (likeloc1
,event_id
,unit1
, etc) as well as the game state (such asmap
,units
,turn
, andtime_of_day
). In particular, it exposes event context info that nothing else does inevent_data
, although there may not be any way to actually set that data yet in[fire_event]
.Thefilter
key in[event]
takes Lua code that determines whether the event should trigger. If there is a[filter_args]
tag, its contents is passed to this function.One other thing I've done here is to divorce menu items from events at the Lua level. This was already the case in C++, and it seemed to make for a cleaner API. The relevant functions were never documented, so this is probably a minor thing, but basically:
wesnoth.interface.set_menu_item
adds or updates a menu item but does not make it do anything - the[command]
tag is ignored. To make it do something, you need to usewesnoth.game_events.add
to create the event that the menu item will trigger. Of course,[set_menu_item]
still does both for you.