Initial commit
commit
4ca6689e97
|
@ -0,0 +1,2 @@
|
|||
/client/
|
||||
/server/
|
|
@ -0,0 +1,6 @@
|
|||
[submodule "moongl"]
|
||||
path = deps/moongl
|
||||
url = https://github.com/stetre/moongl
|
||||
[submodule "moonglfw"]
|
||||
path = deps/moonglfw
|
||||
url = https://github.com/stetre/moonglfw
|
|
@ -0,0 +1,7 @@
|
|||
depends:
|
||||
$ sudo apt install lua5.3 libsqlite3
|
||||
$ luarocks install lsqlite3
|
||||
$ luarocks install luasocket
|
||||
$ luarocks install luafilesystem
|
||||
|
||||
Build moongl and moonglfw: See build README.md in deps/moongl and deps/moonglfw
|
|
@ -0,0 +1,17 @@
|
|||
#! /usr/bin/env lua
|
||||
require("lfs")
|
||||
require("socket")
|
||||
require("lsqlite3")
|
||||
require("moongl")
|
||||
require("moonglfw")
|
||||
require("util/objectmgr")
|
||||
require("util/split")
|
||||
require("util/indexof")
|
||||
|
||||
Dragonblocks = ObjectMgr.create()
|
||||
|
||||
require("src/init")
|
||||
|
||||
Dragonblocks:init()
|
||||
|
||||
Dragonblocks:start_module(arg[1] or "Menu")
|
|
@ -0,0 +1,4 @@
|
|||
print("Success!")
|
||||
Menu:add_proto(Dragonblocks.serializer)
|
||||
Menu:init()
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
local class = {}
|
||||
|
||||
local instance_metatable = {
|
||||
__index = function(t, k)
|
||||
if k == "_call" then return end
|
||||
local f = rawget(t._class, k)
|
||||
if type(f) == "function" then
|
||||
return f
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
function class:_call(...)
|
||||
local o = {class = self}
|
||||
setmetatable(o, instance_metatable)
|
||||
if o.constructor then
|
||||
o:constructor(table.unpack(...))
|
||||
end
|
||||
end
|
||||
|
||||
return class
|
|
@ -0,0 +1,40 @@
|
|||
local event_interface = {}
|
||||
|
||||
function event_interface:init()
|
||||
self:clear_event_listeners()
|
||||
end
|
||||
|
||||
function event_interface:fire_event(eventtype, event)
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
function event_interface:add_event_listener(eventtype, eventlistener)
|
||||
self._event_listeners[eventtype] = self._event_listeners[eventtype] or {}
|
||||
table.insert(self._event_listeners[eventtype], eventlistener)
|
||||
end
|
||||
|
||||
function event_interface:remove_event_listener(eventtype, eventlistener)
|
||||
local listeners = self._event_listeners[eventtype]
|
||||
if listeners then
|
||||
for k, listener in ipairs(listeners) do
|
||||
if listener == eventlistener then
|
||||
table.remove(k)
|
||||
return self:removeEventListener(eventtype, eventlistener)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function event_interface:clear_event_listeners()
|
||||
self._event_listeners = {}
|
||||
end
|
||||
|
||||
return event_interface
|
|
@ -0,0 +1,7 @@
|
|||
Dragonblocks.event_interface = require("src/event_interface")
|
||||
Dragonblocks.class = require("src/class")
|
||||
Dragonblocks.module_manager = require("src/module_manager")
|
||||
Dragonblocks.serializer = require("src/serializer")
|
||||
|
||||
Dragonblocks:add_proto(Dragonblocks.module_manager)
|
||||
Dragonblocks:add_proto(Dragonblocks.serializer)
|
|
@ -0,0 +1,54 @@
|
|||
local module_ref = {}
|
||||
|
||||
function module_ref:preinit()
|
||||
self._dependencies = {}
|
||||
self._started = false
|
||||
local depfile = io.open(self._path .. "/.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:start()
|
||||
_G[self._name] = self
|
||||
require(self._path .. "src/init")
|
||||
end
|
||||
|
||||
local module_manager = {}
|
||||
|
||||
module_manager.module_path = "modules/"
|
||||
|
||||
function module_manager:init()
|
||||
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:add_proto(module_ref)
|
||||
m:preinit()
|
||||
self._modules[modulename] = m
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function module_manager:start_module(name)
|
||||
local m = self._modules[name]
|
||||
if not m then
|
||||
error("Failed to start module '" .. name .. "'.")
|
||||
elseif m._started then
|
||||
return
|
||||
end
|
||||
for _, dep in ipairs(m._dependencies) do
|
||||
self:start_module(dep)
|
||||
end
|
||||
m:start()
|
||||
end
|
||||
|
||||
return module_manager
|
|
@ -0,0 +1,49 @@
|
|||
local serializer = {}
|
||||
|
||||
function serializer:serialize()
|
||||
local data = "{"
|
||||
for k, v in pairs(self) do
|
||||
local kdata, vdata
|
||||
local ktype, vtype = type(k), type(v)
|
||||
local serialize_pair = true
|
||||
if ktype == "number" then
|
||||
kdata = "[" .. k .. "]"
|
||||
elseif ktype == "string" then
|
||||
if k:sub(1, 1) == "_" then
|
||||
serialize_pair = false
|
||||
else
|
||||
kdata = "[\"" .. k .. "\"]"
|
||||
end
|
||||
else
|
||||
serialize_pair = false
|
||||
end
|
||||
if vtype == "table" then
|
||||
vdata = serializer.serialize(v)
|
||||
elseif vtype == "string" then
|
||||
vdata = "\"" .. v .. "\""
|
||||
elseif vtype == "number" then
|
||||
vdata = v
|
||||
elseif vtype == "boolean" then
|
||||
vdata = v and "true" or "false"
|
||||
else
|
||||
serialize_pair = false
|
||||
end
|
||||
if serialize_pair then
|
||||
data = data .. kdata .. "=" .. vdata .. ","
|
||||
end
|
||||
end
|
||||
return data .. "}"
|
||||
end
|
||||
|
||||
function serializer:deserialize(raw)
|
||||
raw = "return" .. (raw or "")
|
||||
local f = loadstring(raw)
|
||||
local data = f and f()
|
||||
if type(data) == "table" then
|
||||
for k, v in pairs(data) do
|
||||
self[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return serializer
|
|
@ -0,0 +1,8 @@
|
|||
function table.indexof(list, val)
|
||||
for i, v in ipairs(list) do
|
||||
if v == val then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return -1
|
||||
end
|
|
@ -0,0 +1,39 @@
|
|||
local ObjectRef = {}
|
||||
|
||||
function ObjectRef:init()
|
||||
for _, p in ipairs(self._proto) do
|
||||
if p ~= ObjectRef and p.init then
|
||||
p.init(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ObjectRef:add_proto(p)
|
||||
table.insert(self._proto, p)
|
||||
end
|
||||
|
||||
ObjectMgr = {}
|
||||
|
||||
ObjectMgr.metatable = {
|
||||
__index = function(t, k)
|
||||
for _, p in ipairs(t._proto) do
|
||||
local v = p[k]
|
||||
if v then
|
||||
return v
|
||||
end
|
||||
end
|
||||
end,
|
||||
__call = function(t, ...)
|
||||
return t:_call()
|
||||
end,
|
||||
__tostring = function(t)
|
||||
return t.serialize and t:serialize() or "<not serializable>"
|
||||
end,
|
||||
}
|
||||
|
||||
function ObjectMgr.create()
|
||||
local o = {}
|
||||
o._proto = {ObjectRef}
|
||||
setmetatable(o, ObjectMgr.metatable)
|
||||
return o
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
function string.split(str, delim, include_empty, max_splits, sep_is_pattern)
|
||||
delim = delim or ","
|
||||
max_splits = max_splits or -2
|
||||
local items = {}
|
||||
local pos, len = 1, #str
|
||||
local plain = not sep_is_pattern
|
||||
max_splits = max_splits + 1
|
||||
repeat
|
||||
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)
|
||||
if include_empty or (s ~= "") then
|
||||
max_splits = max_splits - 1
|
||||
items[#items + 1] = s
|
||||
end
|
||||
pos = npe + 1
|
||||
until (max_splits == 0) or (pos > (len + 1))
|
||||
return items
|
||||
end
|
Loading…
Reference in New Issue