summaryrefslogtreecommitdiff
path: root/server/src/task.lua
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/task.lua')
-rw-r--r--server/src/task.lua64
1 files changed, 64 insertions, 0 deletions
diff --git a/server/src/task.lua b/server/src/task.lua
new file mode 100644
index 00000000..a1ed37de
--- /dev/null
+++ b/server/src/task.lua
@@ -0,0 +1,64 @@
+local mt = {}
+mt.__index = mt
+mt.type = 'task'
+
+function mt:remove()
+ if self._removed then
+ return
+ end
+ self._removed = true
+end
+
+function mt:isRemoved()
+ return self._removed
+end
+
+function mt:step()
+ if self._removed then
+ return
+ end
+ local suc, res = coroutine.resume(self.task)
+ if not suc then
+ self:remove()
+ log.error(debug.traceback(self.task, res))
+ return
+ end
+ if coroutine.status(self.task) == 'dead' then
+ self:remove()
+ end
+ return res
+end
+
+function mt:fastForward()
+ if self._removed then
+ return
+ end
+ while true do
+ local suc = coroutine.resume(self.task)
+ if not suc then
+ self:remove()
+ break
+ end
+ if coroutine.status(self.task) == 'dead' then
+ self:remove()
+ break
+ end
+ end
+end
+
+function mt:set(key, value)
+ self.data[key] = value
+end
+
+function mt:get(key)
+ return self.data[key]
+end
+
+return function (callback)
+ local self = setmetatable({
+ callback = callback,
+ data = {},
+ task = coroutine.create(callback),
+ }, mt)
+ return self
+end