-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.lua
121 lines (103 loc) · 2.8 KB
/
util.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
function Promise.resolved(value)
local p = Promise.new()
p:resolve(value)
return p
end
-- empty promise
function Promise.empty()
return Promise.resolved(nil)
end
function Promise.rejected(value)
local p = Promise.new()
p:reject(value)
return p
end
function Promise.after(delay, value, err)
return Promise.new(function(resolve, reject)
minetest.after(delay, function()
if err then
reject(err)
else
resolve(value)
end
end)
end)
end
function Promise.emerge_area(pos1, pos2)
pos2 = pos2 or pos1
return Promise.new(function(resolve)
minetest.emerge_area(pos1, pos2, function(_, _, calls_remaining)
if calls_remaining == 0 then
resolve()
end
end)
end)
end
function Promise.handle_async(fn, ...)
local args = {...}
return Promise.new(function(resolve)
if minetest.handle_async then
-- use threaded async env
minetest.handle_async(fn, resolve, unpack(args))
else
-- fall back to unthreaded async call
resolve(fn(unpack(args)))
end
end)
end
function Promise.dynamic_add_media(options)
return Promise.new(function(resolve, reject)
local success = minetest.dynamic_add_media(options, resolve)
if not success then
reject()
end
end)
end
local mods_loaded_promise = Promise.new()
function Promise.mods_loaded()
return mods_loaded_promise
end
minetest.register_on_mods_loaded(function()
mods_loaded_promise:resolve()
end)
-- pos-hash -> list<Promise>
local punchnode_promises = {}
minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing)
local hash = minetest.hash_node_position(pos)
-- get and clear list for this pos
local list = punchnode_promises[hash]
punchnode_promises[hash] = nil
-- execute promise resolve
if list then
for _, p in ipairs(list) do
p:resolve({
pos = pos,
node = node,
puncher = puncher,
pointed_thing = pointed_thing
})
end
end
end)
function Promise.on_punch(pos, timeout)
timeout = timeout or 5
local p = Promise.new()
local pt = Promise.after(timeout, "timeout")
local hash = minetest.hash_node_position(pos)
-- create and/or append
local list = punchnode_promises[hash]
if not list then
list = {}
punchnode_promises[hash] = list
end
table.insert(list, p)
return Promise.new(function(resolve, reject)
Promise.race(p, pt):next(function(data)
if data == "timeout" then
reject("timeout")
else
resolve(data)
end
end)
end)
end