From 45dbe47d17303050cbea7c2c51e838acfe21c2fb Mon Sep 17 00:00:00 2001 From: sanine-a Date: Tue, 28 Mar 2023 16:35:22 -0500 Subject: add cached mesh loading --- honey/ecs.lua | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++---- honey/ecs.test.lua | 48 ++++++++++++++++++++++++++++ honey/mesh.lua | 17 +++++++--- honey/std.lua | 2 +- 4 files changed, 149 insertions(+), 11 deletions(-) (limited to 'honey') diff --git a/honey/ecs.lua b/honey/ecs.lua index 8aa5c5c..72cc41d 100644 --- a/honey/ecs.lua +++ b/honey/ecs.lua @@ -84,6 +84,7 @@ end setmetatable(EntityDb, {__call=EntityDb.new}) +-- check if a given entity id is legitimate function EntityDb.checkIsValid(self, id) if not self.entities[id] then error(string.format("invalid entity id: %s", tostring(id))) @@ -91,22 +92,29 @@ function EntityDb.checkIsValid(self, id) end -local function uid() - local template ='xxxx:xxxx:xxxx' - return string.gsub(template, 'x', function (c) - local v = math.random(0, 0xf) +local random = math.random +local function uuid() + local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' + return string.gsub(template, '[xy]', function (c) + local v = (c == 'x') and random(0, 0xf) or random(8, 0xb) return string.format('%x', v) end) end -function EntityDb.createEntity(self) - local id = uid() + + +-- create a new entity +function EntityDb.createEntity(self, id) + local id = id or uuid() -- allow inserting entities at preset ids for loading self.entities[id] = true return id end +-- add a component to an entity function EntityDb.addComponent(self, id, name, value) self:checkIsValid(id) + + -- create the relevant component table if it doesn't exist if not self.components[name] then self.components[name] = { count=0 } end @@ -124,6 +132,7 @@ local function shallowCopy(tbl) end +-- get all entities with a given component function EntityDb.queryComponent(self, name) local query = shallowCopy(self.components[name]) query.count = nil @@ -131,6 +140,7 @@ function EntityDb.queryComponent(self, name) end +-- get all components associated with an entity function EntityDb.queryEntity(self, id) self:checkIsValid(id) local query = {} @@ -141,6 +151,14 @@ function EntityDb.queryEntity(self, id) end +-- get a specific component from an entity +function EntityDb.getComponent(self, id, name) + self:checkIsValid(id) + return self.components[name][id] +end + + +-- remove a component from an entity function EntityDb.removeComponent(self, id, name) self:checkIsValid(id) local component = self.components[name] @@ -154,6 +172,7 @@ function EntityDb.removeComponent(self, id, name) end +-- remove an entity from the db function EntityDb.deleteEntity(self, id) self:checkIsValid(id) for name in pairs(self.components) do @@ -162,4 +181,66 @@ function EntityDb.deleteEntity(self, id) self.entities[id] = nil end + +--===== SystemDb =====-- + +SystemDb = {} +SystemDb.__index = SystemDb + + +function SystemDb.new(_) + local self = { + systems = {}, + sorted = {}, + } + setmetatable(self, SystemDb) + return self +end +setmetatable(SystemDb, {__call=SystemDb.new}) + + +local function systemId() + local template = "xx:xx:xx" + return string.gsub(template, "x", function(c) + return string.format("%x", random(0, 0xf)) + end) +end + + +function SystemDb.addSystem(self, systemFunc, params) + local system + if type(systemFunc) == "table" then + system = systemFunc + else + system = systemFunc(params) + end + + local id = systemId() + self.systems[id] = system + table.insert(self.sorted, id) + self:sort() + return id +end + + +function SystemDb.sort(self) + table.sort(self.sorted, function(a, b) return (self.systems[a].priority or 100) < (self.systems[b].priority or 100) end) +end + + +function SystemDb.update(self, dt) + for _, system in ipairs(self.sorted) do + self.systems[system]:update(dt) + end +end + + +function SystemDb.removeSystem(self, id) + self.systems[id] = nil + for i=#self.sorted,1,-1 do + if self.sorted[i] == id then table.remove(self.sorted, i) end + end +end + + return module diff --git a/honey/ecs.test.lua b/honey/ecs.test.lua index 0577dcd..74e27dc 100644 --- a/honey/ecs.test.lua +++ b/honey/ecs.test.lua @@ -229,4 +229,52 @@ test("EntityDb.deleteEntity() correctly removes an entity", function() end) +--===== SystemDb tests =====-- + +local SystemDb = ecs.SystemDb + +test("addSystem() correctly sorts systems", function() + local sdb = SystemDb(nil) + local str = "" + sdb:addSystem(function () return { + update=function(self, dt) str = str .. "c" end, + priority = 3, + } end) + sdb:addSystem{ + update=function(self, dt) str = "a" end, + priority = 1, + } + sdb:addSystem{ + update=function(self, dt) str = str .. "b" end, + priority = 2, + } + sdb:update(0) + assert(str == "abc") +end) + + +test("removeSystem() correctly handles things", function() + local sdb = SystemDb(nil) + local str = "" + sdb:addSystem(function () return { + update=function(self, dt) str = str .. "c" end, + priority = 3, + } end) + sdb:addSystem{ + update=function(self, dt) str = "a" end, + priority = 1, + } + local id = sdb:addSystem{ + update=function(self, dt) str = str .. "b" end, + priority = 2, + } + sdb:update(0) + assert(str == "abc") + + sdb:removeSystem(id) + sdb:update(1) + assert(str == "ac") +end) + + print(string.format("ran %d tests, %d failed", testCount, failCount)) diff --git a/honey/mesh.lua b/honey/mesh.lua index 430d5c3..e46c399 100644 --- a/honey/mesh.lua +++ b/honey/mesh.lua @@ -1,7 +1,7 @@ -local mesh = {} +local module = {} local gl = honey.gl -setmetatable(mesh, {__index=_G}) -setfenv(1, mesh) +setmetatable(module, {__index=_G}) +setfenv(1, module) local function insertVertex(vertices, attrib, vertex) @@ -54,6 +54,15 @@ function loadFile(filename) end +local meshCache = {} +function loadMesh(filename, index) + if not meshCache[filename] then + meshCache[filename] = loadFile(filename) + end + return meshCache[filename][index] +end + + Mesh = {} Mesh.__index = Mesh @@ -92,4 +101,4 @@ function Mesh.drawElements(self) end -return mesh +return module diff --git a/honey/std.lua b/honey/std.lua index a08bf35..2a5d2c2 100644 --- a/honey/std.lua +++ b/honey/std.lua @@ -5,7 +5,7 @@ honey.loop = init.loop honey.terminate = init.terminate honey.ecs = require 'honey.ecs' -honey.standardSystems = require 'honey.ecs-systems' +--honey.standardSystems = require 'honey.ecs-systems' honey.mesh = require 'honey.mesh' honey.Shader = require 'honey.shader' honey.Window = require 'honey.window' -- cgit v1.2.1