114 lines
3.2 KiB
Lua
114 lines
3.2 KiB
Lua
|
local sk_definition_writer = require('sk_definition_writer')
|
||
|
local sk_scene = require('sk_scene')
|
||
|
|
||
|
local name_to_index = {}
|
||
|
local signal_count = 0
|
||
|
|
||
|
local function signal_index_for_name(name)
|
||
|
local result = name_to_index[name]
|
||
|
|
||
|
if result then
|
||
|
return result
|
||
|
end
|
||
|
|
||
|
local result = signal_count
|
||
|
name_to_index[name] = result
|
||
|
signal_count = signal_count + 1
|
||
|
return result
|
||
|
end
|
||
|
|
||
|
local function determine_signal_order(operators, result, used_signals, signal_producers, operation_index)
|
||
|
-- check if the signal has already been added
|
||
|
if used_signals[operation_index] then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
used_signals[operation_index] = true
|
||
|
|
||
|
local input_signal = operators[operation_index]
|
||
|
|
||
|
for _, signal_name in pairs(input_signal.input) do
|
||
|
for _, producer_index in pairs(signal_producers[signal_name] or {}) do
|
||
|
determine_signal_order(operators, result, used_signals, signal_producers, operation_index)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
table.insert(input_signal)
|
||
|
end
|
||
|
|
||
|
local function order_signals(operators)
|
||
|
local signal_producers = {}
|
||
|
|
||
|
for index, operation in pairs(operators) do
|
||
|
if signal_producers[operation.output] then
|
||
|
table.insert(signal_producers[operation.output], index)
|
||
|
else
|
||
|
signal_producers[operation.output] = {index}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local result = {}
|
||
|
local used_signals = {}
|
||
|
|
||
|
for operation_index = 1,#operators do
|
||
|
determine_signal_order(operators, result, used_signals, signal_producers, operation_index)
|
||
|
end
|
||
|
|
||
|
return result
|
||
|
end
|
||
|
|
||
|
local unordered_operators = {}
|
||
|
|
||
|
for _, and_operator in pairs(sk_scene.nodes_for_type('@and')) do
|
||
|
table.insert(unordered_operators, {
|
||
|
type = 'SignalOperatorTypeAnd',
|
||
|
output = and_operator.arguments[1],
|
||
|
input = {table.unpack(and_operator.arguments, 2)},
|
||
|
})
|
||
|
end
|
||
|
|
||
|
for _, or_operator in pairs(sk_scene.nodes_for_type('@or')) do
|
||
|
table.insert(unordered_operators, {
|
||
|
type = 'SignalOperatorTypeOr',
|
||
|
output = or_operator.arguments[1],
|
||
|
input = {table.unpack(or_operator.arguments, 2)},
|
||
|
})
|
||
|
end
|
||
|
|
||
|
for _, not_operator in pairs(sk_scene.nodes_for_type('@not')) do
|
||
|
table.insert(unordered_operators, {
|
||
|
type = 'SignalOperatorTypeNot',
|
||
|
output = not_operator.arguments[1],
|
||
|
input = {not_operator.arguments[2]},
|
||
|
})
|
||
|
end
|
||
|
|
||
|
local ordered_operators = order_signals(unordered_operators)
|
||
|
|
||
|
local function generate_operator_data(operator)
|
||
|
return {
|
||
|
operator.type,
|
||
|
signal_index_for_name(operator.output),
|
||
|
{
|
||
|
signal_index_for_name(operator.input[1]),
|
||
|
operator.input[2] and signal_index_for_name(operator.input[2]) or -1,
|
||
|
},
|
||
|
additionalInputs = {
|
||
|
operator.input[3] and signal_index_for_name(operator.input[3]) or -1,
|
||
|
operator.input[4] and signal_index_for_name(operator.input[4]) or -1,
|
||
|
},
|
||
|
}
|
||
|
end
|
||
|
|
||
|
local operators = {}
|
||
|
|
||
|
for _, operation in pairs(ordered_operators) do
|
||
|
table.insert(operators, generate_operator_data(operation))
|
||
|
end
|
||
|
|
||
|
sk_definition_writer.add_definition('signal_operations', 'struct SignalOperator[]', '_geo', operators)
|
||
|
|
||
|
return {
|
||
|
signal_index_for_name = signal_index_for_name,
|
||
|
operators = operators,
|
||
|
}
|