-
Notifications
You must be signed in to change notification settings - Fork 1
/
event.lua
131 lines (120 loc) · 3.46 KB
/
event.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
--Event Capture
--A 3Ra Gaming revision, original from Factorio-Stdlib by Afforess
-- @module Event
function fail_if_missing(var, msg)
if not var then
if msg then
error(msg, 3)
else
error("Missing value", 3)
end
end
return false
end
Event = {
_registry = {},
core_events = {
init = -1,
load = -2,
configuration_changed = -3,
_register = function(id)
if id == Event.core_events.init then
script.on_init(function()
Event.dispatch({ name = Event.core_events.init, tick = game.tick })
end)
elseif id == Event.core_events.load then
script.on_load(function()
Event.dispatch({ name = Event.core_events.load, tick = -1 })
end)
elseif id == Event.core_events.configuration_changed then
script.on_configuration_changed(function(data)
Event.dispatch({ name = Event.core_events.configuration_changed, tick = game.tick, data = data })
end)
end
end
}
}
--- Registers a function for a given event
-- @param event or array containing events to register
-- @param handler Function to call when event is triggered
-- @return #Event
function Event.register(event, handler)
fail_if_missing(event, "missing event argument")
if type(event) == "number" then
event = { event }
end
for _, event_id in pairs(event) do
fail_if_missing(event_id, "missing event id")
if handler == nil then
Event._registry[event_id] = nil
script.on_event(event_id, nil)
else
if not Event._registry[event_id] then
Event._registry[event_id] = {}
if event_id >= 0 then
script.on_event(event_id, Event.dispatch)
else
Event.core_events._register(event_id)
end
end
table.insert(Event._registry[event_id], handler)
end
end
return Event
end
--- Calls the registerd handlers
-- @param event LuaEvent as created by game.raise_event
function Event.dispatch(event)
fail_if_missing(event, "missing event argument")
if Event._registry[event.name] then
for _, handler in pairs(Event._registry[event.name]) do
local metatbl = { __index = function(tbl, key) if key == '_handler' then return handler else return rawget(tbl, key) end end }
setmetatable(event, metatbl)
local success, err = pcall(handler, event)
if not success then
-- may be nil in on_load
local identifier = event.name
for i,v in pairs(defines.events) do
if v == event.name then
identifier = i
end
end
err = string.gsub(err, "\n", " : ")
if event.name < -1 or global.last_error ~= identifier then
print("output$Error in event "..identifier..": \""..err.."\".")
log("Error in event "..identifier..": \""..err.."\".")
if event.name > -2 then
global.last_error = identifier
end
end
end
end
end
end
--- Removes the handler from the event
-- @param event event or array containing events to remove the handler
-- @param handler to remove
-- @return #Event
function Event.remove(event, handler)
fail_if_missing(event, "missing event argument")
fail_if_missing(handler, "missing handler argument")
if type(event) == "number" then
event = { event }
end
for _, event_id in pairs(event) do
fail_if_missing(event_id, "missing event id")
if Event._registry[event_id] then
for i = #Event._registry[event_id], 1, -1 do
if Event._registry[event_id][i] == handler then
table.remove(Event._registry[event_id], i)
end
end
if #Event._registry[event_id] == 0 then
Event._registry[event_id] = nil
script.on_event(event_id, nil)
end
end
end
return Event
end
return Event