aboutsummaryrefslogtreecommitdiff
path: root/gamemode/nrequire.lua
diff options
context:
space:
mode:
authorAlexander Pickering <alexandermpickering@gmail.com>2017-05-20 11:37:23 -0400
committerAlexander Pickering <alexandermpickering@gmail.com>2017-05-20 11:37:23 -0400
commitc6698dad925e75ffd2ca2f2e30a595d4ce48d240 (patch)
tree226338dc7ee26a6316951554cf953112ba072c76 /gamemode/nrequire.lua
parent9e0537b0aa417e88a6a61238484ddcef74080ae0 (diff)
downloadartery-c6698dad925e75ffd2ca2f2e30a595d4ce48d240.tar.gz
artery-c6698dad925e75ffd2ca2f2e30a595d4ce48d240.tar.bz2
artery-c6698dad925e75ffd2ca2f2e30a595d4ce48d240.zip
Massive changes I guess
Diffstat (limited to 'gamemode/nrequire.lua')
-rw-r--r--gamemode/nrequire.lua41
1 files changed, 32 insertions, 9 deletions
diff --git a/gamemode/nrequire.lua b/gamemode/nrequire.lua
index 6595fed..1fc70bd 100644
--- a/gamemode/nrequire.lua
+++ b/gamemode/nrequire.lua
@@ -1,12 +1,15 @@
--[[
A thing that kinda works like require, or at least, works how I wish require worked.
+ calls hooks:
+ artery_nrequire_defined
+ artery_core_loaded
]]
--Don't run ourselves, or we'll get stuck in a recursive loop!
if nrequire ~= nil then return end
print("hello from nrequire!")
local path = (GM or GAMEMODE).Folder:gsub("gamemodes/","") .. "/gamemode"
--[[
- Calls func on all the files under dir
+ Calls func on all the files under dir.
]]
local function TraverseFolder(dir, func)
local fpath = table.concat({path,dir,"/*"})
@@ -102,6 +105,7 @@ local function scan(pretbl, name)
pathparts[#pathparts + 1] = part:gsub("/$",""):gsub("^/","")
end
local filename = name:gfind("[%w_]+%.lua")()
+ assert(filename ~= nil,string.format("Could not file a filename for %q from parts: %s valid files are:\n\t%s",name,table.concat(pathparts,","),table.concat(collect_paths(pretbl),"\n\t")))
local cursor = pretbl[filename]
assert(cursor ~= nil,string.format("Scan did not find a file named %q, valid files are:\n\t%s",filename,table.concat(collect_paths(pretbl),"\n\t")))
local rev = {}
@@ -126,39 +130,58 @@ local ntbl = rebuild_include_table(paths)
local reqtbl = {}
for k,v in pairs(paths) do
if SERVER and not v:match("/?sv_[%w_]+%.lua$") then
- print("Adding CS lua file",v)
+ --print("Adding CS lua file",v)
AddCSLuaFile(v)
end
end
local pathstack = {}
+local coroutines = {}
--[[
Returns the table returned by executing a file. The table is cached after is is loaded, so calling nrequire() on a file twice will only run it once.
]]
function nrequire(req)
- local tpath = scan(ntbl,req)
- if reqtbl[tpath] then
- --print("Cache hit! returning",reqtbl[tpath])
- --for k,v in pairs(reqtbl[tpath]) do print(k,":",v) end
+ local tpath = scan(ntbl,req) --Find the full path from partial path
+ if reqtbl[tpath] then --And just return it if we've already included it.
return reqtbl[tpath]
end
+ --Otherwise, make sure we don't have a circular dependancy
for k,v in pairs(pathstack) do
assert(v ~= tpath,string.format("Circular dependancy detected:\n\t%s\n\t\t|\n\t\tV\n\t%s",table.concat(pathstack,"\n\t\t|\n\t\tV\n\t"),v))
end
+
+ --Override print so it's easy to see what file is printing what
local tab_rep = {}
for k = 1, #pathstack do tab_rep[k] = "\t" end
- print(string.format("%sIncluding %q",table.concat(tab_rep),tpath))
+ --print(string.format("%sIncluding %q",table.concat(tab_rep),tpath))
local oldprint = print
print = function(...) oldprint(" ",unpack({...})) end
+
+ --Deal with bookkeeping dealing with circular dependancies, and include
pathstack[#pathstack + 1] = tpath
- reqtbl[tpath] = include(tpath)
+ co = coroutine.create(function()
+ reqtbl[tpath] = include(tpath)
+ --print("Finished ", tpath)
+ end)
+ coroutines[#coroutines + 1] = co
+ coroutine.resume(co)
pathstack[#pathstack] = nil
+
+ --Try to resume everyone else waiting on something
+ for k,v in pairs(coroutines) do
+ --V will be nil when the coroutine finishes, which removes it from the list, nifty.
+ coroutine.resume(v)
+ end
+
+ --Undo the crazy print
print = oldprint
- print(string.format("%sIncluded %q",table.concat(tab_rep),tpath))
+ --print(string.format("%sIncluded %q",table.concat(tab_rep),tpath))
return reqtbl[tpath]
end
+hook.Call("artery_nrequire_defined")
+
--[[
Automatically include all the files in the gamemode directory based on the file name.
If the file starts with cl_ it will only be included on the client, if it starts with sv_ it will only be included on the server. If it starts with anything else, it will be shared. Will detect and error on circuar dependancy.