183 lines
4.5 KiB
Lua
183 lines
4.5 KiB
Lua
local config = require 'config'
|
|
|
|
|
|
local _M = {}
|
|
|
|
|
|
_M.EVERYTHING = {type = 'virtual', name = 'signal-everything'}
|
|
|
|
|
|
local cache_mt = {
|
|
__index = function(self, key)
|
|
local entity = self.__entity.surface.create_entity {
|
|
name = config.SIGNAL_CACHE_NAME,
|
|
position = self.__entity.position,
|
|
force = self.__entity.force,
|
|
create_build_effect_smoke = false,
|
|
}
|
|
self.__cache_entities[key] = entity
|
|
entity.destructible = false
|
|
|
|
self.__entity.connect_neighbour {
|
|
wire = defines.wire_type.red,
|
|
target_entity = entity,
|
|
source_circuit_id = self.__circuit_id or nil,
|
|
}
|
|
self.__entity.connect_neighbour {
|
|
wire = defines.wire_type.green,
|
|
target_entity = entity,
|
|
source_circuit_id = self.__circuit_id or nil,
|
|
}
|
|
|
|
self[key] = {
|
|
__cb = entity.get_or_create_control_behavior(),
|
|
}
|
|
|
|
return self[key]
|
|
end,
|
|
}
|
|
|
|
|
|
function _M.init_global()
|
|
global.signals = global.signals or {}
|
|
global.signals.cache = global.signals.cache or {}
|
|
end
|
|
|
|
function _M.on_load()
|
|
for _, cache in pairs(global.signals.cache) do setmetatable(cache, cache_mt); end
|
|
end
|
|
|
|
|
|
_M.cache = {}
|
|
|
|
function _M.cache.get(entity, circuit_id)
|
|
local cache = global.signals.cache[entity.unit_number]
|
|
if not cache then
|
|
cache = setmetatable({
|
|
__entity = entity,
|
|
__circuit_id = circuit_id or false, -- Avoid calling __index when the id is nil
|
|
__cache_entities = {},
|
|
}, cache_mt)
|
|
global.signals.cache[entity.unit_number] = cache
|
|
end
|
|
return cache
|
|
end
|
|
|
|
function _M.cache.reset(entity, name)
|
|
local cache = global.signals.cache[entity.unit_number]
|
|
if cache and rawget(cache, name) then
|
|
global.signals.cache[entity.unit_number][name] = {
|
|
control_behavior = entity.get_or_create_control_behavior(),
|
|
}
|
|
end
|
|
end
|
|
|
|
function _M.cache.drop(entity)
|
|
local cache = global.signals.cache[entity.unit_number]
|
|
if cache then
|
|
for key, e in pairs(cache.__cache_entities) do e.destroy(); end
|
|
global.signals.cache[entity.unit_number] = nil
|
|
end
|
|
end
|
|
|
|
function _M.cache.move(entity)
|
|
local cache = global.signals.cache[entity.unit_number]
|
|
if cache then
|
|
for _, e in pairs(cache.__cache_entities) do e.teleport(entity); end
|
|
end
|
|
end
|
|
|
|
|
|
function _M.get_merged_signals(entity, circuit_id)
|
|
return circuit_id and (entity.get_merged_signals(circuit_id) or {}) or entity.get_merged_signals() or {}
|
|
end
|
|
function _M.get_merged_signal(entity, signal, circuit_id)
|
|
if circuit_id then return entity.get_merged_signal(signal, circuit_id)
|
|
else return entity.get_merged_signal(signal); end
|
|
end
|
|
|
|
|
|
function _M.get_highest(entity, circuit_id, update_count)
|
|
local cache = _M.cache.get(entity, circuit_id)
|
|
|
|
if cache.highest.valid
|
|
and not cache.highest.__cb.disabled
|
|
and (not cache.highest.value or not cache.highest_present.__cb.disabled)
|
|
then
|
|
if update_count and cache.highest.value and cache.highest_count.__cb.disabled then
|
|
local count = _M.get_merged_signal(entity, cache.highest.value.signal, circuit_id)
|
|
|
|
cache.highest.value.count = count
|
|
cache.highest_count.__cb.circuit_condition = {condition = {
|
|
comparator = '=',
|
|
first_signal = cache.highest.value.signal,
|
|
constant = count,
|
|
}}
|
|
end
|
|
return cache.highest.value
|
|
end
|
|
|
|
local highest = nil
|
|
for _, signal in pairs(_M.get_merged_signals(entity, circuit_id)) do
|
|
if highest == nil or signal.count > highest.count then highest = signal; end
|
|
end
|
|
|
|
cache.highest.valid = true
|
|
|
|
if highest then
|
|
cache.highest.value = highest
|
|
cache.highest.__cb.circuit_condition = {condition = {
|
|
comparator = '≤',
|
|
first_signal = _M.EVERYTHING,
|
|
second_signal = highest.signal,
|
|
}}
|
|
|
|
cache.highest_present.__cb.circuit_condition = {condition = {
|
|
comparator = '≠',
|
|
first_signal = highest.signal,
|
|
constant = 0,
|
|
}}
|
|
|
|
cache.highest_count.__cb.circuit_condition = {condition = {
|
|
comparator = '=',
|
|
first_signal = highest.signal,
|
|
constant = highest.count,
|
|
}}
|
|
else
|
|
cache.highest.value = nil
|
|
cache.highest.__cb.circuit_condition = {condition = {
|
|
comparator = '=',
|
|
first_signal = _M.EVERYTHING,
|
|
constant = 0,
|
|
}}
|
|
end
|
|
|
|
return highest
|
|
end
|
|
|
|
|
|
function _M.watch_highest_presence(entity, circuit_id)
|
|
local highest = _M.get_highest(entity, circuit_id)
|
|
local cache = _M.cache.get(entity, circuit_id)
|
|
|
|
if not highest then
|
|
cache.signal_present.valid = false
|
|
else
|
|
cache.signal_present.valid = true
|
|
cache.signal_present.__cb.circuit_condition = {condition = {
|
|
comparator = '>',
|
|
first_signal = highest.signal,
|
|
constant = 0,
|
|
}}
|
|
end
|
|
|
|
return highest
|
|
end
|
|
function _M.signal_present(entity, circuit_id)
|
|
local cache = _M.cache.get(entity, circuit_id)
|
|
return cache.signal_present.valid and not cache.signal_present.__cb.disabled
|
|
end
|
|
|
|
|
|
return _M
|