Unrefined ECS feeling-it-out nonsense.

This commit is contained in:
Sage Vaillancourt 2025-01-30 11:00:31 -05:00
parent 533c625d47
commit 109d67bea9
1 changed files with 170 additions and 0 deletions

170
src/ecs.lua Normal file
View File

@ -0,0 +1,170 @@
local ENTITY_STORAGE = {}
local PLACEHOLDER = {}
ecs = { }
function ecs.addEntity(entity)
ENTITY_STORAGE[entity] = true
end
---@return any
function ecs.field()
return PLACEHOLDER
end
function allKeysIncluded(entity, filter)
for k, _ in pairs(filter) do
if not entity[k] then
return false
end
end
return true
end
function allFiltersMatch(entity, filters)
for _, filter in pairs(filters) do
if not allKeysIncluded(entity, filter) then
return false
end
end
return true
end
---@generic T
---@param shape T
---@return fun(): T[]
function ecs.buildEntityFilter(shape)
local filters = {shape}
return function()
-- TODO? Cache all this?
local ret = {}
for entity,_ in pairs(ENTITY_STORAGE) do
if allFiltersMatch(entity, filters) then
ret[#ret + 1] = entity;
end
end
return ret
end
end
---@generic T
---@return fun(): T[]
function ecs.buildRequiredFields(...)
local filters = arg
return function()
-- TODO? Cache all this?
local ret = {}
for entity,_ in pairs(ENTITY_STORAGE) do
if allKeysIncluded(entity, filters) then
ret[#ret + 1] = entity;
end
end
return ret
end
end
-- --@overload fun(tShape: `T`): fun(callback: fun(componentT: `T`))
---@generic T
---@generic U
---@generic V
---@generic W
---@param tShape T
---@param uShape U?
---@param vShape V?
---@param wShape W?
---@return fun(callback: fun(componentT: T, componentU: U, componentV: V, componentW: W))
function ecs.entitiesWithShapes(tShape, uShape, vShape, wShape)
return function()
end
end
--- Returns a function that accepts a callback. This callback will receive one argument for each Shape provided.
---
---@generic T
---@generic TKey
---@generic U
---@generic UKey
---@generic V
---@generic VKey
---@generic W
---@generic WKey
---@param tShape { [TKey]: T }
---@param uShape { [UKey]: U }?
---@param vShape { [VKey]: V }?
---@param wShape { [WKey]: W }?
---@return fun(callback: fun(componentT: T, componentU: U, componentV: V, componentW: W))
function ecs.entitiesWithShapes2(tShape, uShape, vShape, wShape)
local filters = {tShape, uShape, vShape, wShape}
return function(callback)
-- TODO? Cache all this?
local ret = {}
for entity,_ in pairs(ENTITY_STORAGE) do
if allFiltersMatch(entity, filters) then
callback(entity, entity, entity, entity)
end
end
return ret
end
end
local f = ecs.field()
---@alias XYPair { x:number, y: number }
---@type XYPair
local XYPair = { x = f, y = f }
local HasPosition = { position = XYPair }
local HasVelocity = { velocity = XYPair }
local entIt = ecs.entitiesWithShapes(HasPosition, HasVelocity)
entIt(function(hasPos, hasVel)
hasPos.position.x = hasPos.position.x + hasVel.velocity.y
end)
local entIt2 = ecs.entitiesWithShapes2(HasPosition)
entIt2(function(position, velocity)
---@type number
local num = 0
num = position.x
num = velocity.z
print(num)
end)
---@return fun(callback: fun(T))
function ecs.entitiesWithFields(...)
local filters = {...}
return function(callback)
-- TODO? Cache all this?
for entity,_ in pairs(ENTITY_STORAGE) do
if allKeysIncluded(entity, filters) then
callback(entity)
end
end
end
end
---@type unknown
function ecs.shape(...)
local shape = {}
for _,incomingShape in ipairs(arg) do
for k,v in pairs(incomingShape) do
shape[k] = v
end
end
return shape
end
local exampleEntity = {
position = { x = 0, y = 0 },
velocity = { x = 1, y = 1 }
}
ecs.addEntity(exampleEntity)
---@type fun(system: fun(entity: { position: XYPair, velocity: XYPair }))
local forEachPosVel = ecs.entitiesWithFields('position', 'velocity')
forEachPosVel(function(hasVelPos)
print(hasVelPos.velocity.x)
end)