Skip to content

Instantly share code, notes, and snippets.

@devSparkle
Last active May 12, 2017 18:21
Show Gist options
  • Save devSparkle/634ea5831c04ffe10904cc4fedf3c041 to your computer and use it in GitHub Desktop.
Save devSparkle/634ea5831c04ffe10904cc4fedf3c041 to your computer and use it in GitHub Desktop.
My own flavor of the Nevermore framework by @Quenty
--// Initialization
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Engine = {}
--// Variables
local RepositoryName = "Modules"
local DEBUG_MODE = false
--// Functions
local function Modify(Instance, Values)
assert(type(Values) == "table", "Error: Values is not a table.")
for Index, Value in next, Values do
if type(Index) == "number" then
Value.Parent = Instance
else
Instance[Index] = Value
end
end
return Instance
end
local function Make(ClassType, Properties)
return Modify(Instance.new(ClassType), Properties)
end
local function CallOnChildren(Instance, FunctionToCall)
FunctionToCall(Instance)
for ChildIndex, Child in next, Instance:GetChildren() do
CallOnChildren(Child, FunctionToCall)
end
end
local function HandleRetrieving(Retrieving, Function, Argument)
assert(type(Retrieving) == "table", "Error: Retrieving must be a table.")
assert(type(Function) == "function", "Error: Function must be a function.")
local Signal = Instance.new("BindableEvent")
local Result
Retrieving[Argument] = function()
return Result ~= nil and Result or Signal.Event:wait()
end;
Result = Function(Argument)
Retrieving[Argument] = nil
Signal:Fire(Result)
return Result
end
local function Cache(Function)
assert(type(Function) == "function", "Error: Function must be a userdata.")
local Cache = {}
local Retrieving = {}
return function(Argument)
assert(Argument ~= nil, "Error: Argument is nil.")
if Cache[Argument] then
return Cache[Argument]
elseif Retrieving[Argument] then
return Retrieving[Argument]()
else
Cache[Argument] = HandleRetrieving(Retrieving, Function, Argument)
return Cache[Argument]
end
end
end
local function Retrieve(Parent, ClassName)
assert(type(ClassName) == "string", "Error: ClassName must be a string")
assert(type(Parent) == "userdata", "Error: Parent must be a userdata")
return RunService:IsServer() and function(Name)
if DEBUG_MODE then
print(ClassName,Name)
end
return Parent:FindFirstChild(Name) or Make(ClassName, {
Parent = Parent;
Archivable = false;
Name = Name;
})
end or function(Name)
return Parent:WaitForChild(Name)
end
end
--// Engine
local ResourceFolder = Retrieve(ReplicatedStorage, "Folder")("EngineResources")
local _LibraryCache = {} do
local Repository
if RunService:IsServer() then
Repository = ServerScriptService:FindFirstChild(RepositoryName)
if not Repository then
warn("Warning: No repository of modules found (Expected in ServerScriptService with name \"Engine\"). Library retrieval will fail.")
Repository = Instance.new("Folder")
Repository.Name = RepositoryName
end
else
Repository = ResourceFolder:WaitForChild("Modules")
end
CallOnChildren(Repository, function(Child)
if Child:IsA("ModuleScript") then
assert(not _LibraryCache[Child.Name], "Error: Duplicate name of \"" .. Child.Name .. "\" already exists!")
_LibraryCache[Child.Name] = Child
end
end)
if not RunService:IsClient() then --/ Written in this way to prevent issues with SoloTestMode.
local ReplicationFolder = ResourceFolder:FindFirstChild("Modules") or Make("Folder", {
Name = "Modules";
Archivable = false;
Parent = ResourceFolder;
})
local Secondary
for Name, Library in pairs(_LibraryCache) do
if not Name:lower():find("server") then
Library.Parent = ReplicationFolder
end
end
end
end
do
local SecondCache = {}
local DebugID = 0
local RequestDepth = 0
function Engine.LoadLibrary(LibraryName)
assert(type(LibraryName) == "string", "Error: LibraryName must be a string!")
if SecondCache[LibraryName] then
return SecondCache[LibraryName]
end
DebugID = DebugID + 1
local LocalDebugID = DebugID
if DEBUG_MODE then
print(("\t"):rep(RequestDepth), LocalDebugID, "Loading: ", LibraryName)
RequestDepth = RequestDepth + 1
end
local Library = require(_LibraryCache[LibraryName] or error("Error: Library \"" .. LibraryName .. "\" does not exist."))
SecondCache[LibraryName] = Library
if DEBUG_MODE then
RequestDepth = RequestDepth - 1
print(("\t"):rep(RequestDepth), LocalDebugID, "Done Loading: ", LibraryName)
end
return Library
end
end
Engine.GetRemoteEvent = Cache(Retrieve(Retrieve(ResourceFolder, "Folder")("RemoteEvents"), "RemoteEvent"))
Engine.GetBindableEvent = Cache(Retrieve(Retrieve(ResourceFolder, "Folder")("BindableEvents"), "BindableEvent"))
Engine.GetRemoteFunction = Cache(Retrieve(Retrieve(ResourceFolder, "Folder")("RemoteFunctions"), "RemoteFunction"))
Engine.GetBindableFunction = Cache(Retrieve(Retrieve(ResourceFolder, "Folder")("BindableFunctions"), "BindableFunction"))
return Engine
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment