Skip to content

Commit 0146323

Browse files
authored
Merge pull request #17 from Insality/develop
Release v14
2 parents 6e4a360 + 05f7819 commit 0146323

File tree

12 files changed

+136
-41
lines changed

12 files changed

+136
-41
lines changed

.github/workflows/ci_workflow.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
- uses: actions/setup-java@v3
1515
with:
1616
distribution: 'zulu'
17-
java-version: '21'
17+
java-version: '25'
1818

1919
- name: Build && Run
2020
run: |

.vscode/settings.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"Lua.completion.autoRequire": false,
2424
"Lua.workspace.ignoreDir": [
2525
".vscode",
26-
"annotations"
2726
],
2827
"Lua.workspace.library": [
2928
"~/Library/Application Support/Code/User/workspaceStorage/ac07c8aee1c361dc3b09cd3c42fcca08/astronachos.defold",

README.md

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@
3030

3131
Open your `game.project` file and add the following line to the dependencies field under the project section:
3232

33-
**[Defold Event](https://github.com/Insality/defold-event/archive/refs/tags/13.zip)**
33+
**[Defold Event](https://github.com/Insality/defold-event/archive/refs/tags/14.zip)**
3434

3535
```
36-
https://github.com/Insality/defold-event/archive/refs/tags/13.zip
36+
https://github.com/Insality/defold-event/archive/refs/tags/14.zip
3737
```
3838

3939
### Library Size
@@ -51,38 +51,55 @@ https://github.com/Insality/defold-event/archive/refs/tags/13.zip
5151

5252
Event module can work in 3 modes:
5353

54-
| Mode | Default | Cross-Context | Error Behavior | Tracebacks | Notes |
55-
| --- | --- | --- | --- | --- | --- |
56-
| `pcall` | | | **Continue on error** | Basic | Errors are logged, other subscribers still run, code after trigger continues. |
57-
| `xpcall` ||| **Continue on error** | Full | Same as pcall but with detailed tracebacks. More memory usage. |
58-
| `none` ||| **Stop on error** | Full | Error stops all execution immediately. No cross-context support. |
54+
| Mode | Default | Error Behavior | Tracebacks | Notes |
55+
|-----------|:-------:|-----------------------|------------|---------------------------------------------------------------------------------------------|
56+
| `pcall` | | Continue on error | Basic | Errors are logged; other subscribers still run; code after trigger continues. |
57+
| `xpcall` || Continue on error | Full | Same as pcall but with detailed tracebacks. More memory usage. |
58+
| `none` || Stop on error | Full | Error stops all execution immediately. Callbacks run with xpcall; error rethrown w/ traceback. |
5959

60-
You can set the Event Mode with code:
61-
62-
```lua
63-
event.set_mode("pcall")
64-
event.set_mode("xpcall")
65-
event.set_mode("none")
66-
```
6760

6861
## What is context?
6962

7063
Context is the script context where the event is triggered. It can be a GO script or a GUI script in Defold. Without context changing, you can't call `gui.set_text` from GO script for example.
7164

72-
## Error Behavior
7365

74-
**Continue on error** (`pcall` and `xpcall` modes):
75-
- If one subscriber throws an error, it gets logged but other subscribers still run
76-
- Code after `event:trigger()` continues executing
66+
## Basic Usage
67+
68+
```lua
69+
-- Lua module /my_module.lua
70+
local event = require("event.event")
71+
72+
local M = {}
73+
74+
-- Create events anywhere
75+
M.on_value_changed = event.create()
76+
77+
function M.set_value(self, value)
78+
M._value = value
79+
-- Trigger the event when required to call subscribers
80+
M.on_value_changed:trigger(value)
81+
end
7782

78-
**Stop on error** (`none` mode):
79-
- If any subscriber throws an error, execution stops immediately
80-
- No more subscribers are called, code after `event:trigger()` doesn't run
81-
- **Important limitation**: Cross-context switching is disabled. Callbacks execute in the trigger's context rather than their subscription context, which removes the primary advantage of this event system over standard Lua function calls
83+
return M
8284

83-
The mode setting is global and affects all events in your project.
85+
-- Lua script /my_script.script
86+
local my_module = require("my_module")
8487

85-
**Recommendation**: Use `pcall` for production (safe, fast) and `xpcall` for debugging (detailed errors).
88+
local function on_value_changed(self, value)
89+
print("Value changed to:", value)
90+
end
91+
92+
function init(self)
93+
-- Subscribe to the event when required to call subscribers
94+
-- Self is passed as the first parameter to the callback
95+
my_module.on_value_changed:subscribe(on_value_changed, self)
96+
end
97+
98+
function final(self)
99+
-- Unsubscribe from the event when the script is destroyed
100+
my_module.on_value_changed:unsubscribe(on_value_changed, self)
101+
end
102+
```
86103

87104
## API Reference
88105

@@ -94,7 +111,7 @@ event.set_logger([logger])
94111
event.set_mode("pcall" | "xpcall" | "none")
95112

96113
local object = event.create([callback], [callback_context])
97-
object(...)
114+
object(...) -- Alias for object:trigger(...)
98115
object:trigger(...)
99116
object:subscribe(callback, [callback_context])
100117
object:unsubscribe(callback, [callback_context])
@@ -103,7 +120,7 @@ object:is_empty()
103120
object:clear()
104121

105122
local events = require("event.events")
106-
events(event_id, ...)
123+
events(event_id, ...) -- Alias for events.trigger(event_id, ...)
107124
events.trigger(event_id, ...)
108125
events.subscribe(event_id, callback, [callback_context])
109126
events.unsubscribe(event_id, callback, [callback_context])
@@ -121,6 +138,7 @@ For detailed API documentation, please refer to:
121138
- [Global Queues API](api/queues_api.md)
122139
- [Promise API](api/promise_api.md)
123140

141+
124142
## Use Cases
125143

126144
Read the [Use Cases](USE_CASES.md) file to see several examples of how to use the Event module in your Defold game development projects.
@@ -219,6 +237,10 @@ If you have any issues, questions or suggestions please [create an issue](https:
219237
- Added `promise:append` function to append a task to the promise
220238
- Added `promise:tail` and `promise:reset` functions to manage the promise tail
221239

240+
### **V14**
241+
- Enable cross-context for "none" event mode
242+
- In "none" mode callbacks are run with xpcall; on error, error is rethrown with `error()` (full traceback)
243+
222244
</details>
223245

224246
## ❤️ Support project ❤️

api/api.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ event.set_logger(logger)
88
event.set_mode("pcall" | "xpcall" | "none")
99

1010
local object = event.create([callback], [callback_context])
11-
object(...)
11+
object(...) -- Alias for object:trigger(...)
1212
object:trigger(...)
1313
object:subscribe(callback, [callback_context])
1414
object:unsubscribe(callback, [callback_context])
@@ -21,7 +21,9 @@ object:clear()
2121
```lua
2222
local events = require("event.events")
2323

24+
events(event_id, ...) -- Alias for events.trigger(event_id, ...)
2425
events.trigger(event_id, ...)
26+
events.get(event_id)
2527
events.subscribe(event_id, callback, [callback_context])
2628
events.unsubscribe(event_id, callback, [callback_context])
2729
events.is_subscribed(event_id, callback, [callback_context])

api/event_api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ By default, the module uses the `pprint` logger for errors.
4040
event.set_mode(mode)
4141
```
4242

43-
Set the mode of the event module.
43+
Set the mode of the event module. All modes support cross-context. In "none" mode callbacks run with xpcall; on error, the error is rethrown with full traceback.
4444
```lua
4545
mode:
4646
| "pcall"

api/events_api.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This is particularly useful for events that need to be handled by multiple scrip
1010
- [trigger](#trigger)
1111
- [clear](#clear)
1212
- [clear_all](#clear_all)
13+
- [get](#get)
1314
- [subscribe](#subscribe)
1415
- [unsubscribe](#unsubscribe)
1516
- [is_subscribed](#is_subscribed)
@@ -61,6 +62,27 @@ Remove all callbacks subscribed to the specified global event.
6162
```lua
6263
events.clear("on_game_over")
6364
```
65+
### get
66+
67+
---
68+
```lua
69+
events.get(event_id)
70+
```
71+
72+
Get an event instance for the specified global event. Creates the event if it does not exist.
73+
74+
- **Parameters:**
75+
- `event_id` *(string)*: The id of the global event.
76+
77+
- **Returns:**
78+
- `event_instance` *(event)*: An event instance that can be used to subscribe to and trigger the event.
79+
80+
- **Example Usage:**
81+
82+
```lua
83+
local on_game_over = events.get("on_game_over")
84+
on_game_over:subscribe(callback, self)
85+
```
6486
### clear_all
6587

6688
---

event/event.lua

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
local event_mode = sys.get_config_string("event.event_mode", "pcall")
22
local USE_XPCALL = event_mode == "xpcall"
33
local USE_PCALL = event_mode == "pcall"
4-
local USE_CONTEXT_CHANGE = USE_PCALL or USE_XPCALL
4+
local USE_NONE = event_mode == "none"
55

66
---Array of next items: { callback, callback_context, script_context }
77
---@class event.callback_data: table
@@ -70,7 +70,7 @@ end
7070
function M.set_mode(mode)
7171
USE_PCALL = mode == "pcall"
7272
USE_XPCALL = mode == "xpcall"
73-
USE_CONTEXT_CHANGE = USE_PCALL or USE_XPCALL
73+
USE_NONE = mode == "none"
7474
end
7575

7676

@@ -120,7 +120,6 @@ end
120120
function M:subscribe(callback, callback_context)
121121
assert(callback, "A function must be passed to subscribe to an event")
122122

123-
-- If callback is an event, subscribe to it and return
124123
if M.is_event(callback) then
125124
return self:subscribe(callback.trigger, callback)
126125
end
@@ -228,7 +227,7 @@ function M:trigger(...)
228227
local event_script_context = callback[3]
229228

230229
-- Set context for the callback
231-
if USE_CONTEXT_CHANGE and current_script_context ~= event_script_context then
230+
if current_script_context ~= event_script_context then
232231
set_context(event_script_context)
233232
end
234233

@@ -237,7 +236,7 @@ function M:trigger(...)
237236
if event_callback_context then
238237
if USE_PCALL then
239238
ok, result_or_error = pcall(event_callback, event_callback_context, ...)
240-
elseif USE_XPCALL then
239+
elseif USE_XPCALL or USE_NONE then
241240
local args = { event_callback_context }
242241
local n = select("#", ...)
243242
for i = 1, n do
@@ -254,7 +253,7 @@ function M:trigger(...)
254253
else
255254
if USE_PCALL then
256255
ok, result_or_error = pcall(event_callback, ...)
257-
elseif USE_XPCALL then
256+
elseif USE_XPCALL or USE_NONE then
258257
local args = {}
259258
local n = select("#", ...)
260259
for i = 1, n do
@@ -271,15 +270,19 @@ function M:trigger(...)
271270
end
272271

273272
-- Restore context
274-
if USE_CONTEXT_CHANGE and current_script_context ~= event_script_context then
273+
if current_script_context ~= event_script_context then
275274
set_context(current_script_context)
276275
end
277276

278277
-- Handle errors
279278
if not ok then
279+
if USE_NONE then
280+
error(result_or_error, 2)
281+
end
282+
280283
local caller_info = debug.getinfo(2)
281284
local place = caller_info.short_src .. ":" .. caller_info.currentline
282-
logger:error("Error from trigger event here: " .. place)
285+
logger:error("Error from trigger event here: " .. place, 2)
283286
logger:error(USE_XPCALL and result_or_error or debug.traceback(result_or_error, 2))
284287
end
285288

event/events.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,15 @@ function M.is_empty(event_id)
105105
end
106106

107107

108+
---Get a event instance for the specified global event.
109+
---@param event_id string The id of the global event to get a callback for.
110+
---@return event event_instance A event instance that can be used to subscribe to and trigger the event.
111+
function M.get(event_id)
112+
M.events[event_id] = M.events[event_id] or Event.create()
113+
return M.events[event_id]
114+
end
115+
116+
108117
-- Make the module callable as a shorthand for trigger
109118
setmetatable(M, {
110119
__call = function(_, event_id, ...)

game.project

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ input_method = HiddenInputField
1313

1414
[project]
1515
title = Defold Event
16-
version = 13
16+
version = 14
1717
publisher = Insality
1818
developer = Maksim Tuprikov, Insality
1919
dependencies#0 = https://github.com/Insality/defold-log/archive/refs/tags/2.zip

settings_deployer

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
bob_folder=./
33

44
# You can point bob version for project in format "filename:sha"
5-
bob_sha="181:fd1ad4c17bfdcd890ea7176f2672c35102384419"
5+
bob_sha="1_12_0:3206f699aaff89f357c9d549050b8453e080c5d2"
66

77
# Select Defold channel. Values: stable, beta, alpha
88
bob_channel="stable"
99

1010
# If true, it will check and download latest bob version. It will ignore bob_sha param
11-
use_latest_bob=true
11+
use_latest_bob=false
1212

1313
# Select Defold build server
1414
build_server="https://build.defold.com"

0 commit comments

Comments
 (0)