You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
2.8 KiB
130 lines
2.8 KiB
local script_name = ...
|
|
|
|
if not script_name then
|
|
print("Usage:")
|
|
print(" ddb_logic.lua <script>")
|
|
return
|
|
end
|
|
|
|
local output_values = {}
|
|
outputs = {
|
|
dirty = {},
|
|
}
|
|
|
|
local signal_map = {}
|
|
|
|
local output_converters = {}
|
|
local output_map = {}
|
|
|
|
inputs = {}
|
|
local input_converters = {}
|
|
local input_map = {}
|
|
|
|
setmetatable(outputs, {
|
|
__index = function(t,k)
|
|
return output_values[k]
|
|
end,
|
|
__newindex = function (t,k,v)
|
|
if output_values[k] ~= v then
|
|
output_values[k] = v
|
|
t.dirty[k] = true
|
|
end
|
|
end,
|
|
})
|
|
|
|
local function update_output(output_map, output_converters, outputs)
|
|
for k,_ in pairs(outputs.dirty) do
|
|
outputs.dirty[k] = nil
|
|
local id = output_map[k] or "_ "..k
|
|
if outputs[k] == nil then
|
|
local cmd = ("u "..id):gsub("\n","")
|
|
print(cmd)
|
|
else
|
|
local converter = output_converters[k] or tostring
|
|
local cmd = ("> "..id.." "..converter(outputs[k])):gsub("\n","")
|
|
print(cmd)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function handle_input(input_map, input_converters, key, value, inputs)
|
|
local name = input_map[key]
|
|
if not name then return false end
|
|
local converter = input_converters[name] or tostring
|
|
inputs[name] = converter(value)
|
|
return true
|
|
end
|
|
|
|
local function handle_signal(signal_map, inputs, outputs, helpers, signal)
|
|
local func = signal_map[signal]
|
|
if func then
|
|
func(inputs, outputs, helpers)
|
|
end
|
|
end
|
|
|
|
-- API for subscript
|
|
|
|
function message(msg)
|
|
io.stderr:write(tostring(msg).."\n")
|
|
end
|
|
|
|
function add_signal(global_name, callback)
|
|
signal_map[global_name] = callback
|
|
end
|
|
|
|
function add_output(name, global_name, converter, default)
|
|
output_values[name] = default
|
|
output_converters[name] = converter
|
|
output_map[name] = global_name
|
|
end
|
|
|
|
function add_input(name, global_name, converter, default)
|
|
inputs[name] = default
|
|
input_converters[name] = converter
|
|
input_map[global_name] = name
|
|
end
|
|
|
|
dofile(script_name)
|
|
|
|
add_signal = nil
|
|
add_output = nil
|
|
add_input = nil
|
|
|
|
subscribe_to = {}
|
|
|
|
for k,_ in pairs(signal_map) do
|
|
local obj = k:match("(.-) ")
|
|
subscribe_to[obj] = true
|
|
end
|
|
|
|
for k,_ in pairs(input_map) do
|
|
local obj = k:match("(.-) ")
|
|
subscribe_to[obj] = true
|
|
print("r "..k)
|
|
end
|
|
|
|
for k,_ in pairs(subscribe_to) do
|
|
print("+ "..k)
|
|
end
|
|
|
|
while true do
|
|
local i = io.read()
|
|
if not i then break end
|
|
local key = i:match("^u ([a-zA-z0-9%-_%.]+ [a-zA-z0-9%-_%.]+)$")
|
|
if key then
|
|
handle_input(input_map, input_converters, key, nil, inputs)
|
|
do_logic(inputs, outputs, helpers)
|
|
update_output(output_map, output_converters, outputs)
|
|
end
|
|
local key,value = i:match("> ([a-zA-z0-9%-_%.]+ [a-zA-z0-9%-_%.]+) (.+)$")
|
|
if key and value then
|
|
handle_input(input_map, input_converters, key, value, inputs)
|
|
do_logic(inputs, outputs, helpers)
|
|
update_output(output_map, output_converters, outputs)
|
|
end
|
|
local signal = i:match("^s (.+)$")
|
|
if signal then
|
|
handle_signal(signal_map, inputs, outputs, helpers, signal)
|
|
update_output(output_map, output_converters, outputs)
|
|
end
|
|
end
|
|
|