diff options
Diffstat (limited to 'honey')
-rw-r--r-- | honey/ecs.lua.bak | 228 | ||||
-rw-r--r-- | honey/image.lua | 50 | ||||
-rw-r--r-- | honey/ode.lua | 55 | ||||
-rw-r--r-- | honey/shader.lua | 20 | ||||
-rw-r--r-- | honey/std.lua | 9 |
5 files changed, 360 insertions, 2 deletions
diff --git a/honey/ecs.lua.bak b/honey/ecs.lua.bak new file mode 100644 index 0000000..3632f34 --- /dev/null +++ b/honey/ecs.lua.bak @@ -0,0 +1,228 @@ +local module = {} +setmetatable(module, {__index=_G}) +setfenv(1, module) + + +--===== filters =====-- + + +Filter = {} + +-- base filter creation +function Filter.new(_, operation, tbl) + local self = {} + self.keys = {} + self.filters = {} + self.op = operation + + for _, v in ipairs(tbl) do + if type(v) == "function" then + table.insert(self.filters, v) + elseif type(v) == "string" then + table.insert(self.keys, v) + end + end + + return function(entity, _self) + local entity = _self or entity -- able to call as . or : + return Filter.check(self, entity) + end +end +setmetatable(Filter, {__call=Filter.new}) + + +-- base filter checking +function Filter.check(self, entity) + local funcname = "check" .. self.op + return Filter[funcname](self, entity) +end + + +-- AND filter (all keys and subfilters must match) +function Filter.AND(tbl) + return Filter("AND", tbl) +end +function Filter.checkAND(self, entity) + for _, subfilter in ipairs(self.filters) do + if not subfilter(entity) then return false end + end + for _, key in ipairs(self.keys) do + if entity[key] == nil then return false end + end + return true +end + + +-- OR filter (at least one key or subfilter must match) +function Filter.OR(tbl) + return Filter("OR", tbl) +end +function Filter.checkOR(self, entity) + for _, subfilter in ipairs(self.filters) do + if subfilter(entity) then return true end + end + for _, key in ipairs(self.keys) do + if entity[key] ~= nil then return true end + end + return false +end + + +-- NAND filter (at least one key or subfilter must NOT match) +function Filter.NAND(tbl) + return Filter("NAND", tbl) +end +function Filter.checkNAND(self, entity) + for _, subfilter in ipairs(self.filters) do + if not subfilter(entity) then return true end + end + for _, key in ipairs(self.keys) do + if entity[key] == nil then return true end + end + return false +end + + +-- NOR filter (no keys or subfilters may match) +function Filter.NOR(tbl) + return Filter("NOR", tbl) +end +function Filter.checkNOR(self, entity) + for _, subfilter in ipairs(self.filters) do + if subfilter(entity) then return false end + end + for _, key in ipairs(self.keys) do + if entity[key] ~= nil then return false end + end + return true +end + + +--===== levels =====-- + +Level = {} +Level.__index = Level + +function Level.new(_) + local self = {} + self.systems = {} + self.entities = {} + self.nextId = 1 + setmetatable(self, Level) + return self +end +setmetatable(Level, {__call=Level.new}) + + +local function systemLt(a, b) + return (a.priority or 50) < (b.priority or 50) +end +function Level.addSystem(self, system) + assert(system.update, "systems must have an 'update' key") + assert(system.filter, "systems must have a 'filter' key") + system.entities = {} + table.insert(self.systems, system) + table.sort(self.systems, systemLt) + if system.setup then + system.setup(system) + end +end + + +local function addEntityToSystem(system, id, entity) + -- check if entity is already present + if system.entities[id] then return end + + if system.onAddEntity then + system:onAddEntity(id, entity) + end + system.entities[id] = true +end + + +local function removeEntityFromSystem(system, id, entity) + -- check if entity is already absent + if not system.entities[id] then return end + + if system.onRemoveEntity then + system:onRemoveEntity(id, entity) + end + system.entities[id] = nil +end + + +function Level.addEntity(self, entity) + local id = self.nextId + self.entities[id] = entity + self.nextId = id + 1 + + for _, system in ipairs(self.systems) do + if system.filter(entity) then + addEntityToSystem(system, id, entity) + end + end + + return id +end + + +function Level.reconfigureEntity(self, id) + local entity = self.entities[id] + + for _, system in ipairs(self.systems) do + if system.filter(entity) then + addEntityToSystem(system, id, entity) + else + removeEntityFromSystem(system, id, entity) + end + end +end + + +function Level.removeEntity(self, id) + local entity = self.entities[id] + if not entity then error("bad id: "..tostring(id)) end + for _, system in ipairs(self.systems) do + removeEntityFromSystem(system, id, entity) + end + self.entities[id] = nil +end + + +function Level.reconfigureAllEntities(self) + for id in ipairs(self.entities) do + self:reconfigureEntity(id) + end +end + + +function Level.update(self, dt, paused) + local paused = paused or false + for _, system in ipairs(self.systems) do + if (not paused) or (paused and system.nopause) then + if system.preUpdate then + system:preUpdate() + end + if system.prepareEntity then + for id in pairs(system.entities) do + local entity = self.entities[id] + if entity then + system:prepareEntity(entity) + end + end + end + for id in pairs(system.entities) do + local entity = self.entities[id] + if entity then + system:update(entity, dt) + end + end + if system.postUpdate then + system:postUpdate() + end + end + end +end + + +return module diff --git a/honey/image.lua b/honey/image.lua new file mode 100644 index 0000000..f074272 --- /dev/null +++ b/honey/image.lua @@ -0,0 +1,50 @@ +local gl = honey.gl + +local module = {} +setmetatable(module, {__index=_G}) +setfenv(1, module) + +function Image(filename, params) + local params = params or {} + local data, width, height = honey.image.load(filename, 4) + local self = {} + self.width = width + self.height = height + + self.texture = gl.GenTextures() + gl.BindTexture(gl.TEXTURE_2D, self.texture) + for param, value in pairs(params) do + gl.TexParameteri(gl.TEXTURE_2D, gl[param], value) + end + gl.TexImage2D( + gl.TEXTURE_2D, 0, + gl.RGBA, width, height, + gl.RGBA, gl.UNSIGNED_BYTE, data + ) + gl.GenerateMipmap(gl.TEXTURE_2D) + honey.image.destroy(data) + + self.__gc = honey.util.gc_canary(function() + gl.DeleteTextures(self.texture) + end) + + return self +end + + +local cache = {} +function loadImage(filename, params) + if not cache[filename] then + local img = Image(filename, params) + cache[filename] = img + return img + end + + return cache[filename] +end + +function clearImageCache() + cache = {} +end + +return module diff --git a/honey/ode.lua b/honey/ode.lua new file mode 100644 index 0000000..4cd2e54 --- /dev/null +++ b/honey/ode.lua @@ -0,0 +1,55 @@ +local module = {} +setmetatable(module, {__index=_G} +setfenv(1, module) + + +--===== collision =====-- + +Geom = {} +Geom.__index = Geom + + +function Geom.new(_, type, params) + local self = {} + self.type = type + self.params = params + setmetatable(self, Geom) + return self +end +setmetatable(Geom, {__call=Geom.new}) + + +function Geom.renew(geom) + return ode.GeomGetData(geom) +end + + +local function instantiateSphere(space, params) + local geom = ode.CreateSphere(space, params.radius) + return geom +end + + +local function instantiatePlane(space, params) + local geom = ode.CreatePlane(space, params.a, params.b, params.c, params.d) + return geom +end + + +function Geom.instantiate(self, space) + if self.type == "sphere" then + self.geom = instantiateSphere(space, self.params) + elseif self.type == "plane" then + self.geom = instantiatePlane(space, self.params) + else + error(string.format("bad geom type: %s", self.type)) + end + ode.GeomSetData(self.geom, self) + return self +end + + +function Geom.setBody(self, body) + ode.GeomSetBody(self.geom, body.body) + return self +end diff --git a/honey/shader.lua b/honey/shader.lua index 083b260..6b281f7 100644 --- a/honey/shader.lua +++ b/honey/shader.lua @@ -52,6 +52,10 @@ function Shader.new(_, sources) gl.DeleteShader(shader) end + self.__gc = honey.util.gc_canary(function() + gl.DeleteProgram(self.program) + end) + setmetatable(self, Shader) return self end @@ -115,4 +119,18 @@ function Shader.configure(self, tbl) processKey("matrix", "setMatrix") end -return module.Shader + +local shaderCache = {} +function loadShader(vertex, fragment) + local id = vertex .. "+" .. fragment + if not shaderCache[id] then + local shader = Shader{vertexFile=vertex, fragmentFile=fragment} + shaderCache[id] = shader + end + return shaderCache[id] +end +function clearShaderCache() + shaderCache = {} +end + +return module diff --git a/honey/std.lua b/honey/std.lua index 2a5d2c2..98e942d 100644 --- a/honey/std.lua +++ b/honey/std.lua @@ -7,10 +7,17 @@ honey.terminate = init.terminate honey.ecs = require 'honey.ecs' --honey.standardSystems = require 'honey.ecs-systems' honey.mesh = require 'honey.mesh' -honey.Shader = require 'honey.shader' +honey.shader = require 'honey.shader' honey.Window = require 'honey.window' +-- image +local image = require 'honey.image' +for k, v in pairs(image) do + honey.image[k] = v +end + + local glm = require 'honey.glm' honey.Vec3 = glm.Vec3 honey.Mat4 = glm.Mat4 |