- Joined
- Apr 27, 2008
- Messages
- 2,455
So, i was looking for a way to build library and requirements directly inside the editor.
I thought about that :
the InitGlobals hook is directly copied/paste from Bribe's library
Then, all you need is to build packages :
If you want an initializer create a method spelled init.
Each initializers will be called in a correct order (checking for requirements), unlike Bribe's method, but i know it can be changed, i'm just saying.
If you want requirements create a table in your package spelled uses
Like these examples :
I'm totally aware that it doesn't handle cycle requirements, (A requires B and B requires A).
In this case it should raise an error.
For now it's just a proof of concept, it can be improved later.
What do you think about that concept ?
EDIT : Requirement cycle error detected now.
It won't raise an error if there is no initializer on a circle requirement (A uses B, B uses A).
Because it's simply how it was build.
It only handles initializers orders according requirements.
Functions, global variables, list, whatever ... of packages will already be on the global space when the InitGlobals hook will be done, so it only needs to do that.
But that also mean you must use functions and call them from initializers instead of just writing code outside the package (unless you don't care when it runs).
I thought about that :
Lua:
do
local function runGlobalInit()
local n = 0
local q_pos= {} -- relative order of packages according requirements and initializers
local packages={} -- found packages in global env
local packages_name = {}
local req_list = {}
local function isCircleReq(pack,req)
if (req_list[pack])[req] and (req_list[req])[pack] then
local s = "requirement error : packages "..pack.." and "..req.." need both each others"
print(s) ; error(s)
return true
end
end
for pack,code in pairs(_ENV) do -- searching for all packages in global env
if not packages[pack] and type(code)=="table" and type(code.init)=="function" then -- matching packages
packages[pack]=code
table.insert(packages_name,pack)
req_list[pack]={}
end
end
table.sort(packages_name) -- sorting table so everyone will have the same input
for _ , pack in ipairs(packages_name) do
local code = packages[pack]
if not q_pos[pack] then -- package not yet in the list
n = n+1
q_pos[pack] = n
end
if code.uses then
for _ , req in ipairs(code.uses) do -- scrolling package requirements
if packages[req] then -- valid package requirement
if not q_pos[req] then -- required package not yet in the list
for key,value in pairs(q_pos) do
q_pos[key] = value+1
end
n = n+1
q_pos[req] = 1
elseif q_pos[req] > q_pos[pack] then
q_pos[req] , q_pos[pack] = q_pos[pack] , q_pos[req]
end
(req_list[pack])[req] = true
if isCircleReq(pack,req) then return end
for k , v in pairs(req_list[req]) do
req_list[pack][k]=true
if isCircleReq(pack,k) then return end
end
end
end
end
end
local t = {}
for k,v in pairs(q_pos) do t[v]=k end
for _ , v in ipairs(t) do
local f = packages[v].init
if f then f() end
end
end
local old = InitGlobals
if old then
function InitGlobals()
old()
runGlobalInit()
end
else
runGlobalInit()
end
end
the InitGlobals hook is directly copied/paste from Bribe's library
Then, all you need is to build packages :
If you want an initializer create a method spelled init.
Each initializers will be called in a correct order (checking for requirements), unlike Bribe's method, but i know it can be changed, i'm just saying.
If you want requirements create a table in your package spelled uses
Like these examples :
Lua:
Aa={}
function Aa.init()
print("A init")
end
Aa.uses={
"Cc";
"Bb";
}
Dd={}
Dd.uses={
"Aa"
}
function Dd.init()
print("D init")
end
Bb={
}
function Bb.init()
print("B init")
end
Cc={
}
function Cc.init()
print("C init")
end
In this case it should raise an error.
For now it's just a proof of concept, it can be improved later.
What do you think about that concept ?
EDIT : Requirement cycle error detected now.
It won't raise an error if there is no initializer on a circle requirement (A uses B, B uses A).
Because it's simply how it was build.
It only handles initializers orders according requirements.
Functions, global variables, list, whatever ... of packages will already be on the global space when the InitGlobals hook will be done, so it only needs to do that.
But that also mean you must use functions and call them from initializers instead of just writing code outside the package (unless you don't care when it runs).
Last edited: