From 8730b3844491aa72153e69415dac5a5a6a6ecb68 Mon Sep 17 00:00:00 2001
From: Sage Vaillancourt <sage@sagev.space>
Date: Wed, 19 Mar 2025 14:54:31 -0400
Subject: [PATCH] Process LiveForNFrames at end of frame.

Button -> Key
---
 generated/filter-types.lua   |  8 ++---
 generated/filter-types.lua2p |  2 +-
 main.lua                     | 11 ++++++-
 systems/decay.lua            |  1 +
 systems/input.lua            | 57 ++++++++++++++++++++++++++++++++----
 5 files changed, 67 insertions(+), 12 deletions(-)

diff --git a/generated/filter-types.lua b/generated/filter-types.lua
index 8f3660e..314ed91 100644
--- a/generated/filter-types.lua
+++ b/generated/filter-types.lua
@@ -7,10 +7,10 @@ local SOME_TABLE = {}
 
 ---@alias AnyComponent any
 ---@alias BitMask number
----@alias ButtonState { receivedInputThisFrame: boolean, aJustPressed: boolean, bJustPressed: boolean, upJustPressed: boolean, downJustPressed: boolean, leftJustPressed: boolean, rightJustPressed: boolean }
 ---@alias Collision { collisionBetween: Entity[] }
 ---@alias Entity table
 ---@alias FontData love.FontData
+---@alias KeyState table<string, boolean>
 ---@alias XyPair { x: number, y: number }
 
 T = {
@@ -28,9 +28,6 @@ T = {
     ---@type BitMask
     BitMask = 0,
 
-    ---@type ButtonState
-    ButtonState = SOME_TABLE,
-
     ---@type Collision
     Collision = SOME_TABLE,
 
@@ -40,6 +37,9 @@ T = {
     ---@type FontData
     FontData = SOME_TABLE,
 
+    ---@type KeyState
+    KeyState = SOME_TABLE,
+
     ---@type XyPair
     XyPair = SOME_TABLE,
 }
diff --git a/generated/filter-types.lua2p b/generated/filter-types.lua2p
index 490ff02..a4071f4 100644
--- a/generated/filter-types.lua2p
+++ b/generated/filter-types.lua2p
@@ -60,7 +60,7 @@ local SOME_TABLE = {}
     Collision = "{ collisionBetween: Entity[] }",
     BitMask = "number",
     FontData = "love.FontData",
-    ButtonState = "{ receivedInputThisFrame: boolean, aJustPressed: boolean, bJustPressed: boolean, upJustPressed: boolean, downJustPressed: boolean, leftJustPressed: boolean, rightJustPressed: boolean }",
+    KeyState = "table<string, boolean>",
 }))
 T = {
     bool = true,
diff --git a/main.lua b/main.lua
index 30d54b1..b242d2e 100644
--- a/main.lua
+++ b/main.lua
@@ -33,7 +33,6 @@ local delta
 
 function love.load()
     currentScenario()
-    World:setSystemIndex(LiveForNFrames, 1)
     love.graphics.setBackgroundColor(1, 1, 1)
     love.graphics.setFont(EtBt7001Z0xa(32))
 end
@@ -55,12 +54,22 @@ function love.update(dt)
     end
 
     World:update(delta, function(_, system)
+        if system.deferToEnd then
+            return false
+        end
         return not system.isDrawSystem
     end)
 end
 
 function love.draw()
     World:update(delta, function(_, system)
+        if system.deferToEnd then
+            return false
+        end
         return system.isDrawSystem
     end)
+
+    World:update(delta, function(_, system)
+        return system.deferToEnd
+    end)
 end
diff --git a/systems/decay.lua b/systems/decay.lua
index 53815fe..c8581e6 100644
--- a/systems/decay.lua
+++ b/systems/decay.lua
@@ -12,3 +12,4 @@ LiveForNFrames = filteredSystem("liveForNFrames", { liveForNFrames = T.number },
     end
 end)
 
+LiveForNFrames.deferToEnd = true
\ No newline at end of file
diff --git a/systems/input.lua b/systems/input.lua
index 1ae747f..747f45d 100644
--- a/systems/input.lua
+++ b/systems/input.lua
@@ -1,13 +1,58 @@
----@type ButtonState
-local buttonState = {}
+---@type KeyState
+local keyState = {}
 
-buttonInputSystem = filteredSystem("buttonInput", { canReceiveButtons = T.marker }, function(e, _, system)
-    e.buttonState = buttonState
+local keyInputSystem = filteredSystem("keyInput", { canReceiveKeys = T.marker }, function(e, _, system)
+    e.keyState = keyState
     system.world:addEntity(e)
 end)
 
-function buttonInputSystem:preProcess()
+function keyInputSystem:preProcess()
     if #self.entities == 0 then
         return
     end
-end
\ No newline at end of file
+end
+
+function love.keypressed(key, _, _)
+    keyState[key] = true
+end
+
+function ClearKeyState()
+    for key in pairs(keyState) do
+        keyState[key] = nil
+    end
+end
+
+local mouse = filteredSystem("mouse", { mouseKeyPress = { position = T.XyPair, key = T.number } })
+
+function MouseJustPressed(key, clear)
+    clear = clear ~= nil and clear or true
+    for _, event in pairs(mouse.entities) do
+        if event.mouseKeyPress and event.mouseKeyPress.key == key then
+            if clear then
+                event.mouseKeyPress = nil
+                World:removeEntity(event)
+            end
+            return true
+        end
+    end
+    return false
+end
+
+local mouseX, mouseY = -9999, -9999
+
+function love.mousemoved(x, y)
+    mouseX, mouseY = x, y
+end
+
+function love.mousepressed(x, y, key)
+    World:addEntity({
+        mouseKeyPress = {
+            position = {
+                x = x,
+                y = y,
+            },
+            key = key,
+        },
+        liveForNFrames = 1,
+    })
+end