mod: entity prototype improvements and refactoring
- refactor and move queue & emitter classes for consistency - don't emit all prototypes at once - add simple queue for 'instant' packets so the printer doesn't get overwhelmed and mix up the output
This commit is contained in:
parent
ae0eb98f12
commit
90aa086dd4
33 changed files with 742 additions and 652 deletions
|
|
@ -1,144 +0,0 @@
|
||||||
local ____lualib = require("lualib_bundle")
|
|
||||||
local __TS__Class = ____lualib.__TS__Class
|
|
||||||
local __TS__New = ____lualib.__TS__New
|
|
||||||
local ____exports = {}
|
|
||||||
local ____KafkatorioSettings = require("main.settings.KafkatorioSettings")
|
|
||||||
local KafkatorioSettings = ____KafkatorioSettings.default
|
|
||||||
local ____PacketEmitter = require("main.PacketEmitter")
|
|
||||||
local packetEmitter = ____PacketEmitter.default
|
|
||||||
____exports.EventUpdates = {}
|
|
||||||
local EventUpdates = ____exports.EventUpdates
|
|
||||||
do
|
|
||||||
local CacheEntry
|
|
||||||
EventUpdates.Manager = __TS__Class()
|
|
||||||
local Manager = EventUpdates.Manager
|
|
||||||
Manager.name = "Manager"
|
|
||||||
function Manager.prototype.____constructor(self)
|
|
||||||
end
|
|
||||||
function Manager.prototype.init(self, force)
|
|
||||||
local isAnythingUndefined = global.cache == nil
|
|
||||||
log(((("Initialising EventDataCache (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")...")
|
|
||||||
if force == true or isAnythingUndefined then
|
|
||||||
log("Initialising global.cache")
|
|
||||||
global.cache = {}
|
|
||||||
end
|
|
||||||
log("Finished initialising EventDataCache")
|
|
||||||
end
|
|
||||||
function Manager.prototype.throttle(self, key, ____type, mutate, expirationDurationTicks)
|
|
||||||
self:update(
|
|
||||||
key,
|
|
||||||
____type,
|
|
||||||
mutate,
|
|
||||||
false,
|
|
||||||
expirationDurationTicks
|
|
||||||
)
|
|
||||||
end
|
|
||||||
function Manager.prototype.debounce(self, key, ____type, mutate, expirationDurationTicks)
|
|
||||||
self:update(
|
|
||||||
key,
|
|
||||||
____type,
|
|
||||||
mutate,
|
|
||||||
true,
|
|
||||||
expirationDurationTicks
|
|
||||||
)
|
|
||||||
end
|
|
||||||
function Manager.prototype.update(self, key, ____type, mutate, resetLastUpdated, expirationDurationTicks)
|
|
||||||
local entry = self:getCacheEntry(key, ____type) or EventUpdates.Manager:createCacheEntry(key, ____type)
|
|
||||||
mutate(entry.packet)
|
|
||||||
if resetLastUpdated then
|
|
||||||
entry.lastUpdatedTick = game.tick
|
|
||||||
end
|
|
||||||
if expirationDurationTicks ~= nil then
|
|
||||||
entry.expirationDurationTicks = expirationDurationTicks
|
|
||||||
end
|
|
||||||
if entry.expirationDurationTicks ~= nil and entry.expirationDurationTicks <= 0 then
|
|
||||||
self:extractAndEmitExpiredPackets()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function Manager.prototype.setExpiration(self, key, ____type, expirationDurationTicks)
|
|
||||||
local entry = self:getCacheEntry(key, ____type)
|
|
||||||
if entry ~= nil then
|
|
||||||
entry.expirationDurationTicks = expirationDurationTicks
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function Manager.prototype.extractExpired(self)
|
|
||||||
local countExpired = 0
|
|
||||||
local countTotal = 0
|
|
||||||
local expiredData = {}
|
|
||||||
for key, entry in pairs(global.cache) do
|
|
||||||
countTotal = countTotal + 1
|
|
||||||
if self:isExpired(entry) then
|
|
||||||
countExpired = countExpired + 1
|
|
||||||
expiredData[#expiredData + 1] = entry.packet
|
|
||||||
global.cache[key] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local hasExpiredItems = countExpired > 0
|
|
||||||
local hasAnyItem = countTotal > 0
|
|
||||||
if hasExpiredItems or game.tick % 30 == 0 and hasAnyItem then
|
|
||||||
log((("[extractExpired] expired items: " .. tostring(countExpired)) .. ", total: ") .. tostring(countTotal))
|
|
||||||
end
|
|
||||||
return expiredData
|
|
||||||
end
|
|
||||||
function Manager.prototype.extractAndEmitExpiredPackets(self)
|
|
||||||
local cachedEvents = self:extractExpired()
|
|
||||||
if #cachedEvents > 0 then
|
|
||||||
log((("[EventDataCache] emitting " .. tostring(#cachedEvents)) .. " events on tick ") .. tostring(game.tick))
|
|
||||||
for ____, event in ipairs(cachedEvents) do
|
|
||||||
packetEmitter:emitKeyedPacket(event)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return #cachedEvents
|
|
||||||
end
|
|
||||||
function Manager.prototype.getCacheEntry(self, key, ____type)
|
|
||||||
local hash = EventUpdates.Manager:hashKey(key)
|
|
||||||
if not (global.cache[hash] ~= nil) then
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
local value = global.cache[hash]
|
|
||||||
if self:isEntryInstanceOf(value, ____type) then
|
|
||||||
return value
|
|
||||||
else
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function Manager.createCacheEntry(self, key, ____type)
|
|
||||||
local data = {type = ____type, key = key}
|
|
||||||
local entry = __TS__New(CacheEntry, data)
|
|
||||||
local hash = EventUpdates.Manager:hashKey(key)
|
|
||||||
global.cache[hash] = entry
|
|
||||||
return entry
|
|
||||||
end
|
|
||||||
function Manager.prototype.isExpired(self, entry)
|
|
||||||
local expiryDuration = entry.expirationDurationTicks or KafkatorioSettings:getEventCacheExpirationTicks(entry.packet)
|
|
||||||
if expiryDuration == nil then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return game.tick - entry.lastUpdatedTick > expiryDuration
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function Manager.prototype.isEntryInstanceOf(self, entry, ____type)
|
|
||||||
local ____self_isDataInstanceOf_2 = self.isDataInstanceOf
|
|
||||||
local ____entry_packet_0 = entry
|
|
||||||
if ____entry_packet_0 ~= nil then
|
|
||||||
____entry_packet_0 = ____entry_packet_0.packet
|
|
||||||
end
|
|
||||||
return ____self_isDataInstanceOf_2(self, ____entry_packet_0, ____type)
|
|
||||||
end
|
|
||||||
function Manager.prototype.isDataInstanceOf(self, packet, ____type)
|
|
||||||
return packet ~= nil and packet.type == ____type
|
|
||||||
end
|
|
||||||
function Manager.hashKey(self, key)
|
|
||||||
return game.encode_string(game.table_to_json(key))
|
|
||||||
end
|
|
||||||
CacheEntry = __TS__Class()
|
|
||||||
CacheEntry.name = "CacheEntry"
|
|
||||||
function CacheEntry.prototype.____constructor(self, packet, expirationDurationTicks)
|
|
||||||
self.lastUpdatedTick = game.tick
|
|
||||||
self.packet = packet
|
|
||||||
self.expirationDurationTicks = expirationDurationTicks
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local EventUpdatesManager = __TS__New(____exports.EventUpdates.Manager)
|
|
||||||
____exports.default = EventUpdatesManager
|
|
||||||
return ____exports
|
|
||||||
|
|
@ -5,10 +5,10 @@ local __TS__ParseInt = ____lualib.__TS__ParseInt
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
local ____global_2Dinit = require("main.global-init")
|
local ____global_2Dinit = require("main.global-init")
|
||||||
local initGlobal = ____global_2Dinit.initGlobal
|
local initGlobal = ____global_2Dinit.initGlobal
|
||||||
local ____queue = require("main.queue.queue")
|
|
||||||
local Queue = ____queue.Queue
|
|
||||||
local ____prototypeUpdates = require("main.events.prototypeUpdates")
|
local ____prototypeUpdates = require("main.events.prototypeUpdates")
|
||||||
local emitPrototypes = ____prototypeUpdates.emitPrototypes
|
local emitPrototypes = ____prototypeUpdates.emitPrototypes
|
||||||
|
local ____queue = require("main.queue.queue")
|
||||||
|
local EventDataQueue = ____queue.default
|
||||||
commands.add_command(
|
commands.add_command(
|
||||||
"kafkatorio",
|
"kafkatorio",
|
||||||
"kafkatorio innit bruv",
|
"kafkatorio innit bruv",
|
||||||
|
|
@ -56,7 +56,7 @@ commands.add_command(
|
||||||
surface = surface,
|
surface = surface,
|
||||||
tick = e.tick
|
tick = e.tick
|
||||||
}
|
}
|
||||||
Queue.enqueue(
|
EventDataQueue:enqueue(
|
||||||
(tostring(surface.index) .. tostring(chunk.x)) .. tostring(chunk.y),
|
(tostring(surface.index) .. tostring(chunk.x)) .. tostring(chunk.y),
|
||||||
data,
|
data,
|
||||||
50
|
50
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
local ____lualib = require("lualib_bundle")
|
||||||
|
local __TS__Class = ____lualib.__TS__Class
|
||||||
|
local __TS__New = ____lualib.__TS__New
|
||||||
|
local ____exports = {}
|
||||||
|
local CacheEntry
|
||||||
|
local ____KafkatorioSettings = require("main.settings.KafkatorioSettings")
|
||||||
|
local KafkatorioSettings = ____KafkatorioSettings.default
|
||||||
|
local ____PacketEmitter = require("main.emitting.PacketEmitter")
|
||||||
|
local PacketEmitter = ____PacketEmitter.default
|
||||||
|
____exports.EventUpdatesManager = __TS__Class()
|
||||||
|
local EventUpdatesManager = ____exports.EventUpdatesManager
|
||||||
|
EventUpdatesManager.name = "EventUpdatesManager"
|
||||||
|
function EventUpdatesManager.prototype.____constructor(self)
|
||||||
|
self:init()
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.prototype.init(self, force)
|
||||||
|
local isAnythingUndefined = global.eventUpdatesManagerCache == nil
|
||||||
|
log(((("Initialising EventDataCache (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")...")
|
||||||
|
if force == true or isAnythingUndefined then
|
||||||
|
log("Initialising global.cache")
|
||||||
|
global.eventUpdatesManagerCache = {}
|
||||||
|
end
|
||||||
|
log("Finished initialising EventDataCache")
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.prototype.throttle(self, key, ____type, mutate, expirationDurationTicks)
|
||||||
|
self:update(
|
||||||
|
key,
|
||||||
|
____type,
|
||||||
|
mutate,
|
||||||
|
false,
|
||||||
|
expirationDurationTicks
|
||||||
|
)
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.prototype.debounce(self, key, ____type, mutate, expirationDurationTicks)
|
||||||
|
self:update(
|
||||||
|
key,
|
||||||
|
____type,
|
||||||
|
mutate,
|
||||||
|
true,
|
||||||
|
expirationDurationTicks
|
||||||
|
)
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.prototype.update(self, key, ____type, mutate, resetLastUpdated, expirationDurationTicks)
|
||||||
|
local entry = self:getCacheEntry(key, ____type) or ____exports.EventUpdatesManager:createCacheEntry(key, ____type)
|
||||||
|
mutate(entry.packet)
|
||||||
|
if resetLastUpdated then
|
||||||
|
entry.lastUpdatedTick = game.tick
|
||||||
|
end
|
||||||
|
if expirationDurationTicks ~= nil then
|
||||||
|
entry.expirationDurationTicks = expirationDurationTicks
|
||||||
|
end
|
||||||
|
if entry.expirationDurationTicks ~= nil and entry.expirationDurationTicks <= 0 then
|
||||||
|
self:extractAndEmitExpiredPackets()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.prototype.setExpiration(self, key, ____type, expirationDurationTicks)
|
||||||
|
local entry = self:getCacheEntry(key, ____type)
|
||||||
|
if entry ~= nil then
|
||||||
|
entry.expirationDurationTicks = expirationDurationTicks
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.prototype.extractExpired(self)
|
||||||
|
local countExpired = 0
|
||||||
|
local countTotal = 0
|
||||||
|
local expiredData = {}
|
||||||
|
for key, entry in pairs(global.eventUpdatesManagerCache) do
|
||||||
|
countTotal = countTotal + 1
|
||||||
|
if self:isExpired(entry) then
|
||||||
|
countExpired = countExpired + 1
|
||||||
|
expiredData[#expiredData + 1] = entry.packet
|
||||||
|
global.eventUpdatesManagerCache[key] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local hasExpiredItems = countExpired > 0
|
||||||
|
local hasAnyItem = countTotal > 0
|
||||||
|
if hasExpiredItems or game.tick % 30 == 0 and hasAnyItem then
|
||||||
|
log((("[extractExpired] expired items: " .. tostring(countExpired)) .. ", total: ") .. tostring(countTotal))
|
||||||
|
end
|
||||||
|
return expiredData
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.prototype.extractAndEmitExpiredPackets(self)
|
||||||
|
local cachedEvents = self:extractExpired()
|
||||||
|
if #cachedEvents > 0 then
|
||||||
|
log((("[EventDataCache] emitting " .. tostring(#cachedEvents)) .. " events on tick ") .. tostring(game.tick))
|
||||||
|
for ____, event in ipairs(cachedEvents) do
|
||||||
|
PacketEmitter:emitKeyedPacket(event)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return #cachedEvents
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.prototype.getCacheEntry(self, key, ____type)
|
||||||
|
local hash = ____exports.EventUpdatesManager:hashKey(key)
|
||||||
|
if not (global.eventUpdatesManagerCache[hash] ~= nil) then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local value = global.eventUpdatesManagerCache[hash]
|
||||||
|
if self:isEntryInstanceOf(value, ____type) then
|
||||||
|
return value
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.createCacheEntry(self, key, ____type)
|
||||||
|
local data = {type = ____type, key = key}
|
||||||
|
local entry = __TS__New(CacheEntry, data)
|
||||||
|
local hash = ____exports.EventUpdatesManager:hashKey(key)
|
||||||
|
global.eventUpdatesManagerCache[hash] = entry
|
||||||
|
return entry
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.prototype.isExpired(self, entry)
|
||||||
|
local expiryDuration = entry.expirationDurationTicks or KafkatorioSettings:getEventCacheExpirationTicks(entry.packet)
|
||||||
|
if expiryDuration == nil then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return game.tick - entry.lastUpdatedTick > expiryDuration
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.prototype.isEntryInstanceOf(self, entry, ____type)
|
||||||
|
local ____self_isDataInstanceOf_2 = self.isDataInstanceOf
|
||||||
|
local ____entry_packet_0 = entry
|
||||||
|
if ____entry_packet_0 ~= nil then
|
||||||
|
____entry_packet_0 = ____entry_packet_0.packet
|
||||||
|
end
|
||||||
|
return ____self_isDataInstanceOf_2(self, ____entry_packet_0, ____type)
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.prototype.isDataInstanceOf(self, packet, ____type)
|
||||||
|
return packet ~= nil and packet.type == ____type
|
||||||
|
end
|
||||||
|
function EventUpdatesManager.hashKey(self, key)
|
||||||
|
return game.encode_string(game.table_to_json(key))
|
||||||
|
end
|
||||||
|
local EventUpdates = __TS__New(____exports.EventUpdatesManager)
|
||||||
|
____exports.default = EventUpdates
|
||||||
|
CacheEntry = __TS__Class()
|
||||||
|
CacheEntry.name = "CacheEntry"
|
||||||
|
function CacheEntry.prototype.____constructor(self, packet, expirationDurationTicks)
|
||||||
|
self.lastUpdatedTick = game.tick
|
||||||
|
self.packet = packet
|
||||||
|
self.expirationDurationTicks = expirationDurationTicks
|
||||||
|
end
|
||||||
|
return ____exports
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
local ____lualib = require("lualib_bundle")
|
||||||
|
local __TS__Class = ____lualib.__TS__Class
|
||||||
|
local __TS__SetDescriptor = ____lualib.__TS__SetDescriptor
|
||||||
|
local __TS__New = ____lualib.__TS__New
|
||||||
|
local ____exports = {}
|
||||||
|
____exports.KafkatorioPacketQueueManager = __TS__Class()
|
||||||
|
local KafkatorioPacketQueueManager = ____exports.KafkatorioPacketQueueManager
|
||||||
|
KafkatorioPacketQueueManager.name = "KafkatorioPacketQueueManager"
|
||||||
|
function KafkatorioPacketQueueManager.prototype.____constructor(self)
|
||||||
|
self.size = 0
|
||||||
|
self.first = nil
|
||||||
|
self.last = nil
|
||||||
|
end
|
||||||
|
__TS__SetDescriptor(
|
||||||
|
KafkatorioPacketQueueManager.prototype,
|
||||||
|
"length",
|
||||||
|
{get = function(self)
|
||||||
|
return self.size
|
||||||
|
end},
|
||||||
|
true
|
||||||
|
)
|
||||||
|
function KafkatorioPacketQueueManager.prototype.enqueue(self, packet)
|
||||||
|
local last = self.last
|
||||||
|
self.last = {value = packet}
|
||||||
|
if last ~= nil then
|
||||||
|
last.next = self.last
|
||||||
|
end
|
||||||
|
if self.first == nil then
|
||||||
|
self.first = self.last
|
||||||
|
end
|
||||||
|
self.size = self.size + 1
|
||||||
|
end
|
||||||
|
function KafkatorioPacketQueueManager.prototype.dequeue(self)
|
||||||
|
local first = self.first
|
||||||
|
if first == nil then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
self.first = first.next or nil
|
||||||
|
self.size = self.size - 1
|
||||||
|
return first.value
|
||||||
|
end
|
||||||
|
local KafkatorioPacketQueue = __TS__New(____exports.KafkatorioPacketQueueManager)
|
||||||
|
____exports.default = KafkatorioPacketQueue
|
||||||
|
return ____exports
|
||||||
|
|
@ -1,21 +1,20 @@
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
local ____PacketEmitter = require("main.PacketEmitter")
|
|
||||||
local PacketEmitter = ____PacketEmitter.default
|
|
||||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
local Type = KafkatorioPacketData.Type
|
local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue")
|
||||||
|
local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_console_chat,
|
defines.events.on_console_chat,
|
||||||
function(event)
|
function(event)
|
||||||
local update = {type = Type.ConsoleChatUpdate, authorPlayerIndex = event.player_index or nil, content = event.message}
|
local update = {type = KafkatorioPacketData.Type.ConsoleChatUpdate, authorPlayerIndex = event.player_index or nil, content = event.message}
|
||||||
PacketEmitter:emitInstantPacket(update)
|
KafkatorioPacketQueue:enqueue(update)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_console_command,
|
defines.events.on_console_command,
|
||||||
function(event)
|
function(event)
|
||||||
local update = {type = Type.ConsoleCommandUpdate, authorPlayerIndex = event.player_index or nil, command = event.command, parameters = event.parameters}
|
local update = {type = KafkatorioPacketData.Type.ConsoleCommandUpdate, authorPlayerIndex = event.player_index or nil, command = event.command, parameters = event.parameters}
|
||||||
PacketEmitter:emitInstantPacket(update)
|
KafkatorioPacketQueue:enqueue(update)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
return ____exports
|
return ____exports
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ local __TS__ArrayMap = ____lualib.__TS__ArrayMap
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
local ____PacketEmitter = require("main.PacketEmitter")
|
local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue")
|
||||||
local PacketEmitter = ____PacketEmitter.default
|
local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default
|
||||||
____exports.ConfigurationUpdateHandler = __TS__Class()
|
____exports.ConfigurationUpdateHandler = __TS__Class()
|
||||||
local ConfigurationUpdateHandler = ____exports.ConfigurationUpdateHandler
|
local ConfigurationUpdateHandler = ____exports.ConfigurationUpdateHandler
|
||||||
ConfigurationUpdateHandler.name = "ConfigurationUpdateHandler"
|
ConfigurationUpdateHandler.name = "ConfigurationUpdateHandler"
|
||||||
|
|
@ -24,7 +24,7 @@ function ConfigurationUpdateHandler.prototype.emitConfigurationUpdate(self, chan
|
||||||
allMods = ____exports.ConfigurationUpdateHandler:allMods(changeData),
|
allMods = ____exports.ConfigurationUpdateHandler:allMods(changeData),
|
||||||
factorioData = ____exports.ConfigurationUpdateHandler:factorioData(changeData)
|
factorioData = ____exports.ConfigurationUpdateHandler:factorioData(changeData)
|
||||||
}
|
}
|
||||||
PacketEmitter:emitInstantPacket(configUpdateData)
|
KafkatorioPacketQueue:enqueue(configUpdateData)
|
||||||
end
|
end
|
||||||
function ConfigurationUpdateHandler.factorioData(self, changeData)
|
function ConfigurationUpdateHandler.factorioData(self, changeData)
|
||||||
return {oldVersion = changeData.old_version or nil, newVersion = changeData.new_version or nil}
|
return {oldVersion = changeData.old_version or nil, newVersion = changeData.new_version or nil}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
local ____converters = require("main.events.converters")
|
local ____converters = require("main.events.converters")
|
||||||
local Converters = ____converters.Converters
|
local Converters = ____converters.Converters
|
||||||
local ____EventDataCache = require("main.cache.EventDataCache")
|
local ____EventDataCache = require("main.emitting.EventDataCache")
|
||||||
local EventDataCache = ____EventDataCache.default
|
local EventDataCache = ____EventDataCache.default
|
||||||
____exports.EntityUpdatesHandler = __TS__Class()
|
____exports.EntityUpdatesHandler = __TS__Class()
|
||||||
local EntityUpdatesHandler = ____exports.EntityUpdatesHandler
|
local EntityUpdatesHandler = ____exports.EntityUpdatesHandler
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ local ____eventTypeCheck = require("main.events.eventTypeCheck")
|
||||||
local isEventType = ____eventTypeCheck.isEventType
|
local isEventType = ____eventTypeCheck.isEventType
|
||||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
local ____EventDataCache = require("main.cache.EventDataCache")
|
local ____EventDataCache = require("main.emitting.EventDataCache")
|
||||||
local EventUpdatesManager = ____EventDataCache.default
|
local EventUpdates = ____EventDataCache.default
|
||||||
local MapChunkUpdateHandler = __TS__Class()
|
local MapChunkUpdateHandler = __TS__Class()
|
||||||
MapChunkUpdateHandler.name = "MapChunkUpdateHandler"
|
MapChunkUpdateHandler.name = "MapChunkUpdateHandler"
|
||||||
function MapChunkUpdateHandler.prototype.____constructor(self)
|
function MapChunkUpdateHandler.prototype.____constructor(self)
|
||||||
|
|
@ -124,7 +124,7 @@ function MapChunkUpdateHandler.prototype.handlePreChunkDeleted(self, event)
|
||||||
end
|
end
|
||||||
for ____, position in ipairs(event.positions) do
|
for ____, position in ipairs(event.positions) do
|
||||||
local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}}
|
local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}}
|
||||||
EventUpdatesManager:debounce(
|
EventUpdates:debounce(
|
||||||
key,
|
key,
|
||||||
KafkatorioPacketData.Type.MapChunkTileUpdate,
|
KafkatorioPacketData.Type.MapChunkTileUpdate,
|
||||||
function(data)
|
function(data)
|
||||||
|
|
@ -141,7 +141,7 @@ function MapChunkUpdateHandler.mapTilesUpdateDebounce(self, surface, chunkPositi
|
||||||
end
|
end
|
||||||
local eventName = Converters.eventNameString(event.name)
|
local eventName = Converters.eventNameString(event.name)
|
||||||
local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition}
|
local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition}
|
||||||
EventUpdatesManager:debounce(
|
EventUpdates:debounce(
|
||||||
key,
|
key,
|
||||||
KafkatorioPacketData.Type.MapChunkTileUpdate,
|
KafkatorioPacketData.Type.MapChunkTileUpdate,
|
||||||
function(data)
|
function(data)
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
local ____converters = require("main.events.converters")
|
local ____converters = require("main.events.converters")
|
||||||
local Converters = ____converters.Converters
|
local Converters = ____converters.Converters
|
||||||
local ____EventDataCache = require("main.cache.EventDataCache")
|
local ____EventDataCache = require("main.emitting.EventDataCache")
|
||||||
local EventUpdatesManager = ____EventDataCache.default
|
local EventUpdates = ____EventDataCache.default
|
||||||
____exports.PlayerUpdateHandler = __TS__Class()
|
____exports.PlayerUpdateHandler = __TS__Class()
|
||||||
local PlayerUpdateHandler = ____exports.PlayerUpdateHandler
|
local PlayerUpdateHandler = ____exports.PlayerUpdateHandler
|
||||||
PlayerUpdateHandler.name = "PlayerUpdateHandler"
|
PlayerUpdateHandler.name = "PlayerUpdateHandler"
|
||||||
|
|
@ -31,7 +31,7 @@ function PlayerUpdateHandler.prototype.playerUpdateThrottle(self, event, mutate,
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local eventName = Converters.eventNameString(event.name)
|
local eventName = Converters.eventNameString(event.name)
|
||||||
EventUpdatesManager:throttle(
|
EventUpdates:throttle(
|
||||||
{index = playerIndex},
|
{index = playerIndex},
|
||||||
KafkatorioPacketData.Type.PlayerUpdate,
|
KafkatorioPacketData.Type.PlayerUpdate,
|
||||||
function(data)
|
function(data)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ local ____converters = require("main.events.converters")
|
||||||
local Converters = ____converters.Converters
|
local Converters = ____converters.Converters
|
||||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
local ____PacketEmitter = require("main.PacketEmitter")
|
local ____PacketEmitter = require("main.emitting.PacketEmitter")
|
||||||
local packetEmitter = ____PacketEmitter.default
|
local packetEmitter = ____PacketEmitter.default
|
||||||
local ____PlayerUpdateHandler = require("main.events.handlers.PlayerUpdateHandler")
|
local ____PlayerUpdateHandler = require("main.events.handlers.PlayerUpdateHandler")
|
||||||
local PlayerUpdates = ____PlayerUpdateHandler.default
|
local PlayerUpdates = ____PlayerUpdateHandler.default
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,21 @@
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
local emit, getMapTilePrototypes, getEntityPrototypes, convertItemGroup, convertItemSubgroup
|
local emit, getMapTilePrototypes, getEntityPrototypes, convertItemGroup, convertItemSubgroup
|
||||||
local ____PacketEmitter = require("main.PacketEmitter")
|
|
||||||
local PacketEmitter = ____PacketEmitter.default
|
|
||||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
local FactorioPrototype = ____kafkatorio_2Dschema.FactorioPrototype
|
local FactorioPrototype = ____kafkatorio_2Dschema.FactorioPrototype
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
local ____converters = require("main.events.converters")
|
local ____converters = require("main.events.converters")
|
||||||
local Converters = ____converters.Converters
|
local Converters = ____converters.Converters
|
||||||
|
local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue")
|
||||||
|
local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default
|
||||||
function emit(protosByType)
|
function emit(protosByType)
|
||||||
for ____, protos in pairs(protosByType) do
|
for ____, protos in pairs(protosByType) do
|
||||||
PacketEmitter:emitInstantPacket({type = KafkatorioPacketData.Type.PrototypesUpdate, prototypes = protos})
|
KafkatorioPacketQueue:enqueue({type = KafkatorioPacketData.Type.PrototypesUpdate, prototypes = protos})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function getMapTilePrototypes()
|
function getMapTilePrototypes()
|
||||||
local tiles = {}
|
local tiles = {}
|
||||||
if not (tiles.tile ~= nil) then
|
|
||||||
tiles.tile = {}
|
|
||||||
end
|
|
||||||
for ____, tile in pairs(game.tile_prototypes) do
|
for ____, tile in pairs(game.tile_prototypes) do
|
||||||
local ____tiles_tile_0 = tiles.tile
|
tiles[#tiles + 1] = {
|
||||||
____tiles_tile_0[#____tiles_tile_0 + 1] = {
|
|
||||||
type = FactorioPrototype.Type.MapTile,
|
type = FactorioPrototype.Type.MapTile,
|
||||||
protoId = Converters.prototypeId("tile", tile.name),
|
protoId = Converters.prototypeId("tile", tile.name),
|
||||||
order = tile.order,
|
order = tile.order,
|
||||||
|
|
@ -29,13 +25,13 @@ function getMapTilePrototypes()
|
||||||
canBeMined = tile.mineable_properties.minable
|
canBeMined = tile.mineable_properties.minable
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
return tiles
|
return {tiles = tiles}
|
||||||
end
|
end
|
||||||
function getEntityPrototypes()
|
function getEntityPrototypes()
|
||||||
local protos = {}
|
local protos = {}
|
||||||
for ____, entity in pairs(game.entity_prototypes) do
|
for ____, entity in pairs(game.entity_prototypes) do
|
||||||
local key = (entity.group.name .. "/") .. entity.subgroup.name
|
local key = (entity.group.name .. "/") .. entity.subgroup.name
|
||||||
if not (protos[key] ~= nil) then
|
if protos[key] == nil then
|
||||||
protos[key] = {}
|
protos[key] = {}
|
||||||
end
|
end
|
||||||
local entityProto = {
|
local entityProto = {
|
||||||
|
|
@ -58,8 +54,8 @@ function getEntityPrototypes()
|
||||||
entityProto.mapColourEnemy = Converters.mapColour(entity.enemy_map_color)
|
entityProto.mapColourEnemy = Converters.mapColour(entity.enemy_map_color)
|
||||||
end
|
end
|
||||||
entityProto.miningProperties = Converters.miningProperties(entity.mineable_properties)
|
entityProto.miningProperties = Converters.miningProperties(entity.mineable_properties)
|
||||||
local ____protos_key_1 = protos[key]
|
local ____protos_key_0 = protos[key]
|
||||||
____protos_key_1[#____protos_key_1 + 1] = entityProto
|
____protos_key_0[#____protos_key_0 + 1] = entityProto
|
||||||
end
|
end
|
||||||
return protos
|
return protos
|
||||||
end
|
end
|
||||||
|
|
@ -67,19 +63,17 @@ function convertItemGroup(itemGroup)
|
||||||
return {name = itemGroup.name, type = itemGroup.type, parentName = nil}
|
return {name = itemGroup.name, type = itemGroup.type, parentName = nil}
|
||||||
end
|
end
|
||||||
function convertItemSubgroup(itemGroup)
|
function convertItemSubgroup(itemGroup)
|
||||||
local ____itemGroup_name_4 = itemGroup.name
|
local ____itemGroup_name_3 = itemGroup.name
|
||||||
local ____itemGroup_type_5 = itemGroup.type
|
local ____itemGroup_type_4 = itemGroup.type
|
||||||
local ____itemGroup_group_name_2 = itemGroup.group
|
local ____itemGroup_group_name_1 = itemGroup.group
|
||||||
if ____itemGroup_group_name_2 ~= nil then
|
if ____itemGroup_group_name_1 ~= nil then
|
||||||
____itemGroup_group_name_2 = ____itemGroup_group_name_2.name
|
____itemGroup_group_name_1 = ____itemGroup_group_name_1.name
|
||||||
end
|
end
|
||||||
return {name = ____itemGroup_name_4, type = ____itemGroup_type_5, parentName = ____itemGroup_group_name_2}
|
return {name = ____itemGroup_name_3, type = ____itemGroup_type_4, parentName = ____itemGroup_group_name_1}
|
||||||
end
|
end
|
||||||
function ____exports.emitPrototypes()
|
function ____exports.emitPrototypes()
|
||||||
local mapTileProtos = getMapTilePrototypes()
|
local mapTileProtos = getMapTilePrototypes()
|
||||||
emit(mapTileProtos)
|
emit(mapTileProtos)
|
||||||
local ____ = game.item_group_prototypes
|
|
||||||
local ____ = game.item_subgroup_prototypes
|
|
||||||
local entityProtos = getEntityPrototypes()
|
local entityProtos = getEntityPrototypes()
|
||||||
emit(entityProtos)
|
emit(entityProtos)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
local ____queue = require("main.queue.queue")
|
|
||||||
local Queue = ____queue.Queue
|
|
||||||
local ____eventTypeCheck = require("main.events.eventTypeCheck")
|
local ____eventTypeCheck = require("main.events.eventTypeCheck")
|
||||||
local isEventType = ____eventTypeCheck.isEventType
|
local isEventType = ____eventTypeCheck.isEventType
|
||||||
local ____converters = require("main.events.converters")
|
local ____converters = require("main.events.converters")
|
||||||
local Converters = ____converters.Converters
|
local Converters = ____converters.Converters
|
||||||
local ____surfaceUpdates = require("main.events.surfaceUpdates")
|
local ____surfaceUpdates = require("main.events.surfaceUpdates")
|
||||||
local handleSurfaceUpdate = ____surfaceUpdates.handleSurfaceUpdate
|
local handleSurfaceUpdate = ____surfaceUpdates.handleSurfaceUpdate
|
||||||
local ____EventDataCache = require("main.cache.EventDataCache")
|
local ____EventDataCache = require("main.emitting.EventDataCache")
|
||||||
local EventCacheService = ____EventDataCache.default
|
local EventCacheService = ____EventDataCache.default
|
||||||
local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler")
|
local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler")
|
||||||
local MapChunkUpdate = ____MapChunkUpdateHandler.default
|
local MapChunkUpdate = ____MapChunkUpdateHandler.default
|
||||||
|
local ____queue = require("main.queue.queue")
|
||||||
|
local EventDataQueue = ____queue.default
|
||||||
|
local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue")
|
||||||
|
local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default
|
||||||
|
local ____PacketEmitter = require("main.emitting.PacketEmitter")
|
||||||
|
local PacketEmitter = ____PacketEmitter.default
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_tick,
|
defines.events.on_tick,
|
||||||
function(event)
|
function(event)
|
||||||
|
|
@ -23,6 +27,10 @@ script.on_event(
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
local kPacket = KafkatorioPacketQueue:dequeue()
|
||||||
|
if kPacket ~= nil then
|
||||||
|
PacketEmitter:emitInstantPacket(kPacket)
|
||||||
|
end
|
||||||
if event.tick % 6 == 0 then
|
if event.tick % 6 == 0 then
|
||||||
local emittedCount = EventCacheService:extractAndEmitExpiredPackets()
|
local emittedCount = EventCacheService:extractAndEmitExpiredPackets()
|
||||||
if emittedCount > 0 then
|
if emittedCount > 0 then
|
||||||
|
|
@ -30,9 +38,9 @@ script.on_event(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if event.tick % 7 == 0 then
|
if event.tick % 7 == 0 then
|
||||||
local events = Queue.dequeueValues(1)
|
local events = EventDataQueue:dequeueValues(1)
|
||||||
if #events > 0 then
|
if #events > 0 then
|
||||||
log((((("[on_tick:" .. tostring(event.tick)) .. "] dequeued ") .. tostring(#events)) .. " events, current size: ") .. tostring(Queue.size()))
|
log((((("[on_tick:" .. tostring(event.tick)) .. "] dequeued ") .. tostring(#events)) .. " events, current size: ") .. tostring(EventDataQueue:size()))
|
||||||
local i = 1
|
local i = 1
|
||||||
for ____, event in ipairs(events) do
|
for ____, event in ipairs(events) do
|
||||||
if isEventType(event, defines.events.on_chunk_generated) then
|
if isEventType(event, defines.events.on_chunk_generated) then
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
local ____PacketEmitter = require("main.PacketEmitter")
|
local ____PacketEmitter = require("main.emitting.PacketEmitter")
|
||||||
local PacketEmitter = ____PacketEmitter.default
|
local PacketEmitter = ____PacketEmitter.default
|
||||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
|
local ____EventDataCache = require("main.emitting.EventDataCache")
|
||||||
|
local EventUpdates = ____EventDataCache.default
|
||||||
local ____queue = require("main.queue.queue")
|
local ____queue = require("main.queue.queue")
|
||||||
local Queue = ____queue.Queue
|
local EventDataQueueManager = ____queue.EventDataQueueManager
|
||||||
local ____EventDataCache = require("main.cache.EventDataCache")
|
|
||||||
local EventUpdatesManager = ____EventDataCache.default
|
|
||||||
function ____exports.initGlobal(force)
|
function ____exports.initGlobal(force)
|
||||||
if force == nil then
|
if force == nil then
|
||||||
force = false
|
force = false
|
||||||
|
|
@ -10,8 +10,8 @@ function ____exports.initGlobal(force)
|
||||||
log(("Initialising Kafkatorio Global variables (force=" .. tostring(force)) .. ")...")
|
log(("Initialising Kafkatorio Global variables (force=" .. tostring(force)) .. ")...")
|
||||||
global.MOD_VERSION = script.active_mods[script.mod_name]
|
global.MOD_VERSION = script.active_mods[script.mod_name]
|
||||||
global.FACTORIO_VERSION = script.active_mods.base
|
global.FACTORIO_VERSION = script.active_mods.base
|
||||||
Queue.init(true)
|
EventDataQueueManager:init(true)
|
||||||
EventUpdatesManager:init(true)
|
EventUpdates:init(true)
|
||||||
log("Finished initialising Kafkatorio Global variables")
|
log("Finished initialising Kafkatorio Global variables")
|
||||||
end
|
end
|
||||||
return ____exports
|
return ____exports
|
||||||
|
|
|
||||||
|
|
@ -1,84 +1,87 @@
|
||||||
local ____lualib = require("lualib_bundle")
|
local ____lualib = require("lualib_bundle")
|
||||||
local __TS__New = ____lualib.__TS__New
|
|
||||||
local __TS__Class = ____lualib.__TS__Class
|
local __TS__Class = ____lualib.__TS__Class
|
||||||
|
local __TS__New = ____lualib.__TS__New
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
____exports.Queue = {}
|
local Node
|
||||||
local Queue = ____exports.Queue
|
____exports.EventDataQueueManager = __TS__Class()
|
||||||
do
|
local EventDataQueueManager = ____exports.EventDataQueueManager
|
||||||
local Node
|
EventDataQueueManager.name = "EventDataQueueManager"
|
||||||
function Queue.init(force)
|
function EventDataQueueManager.prototype.____constructor(self)
|
||||||
local isAnythingUndefined = global.store == nil or global.size == nil or global.head == nil or global.tail == nil
|
end
|
||||||
log(((("Initialising EventQueue globals (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")")
|
function EventDataQueueManager.init(self, force)
|
||||||
if force == true or isAnythingUndefined then
|
local isAnythingUndefined = global.store == nil or global.size == nil or global.head == nil or global.tail == nil
|
||||||
global.store = {}
|
log(((("Initialising EventDataQueueManager globals (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")")
|
||||||
global.head = nil
|
if force == true or isAnythingUndefined then
|
||||||
global.tail = nil
|
global.store = {}
|
||||||
global.size = 0
|
global.head = nil
|
||||||
end
|
global.tail = nil
|
||||||
log("Finished initialising EventQueue")
|
global.size = 0
|
||||||
end
|
end
|
||||||
function Queue.size()
|
log("Finished initialising EventDataQueueManager")
|
||||||
return global.size
|
end
|
||||||
|
function EventDataQueueManager.prototype.size(self)
|
||||||
|
return global.size
|
||||||
|
end
|
||||||
|
function EventDataQueueManager.prototype.enqueue(self, key, event, weight)
|
||||||
|
if weight == nil then
|
||||||
|
weight = 1
|
||||||
end
|
end
|
||||||
function Queue.enqueue(key, event, weight)
|
if global.store[key] ~= nil then
|
||||||
if weight == nil then
|
local node = __TS__New(Node, key, weight)
|
||||||
weight = 1
|
|
||||||
end
|
|
||||||
if global.store[key] ~= nil then
|
|
||||||
local node = __TS__New(Node, key, weight)
|
|
||||||
if global.head == nil then
|
|
||||||
global.head = node
|
|
||||||
end
|
|
||||||
if global.tail ~= nil then
|
|
||||||
global.tail.next = node
|
|
||||||
end
|
|
||||||
global.tail = node
|
|
||||||
global.size = global.size + 1
|
|
||||||
end
|
|
||||||
global.store[key] = event
|
|
||||||
end
|
|
||||||
function Queue.dequeue()
|
|
||||||
if global.head == nil then
|
if global.head == nil then
|
||||||
|
global.head = node
|
||||||
|
end
|
||||||
|
if global.tail ~= nil then
|
||||||
|
global.tail.next = node
|
||||||
|
end
|
||||||
|
global.tail = node
|
||||||
|
global.size = global.size + 1
|
||||||
|
end
|
||||||
|
global.store[key] = event
|
||||||
|
end
|
||||||
|
function EventDataQueueManager.prototype.dequeue(self)
|
||||||
|
if global.head == nil then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
local weight = global.head.weight
|
||||||
|
local storeKey = global.head.storeKey
|
||||||
|
global.head = global.head.next
|
||||||
|
global.size = global.size - 1
|
||||||
|
local storedPacket = global.store[storeKey]
|
||||||
|
global.store[storeKey] = nil
|
||||||
|
if storedPacket == nil then
|
||||||
return nil
|
return nil
|
||||||
else
|
else
|
||||||
local weight = global.head.weight
|
return {value = storedPacket, weight = weight}
|
||||||
local storeKey = global.head.storeKey
|
|
||||||
global.head = global.head.next
|
|
||||||
global.size = global.size - 1
|
|
||||||
local storedPacket = global.store[storeKey]
|
|
||||||
global.store[storeKey] = nil
|
|
||||||
if storedPacket == nil then
|
|
||||||
return nil
|
|
||||||
else
|
|
||||||
return {value = storedPacket, weight = weight}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function Queue.dequeueValues(targetWeight)
|
end
|
||||||
if targetWeight == nil then
|
function EventDataQueueManager.prototype.dequeueValues(self, targetWeight)
|
||||||
targetWeight = 50
|
if targetWeight == nil then
|
||||||
end
|
targetWeight = 50
|
||||||
local values = {}
|
end
|
||||||
local weight = 0
|
local values = {}
|
||||||
repeat
|
local weight = 0
|
||||||
do
|
repeat
|
||||||
local packet = Queue.dequeue()
|
do
|
||||||
if packet == nil then
|
local packet = self:dequeue()
|
||||||
break
|
if packet == nil then
|
||||||
else
|
break
|
||||||
weight = weight + packet.weight
|
else
|
||||||
values[#values + 1] = packet.value
|
weight = weight + packet.weight
|
||||||
end
|
values[#values + 1] = packet.value
|
||||||
end
|
end
|
||||||
until not (weight <= targetWeight)
|
end
|
||||||
return values
|
until not (weight <= targetWeight)
|
||||||
end
|
return values
|
||||||
Node = __TS__Class()
|
end
|
||||||
Node.name = "Node"
|
local EventDataQueue = __TS__New(____exports.EventDataQueueManager)
|
||||||
function Node.prototype.____constructor(self, storeKey, weight)
|
____exports.default = EventDataQueue
|
||||||
self.next = nil
|
Node = __TS__Class()
|
||||||
self.storeKey = storeKey
|
Node.name = "Node"
|
||||||
self.weight = weight
|
function Node.prototype.____constructor(self, storeKey, weight)
|
||||||
end
|
self.next = nil
|
||||||
|
self.storeKey = storeKey
|
||||||
|
self.weight = weight
|
||||||
end
|
end
|
||||||
return ____exports
|
return ____exports
|
||||||
|
|
|
||||||
|
|
@ -1,235 +0,0 @@
|
||||||
import KafkatorioSettings from "../settings/KafkatorioSettings";
|
|
||||||
import {KafkatorioKeyedPacketData} from "../types";
|
|
||||||
import packetEmitter from "../PacketEmitter";
|
|
||||||
|
|
||||||
export namespace EventUpdates {
|
|
||||||
|
|
||||||
|
|
||||||
declare const global: {
|
|
||||||
/** Map the hash of the key, as a string, a cache entry */
|
|
||||||
cache: LuaTable<string, CacheEntry<KafkatorioKeyedPacketData>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class Manager {
|
|
||||||
|
|
||||||
|
|
||||||
init(force?: boolean) {
|
|
||||||
|
|
||||||
const isAnythingUndefined = global.cache == undefined
|
|
||||||
|
|
||||||
log(`Initialising EventDataCache (force=${force}, isAnythingUndefined=${isAnythingUndefined})...`)
|
|
||||||
|
|
||||||
if (force == true || isAnythingUndefined) {
|
|
||||||
log("Initialising global.cache")
|
|
||||||
global.cache = new LuaTable<string, CacheEntry<KafkatorioKeyedPacketData>>()
|
|
||||||
}
|
|
||||||
log(`Finished initialising EventDataCache`)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the cache data without restarting the 'time-to-emit' countdown, so that the data won't
|
|
||||||
* be emitted more than once per {@link CacheEntry.expirationDurationTicks}.
|
|
||||||
*/
|
|
||||||
public throttle<PACKET extends KafkatorioKeyedPacketData>(
|
|
||||||
key: PacketKey<PACKET>,
|
|
||||||
type: PacketType<PACKET>,
|
|
||||||
mutate: CacheDataMutator<PACKET>,
|
|
||||||
expirationDurationTicks?: uint,
|
|
||||||
) {
|
|
||||||
this.update(key, type, mutate, false, expirationDurationTicks)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the cache data and reset the 'time-to-emit' countdown, so the data won't be emitted
|
|
||||||
* until there's an inactivity gap of {@link CacheEntry.expirationDurationTicks}.
|
|
||||||
*/
|
|
||||||
public debounce<PACKET extends KafkatorioKeyedPacketData>(
|
|
||||||
key: PacketKey<PACKET>,
|
|
||||||
type: PacketType<PACKET>,
|
|
||||||
mutate: CacheDataMutator<PACKET>,
|
|
||||||
expirationDurationTicks?: uint,
|
|
||||||
) {
|
|
||||||
this.update(key, type, mutate, true, expirationDurationTicks)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private update<PACKET extends KafkatorioKeyedPacketData>(
|
|
||||||
key: PacketKey<PACKET>,
|
|
||||||
type: PacketType<PACKET>,
|
|
||||||
mutate: CacheDataMutator<PACKET>,
|
|
||||||
resetLastUpdated: boolean,
|
|
||||||
expirationDurationTicks?: uint,
|
|
||||||
) {
|
|
||||||
const entry: CacheEntry<PACKET> = this.getCacheEntry(key, type) ??
|
|
||||||
Manager.createCacheEntry(key, type)
|
|
||||||
mutate(entry.packet)
|
|
||||||
if (resetLastUpdated) {
|
|
||||||
entry.lastUpdatedTick = game.tick
|
|
||||||
}
|
|
||||||
if (expirationDurationTicks != undefined) {
|
|
||||||
entry.expirationDurationTicks = expirationDurationTicks
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry.expirationDurationTicks != undefined && entry.expirationDurationTicks <= 0) {
|
|
||||||
this.extractAndEmitExpiredPackets()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Usage example: If an urgent update comes in, then the expiration can be reduced so that
|
|
||||||
* it's transmitted sooner.
|
|
||||||
*/
|
|
||||||
public setExpiration<PACKET extends KafkatorioKeyedPacketData>(
|
|
||||||
key: PacketKey<PACKET>,
|
|
||||||
type: PacketType<PACKET>,
|
|
||||||
expirationDurationTicks: uint,
|
|
||||||
) {
|
|
||||||
const entry = this.getCacheEntry(key, type)
|
|
||||||
if (entry != undefined) {
|
|
||||||
entry.expirationDurationTicks = expirationDurationTicks
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Removes all expired entries from the cache, and return them. */
|
|
||||||
// use in/out v4.7.0 https://github.com/microsoft/TypeScript/pull/48240
|
|
||||||
private extractExpired(): Array<KafkatorioKeyedPacketData> {
|
|
||||||
let countExpired = 0
|
|
||||||
let countTotal = 0
|
|
||||||
const expiredData: Array<KafkatorioKeyedPacketData> = []
|
|
||||||
for (const [key, entry] of global.cache) {
|
|
||||||
countTotal++
|
|
||||||
if (this.isExpired(entry)) {
|
|
||||||
countExpired++
|
|
||||||
expiredData.push(entry.packet)
|
|
||||||
global.cache.delete(key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const hasExpiredItems = countExpired > 0
|
|
||||||
const hasAnyItem = countTotal > 0
|
|
||||||
|
|
||||||
if (hasExpiredItems || (game.tick % 30 == 0 && hasAnyItem)) {
|
|
||||||
log(`[extractExpired] expired items: ${countExpired}, total: ${countTotal}`)
|
|
||||||
}
|
|
||||||
return expiredData
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes and emits all expired packets.
|
|
||||||
*
|
|
||||||
* @return the number of emitted packets
|
|
||||||
*/
|
|
||||||
public extractAndEmitExpiredPackets() {
|
|
||||||
const cachedEvents: Array<KafkatorioKeyedPacketData> = this.extractExpired()
|
|
||||||
|
|
||||||
if (cachedEvents.length > 0) {
|
|
||||||
log(`[EventDataCache] emitting ${cachedEvents.length} events on tick ${game.tick}`)
|
|
||||||
for (const event of cachedEvents) {
|
|
||||||
packetEmitter.emitKeyedPacket(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cachedEvents.length
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private getCacheEntry<PACKET extends KafkatorioKeyedPacketData>(
|
|
||||||
key: EventUpdates.PacketKey<PACKET>,
|
|
||||||
type: EventUpdates.PacketType<PACKET>,
|
|
||||||
): CacheEntry<PACKET> | undefined {
|
|
||||||
const hash = Manager.hashKey(key)
|
|
||||||
if (!global.cache.has(hash)) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
const value: CacheEntry<any> = global.cache.get(hash)
|
|
||||||
if (this.isEntryInstanceOf(value, type)) {
|
|
||||||
return value
|
|
||||||
} else {
|
|
||||||
// Type mismatch. This shouldn't happen...
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static createCacheEntry<PACKET extends KafkatorioKeyedPacketData>(
|
|
||||||
key: PacketKey<PACKET>,
|
|
||||||
type: PacketType<PACKET>,
|
|
||||||
): CacheEntry<PACKET> {
|
|
||||||
const data: PACKET = <PACKET>{
|
|
||||||
type: type,
|
|
||||||
key: key,
|
|
||||||
}
|
|
||||||
const entry: CacheEntry<PACKET> = new CacheEntry<PACKET>(data)
|
|
||||||
const hash = Manager.hashKey(key)
|
|
||||||
global.cache.set(hash, entry)
|
|
||||||
return entry
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
isExpired<TYPE extends KafkatorioKeyedPacketData>(entry: CacheEntry<TYPE>): boolean {
|
|
||||||
const expiryDuration =
|
|
||||||
entry.expirationDurationTicks
|
|
||||||
?? KafkatorioSettings.getEventCacheExpirationTicks(entry.packet)
|
|
||||||
|
|
||||||
if (expiryDuration == undefined) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return game.tick - entry.lastUpdatedTick > expiryDuration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
isEntryInstanceOf<PACKET extends KafkatorioKeyedPacketData>(
|
|
||||||
entry: CacheEntry<any> | undefined,
|
|
||||||
type: EventUpdates.PacketType<PACKET>,
|
|
||||||
): entry is CacheEntry<PACKET> {
|
|
||||||
return this.isDataInstanceOf(entry?.packet, type)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
isDataInstanceOf<PACKET extends KafkatorioKeyedPacketData>(
|
|
||||||
packet: PACKET | undefined,
|
|
||||||
type: EventUpdates.PacketType<PACKET>,
|
|
||||||
): packet is PACKET {
|
|
||||||
return packet != undefined && packet.type == type
|
|
||||||
}
|
|
||||||
|
|
||||||
private static hashKey<PACKET extends KafkatorioKeyedPacketData>(
|
|
||||||
key: PacketKey<PACKET>,
|
|
||||||
): string {
|
|
||||||
return game.encode_string(game.table_to_json(key))!!
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PacketKey<PACKET extends KafkatorioKeyedPacketData> = PACKET["key"]
|
|
||||||
export type PacketType<PACKET extends KafkatorioKeyedPacketData> = PACKET["type"]
|
|
||||||
|
|
||||||
export type CacheDataMutator<PACKET extends KafkatorioKeyedPacketData> = (packet: PACKET) => void
|
|
||||||
|
|
||||||
class CacheEntry<PACKET extends KafkatorioKeyedPacketData> {
|
|
||||||
lastUpdatedTick: uint = game.tick
|
|
||||||
expirationDurationTicks?: uint
|
|
||||||
|
|
||||||
packet: PACKET
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
packet: PACKET,
|
|
||||||
expirationDurationTicks?: uint,
|
|
||||||
) {
|
|
||||||
|
|
||||||
this.packet = packet
|
|
||||||
this.expirationDurationTicks = expirationDurationTicks
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const EventUpdatesManager = new EventUpdates.Manager()
|
|
||||||
|
|
||||||
export default EventUpdatesManager
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import {initGlobal} from "../global-init";
|
import {initGlobal} from "../global-init";
|
||||||
import {Queue} from "../queue/queue";
|
|
||||||
import {emitPrototypes} from "../events/prototypeUpdates";
|
import {emitPrototypes} from "../events/prototypeUpdates";
|
||||||
|
import EventDataQueue from "../queue/queue";
|
||||||
|
|
||||||
|
|
||||||
commands.add_command(
|
commands.add_command(
|
||||||
|
|
@ -58,7 +58,7 @@ commands.add_command(
|
||||||
tick: e.tick,
|
tick: e.tick,
|
||||||
}
|
}
|
||||||
|
|
||||||
Queue.enqueue(
|
EventDataQueue.enqueue(
|
||||||
`${surface.index}${chunk.x}${chunk.y}`,
|
`${surface.index}${chunk.x}${chunk.y}`,
|
||||||
data,
|
data,
|
||||||
50
|
50
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,240 @@
|
||||||
|
import KafkatorioSettings from "../settings/KafkatorioSettings";
|
||||||
|
import {KafkatorioKeyedPacketData} from "../types";
|
||||||
|
import PacketEmitter from "./PacketEmitter";
|
||||||
|
|
||||||
|
|
||||||
|
declare const global: {
|
||||||
|
/** Map the hash of the key, as a string, a cache entry */
|
||||||
|
eventUpdatesManagerCache: LuaTable<string, CacheEntry<KafkatorioKeyedPacketData>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class EventUpdatesManager {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
init(force?: boolean) {
|
||||||
|
|
||||||
|
const isAnythingUndefined = global.eventUpdatesManagerCache == undefined
|
||||||
|
|
||||||
|
log(`Initialising EventDataCache (force=${force}, isAnythingUndefined=${isAnythingUndefined})...`)
|
||||||
|
|
||||||
|
if (force == true || isAnythingUndefined) {
|
||||||
|
log("Initialising global.cache")
|
||||||
|
global.eventUpdatesManagerCache = new LuaTable<string, CacheEntry<KafkatorioKeyedPacketData>>()
|
||||||
|
}
|
||||||
|
log(`Finished initialising EventDataCache`)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the cache data without restarting the 'time-to-emit' countdown, so that the data won't
|
||||||
|
* be emitted more than once per {@link CacheEntry.expirationDurationTicks}.
|
||||||
|
*/
|
||||||
|
public throttle<PACKET extends KafkatorioKeyedPacketData>(
|
||||||
|
key: PacketKey<PACKET>,
|
||||||
|
type: PacketType<PACKET>,
|
||||||
|
mutate: CacheDataMutator<PACKET>,
|
||||||
|
expirationDurationTicks?: uint,
|
||||||
|
) {
|
||||||
|
this.update(key, type, mutate, false, expirationDurationTicks)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the cache data and reset the 'time-to-emit' countdown, so the data won't be emitted
|
||||||
|
* until there's an inactivity gap of {@link CacheEntry.expirationDurationTicks}.
|
||||||
|
*/
|
||||||
|
public debounce<PACKET extends KafkatorioKeyedPacketData>(
|
||||||
|
key: PacketKey<PACKET>,
|
||||||
|
type: PacketType<PACKET>,
|
||||||
|
mutate: CacheDataMutator<PACKET>,
|
||||||
|
expirationDurationTicks?: uint,
|
||||||
|
) {
|
||||||
|
this.update(key, type, mutate, true, expirationDurationTicks)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private update<PACKET extends KafkatorioKeyedPacketData>(
|
||||||
|
key: PacketKey<PACKET>,
|
||||||
|
type: PacketType<PACKET>,
|
||||||
|
mutate: CacheDataMutator<PACKET>,
|
||||||
|
resetLastUpdated: boolean,
|
||||||
|
expirationDurationTicks?: uint,
|
||||||
|
) {
|
||||||
|
const entry: CacheEntry<PACKET> = this.getCacheEntry(key, type) ??
|
||||||
|
EventUpdatesManager.createCacheEntry(key, type)
|
||||||
|
mutate(entry.packet)
|
||||||
|
if (resetLastUpdated) {
|
||||||
|
entry.lastUpdatedTick = game.tick
|
||||||
|
}
|
||||||
|
if (expirationDurationTicks != undefined) {
|
||||||
|
entry.expirationDurationTicks = expirationDurationTicks
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.expirationDurationTicks != undefined && entry.expirationDurationTicks <= 0) {
|
||||||
|
this.extractAndEmitExpiredPackets()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage example: If an urgent update comes in, then the expiration can be reduced so that
|
||||||
|
* it's transmitted sooner.
|
||||||
|
*/
|
||||||
|
public setExpiration<PACKET extends KafkatorioKeyedPacketData>(
|
||||||
|
key: PacketKey<PACKET>,
|
||||||
|
type: PacketType<PACKET>,
|
||||||
|
expirationDurationTicks: uint,
|
||||||
|
) {
|
||||||
|
const entry = this.getCacheEntry(key, type)
|
||||||
|
if (entry != undefined) {
|
||||||
|
entry.expirationDurationTicks = expirationDurationTicks
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Removes all expired entries from the cache, and return them. */
|
||||||
|
// use in/out v4.7.0 https://github.com/microsoft/TypeScript/pull/48240
|
||||||
|
private extractExpired(): Array<KafkatorioKeyedPacketData> {
|
||||||
|
let countExpired = 0
|
||||||
|
let countTotal = 0
|
||||||
|
const expiredData: Array<KafkatorioKeyedPacketData> = []
|
||||||
|
for (const [key, entry] of global.eventUpdatesManagerCache) {
|
||||||
|
countTotal++
|
||||||
|
if (this.isExpired(entry)) {
|
||||||
|
countExpired++
|
||||||
|
expiredData.push(entry.packet)
|
||||||
|
global.eventUpdatesManagerCache.delete(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasExpiredItems = countExpired > 0
|
||||||
|
const hasAnyItem = countTotal > 0
|
||||||
|
|
||||||
|
if (hasExpiredItems || (game.tick % 30 == 0 && hasAnyItem)) {
|
||||||
|
log(`[extractExpired] expired items: ${countExpired}, total: ${countTotal}`)
|
||||||
|
}
|
||||||
|
return expiredData
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes and emits all expired packets.
|
||||||
|
*
|
||||||
|
* @return the number of emitted packets
|
||||||
|
*/
|
||||||
|
public extractAndEmitExpiredPackets() {
|
||||||
|
const cachedEvents: Array<KafkatorioKeyedPacketData> = this.extractExpired()
|
||||||
|
|
||||||
|
if (cachedEvents.length > 0) {
|
||||||
|
log(`[EventDataCache] emitting ${cachedEvents.length} events on tick ${game.tick}`)
|
||||||
|
for (const event of cachedEvents) {
|
||||||
|
PacketEmitter.emitKeyedPacket(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cachedEvents.length
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private getCacheEntry<PACKET extends KafkatorioKeyedPacketData>(
|
||||||
|
key: PacketKey<PACKET>,
|
||||||
|
type: PacketType<PACKET>,
|
||||||
|
): CacheEntry<PACKET> | undefined {
|
||||||
|
const hash = EventUpdatesManager.hashKey(key)
|
||||||
|
if (!global.eventUpdatesManagerCache.has(hash)) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
const value: CacheEntry<any> = global.eventUpdatesManagerCache.get(hash)
|
||||||
|
if (this.isEntryInstanceOf(value, type)) {
|
||||||
|
return value
|
||||||
|
} else {
|
||||||
|
// Type mismatch. This shouldn't happen...
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static createCacheEntry<PACKET extends KafkatorioKeyedPacketData>(
|
||||||
|
key: PacketKey<PACKET>,
|
||||||
|
type: PacketType<PACKET>,
|
||||||
|
): CacheEntry<PACKET> {
|
||||||
|
const data: PACKET = <PACKET>{
|
||||||
|
type: type,
|
||||||
|
key: key,
|
||||||
|
}
|
||||||
|
const entry: CacheEntry<PACKET> = new CacheEntry<PACKET>(data)
|
||||||
|
const hash = EventUpdatesManager.hashKey(key)
|
||||||
|
global.eventUpdatesManagerCache.set(hash, entry)
|
||||||
|
return entry
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
isExpired<TYPE extends KafkatorioKeyedPacketData>(entry: CacheEntry<TYPE>): boolean {
|
||||||
|
const expiryDuration =
|
||||||
|
entry.expirationDurationTicks
|
||||||
|
?? KafkatorioSettings.getEventCacheExpirationTicks(entry.packet)
|
||||||
|
|
||||||
|
if (expiryDuration == undefined) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return game.tick - entry.lastUpdatedTick > expiryDuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
isEntryInstanceOf<PACKET extends KafkatorioKeyedPacketData>(
|
||||||
|
entry: CacheEntry<any> | undefined,
|
||||||
|
type: PacketType<PACKET>,
|
||||||
|
): entry is CacheEntry<PACKET> {
|
||||||
|
return this.isDataInstanceOf(entry?.packet, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
isDataInstanceOf<PACKET extends KafkatorioKeyedPacketData>(
|
||||||
|
packet: PACKET | undefined,
|
||||||
|
type: PacketType<PACKET>,
|
||||||
|
): packet is PACKET {
|
||||||
|
return packet != undefined && packet.type == type
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static hashKey<PACKET extends KafkatorioKeyedPacketData>(
|
||||||
|
key: PacketKey<PACKET>,
|
||||||
|
): string {
|
||||||
|
return game.encode_string(game.table_to_json(key))!!
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const EventUpdates = new EventUpdatesManager()
|
||||||
|
|
||||||
|
export default EventUpdates
|
||||||
|
|
||||||
|
|
||||||
|
export type PacketKey<PACKET extends KafkatorioKeyedPacketData> = PACKET["key"]
|
||||||
|
export type PacketType<PACKET extends KafkatorioKeyedPacketData> = PACKET["type"]
|
||||||
|
|
||||||
|
export type CacheDataMutator<PACKET extends KafkatorioKeyedPacketData> = (packet: PACKET) => void
|
||||||
|
|
||||||
|
|
||||||
|
class CacheEntry<PACKET extends KafkatorioKeyedPacketData> {
|
||||||
|
lastUpdatedTick: uint = game.tick
|
||||||
|
expirationDurationTicks?: uint
|
||||||
|
|
||||||
|
packet: PACKET
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
packet: PACKET,
|
||||||
|
expirationDurationTicks?: uint,
|
||||||
|
) {
|
||||||
|
|
||||||
|
this.packet = packet
|
||||||
|
this.expirationDurationTicks = expirationDurationTicks
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
import {KafkatorioPacketData} from "../../generated/kafkatorio-schema";
|
||||||
|
|
||||||
|
export class KafkatorioPacketQueueManager {
|
||||||
|
|
||||||
|
private size: int = 0
|
||||||
|
private first: Node<any> | null = null
|
||||||
|
private last: Node<any> | null = null
|
||||||
|
|
||||||
|
public get length() {
|
||||||
|
return this.size
|
||||||
|
}
|
||||||
|
|
||||||
|
public enqueue<T extends KafkatorioPacketData>(packet: T) {
|
||||||
|
const last = this.last
|
||||||
|
this.last = {
|
||||||
|
value: packet
|
||||||
|
}
|
||||||
|
if (last != null) {
|
||||||
|
last.next = this.last
|
||||||
|
}
|
||||||
|
if (this.first == null) {
|
||||||
|
this.first = this.last
|
||||||
|
}
|
||||||
|
this.size++
|
||||||
|
}
|
||||||
|
|
||||||
|
public dequeue<T extends KafkatorioPacketData>(): T | null {
|
||||||
|
const first = this.first
|
||||||
|
|
||||||
|
if (first == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
this.first = first.next ?? null
|
||||||
|
this.size--
|
||||||
|
return first.value
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const KafkatorioPacketQueue = new KafkatorioPacketQueueManager()
|
||||||
|
|
||||||
|
export default KafkatorioPacketQueue
|
||||||
|
|
||||||
|
interface Node<T extends KafkatorioPacketData> {
|
||||||
|
value: T
|
||||||
|
next?: Node<T>
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
import {
|
import {KafkatorioPacket, KafkatorioPacketData} from "../../generated/kafkatorio-schema";
|
||||||
KafkatorioPacket,
|
import {KafkatorioKeyedPacketData} from "../types";
|
||||||
KafkatorioPacketData
|
|
||||||
} from "../generated/kafkatorio-schema";
|
|
||||||
import {KafkatorioKeyedPacketData} from "./types";
|
|
||||||
|
|
||||||
|
|
||||||
export class KafkatorioPacketEmitter {
|
export class KafkatorioPacketEmitter {
|
||||||
|
|
@ -1,33 +1,26 @@
|
||||||
import PacketEmitter from "../PacketEmitter";
|
|
||||||
import {KafkatorioPacketData} from "../../generated/kafkatorio-schema";
|
import {KafkatorioPacketData} from "../../generated/kafkatorio-schema";
|
||||||
import Type = KafkatorioPacketData.Type;
|
import KafkatorioPacketQueue from "../emitting/KafkatorioPacketQueue";
|
||||||
|
|
||||||
|
|
||||||
script.on_event(
|
script.on_event(defines.events.on_console_chat, (event: OnConsoleChatEvent) => {
|
||||||
defines.events.on_console_chat,
|
const update: KafkatorioPacketData.ConsoleChatUpdate = {
|
||||||
(event: OnConsoleChatEvent) => {
|
type: KafkatorioPacketData.Type.ConsoleChatUpdate,
|
||||||
const update: KafkatorioPacketData.ConsoleChatUpdate = {
|
|
||||||
type: Type.ConsoleChatUpdate,
|
|
||||||
|
|
||||||
authorPlayerIndex: event.player_index ?? null,
|
authorPlayerIndex: event.player_index ?? null,
|
||||||
content: event.message
|
content: event.message
|
||||||
}
|
}
|
||||||
PacketEmitter.emitInstantPacket(update)
|
KafkatorioPacketQueue.enqueue(update)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
script.on_event(
|
script.on_event(defines.events.on_console_command, (event: OnConsoleCommandEvent) => {
|
||||||
defines.events.on_console_command,
|
const update: KafkatorioPacketData.ConsoleCommandUpdate = {
|
||||||
(event: OnConsoleCommandEvent) => {
|
type: KafkatorioPacketData.Type.ConsoleCommandUpdate,
|
||||||
const update: KafkatorioPacketData.ConsoleCommandUpdate = {
|
|
||||||
type: Type.ConsoleCommandUpdate,
|
|
||||||
|
|
||||||
authorPlayerIndex: event.player_index ?? null,
|
authorPlayerIndex: event.player_index ?? null,
|
||||||
command: event.command,
|
command: event.command,
|
||||||
parameters: event.parameters,
|
parameters: event.parameters,
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketEmitter.emitInstantPacket(update)
|
KafkatorioPacketQueue.enqueue(update)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,9 @@ import {
|
||||||
ConfigurationUpdateModData,
|
ConfigurationUpdateModData,
|
||||||
KafkatorioPacketData
|
KafkatorioPacketData
|
||||||
} from "../../../generated/kafkatorio-schema";
|
} from "../../../generated/kafkatorio-schema";
|
||||||
import PacketEmitter from "../../PacketEmitter";
|
import PacketEmitter from "../../emitting/PacketEmitter";
|
||||||
import ConfigurationUpdate = KafkatorioPacketData.ConfigurationUpdate;
|
import ConfigurationUpdate = KafkatorioPacketData.ConfigurationUpdate;
|
||||||
|
import KafkatorioPacketQueue from "../../emitting/KafkatorioPacketQueue";
|
||||||
|
|
||||||
|
|
||||||
export class ConfigurationUpdateHandler {
|
export class ConfigurationUpdateHandler {
|
||||||
|
|
@ -20,7 +21,7 @@ export class ConfigurationUpdateHandler {
|
||||||
factorioData: ConfigurationUpdateHandler.factorioData(changeData)
|
factorioData: ConfigurationUpdateHandler.factorioData(changeData)
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketEmitter.emitInstantPacket(configUpdateData)
|
KafkatorioPacketQueue.enqueue(configUpdateData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import {
|
||||||
Tick
|
Tick
|
||||||
} from "../../../generated/kafkatorio-schema";
|
} from "../../../generated/kafkatorio-schema";
|
||||||
import {Converters} from "../converters";
|
import {Converters} from "../converters";
|
||||||
import EventDataCache from "../../cache/EventDataCache";
|
import EventDataCache from "../../emitting/EventDataCache";
|
||||||
|
|
||||||
|
|
||||||
export class EntityUpdatesHandler {
|
export class EntityUpdatesHandler {
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,11 @@ import {isEventType} from "../eventTypeCheck";
|
||||||
import {
|
import {
|
||||||
KafkatorioPacketData,
|
KafkatorioPacketData,
|
||||||
MapChunkPosition,
|
MapChunkPosition,
|
||||||
MinedProduct,
|
|
||||||
PrototypeKey
|
PrototypeKey
|
||||||
} from "../../../generated/kafkatorio-schema";
|
} from "../../../generated/kafkatorio-schema";
|
||||||
import EventUpdatesManager, {EventUpdates} from "../../cache/EventDataCache";
|
import EventUpdates, {PacketKey} from "../../emitting/EventDataCache";
|
||||||
import {MapChunkUpdateEvent, MapTileChangeEvent} from "../mapChunkUpdates";
|
import {MapChunkUpdateEvent, MapTileChangeEvent} from "../mapChunkUpdates";
|
||||||
import PacketKey = EventUpdates.PacketKey;
|
|
||||||
import Type = MinedProduct.Type;
|
|
||||||
|
|
||||||
type MapChunkTileUpdater = (data: KafkatorioPacketData.MapChunkTileUpdate) => void
|
type MapChunkTileUpdater = (data: KafkatorioPacketData.MapChunkTileUpdate) => void
|
||||||
|
|
||||||
|
|
@ -141,7 +139,7 @@ class MapChunkUpdateHandler {
|
||||||
chunkPosition: [position.x, position.y],
|
chunkPosition: [position.x, position.y],
|
||||||
}
|
}
|
||||||
|
|
||||||
EventUpdatesManager.debounce<KafkatorioPacketData.MapChunkTileUpdate>(
|
EventUpdates.debounce<KafkatorioPacketData.MapChunkTileUpdate>(
|
||||||
key,
|
key,
|
||||||
KafkatorioPacketData.Type.MapChunkTileUpdate,
|
KafkatorioPacketData.Type.MapChunkTileUpdate,
|
||||||
data => data.isDeleted = true,
|
data => data.isDeleted = true,
|
||||||
|
|
@ -171,7 +169,7 @@ class MapChunkUpdateHandler {
|
||||||
chunkPosition: chunkPosition,
|
chunkPosition: chunkPosition,
|
||||||
}
|
}
|
||||||
|
|
||||||
EventUpdatesManager.debounce<KafkatorioPacketData.MapChunkTileUpdate>(
|
EventUpdates.debounce<KafkatorioPacketData.MapChunkTileUpdate>(
|
||||||
key,
|
key,
|
||||||
KafkatorioPacketData.Type.MapChunkTileUpdate,
|
KafkatorioPacketData.Type.MapChunkTileUpdate,
|
||||||
data => {
|
data => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import {KafkatorioPacketData} from "../../../generated/kafkatorio-schema";
|
import {KafkatorioPacketData} from "../../../generated/kafkatorio-schema";
|
||||||
import {Converters} from "../converters";
|
import {Converters} from "../converters";
|
||||||
import EventUpdatesManager from "../../cache/EventDataCache";
|
import EventUpdates from "../../emitting/EventDataCache";
|
||||||
|
|
||||||
|
|
||||||
export type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void
|
export type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void
|
||||||
|
|
@ -43,7 +43,7 @@ export class PlayerUpdateHandler {
|
||||||
|
|
||||||
const eventName = Converters.eventNameString(event.name)
|
const eventName = Converters.eventNameString(event.name)
|
||||||
|
|
||||||
EventUpdatesManager.throttle<KafkatorioPacketData.PlayerUpdate>(
|
EventUpdates.throttle<KafkatorioPacketData.PlayerUpdate>(
|
||||||
{index: playerIndex},
|
{index: playerIndex},
|
||||||
KafkatorioPacketData.Type.PlayerUpdate,
|
KafkatorioPacketData.Type.PlayerUpdate,
|
||||||
data => {
|
data => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import {Converters} from "./converters";
|
import {Converters} from "./converters";
|
||||||
import {ForceIndex, KafkatorioPacketData, PlayerUpdateKey} from "../../generated/kafkatorio-schema";
|
import {ForceIndex, KafkatorioPacketData, PlayerUpdateKey} from "../../generated/kafkatorio-schema";
|
||||||
import packetEmitter from "../PacketEmitter";
|
import packetEmitter from "../emitting/PacketEmitter";
|
||||||
import PlayerUpdates from "./handlers/PlayerUpdateHandler";
|
import PlayerUpdates from "./handlers/PlayerUpdateHandler";
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
import PacketEmitter from "../PacketEmitter";
|
import PacketEmitter from "../emitting/PacketEmitter";
|
||||||
import {
|
import {
|
||||||
EntityItemGroup,
|
EntityItemGroup,
|
||||||
FactorioPrototype,
|
FactorioPrototype,
|
||||||
KafkatorioPacketData
|
KafkatorioPacketData
|
||||||
} from "../../generated/kafkatorio-schema";
|
} from "../../generated/kafkatorio-schema";
|
||||||
import {Converters} from "./converters";
|
import {Converters} from "./converters";
|
||||||
|
import KafkatorioPacketQueue from "../emitting/KafkatorioPacketQueue";
|
||||||
|
|
||||||
|
|
||||||
type PrototypesByType<T extends FactorioPrototype> = LuaTable<string, T[]>
|
type PrototypesByType<T extends FactorioPrototype> = Record<string, T[]>
|
||||||
|
|
||||||
|
|
||||||
export function emitPrototypes() {
|
export function emitPrototypes() {
|
||||||
|
|
@ -16,10 +17,6 @@ export function emitPrototypes() {
|
||||||
emit(mapTileProtos)
|
emit(mapTileProtos)
|
||||||
|
|
||||||
|
|
||||||
game.item_group_prototypes
|
|
||||||
game.item_subgroup_prototypes
|
|
||||||
|
|
||||||
|
|
||||||
const entityProtos: PrototypesByType<FactorioPrototype.Entity> = getEntityPrototypes()
|
const entityProtos: PrototypesByType<FactorioPrototype.Entity> = getEntityPrototypes()
|
||||||
emit(entityProtos)
|
emit(entityProtos)
|
||||||
}
|
}
|
||||||
|
|
@ -27,7 +24,7 @@ export function emitPrototypes() {
|
||||||
|
|
||||||
function emit<T extends FactorioPrototype>(protosByType: PrototypesByType<T>) {
|
function emit<T extends FactorioPrototype>(protosByType: PrototypesByType<T>) {
|
||||||
for (const [, protos] of pairs(protosByType)) {
|
for (const [, protos] of pairs(protosByType)) {
|
||||||
PacketEmitter.emitInstantPacket({
|
KafkatorioPacketQueue.enqueue({
|
||||||
type: KafkatorioPacketData.Type.PrototypesUpdate,
|
type: KafkatorioPacketData.Type.PrototypesUpdate,
|
||||||
prototypes: protos,
|
prototypes: protos,
|
||||||
})
|
})
|
||||||
|
|
@ -36,13 +33,10 @@ function emit<T extends FactorioPrototype>(protosByType: PrototypesByType<T>) {
|
||||||
|
|
||||||
|
|
||||||
function getMapTilePrototypes(): PrototypesByType<FactorioPrototype.MapTile> {
|
function getMapTilePrototypes(): PrototypesByType<FactorioPrototype.MapTile> {
|
||||||
const tiles = new LuaTable<string, FactorioPrototype.MapTile[]>()
|
const tiles: FactorioPrototype.MapTile[] = []
|
||||||
if (!tiles.has("tile")) {
|
|
||||||
tiles.set("tile", [])
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [, tile] of game.tile_prototypes) {
|
for (const [, tile] of game.tile_prototypes) {
|
||||||
tiles.get("tile").push({
|
tiles[tiles.length] = {
|
||||||
type: FactorioPrototype.Type.MapTile,
|
type: FactorioPrototype.Type.MapTile,
|
||||||
|
|
||||||
protoId: Converters.prototypeId("tile", tile.name),
|
protoId: Converters.prototypeId("tile", tile.name),
|
||||||
|
|
@ -51,21 +45,22 @@ function getMapTilePrototypes(): PrototypesByType<FactorioPrototype.MapTile> {
|
||||||
collisionMasks: Converters.convertCollisionMaskToNames(tile.collision_mask),
|
collisionMasks: Converters.convertCollisionMaskToNames(tile.collision_mask),
|
||||||
mapColour: Converters.mapColour(tile.map_color),
|
mapColour: Converters.mapColour(tile.map_color),
|
||||||
canBeMined: tile.mineable_properties.minable,
|
canBeMined: tile.mineable_properties.minable,
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"tiles": tiles
|
||||||
}
|
}
|
||||||
return tiles
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getEntityPrototypes(): PrototypesByType<FactorioPrototype.Entity> {
|
function getEntityPrototypes(): PrototypesByType<FactorioPrototype.Entity> {
|
||||||
const protos = new LuaTable<string, FactorioPrototype.Entity[]>()
|
const protos: PrototypesByType<FactorioPrototype.Entity> = {}
|
||||||
|
|
||||||
for (const [, entity] of game.entity_prototypes) {
|
for (const [, entity] of game.entity_prototypes) {
|
||||||
const key: string = `${entity.group.name}/${entity.subgroup.name}`
|
const key: string = `${entity.group.name}/${entity.subgroup.name}`
|
||||||
|
|
||||||
if (!protos.has(key)) {
|
protos[key] ??= []
|
||||||
protos.set(key, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
const entityProto: FactorioPrototype.Entity = {
|
const entityProto: FactorioPrototype.Entity = {
|
||||||
type: FactorioPrototype.Type.Entity,
|
type: FactorioPrototype.Type.Entity,
|
||||||
|
|
@ -91,7 +86,7 @@ function getEntityPrototypes(): PrototypesByType<FactorioPrototype.Entity> {
|
||||||
}
|
}
|
||||||
entityProto.miningProperties = Converters.miningProperties(entity.mineable_properties)
|
entityProto.miningProperties = Converters.miningProperties(entity.mineable_properties)
|
||||||
|
|
||||||
protos.get(key).push(entityProto)
|
protos[key].push(entityProto)
|
||||||
}
|
}
|
||||||
return protos
|
return protos
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,50 @@
|
||||||
import {Queue} from "../queue/queue";
|
|
||||||
import {isEventType} from "./eventTypeCheck";
|
import {isEventType} from "./eventTypeCheck";
|
||||||
import {Converters} from "./converters";
|
import {Converters} from "./converters";
|
||||||
import {handleSurfaceUpdate} from "./surfaceUpdates";
|
import {handleSurfaceUpdate} from "./surfaceUpdates";
|
||||||
import EventCacheService from "../cache/EventDataCache";
|
import EventCacheService from "../emitting/EventDataCache";
|
||||||
import MapChunkUpdate from "./handlers/MapChunkUpdateHandler";
|
import MapChunkUpdate from "./handlers/MapChunkUpdateHandler";
|
||||||
|
import EventDataQueue from "../queue/queue";
|
||||||
|
import KafkatorioPacketQueue from "../emitting/KafkatorioPacketQueue";
|
||||||
|
import PacketEmitter from "../emitting/PacketEmitter";
|
||||||
|
import {KafkatorioPacketData} from "../../generated/kafkatorio-schema";
|
||||||
|
|
||||||
|
|
||||||
script.on_event(
|
script.on_event(defines.events.on_tick, (event: OnTickEvent) => {
|
||||||
defines.events.on_tick,
|
if (event.tick % 1000 == 0) {
|
||||||
(event: OnTickEvent) => {
|
for (const [, surface] of game.surfaces) {
|
||||||
if (event.tick % 1000 == 0) {
|
handleSurfaceUpdate(event, Converters.eventNameString(event.name), surface)
|
||||||
for (const [, surface] of game.surfaces) {
|
}
|
||||||
handleSurfaceUpdate(event, Converters.eventNameString(event.name), surface)
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.tick % 6 == 0) {
|
const kPacket: KafkatorioPacketData | null = KafkatorioPacketQueue.dequeue()
|
||||||
// Every 0.1 seconds
|
if (kPacket != null) {
|
||||||
const emittedCount = EventCacheService.extractAndEmitExpiredPackets()
|
PacketEmitter.emitInstantPacket(kPacket)
|
||||||
if (emittedCount > 0) {
|
}
|
||||||
log(`[on_tick:${event.tick}] emitted ${emittedCount} events`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.tick % 7 == 0) {
|
if (event.tick % 6 == 0) {
|
||||||
const events: EventData[] = Queue.dequeueValues(1)
|
// Every 0.1 seconds
|
||||||
|
const emittedCount = EventCacheService.extractAndEmitExpiredPackets()
|
||||||
|
if (emittedCount > 0) {
|
||||||
|
log(`[on_tick:${event.tick}] emitted ${emittedCount} events`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (events.length > 0) {
|
if (event.tick % 7 == 0) {
|
||||||
log(`[on_tick:${event.tick}] dequeued ${events.length} events, current size: ${Queue.size()}`)
|
const events: EventData[] = EventDataQueue.dequeueValues(1)
|
||||||
|
|
||||||
let i = 1
|
if (events.length > 0) {
|
||||||
for (const event of events) {
|
log(`[on_tick:${event.tick}] dequeued ${events.length} events, current size: ${EventDataQueue.size()}`)
|
||||||
if (isEventType(event, defines.events.on_chunk_generated)) {
|
|
||||||
let eName = Converters.eventNameString(event.name)
|
|
||||||
|
|
||||||
log(`[on_tick:${event.tick}] dequed event ${eName}, delay ${i}`)
|
let i = 1
|
||||||
MapChunkUpdate.handleChunkGeneratedEvent(event, i)
|
for (const event of events) {
|
||||||
i += 1
|
if (isEventType(event, defines.events.on_chunk_generated)) {
|
||||||
}
|
let eName = Converters.eventNameString(event.name)
|
||||||
}
|
|
||||||
|
log(`[on_tick:${event.tick}] dequed event ${eName}, delay ${i}`)
|
||||||
|
MapChunkUpdate.handleChunkGeneratedEvent(event, i)
|
||||||
|
i += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
script.on_event(
|
script.on_event(defines.events.on_runtime_mod_setting_changed, (e: OnRuntimeModSettingChangedEvent) => {
|
||||||
defines.events.on_runtime_mod_setting_changed,
|
print(`Settings changed ${e.setting_type}, ${e.player_index}, ${e.setting}, ${e.mod_name}`)
|
||||||
(e: OnRuntimeModSettingChangedEvent) => {
|
// KafkatorioSettings.loadSettings()
|
||||||
print(`Settings changed ${e.setting_type}, ${e.player_index}, ${e.setting}, ${e.mod_name}`)
|
})
|
||||||
// KafkatorioSettings.loadSettings()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import PacketEmitter from "../PacketEmitter";
|
import PacketEmitter from "../emitting/PacketEmitter";
|
||||||
import {KafkatorioPacketData} from "../../generated/kafkatorio-schema";
|
import {KafkatorioPacketData} from "../../generated/kafkatorio-schema";
|
||||||
import Type = KafkatorioPacketData.Type;
|
import Type = KafkatorioPacketData.Type;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import {Queue} from "./queue/queue";
|
import EventUpdates from "./emitting/EventDataCache";
|
||||||
import EventUpdatesManager from "./cache/EventDataCache";
|
import {EventDataQueueManager} from "./queue/queue";
|
||||||
|
|
||||||
|
|
||||||
export function initGlobal(force: boolean = false) {
|
export function initGlobal(force: boolean = false) {
|
||||||
|
|
@ -8,8 +8,8 @@ export function initGlobal(force: boolean = false) {
|
||||||
global.MOD_VERSION = script.active_mods[script.mod_name]
|
global.MOD_VERSION = script.active_mods[script.mod_name]
|
||||||
global.FACTORIO_VERSION = script.active_mods["base"]
|
global.FACTORIO_VERSION = script.active_mods["base"]
|
||||||
|
|
||||||
Queue.init(true)
|
EventDataQueueManager.init(true)
|
||||||
EventUpdatesManager.init(true)
|
EventUpdates.init(true)
|
||||||
|
|
||||||
log("Finished initialising Kafkatorio Global variables")
|
log("Finished initialising Kafkatorio Global variables")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,13 @@
|
||||||
export namespace Queue {
|
export class EventDataQueueManager {
|
||||||
|
|
||||||
declare const global: {
|
static init(force?: boolean) {
|
||||||
store: EventQueueStore
|
|
||||||
|
|
||||||
head: Node | null
|
|
||||||
tail: Node | null
|
|
||||||
|
|
||||||
size: uint
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export function init(force?: boolean) {
|
|
||||||
|
|
||||||
const isAnythingUndefined = global.store == undefined ||
|
const isAnythingUndefined = global.store == undefined ||
|
||||||
global.size == undefined ||
|
global.size == undefined ||
|
||||||
global.head == undefined ||
|
global.head == undefined ||
|
||||||
global.tail == undefined
|
global.tail == undefined
|
||||||
|
|
||||||
log(`Initialising EventQueue globals (force=${force}, isAnythingUndefined=${isAnythingUndefined})`)
|
log(`Initialising EventDataQueueManager globals (force=${force}, isAnythingUndefined=${isAnythingUndefined})`)
|
||||||
|
|
||||||
if (force == true || isAnythingUndefined) {
|
if (force == true || isAnythingUndefined) {
|
||||||
global.store = {}
|
global.store = {}
|
||||||
|
|
@ -26,16 +16,16 @@ export namespace Queue {
|
||||||
global.size = 0
|
global.size = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
log(`Finished initialising EventQueue`)
|
log(`Finished initialising EventDataQueueManager`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function size(): uint | undefined {
|
size(): uint | undefined {
|
||||||
return global.size
|
return global.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function enqueue(key: string, event: EventData, weight: int = 1) {
|
enqueue(key: string, event: EventData, weight: int = 1) {
|
||||||
if (key ! in global.store) {
|
if (key ! in global.store) {
|
||||||
let node = new Node(key, weight)
|
let node = new Node(key, weight)
|
||||||
if (global.head == null) {
|
if (global.head == null) {
|
||||||
|
|
@ -52,7 +42,7 @@ export namespace Queue {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function dequeue(): WeightedPacket | null {
|
dequeue(): WeightedPacket | null {
|
||||||
if (global.head == null) {
|
if (global.head == null) {
|
||||||
return null
|
return null
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -76,12 +66,12 @@ export namespace Queue {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function dequeueValues(targetWeight: uint = 50): EventData[] {
|
dequeueValues(targetWeight: uint = 50): EventData[] {
|
||||||
let values: EventData[] = []
|
let values: EventData[] = []
|
||||||
let weight: uint = 0
|
let weight: uint = 0
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let packet = dequeue()
|
let packet = this.dequeue()
|
||||||
|
|
||||||
if (packet == null) {
|
if (packet == null) {
|
||||||
break;
|
break;
|
||||||
|
|
@ -94,27 +84,43 @@ export namespace Queue {
|
||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
class Node {
|
|
||||||
storeKey: string;
|
|
||||||
next: Node | null = null;
|
const EventDataQueue = new EventDataQueueManager()
|
||||||
weight: uint
|
|
||||||
|
|
||||||
constructor(storeKey: string, weight: uint) {
|
export default EventDataQueue
|
||||||
this.storeKey = storeKey;
|
|
||||||
this.weight = weight
|
|
||||||
}
|
declare const global: {
|
||||||
}
|
store: EventQueueStore
|
||||||
|
|
||||||
|
head: Node | null
|
||||||
interface EventQueueStore {
|
tail: Node | null
|
||||||
[key: string]: EventData | null;
|
|
||||||
}
|
size: uint
|
||||||
|
}
|
||||||
|
|
||||||
interface WeightedPacket {
|
|
||||||
value: EventData,
|
class Node {
|
||||||
weight: int,
|
storeKey: string;
|
||||||
}
|
next: Node | null = null;
|
||||||
|
weight: uint
|
||||||
|
|
||||||
|
constructor(storeKey: string, weight: uint) {
|
||||||
|
this.storeKey = storeKey;
|
||||||
|
this.weight = weight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface EventQueueStore {
|
||||||
|
[key: string]: EventData | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface WeightedPacket {
|
||||||
|
value: EventData,
|
||||||
|
weight: int,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue