1
0
Fork 0
mirror of https://github.com/Reuh/anselme.git synced 2025-10-27 16:49:31 +00:00

Add interrupt events

This commit is contained in:
Étienne Fildadut 2019-12-26 22:00:40 +01:00
parent 4d38e0afc2
commit e69b99e2a7

View file

@ -945,12 +945,11 @@ formatText = (context, text, yield)
end end
--- Send event to the engine. --- Send event to the engine.
-- root is the root node or an event
sendEvent = (root) sendEvent = (root)
let e = root.event let e = root.event or root
root.event = nil root.event = nil
if e[1] == "text" then if e[1] == "choice" then
coroutine.yield("text", e[2])
elseif e[1] == "choice" then
let vm = coroutine.yield("choice", e[2]) let vm = coroutine.yield("choice", e[2])
if not vm.state.chosen then if not vm.state.chosen then
error("no choice has been made by the engine, I don't know what to doooooo") error("no choice has been made by the engine, I don't know what to doooooo")
@ -958,6 +957,8 @@ sendEvent = (root)
let c = assert(e[3][vm.state.chosen], "invalid choice %s, expected something in [1,%s]":format(vm.state.chosen, #e[2])) let c = assert(e[3][vm.state.chosen], "invalid choice %s, expected something in [1,%s]":format(vm.state.chosen, #e[2]))
vm.state.chosen = nil vm.state.chosen = nil
runChildren(c) runChildren(c)
else
coroutine.yield(e[1], e[2])
end end
end end
@ -1005,6 +1006,13 @@ run = (lines, i=1)
while i <= #lines do while i <= #lines do
let line = lines[i] let line = lines[i]
i += 1 i += 1
-- Interrupt events
if #root.interrupts > 0 then
for _, e in ipairs(root.interrupts) do
sendEvent(e)
end
root.interrupts = {}
end
-- Condition decorator -- Condition decorator
if line.condition then if line.condition then
if evalBool(line, line.condition).value == 0 then if evalBool(line, line.condition).value == 0 then
@ -1136,6 +1144,7 @@ end
--- Step the VM. Use in a coroutine. --- Step the VM. Use in a coroutine.
step = :() step = :()
@_coroutine = coroutine.running()
while true do while true do
@state.lastLine = run(@state.children, @state.lastLine) @state.lastLine = run(@state.children, @state.lastLine)
if @state.event then sendEvent(@state) end if @state.event then sendEvent(@state) end
@ -1242,13 +1251,27 @@ let vm_mt = {
return @ return @
end, end,
--- Throw an interrupt event; i.e., pause the VM and send the event as soon as possible.
-- This can be used to trigger custom events that need to be handled outside of Anselme.
-- Can be called from an luafunction, or from outside.
interrupt = :(name, data)
if coroutine.running() == @_coroutine then
coroutine.yield(name, data)
else
table.insert(@state.interrupts, { name, data })
end
end,
--- Wrapped coroutine that returns event, data each time it is called. --- Wrapped coroutine that returns event, data each time it is called.
-- Will run all the code at the root element, and then wait for more. It never die. -- Will run all the code at the root element, and then wait for more. It never die.
-- "text", message: text to display -- "text", message: text to display
-- "choice", {message1, message2, ...}: a choice. Anselme will expect an answer to be chosen using the choose method before the next call to step. -- "choice", {message1, message2, ...}: a choice. Anselme will expect an answer to be chosen using the choose method before the next call to step.
-- "end", nil: end of the script -- "end", nil: end of the script
-- Messages are tables: { text = "string", tags = { tagName = tagValue, ... } } -- Messages are tables: { text = "string", tags = { tagName = tagValue, ... } }
step = nil step = nil,
--- The VM coroutine. Do not use this directly, use :step.
_coroutine = nil
} }
vm_mt.__index = vm_mt vm_mt.__index = vm_mt
@ -1265,6 +1288,7 @@ let newVM = (state)
-- Useful stuff that's only on root -- Useful stuff that's only on root
chosen = nil, -- chosen answer. See the choose method. chosen = nil, -- chosen answer. See the choose method.
event = nil, -- event buffer - contains { event(str), data, other } if an event is waiting to be sent. event = nil, -- event buffer - contains { event(str), data, other } if an event is waiting to be sent.
interrupts = {}, -- list of interrupt events; they will be sent as soon as possible, regardless of the current event buffer
lastLine = 1, -- The last line run in the root element. Used to always resume at the exact right spot™ in the step method. lastLine = 1, -- The last line run in the root element. Used to always resume at the exact right spot™ in the step method.
tags = {}, -- Currently active tags. tags = {}, -- Currently active tags.
aliases = {}, -- Name aliases aliases = {}, -- Name aliases