summaryrefslogtreecommitdiff
path: root/honey
diff options
context:
space:
mode:
Diffstat (limited to 'honey')
-rw-r--r--honey/ecs.lua.bak228
-rw-r--r--honey/image.lua50
-rw-r--r--honey/ode.lua55
-rw-r--r--honey/shader.lua20
-rw-r--r--honey/std.lua9
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