Skip to content

Commit

Permalink
Start refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
thegrb93 committed Aug 18, 2024
1 parent aec7433 commit 64d16b5
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 319 deletions.
71 changes: 38 additions & 33 deletions lua/entities/starfall_processor/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -77,50 +77,55 @@ function ENT:Think()
end

function ENT:GetSendData(toowner)
if not self.instance then return end

local ppdata = self.instance.ppdata
local senddata = {
owner = self.sfdata.owner,
files = {},
mainfile = self.sfdata.mainfile,
mainfile = ppdata:Get(self.sfdata.mainfile, "clientmain") or self.sfdata.mainfile,
proc = self
}
local ownersenddata

for k, v in pairs(self.sfdata.files) do senddata.files[k] = v end
local files = {} for k, v in pairs(self.sfdata.files) do files[k] = v end

local ppdata = self.instance and self.instance.ppdata
if ppdata then
if ppdata.serverorclient or (not toowner and ppdata.owneronly) then
for filename, code in pairs(senddata.files) do
local isserver, isowneronly = ppdata.serverorclient and ppdata.serverorclient[filename] == "server", ppdata.owneronly and ppdata.owneronly[filename]
if isserver or (not toowner and isowneronly) then
local infodata = {}
if ppdata.scriptnames and ppdata.scriptnames[filename] then
infodata[#infodata + 1] = "--@name " .. ppdata.scriptnames[filename]
end
if ppdata.scriptauthors and ppdata.scriptauthors[filename] then
infodata[#infodata + 1] = "--@author " .. ppdata.scriptauthors[filename]
end
infodata[#infodata + 1] = isserver and "--@server" or "--@owneronly"
senddata.files[filename] = table.concat(infodata, "\n")
end
end
for filename, fileppdata in pairs(ppdata.files) do
if fileppdata.owneronly then ownersenddata = true end
if fileppdata.serverorclient == "server" then
files[filename] = table.concat({
"--@name " .. (fileppdata.scriptname or ""),
"--@author " .. (fileppdata.scriptauthor or ""),
"--@server",
""
}, "\n")
end
local clientmain = ppdata.clientmain and ppdata.clientmain[self.sfdata.mainfile]
if clientmain then
if senddata.files[clientmain] then
senddata.mainfile = clientmain
else
clientmain = SF.NormalizePath(string.GetPathFromFilename(self.sfdata.mainfile) .. clientmain)
if senddata.files[clientmain] then
senddata.mainfile = clientmain
end
end

if ownersenddata then
local ownerfiles = {} for k, v in pairs(files) do ownerfiles[k] = v end

for filename, fileppdata in pairs(ppdata.files) do
if fileppdata.owneronly then
files[filename] = table.concat({
"--@name " .. (fileppdata.scriptname or ""),
"--@author " .. (fileppdata.scriptauthor or ""),
"--@owneronly",
""
}, "\n")
end
end

ownersenddata = {
owner = senddata.owner,
mainfile = senddata.mainfile,
proc = self,
files = ownerfiles,
compressed = SF.CompressFiles(ownerfiles)
}
end
senddata.compressed = SF.CompressFiles(senddata.files)

return senddata
senddata.files = files
senddata.compressed = SF.CompressFiles(files)

return senddata, ownersenddata
end

function ENT:SendCode(recipient)
Expand Down
28 changes: 9 additions & 19 deletions lua/entities/starfall_processor/shared.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,18 @@ function ENT:Compile(sfdata)
local ok, instance = SF.Instance.Compile(sfdata.files, sfdata.mainfile, self.owner, self)
if not ok then self:Error(instance) return end

if instance.ppdata.scriptnames and instance.mainfile and instance.ppdata.scriptnames[instance.mainfile] then
self.name = string.sub(tostring(instance.ppdata.scriptnames[instance.mainfile]), 1, 64)
else
self.name = "Generic ( No-Name )"
end
self.name = instance.ppdata:Get(instance.mainfile, "scriptname") or "Generic ( No-Name )"
self.author = instance.ppdata:Get(instance.mainfile, "scriptauthor") or "No-Author"

if instance.ppdata.scriptauthors and instance.mainfile and instance.ppdata.scriptauthors[instance.mainfile] then
self.author = string.sub(tostring(instance.ppdata.scriptauthors[instance.mainfile]), 1, 64)
else
self.author = nil
if SERVER then
local model = instance.ppdata:Get(instance.mainfile, "models")
if model then
pcall(function() self:SetCustomModel(SF.CheckModel(model, self.owner, true)) end)
end
end

self.instance = instance

instance.runOnError = function(err)
-- Have to make sure it's valid because the chip can be deleted before deinitialization and trigger errors
if IsValid(self) then
Expand Down Expand Up @@ -95,16 +94,7 @@ function ENT:SetupFiles(sfdata)
self:Compile(sfdata)

if SERVER and self.instance then
self.sfsenddata = self:GetSendData()
self.sfownerdata = self.instance and self.instance.ppdata and self.instance.ppdata.owneronly and self:GetSendData(true) or nil

if self.instance and self.instance.ppdata.models and self.instance.mainfile then
local model = self.instance.ppdata.models[self.instance.mainfile]
if model then
pcall(function() self:SetCustomModel(SF.CheckModel(model, self.owner, true)) end)
end
end

self.sfsenddata, self.sfownerdata = self:GetSendData()
self:SendCode()
end
end
Expand Down
155 changes: 2 additions & 153 deletions lua/starfall/editor/editor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,6 @@ if CLIENT then
permsPanel:Dock(FILL)
end

--- (Client) Builds a table for the compiler to use
-- @param mainfile Manual selection of which file should be main. Otherwise it's the open file
-- @return True if ok, false if a file was missing
-- @return A table with mainfile name and files
function SF.Editor.BuildIncludesTable(mainfile, success, err)
if not SF.Editor.initialized then SF.Editor.init() end

Expand All @@ -223,157 +219,10 @@ if CLIENT then
openfiles[mainfile] = SF.Editor.getCode()
end

local tbl = {}
tbl.mainfile = mainfile
tbl.files = {}

local ppdata = {}

local function getInclude(path)
return openfiles[path] or file.Read("starfall/" .. path, "DATA") or error("Bad include: " .. path)
end
local function getIncludePath(path, curdir)
local path = SF.ChoosePath(path, curdir, function(testpath)
return openfiles[testpath] or file.Exists("starfall/" .. testpath, "DATA")
end) or error("Bad include: " .. path)
return path, string.GetPathFromFilename(path)
end

local function recursiveLoad(codepath, codedir, code, dontParse)
if tbl.files[codepath] then return end
tbl.files[codepath] = code

if dontParse then return end

SF.Preprocessor.ParseDirectives(codepath, code, ppdata)

local clientmain = ppdata.clientmain and ppdata.clientmain[codepath]
if clientmain then
clientmain = getIncludePath(clientmain, codedir)
if clientmain then ppdata.clientmain[codepath] = clientmain end
end

local dontParseTbl = {}
local dataincludes = ppdata.includesdata and ppdata.includesdata[codepath]
if dataincludes then
for k, v in ipairs(dataincludes) do
local datapath = getIncludePath(v, codedir)
if datapath then dontParseTbl[datapath] = true end
end
end

local includes = ppdata.includes and ppdata.includes[codepath]
if includes then
for k, v in ipairs(includes) do
local codepath, codedir = getIncludePath(v, codedir)
local code = getInclude(codepath)
recursiveLoad(codepath, codedir, code, dontParseTbl[codepath])
end
end

if ppdata.includedirs and ppdata.includedirs[codepath] then
local inc = ppdata.includedirs[codepath]

for i = 1, #inc do
local origdir = inc[i]
local dir = origdir
local files
if string.sub(dir, 1, 1)~="/" then
dir = SF.NormalizePath(codedir .. origdir)
files = file.Find("starfall/" .. dir .. "/*", "DATA")
end
if not files or #files==0 then
dir = SF.NormalizePath(origdir)
files = file.Find("starfall/" .. dir .. "/*", "DATA")
end
for k, v in ipairs(files) do
local codepath, codedir = getIncludePath(v, dir.."/")
local code = getInclude(codepath)
recursiveLoad(codepath, codedir, code, dontParseTbl[codepath])
end
end
end
end

local ok, msg = pcall(function()
local codepath, codedir = getIncludePath(mainfile, string.GetPathFromFilename(mainfile))
local code = getInclude(codepath)
recursiveLoad(codepath, codedir, code)
end)

if not ok then
local file = string.match(msg, "(Bad include%: .*)")
return err(file or msg)
end

local clientmain = ppdata.clientmain and ppdata.clientmain[tbl.mainfile]
if clientmain and not tbl.files[clientmain] then
return err("Clientmain not found: " .. clientmain)
end

local includes = ppdata.includes
local serverorclient = ppdata.serverorclient
if includes and serverorclient then
for filename, files in pairs(includes) do
for _, inc in ipairs(files) do
if serverorclient[inc] and serverorclient[filename] and serverorclient[filename] ~= serverorclient[inc] then
return err("Incompatible client/server realm: \""..filename.."\" trying to include \""..inc.."\"")
end
end
end
end

SF.Editor.HandlePostProcessing(tbl, ppdata, success, err)
end

--- Handles post-processing (as part of BuildIncludesTable)
function SF.Editor.HandlePostProcessing(list, ppdata, onSuccessSignal, onErrorSignal)
if not ppdata.httpincludes then onSuccessSignal(list) return end
local files = list.files
local usingCache, pendingRequestCount = {}, 0 -- a temporary HTTP in-memory cache
-- First stage: Iterate through all http --@include directives in all files and prepare our HTTP queue structure.
for fileName, fileUsing in next, ppdata.httpincludes do
for _, data in next, fileUsing do
local url, name = data[1], data[2]
if not usingCache[url] then
usingCache[url] = name or true -- prevents duplicate requests to the same URL
pendingRequestCount = pendingRequestCount + 1
end
end
end
-- Second stage: Once we know the total amount of requests and URLs, we fetch all URLs as HTTP resources.
-- Then we wait for all HTTP requests to complete.
local function CheckAndUploadIfReady()
pendingRequestCount = pendingRequestCount - 1
if pendingRequestCount > 0 then return end
-- The following should run only once, at the end when there are no more pending HTTP requests:
-- Final stage: Substitute all http --@include directives with the contents of their HTTP response.
for fileName, fileUsing in next, ppdata.httpincludes do
local code = files[fileName]
for _, data in next, fileUsing do
local url, name = data[1], data[2]
local result = usingCache[url]
files[name] = result
end
end
onSuccessSignal(list)
end
for url in next, usingCache do
HTTP {
method = "GET";
url = url;
success = function(_, contents)
usingCache[url] = contents
CheckAndUploadIfReady()
end;
failed = function(reason)
onErrorSignal(string.format("Could not fetch --@include link (due %s): %s", reason, url))
end;
}
end
SF.Preprocessor():LoadFiles(openfiles, success, err)
end

function SF.Editor.createModelViewer ()
function SF.Editor.createModelViewer()
local frame = vgui.Create("StarfallFrame")
frame:SetTitle("Model Viewer - Click an icon to insert model filename into editor")
frame:SetVisible(false)
Expand Down
10 changes: 3 additions & 7 deletions lua/starfall/editor/sfframe.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1846,13 +1846,9 @@ function Editor:Close()
local activeWep = LocalPlayer():GetActiveWeapon()
if activeWep:IsValid() and activeWep:GetClass() == "gmod_tool" and activeWep.Mode == "starfall_processor" then
local model = nil
local ppdata = {}
pcall(SF.Preprocessor.ParseDirectives, "file", self:GetCode(), ppdata)
if ppdata.models and ppdata.models.file ~= "" then
model = ppdata.models.file
end

RunConsoleCommand("starfall_processor_ScriptModel", model or "")
local ppdata = SF.Preprocessor()
pcall(ppdata.ProcessFile, ppdata, "file", self:GetCode())
RunConsoleCommand("starfall_processor_ScriptModel", ppdata:Get("file", "models") or "")
end
hook.Run("StarfallEditorClose")
end
Expand Down
36 changes: 11 additions & 25 deletions lua/starfall/instance.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,13 @@ function SF.Instance.Compile(code, mainfile, player, entity)
instance.requires = {}
instance.permissionOverrides = {}

instance.ppdata = {}
for filename, source in pairs(code) do
local ok, err = pcall(SF.Preprocessor.ParseDirectives, filename, source, instance.ppdata)
if not ok then
return false, { message = err, traceback = "" }
end
end
instance.ppdata = SF.Preprocessor()
local ok, err = pcall(instance.ppdata.ProcessFiles, instance.ppdata, code)
if not ok then return false, { message = err, traceback = "" } end

if player:IsWorld() then
player = SF.Superuser
elseif instance.ppdata.superuser and instance.ppdata.superuser[mainfile] then
elseif instance.ppdata:Get(mainfile, "superuser") then
if not SF.AllowSuperUser:GetBool() then return false, { message = "Can't use --@superuser unless sf_superuserallowed is enabled!", traceback = "" } end
local ok, message = hook.Run("StarfallCanSuperUser", player)
if ok == false or (ok == nil and not player:IsSuperAdmin()) then return false, { message = message or "Can't use --@superuser unless you are superadmin!", traceback = "" } end
Expand Down Expand Up @@ -119,30 +115,20 @@ function SF.Instance.Compile(code, mainfile, player, entity)
return false, { message = "", traceback = err }
end

local doNotRun = {}
local includesdata = instance.ppdata.includesdata
if includesdata then
for filename, t in pairs(includesdata) do
for _, datapath in ipairs(t) do
local codepath = SF.ChoosePath(datapath, string.GetPathFromFilename(filename), function(testpath)
return instance.source[testpath]
end)
if codepath then doNotRun[codepath] = true end
end
end
end

local serverorclientpp, owneronlypp = instance.ppdata.serverorclient or {}, instance.ppdata.owneronly or {}
for filename, source in pairs(code) do
if doNotRun[filename] then continue end -- Don't compile data files
if CLIENT and owneronlypp[filename] and LocalPlayer() ~= player then continue end -- Don't compile owner-only files if not owner
local serverorclient = serverorclientpp[filename]
local ppfiledata = instance.ppdata.files[filename]

if instance.ppdata.datafiles[filename] then continue end -- Don't compile data files
if CLIENT and ppfiledata.owneronly and LocalPlayer() ~= player then continue end -- Don't compile owner-only files if not owner
local serverorclient = ppfiledata.serverorclient
if (serverorclient == "server" and CLIENT) or (serverorclient == "client" and SERVER) then continue end -- Don't compile files for other realm

local func = SF.CompileString(source, "SF:"..filename, false)
if isstring(func) then
return false, { message = func, traceback = "" }
end
debug.setfenv(func, instance.env)

instance.scripts[filename] = func
end

Expand Down
Loading

0 comments on commit 64d16b5

Please sign in to comment.