diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index d179872..df1cacc 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1,6 +1,13 @@ import {handleConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate"; +import {emitPrototypes} from "./main/config-update/prototypes"; +import {Queue} from "./main/queue/queue"; require("./main/events/registerHandlers") require("./main/commands/kafkatorioCommands") script.on_configuration_changed(handleConfigurationUpdate) + +script.on_init(() => { + Queue.reset() + emitPrototypes() +}) diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index 20b692a..c1ecb3b 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -1,7 +1,9 @@ import {emitPrototypes} from "../config-update/prototypes"; import {handleChunkUpdate} from "../events/handlers"; +import {Queue} from "../queue/queue"; import floor = math.floor; + commands.add_command( "kafkatorio", "kafkatorio innit bruv", @@ -36,7 +38,7 @@ commands.add_command( handleChunkUpdate( e.tick, - "player-command", + "player-command-" + e.parameter, player.surface.index, chunkPosition, chunkArea, @@ -44,23 +46,50 @@ commands.add_command( } } else if ("CHUNKS" == e.parameter.toUpperCase()) { - for (let [, surface] of game.surfaces) { - for (let chunk of surface.get_chunks()) { - if ( - (chunk.x >= -16 || chunk.x <= 16) - && - (chunk.y >= -16 || chunk.y <= 16) - ) { - handleChunkUpdate( - e.tick, - "player-command", - surface.index, - chunk, - chunk.area, - ) + if (e.player_index != undefined) { + let player = game.players[e.player_index] + + let chunkPosition: ChunkPosition = { + x: floor(player.position.x / 32), + y: floor(player.position.y / 32), + } + + let delta = 1 + + let chunkXMin = chunkPosition.x - delta + let chunkXMax = chunkPosition.x + delta + let chunkYMin = chunkPosition.y - delta + let chunkYMax = chunkPosition.y + delta + + for (let [, surface] of game.surfaces) { + for (let chunk of surface.get_chunks()) { + if ( + (chunk.x >= chunkXMin || chunk.x <= chunkXMax) + && + (chunk.y >= chunkYMin || chunk.y <= chunkYMax) + ) { + + let data: OnChunkGeneratedEvent = { + name: defines.events.on_chunk_generated, + position: {x: chunk.x, y: chunk.y}, + area: chunk.area, + surface: surface, + tick: e.tick + } + + Queue.enqueue( + `${surface.index}${chunk.x}${chunk.y}`, + data, + 50 + ) + } } } } + } else if ("QUEUE_RESET" == e.parameter.toUpperCase()) { + Queue.reset() + } else if ("QUEUE_INIT" == e.parameter.toUpperCase()) { + Queue.init() } } ) diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts index 2d58bbd..8bb456f 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -1,6 +1,7 @@ import {emitPacket} from "../emitKafkatorioPacket"; import {updateGlobal} from "./updateGlobal"; import {emitPrototypes} from "./prototypes"; +import {Queue} from "../queue/queue"; export function handleConfigurationUpdate(changeData: ConfigurationChangedData) { updateGlobal() @@ -12,6 +13,7 @@ export function handleConfigurationUpdate(changeData: ConfigurationChangedData) factorioData: factorioData(changeData) }) + Queue.reset() emitPrototypes() } diff --git a/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts b/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts index c86af5d..fcaa92f 100644 --- a/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts +++ b/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts @@ -1,6 +1,7 @@ /** Emit a serialised KafkatorioPacket */ export function emitPacket(packet: T) { let data = game.table_to_json(packet) + // localised_print(`KafkatorioPacket: ${packet.packetType}`) localised_print(`KafkatorioPacket: ${data}`) // rcon.print(`KafkatorioPacket: ${data}`) } diff --git a/modules/events-mod/src/main/typescript/main/events/emitEvent.ts b/modules/events-mod/src/main/typescript/main/events/emitEvent.ts index 771b408..ab98b7f 100644 --- a/modules/events-mod/src/main/typescript/main/events/emitEvent.ts +++ b/modules/events-mod/src/main/typescript/main/events/emitEvent.ts @@ -1,6 +1,3 @@ -// const SERVER_ID: uint = 0 -// const EVENT_FILE_DIR: string = "events" - import {emitPacket} from "../emitKafkatorioPacket"; /** Emit a serialised event */ diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index a35da1b..1599367 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -1,12 +1,10 @@ import {Converters} from "./converters" import {emitEvent} from "./emitEvent"; - export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) { let player: LuaPlayer = game.players[playerIndex] let table = Converters.playerToTable(player) - emitEvent(table, tick, eventType) handleCharactersEvent(tick, eventType, playerIndex) @@ -50,8 +48,6 @@ export function handleConsoleChat( emitEvent(table, tick, eventType) } -// const CHUNK_SIZE = 32 - export function handleChunkUpdate( tick: uint, eventType: string, @@ -64,8 +60,6 @@ export function handleChunkUpdate( let tiles: LuaTile[] = surface?.find_tiles_filtered({ area: area, - // position: {x: x, y: y}, - // radius: CHUNK_SIZE, collision_mask: ["ground-tile", "water-tile"] } ) ?? [] diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index 4468bac..c1dc0a4 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -6,13 +6,20 @@ import { handleSurfaceUpdate, handleTilesUpdate } from "./handlers"; +import {Queue} from "../queue/queue"; import on_player_built_tile = defines.events.on_player_built_tile; import on_robot_built_tile = defines.events.on_robot_built_tile; const mapEventIdToName = new LuaTable() -for (const [k, v] of pairs(defines.events)) { - mapEventIdToName.set(v, k) +for (const [eventName, eventId] of pairs(defines.events)) { + mapEventIdToName.set(eventId, eventName) +} + +const mapEventIdToDefinedType = new LuaTable, EventId>() +for (const [eventName, eventId] of pairs(defines.events)) { + let definedType = defines.events[eventName] + mapEventIdToDefinedType.set(eventId, definedType) } // script.on_event( @@ -34,6 +41,9 @@ script.on_event( script.on_event( defines.events.on_player_joined_game, (e: OnPlayerJoinedGameEvent) => { + + Queue.init() // TODO make Queue initialisation more stable, not dependent on events + handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index) } ) @@ -52,6 +62,29 @@ script.on_event( for (const [, surface] of pairs(game.surfaces)) { handleSurfaceUpdate(e.tick, mapEventIdToName.get(e.name), surface) } + + // let packets = new KafkatorioPacketQueue().dequeueValues(1) + // for (const packet of packets) { + // emitPacket(packet) + // } + } + + if (e.tick % 30 == 0) { + let events: EventData[] = Queue.dequeueValues(1) + + if (events.length > 0) { + log(`[${e.tick}] dequed ${events.length} events, current size: ${Queue.size()}`) + + for (const event of events) { + + if (isEventType(event)) { + let eName = mapEventIdToName.get(event.name) + + log(`[${e.tick}] dequed event ${eName}`) + handleChunkUpdate(e.tick, eName, event.surface.index, event.position, event.area) + } + } + } } } ) @@ -82,3 +115,14 @@ script.on_event( ) } ) + + +function isEventType(e: EventData): e is E { + let id: EventId | string = e.name + if (typeof id === "string") { + return false + } else { + let name = mapEventIdToDefinedType.get(id) + return e.name == name + } +} diff --git a/modules/events-mod/src/main/typescript/main/queue/queue.ts b/modules/events-mod/src/main/typescript/main/queue/queue.ts new file mode 100644 index 0000000..693c4d1 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/queue/queue.ts @@ -0,0 +1,124 @@ +export namespace Queue { + + declare const global: { + store: EventQueueStore + + head: Node | null + tail: Node | null + + size: uint + } + + + export function init() { + if (global.store == undefined) { + log("initialising EventQueue") + reset() + } + } + + + export function reset() { + log("Resetting EventQueue") + global.store = {} + global.head = null + global.tail = null + global.size = 0 + } + + + export function size(): uint { + return global.size + } + + + export function enqueue(key: string, event: EventData, weight: int = 1) { + if (key ! in global.store) { + let node = new Node(key, weight) + if (global.head == null) { + global.head = node + } + if (global.tail != null) { + global.tail.next = node + } + global.tail = node + } + + global.store[key] = event + global.size++ + } + + + export function dequeue(): WeightedPacket | null { + if (global.head == null) { + return null + } else { + let weight = global.head.weight + let storeKey = global.head.storeKey + global.head = global.head.next + + let storedPacket = global.store[storeKey] + global.store[storeKey] = null + + if (storedPacket == null) { + return null + } else { + global.size-- + return { + value: storedPacket, + weight: weight, + } + } + } + } + + export function dequeueValues(targetWeight: uint = 50): EventData[] { + let values: EventData[] = [] + let weight: uint = 0 + + do { + let packet = dequeue() + + if (packet == null) { + break; + } else { + weight += packet.weight + values[values.length] = packet.value + } + } while (weight <= targetWeight) + + return values + } + + + class Node { + 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 PacketQueue { +// enqueue(key: string, packet: T, weight: int): void +// +// dequeue(): WeightedPacket | null +// +// dequeueValues(targetWeight: int): T[] +// } +// + interface WeightedPacket { + value: EventData, + weight: int, + } + + +} diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 5d7dc4f..a8216e6 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.6", + "version": "0.2.7", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index b4993c8..c9efe3b 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.6", + "version": "0.2.7", "private": true, "scripts": { "build": "tstl", diff --git a/modules/events-mod/src/main/typescript/tsconfig.json b/modules/events-mod/src/main/typescript/tsconfig.json index 70b9ed4..d87f6f4 100644 --- a/modules/events-mod/src/main/typescript/tsconfig.json +++ b/modules/events-mod/src/main/typescript/tsconfig.json @@ -1,9 +1,9 @@ { "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/vscode-typescript-to-lua/master/tsconfig-schema.json", "compilerOptions": { - "target": "es2019", + "target": "esnext", "lib": [ - "es2019" + "esnext" ], "module": "commonjs", "moduleResolution": "node",