-/client/
-/server/
+/data/
#! /usr/bin/env lua
-require("lfs")
-require("socket")
-require("lsqlite3")
-require("moongl")
-require("moonglfw")
+lfs = require("lfs")
+socket = require("socket")
+lsqlite3 = require("lsqlite3")
+gl = require("moongl")
+glfw = require("moonglfw")
require("util/objectmgr")
require("util/split")
require("util/indexof")
Dragonblocks:init()
-Dragonblocks:start_module(arg[1] or "Menu")
+Dragonblocks:start_module(arg[1])
+
+Dragonblocks:start_tasks()
--- /dev/null
+RenderEngine
--- /dev/null
+RenderEngine:open_window()
+RenderEngine:set_window_title("Dragonblocks 3D - Main Menu")
+
+RenderEngine:add_render_task()
+
+MainMenu:init()
+++ /dev/null
-print("Success!")
-Menu:add_proto(Dragonblocks.serializer)
-Menu:init()
-
--- /dev/null
+glfw.window_hint("context version major", 3)
+glfw.window_hint("context version minor", 3)
+glfw.window_hint("opengl profile", "core")
+
+function RenderEngine.reshape(_, width, height)
+ gl.viewport(0, 0, width, height)
+end
+
+function RenderEngine:open_window()
+ self.window = glfw.create_window(50, 50, "Unnamed Window")
+ glfw.make_context_current(self.window)
+ gl.init()
+ glfw.set_framebuffer_size_callback(self.window, RenderEngine.reshape)
+end
+
+function RenderEngine:set_window_title(title)
+ glfw.set_window_title(self.window, title)
+end
+
+function RenderEngine:render()
+ glfw.poll_events()
+ gl.clear_color(1.0, 0.5, 0.2, 1.0)
+ gl.clear("color", "depth")
+ glfw.swap_buffers(self.window)
+ coroutine.yield()
+end
+
+function RenderEngine:render_loop()
+ repeat RenderEngine:render()
+ until glfw.window_should_close(self.window)
+end
+
+function RenderEngine:add_render_task()
+ Dragonblocks:add_task(function() RenderEngine:render_loop() end)
+end
+
+RenderEngine:init()
local event_interface = {}
function event_interface:init()
+ assert(self._task_manager)
self:clear_event_listeners()
end
-function event_interface:fire_event(eventtype, event)
+function event_interface:fire_event(event, callback)
event = event or {}
- event.type = eventtype
event.origin = self
local listeners = self._event_listeners[eventtype]
if listeners then
- for _, listener in ipairs(listeners) do
- listener(event)
- end
+ self._task_manager:add_task(function()
+ for _, listener in ipairs(listeners) do
+ listener(event)
+ coroutine.yield()
+ end
+ callback(event)
+ end)
end
end
Dragonblocks.event_interface = require("src/event_interface")
Dragonblocks.class = require("src/class")
+Dragonblocks.task_manager = require("src/task_manager")
Dragonblocks.module_manager = require("src/module_manager")
Dragonblocks.serializer = require("src/serializer")
Dragonblocks:add_proto(Dragonblocks.module_manager)
+Dragonblocks:add_proto(Dragonblocks.task_manager)
Dragonblocks:add_proto(Dragonblocks.serializer)
+
+Dragonblocks:register_event_interface(Dragonblocks)
+
+print("Started Dragonblocks core")
function module_ref:preinit()
self._dependencies = {}
self._started = false
- local depfile = io.open(self._path .. "/.txt")
+ local depfile = io.open(self._path .. "/dependencies.txt")
if depfile then
local data = depfile:read()
depfile:close()
self._dependencies = data:split("\n")
end
+
end
function module_ref:init()
self._started = true
end
+function module_ref:run_script(s)
+ return require(self._path .. "src/" .. s)
+end
+
function module_ref:start()
_G[self._name] = self
- require(self._path .. "src/init")
+ self:run_script("init")
+ print("Started module " .. self._name)
+end
+
+function module_ref:get_path()
+ return self._path
+end
+
+function module_ref:get_data_path()
+ local p = self._data_path
+ if not lfs.attributes(p, "mode") then
+ lfs.mkdir(p)
+ end
end
local module_manager = {}
module_manager.module_path = "modules/"
+module_manager.data_path = "data/"
function module_manager:init()
+ if not lfs.attributes(self.data_path, "mode") then
+ lfs.mkdir(self.data_path)
+ end
self._modules = {}
for modulename in lfs.dir(self.module_path) do
if modulename:sub(1, 1) ~= "." then
local m = ObjectMgr.create()
m._name = modulename
m._path = self.module_path .. modulename .. "/"
+ m._data_path = self.data_path .. modulename .. "/"
m:add_proto(module_ref)
m:preinit()
self._modules[modulename] = m
function module_manager:start_module(name)
local m = self._modules[name]
if not m then
- error("Failed to start module '" .. name .. "'.")
+ error("Module '" .. name .. "' not found.")
elseif m._started then
return
end
--- /dev/null
+local task_manager = {}
+
+function task_manager:init()
+ self._tasks = {}
+end
+
+function task_manager:add_task(f)
+ local t = coroutine.create(f)
+ table.insert(self._tasks, t)
+ return t
+end
+
+function task_manager:step()
+ local t_start = socket.gettime()
+ local tasks = self._tasks
+ self._tasks = {}
+ for _, t in ipairs(tasks) do
+ if coroutine.resume(t) then
+ table.insert(self._tasks, t)
+ end
+ end
+ self.tps = 1 / (socket.gettime() - t_start)
+end
+
+function task_manager:start_tasks()
+ repeat self:step()
+ until #self._tasks == 0
+end
+
+function task_manager:register_event_interface(e)
+ e._task_manager = self
+end
+
+return task_manager
local plain = not sep_is_pattern
max_splits = max_splits + 1
repeat
- local np, npe = string_find(str, delim, pos, plain)
+ local np, npe = string.find(str, delim, pos, plain)
np, npe = (np or (len+1)), (npe or (len+1))
if (not np) or (max_splits == 1) then
np = len + 1
npe = np
end
- local s = string_sub(str, pos, np - 1)
+ local s = string.sub(str, pos, np - 1)
if include_empty or (s ~= "") then
max_splits = max_splits - 1
items[#items + 1] = s