diff --git a/src/DataSync/Methods.lua b/src/DataSync/Methods.lua index 13dcde3..1ed3d43 100644 --- a/src/DataSync/Methods.lua +++ b/src/DataSync/Methods.lua @@ -7,9 +7,9 @@ local Methods = {} Methods._Occupants = {} Methods._MaxRetries = 5 -local Loader = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) -local Manager = Loader('Manager') -local DataStoreService = Loader['DataStoreService'] +local require = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) +local Manager = require('Manager') +local DataStoreService = game:GetService('DataStoreService') --[=[ Load DataStore @@ -45,7 +45,6 @@ function Methods.LoadData(key: string, index: string, file: table): table & bool end if last == nil then - print('LOADED DEEP COPY') last = Manager.DeepCopy(file) elseif typeof(last) == 'table' then for index,value in pairs(file) do diff --git a/src/DataSync/Subscribe.lua b/src/DataSync/Subscribe.lua index e4a0617..b719278 100644 --- a/src/DataSync/Subscribe.lua +++ b/src/DataSync/Subscribe.lua @@ -4,19 +4,19 @@ ]=] local Subscribe = {} -Subscribe.Cache = {} -Subscribe.All = {} -Subscribe.Remotes = { +Subscribe._Cache = {} +Subscribe._All = {} +Subscribe._Remotes = { ['Download'] = '_DOWNLOAD'; ['Upload'] = '_UPLOAD'; ['Subscribe'] = '_SUBSCRIBE'; } -local Loader = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) -local Manager = Loader('Manager') -local Network = Loader('Network') -local Players = Loader['Players'] -local RunService = Loader['RunService'] +local require = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) +local Manager = require('Manager') +local Network = require('Network') +local Players = game:GetService('Players') +local RunService = game:GetService('RunService') --[=[ Get a player from an index @@ -53,22 +53,22 @@ end @private ]=] local function GetCache(key: string, index: string, value: string): table - if not Subscribe.Cache[key] then - Subscribe.Cache[key] = {} + if not Subscribe._Cache[key] then + Subscribe._Cache[key] = {} end - if not Subscribe.Cache[key][index] then - Subscribe.Cache[key][index] = {} + if not Subscribe._Cache[key][index] then + Subscribe._Cache[key][index] = {} end - if not Subscribe.Cache[key][index][value] then - Subscribe.Cache[key][index][value] = { + if not Subscribe._Cache[key][index][value] then + Subscribe._Cache[key][index][value] = { ['Clients'] = {}; ['Code'] = {}; } end - return Subscribe.Cache[key][index][value] + return Subscribe._Cache[key][index][value] end --[=[ @@ -80,18 +80,18 @@ end @private ]=] local function GetAll(key: string, index: string): table - if not Subscribe.All[key] then - Subscribe.All[key] = {} + if not Subscribe._All[key] then + Subscribe._All[key] = {} end - if not Subscribe.All[key][index] then - Subscribe.All[key][index] = { + if not Subscribe._All[key][index] then + Subscribe._All[key][index] = { ['Clients'] = {}; ['Code'] = {}; } end - return Subscribe.All[key][index] + return Subscribe._All[key][index] end --[=[ @@ -117,14 +117,14 @@ function Subscribe.FireSubscription(key: any, index: any, value: any, data: any) for count,client in pairs(cache['Clients']) do Manager.wrap(function() table.insert(sent,client) - Network:FireClient(Subscribe.Remotes.Download,client,key,index,value,data) + Network:FireClient(Subscribe._Remotes.Download,client,key,index,value,data) end) end for count,client in pairs(all['Clients']) do Manager.wrap(function() if not table.find(sent,client) then - Network:FireClient(Subscribe.Remotes.Download,client,key,index,value,data) + Network:FireClient(Subscribe._Remotes.Download,client,key,index,value,data) end end) end @@ -191,14 +191,14 @@ function Subscribe.ConnectSubscription(info: Instance | any, key: any, index: an end end - Subscribe.Cache[key][index][value] = cache + Subscribe._Cache[key][index][value] = cache if all then - Subscribe.All[key][index] = all + Subscribe._All[key][index] = all end if Manager.IsClient then - Network:FireServer(Subscribe.Remotes.Subscribe,key,index,value) + Network:FireServer(Subscribe._Remotes.Subscribe,key,index,value) end end @@ -245,10 +245,10 @@ function Subscribe.DisconnectSubscription(info: Instance | any, key: any, index: end end - Subscribe.Cache[key][index][value] = nil + Subscribe._Cache[key][index][value] = nil if all then - Subscribe.All[key][index] = all + Subscribe._All[key][index] = all end end diff --git a/src/DataSync/init.lua b/src/DataSync/init.lua index 3e6cde8..16d31cc 100644 --- a/src/DataSync/init.lua +++ b/src/DataSync/init.lua @@ -71,7 +71,6 @@ local DataSync = {} DataSync.__index = DataSync DataSync._Name = string.upper(script.Name) -DataSync._Error = '['.. DataSync._Name ..']: ' DataSync._ShuttingDown = false DataSync._Private = '__' DataSync._Cache = {} @@ -95,13 +94,13 @@ DataSync.AutoSaveTimer = 30 -- how often, in seconds, a DataFile autosaves DataSync.FailProof = true -- kick the player if the datastore failed loading player-based data DataSync.All = 'all' -- the 'all' variable for streamlining data types -local Loader = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) -local Manager = Loader('Manager') -local Network = Loader('Network') -local Methods = Loader(script:WaitForChild('Methods')) -local Subscribe = Loader(script:WaitForChild('Subscribe')) -local Players = Loader['Players'] -local RunService = Loader['RunService'] +local require = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) +local Manager = require('Manager') +local Network = require('Network') +local Methods = require(script:WaitForChild('Methods')) +local Subscribe = require(script:WaitForChild('Subscribe')) +local Players = game:GetService('Players') +local RunService = game:GetService('RunService') --[=[ Get the Player from either the instance or UserId @@ -167,10 +166,10 @@ end @param filter? boolean -- if true, only save these keys, if false, don't save those keys ]=] function DataSync:FilterKeys(keys: table, filter: boolean?): typeof(DataSync.GetStore()) - assert(self._key,DataSync._Error.."':FilterKeys' can only be used with a store") + assert(self._key,"':FilterKeys' can only be used with a store") if not DataSync._Defaults[self._key] then - warn(DataSync._Error..'Unable to set filter, no Default Data table found') + warn('Unable to set filter, no Default Data table found') return self end @@ -178,7 +177,7 @@ function DataSync:FilterKeys(keys: table, filter: boolean?): typeof(DataSync.Get ['Keys'] = keys; ['Type'] = filter and 'Whitelist' or 'Blacklist' } - print(self._key,DataSync._Filters[self._key]) + return self end @@ -189,7 +188,7 @@ end @return DataFileObject ]=] function DataSync:GetFile(index: string | number | nil): typeof(DataSync:GetFile()) - assert(self._key,DataSync._Error.."':GetFile' can only be used with a store") + assert(self._key,"':GetFile' can only be used with a store") if not index and Manager.IsClient and Players.LocalPlayer then index = tostring(Players.LocalPlayer.UserId) @@ -214,6 +213,14 @@ function DataSync:GetFile(index: string | number | nil): typeof(DataSync:GetFile if not DataSync._Cache[self._key][index] and Manager.IsServer and not self._sesh then self._sesh = true + if not DataSync._Defaults[self._key] then + while not DataSync._Files[index] do + Manager.wait() + end + + return DataSync._Files[index] + end + local load,success = Methods.LoadData(self._key,index,DataSync._Defaults[self._key]) if not success then if load == '__OCCUPIED' or DataSync._Sessions[index] then @@ -224,10 +231,10 @@ function DataSync:GetFile(index: string | number | nil): typeof(DataSync:GetFile return DataSync._Files[index] end - warn(DataSync._Error..'DataStores are currently down; returning default data') + warn('DataStores are currently down; returning default data') if player and not Manager.IsStudio and DataSync.FailProof then - player:Kick('\n'.. DataSync._Error ..'DataStores are currently down, please try again later') + player:Kick('\n'..'DataStores are currently down, please try again later') return nil end @@ -296,7 +303,7 @@ end @return DataValue | DataFile? ]=] function DataSync:GetData(value: string | number | nil): any? | table - assert(self._file,DataSync._Error.."':GetData' can only be used with a data file") + assert(self._file,"':GetData' can only be used with a data file") local file = DataSync._Cache[self._key][self._file] @@ -326,7 +333,7 @@ end @return DataFileObject ]=] function DataSync:UpdateData(value: string, data: any?): typeof(DataSync:GetFile()) - assert(self._file,DataSync._Error.."':UpdateData' can only be used with a data file") + assert(self._file,"':UpdateData' can only be used with a data file") local file = DataSync._Cache[self._key][self._file] if data == nil and DataSync._Defaults[self._key][value] ~= nil then @@ -372,13 +379,13 @@ end @return DataFileObject ]=] function DataSync:IncrementData(value: string, num: number): typeof(DataSync:GetFile()) - assert(self._file,DataSync._Error.."':UpdateData' can only be used with a data file") + assert(self._file,"':UpdateData' can only be used with a data file") local current = self:GetData(value) if typeof(current) == 'number' then self:UpdateData(value,current + num) else - error(DataSync._Error.."':IncrementData' failed, tried to increment a non-number") + error("':IncrementData' failed, tried to increment a non-number") end return self @@ -390,7 +397,7 @@ end @return DataFileObject ]=] function DataSync:SaveData(override: boolean?): typeof(DataSync:GetFile()) - assert(self._file,DataSync._Error.."':SaveData' can only be used with a data file") + assert(self._file,"':SaveData' can only be used with a data file") assert(Manager.IsServer,"':SaveData' only works on the server") if (DataSync._ShuttingDown and not override) or self._sesh then @@ -419,7 +426,7 @@ function DataSync:SaveData(override: boolean?): typeof(DataSync:GetFile()) local load,success = Methods.SaveData(self._key,self._file,clone) if not success then - warn(DataSync._Error.."!URGENT! Failed to save file '"..self._file.."' on store '"..self._key.."'") + warn("!URGENT! Failed to save file '"..self._file.."' on store '"..self._key.."'") end if DataSync._Cache[self._key][self._file] then @@ -437,7 +444,7 @@ end @return DestroyedDataFileObject ]=] function DataSync:RemoveData(override: boolean?): typeof(DataSync:RemoveData()) - assert(self._file,DataSync._Error.."':RemoveData' can only be used with a data file") + assert(self._file,"':RemoveData' can only be used with a data file") if self._sesh then return self end if DataSync._ShuttingDown and not override then @@ -468,7 +475,7 @@ end @Return DataFileObject ]=] function DataSync:WipeData(): typeof(DataSync:GetFile()) - assert(self._file,DataSync._Error.."':WipeData' can only be used with a data file") + assert(self._file,"':WipeData' can only be used with a data file") assert(Manager.IsServer,"':SaveData' only works on the server") Methods.WipeData(self._key,self._file) @@ -484,7 +491,7 @@ end @param code function -- the function which to be called whenever the value changes ]=] function DataSync:Subscribe(index: string | number | Player, value: string, code: (any) -> nil, _sent: Player?): typeof(DataSync:Subscribe()) - assert(self._key,DataSync._Error.."':Subscribe' can only be used with a store") + assert(self._key,"':Subscribe' can only be used with a store") local index,player = tostring(GetPlayer(index)) local player = Manager.IsClient and Players.LocalPlayer or Manager.IsServer and _sent @@ -509,8 +516,8 @@ end @return SubscriptionObject ]=] function DataSync:Unsubscribe(): typeof(DataSync:Unsubscribe()) - assert(self._key,DataSync._Error.."':Unsubscribe' can only be used with a store") - assert(self._subscription,DataSync._Error.."':Unsubscribe' can only be used with a subscription created with ':Subscribe'") + assert(self._key,"':Unsubscribe' can only be used with a store") + assert(self._subscription,"':Unsubscribe' can only be used with a subscription created with ':Subscribe'") if not DataSync._Subscriptions[self._subscription.index .. self._subscription.value] then return self @@ -531,7 +538,7 @@ end @return nil ]=] function DataSync:_FireSubscriptions(index: string, value: string, data: any?): nil - assert(self._key,DataSync._Error.."':Subscribe' can only be used with a store") + assert(self._key,"':Subscribe' can only be used with a store") if string.sub(tostring(tostring(value)),1,#DataSync._Private) == DataSync._Private then return true @@ -549,7 +556,7 @@ if Manager.IsServer then return end - print(DataSync._Error..'Shutting down and saving DataSync files') + print('Shutting down and saving DataSync files') for index,file in pairs(DataSync._Files) do file:SaveData(true):RemoveData(true) diff --git a/src/Interface/Animator.lua b/src/Interface/Animator.lua index 14078ac..8e699b2 100644 --- a/src/Interface/Animator.lua +++ b/src/Interface/Animator.lua @@ -29,10 +29,10 @@ ]=] local Animator = {} -Animator.Cache = {} -Animator.Original = {} -Animator.Prefix = 'UI_' -Animator.TagList = { +Animator._Cache = {} +Animator._Original = {} +Animator._Prefix = 'UI_' +Animator._TagList = { ['MouseButton1Click'] = {'BounceUp','BounceDown'}; ['MouseButton1Down'] = {}; ['MouseButton1Up'] = {}; @@ -40,17 +40,13 @@ Animator.TagList = { ['MouseLeave'] = {'Reset'}; } -local Loader = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) -local Manager = Loader('Manager') -local HttpService = Loader['HttpService'] -local CollectionService = Loader['CollectionService'] +local require = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) +local Manager = require('Manager') +local HttpService = game:GetService('HttpService') +local CollectionService = game:GetService('CollectionService') -local AttributeFlag = pcall(function() -- TODO: remove this when Attributes are released - script:GetAttribute('Test') -end) - -local Length = AttributeFlag and script:GetAttribute('AnimationTime') or 0.1 -local Scale = AttributeFlag and script:GetAttribute('AnimationScale') or 0.1 +local Length = 0.1 -- the time it takes to complete an animation, I recommend short & snappy +local Scale = 0.1 -- the scale of the UI (0.1 = 10%), if your UI uses offset, this will be pixels -------------------- -- Common Effects -- @@ -67,7 +63,7 @@ end -- MouseButton1Click -- ----------------------- Animator['BounceUp'] = function(element: GuiObject): nil - local original = Animator.Original[element] + local original = Animator._Original[element] local increment = 1 - Scale local goal; do @@ -85,7 +81,7 @@ Animator['BounceUp'] = function(element: GuiObject): nil end Animator['BounceDown'] = function(element: GuiObject): nil - local original = Animator.Original[element] + local original = Animator._Original[element] local increment = Scale + 1 local goal; do @@ -106,7 +102,7 @@ end -- MouseEnter -- ---------------- Animator['Grow'] = function(element: GuiObject): nil - local original = Animator.Original[element] + local original = Animator._Original[element] local increment = Scale + 1 local goal; do @@ -125,7 +121,7 @@ end -- MouseLeave -- ---------------- Animator['Reset'] = function(element: GuiObject): nil - local original = Animator.Original[element] + local original = Animator._Original[element] local prop,value = {},{} for index,base in pairs(original) do @@ -142,12 +138,12 @@ end ----------------- local function ConnectAnimation(element: GuiObject, event: string, tag: string): nil local identifier = event..'_'..tag..'_'..tostring(element) - if Animator.Cache[element] and Animator.Cache[element][identifier] then return end + if Animator._Cache[element] and Animator._Cache[element][identifier] then return end local IsImage = element:IsA('ImageButton') or element:IsA('ImageLabel') - if not Animator.Original[element] then - Animator.Original[element] = { + if not Animator._Original[element] then + Animator._Original[element] = { AnchorPoint = element.AnchorPoint; Position = element.Position; Size = element.Size; @@ -162,7 +158,7 @@ local function ConnectAnimation(element: GuiObject, event: string, tag: string): end local guid = HttpService:GenerateGUID(false) - local code = Animator[string.sub(tag,#Animator.Prefix + 1)] + local code = Animator[string.sub(tag,#Animator._Prefix + 1)] local signal = element[event]:Connect(function(...) local data = {...} @@ -171,11 +167,11 @@ local function ConnectAnimation(element: GuiObject, event: string, tag: string): end) end) - if not Animator.Cache[element] then - Animator.Cache[element] = {} + if not Animator._Cache[element] then + Animator._Cache[element] = {} end - Animator.Cache[element][identifier] = signal + Animator._Cache[element][identifier] = signal end local function ConnectTag(event: string, tag: string): nil @@ -189,9 +185,9 @@ local function ConnectTag(event: string, tag: string): nil end end -for event,list in pairs(Animator.TagList) do +for event,list in pairs(Animator._TagList) do for count,tag in pairs(list) do - tag = Animator.Prefix..tag + tag = Animator._Prefix..tag ConnectTag(event,tag) end end diff --git a/src/Interface/Components.lua b/src/Interface/Components.lua index bbdb95d..1f8b8cc 100644 --- a/src/Interface/Components.lua +++ b/src/Interface/Components.lua @@ -5,12 +5,11 @@ local Components = {} Components._Name = 'Modular Component System' -Components._Error = '[MCS]: ' Components._Bindings = {} -local Loader = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) -local Manager = Loader('Manager') -local RunService = Loader['RunService'] +local require = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) +local Manager = require('Manager') +local RunService = game:GetService('RunService') --[=[ Construct a new component out of a pre-existing element @@ -66,7 +65,8 @@ end function Components:Fire(name: string, ...): nil assert(Components._Bindings[name],"Attempted to fire a non-existant binding on '"..name.."'") - Manager.wrap(Components._Bindings[name],...) + local code = Components._Bindings[name] + Manager.wrap(code,...) end --[=[ @@ -114,7 +114,7 @@ end function Components:Update(name: string, value: any): any local get = self:Get(name) - assert(get ~= nil,Components._Error.."Attempted to update nil attribute '"..name.."'") + assert(get ~= nil,"Attempted to update nil attribute '"..name.."'") if typeof(get) == 'number' and typeof(value) == 'number' then get += value @@ -136,7 +136,7 @@ end function Components:Attribute(name: string, code: (any, any) -> nil): RBXScriptConnection local last = self:Get(name) - assert(last ~= nil,Components._Error.."Attempted to bind to nil attribute '"..name.."'") + assert(last ~= nil,"Attempted to bind to nil attribute '"..name.."'") Manager.wrap(code,last,last) @@ -239,9 +239,14 @@ end Shorten getting an attribute attached to the component @param name string -- name of the component + @param value any? -- include this to also set the component state @return Value any ]=] -function Components:__call(name: string): any? +function Components:__call(name: string, value: any?): any? + if value ~= nil then + self:Set(name,value) + end + return self:Get(name) end diff --git a/src/Interface/Input.lua b/src/Interface/Input.lua index 07bb678..32f0903 100644 --- a/src/Interface/Input.lua +++ b/src/Interface/Input.lua @@ -9,9 +9,9 @@ Input._InputCallbacks = {} Input._InputTouchCallbacks = {} Input._Buttons = {} -local Loader = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) -local Manager = Loader('Manager') -local UserInputService = Loader['UserInputService'] +local require = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) +local Manager = require('Manager') +local UserInputService = game:GetService('UserInputService') --[=[ Find the center of a map based on a number @@ -241,9 +241,8 @@ if Manager.IsClient then for name,data in pairs(Input._InputCache) do if data['Verify'] and data['Enabled'] and data['Function'] and data['Keys'] then if table.find(data['Keys'],obj.KeyCode) or table.find(data['Keys'],obj.UserInputType) then - Manager.wrap(function() - data['Function'](obj) - end) + local code = data['Function'] + Manager.wrap(code,obj) end end end @@ -251,9 +250,8 @@ if Manager.IsClient then for index,data in pairs(Input._InputCallbacks) do if data['Type'] == 'Began' then if table.find(data['Keys'],obj.KeyCode) or table.find(data['Keys'],obj.UserInputType) then - Manager.wrap(function() - data['Code'](obj) - end) + local code = data['Code'] + Manager.wrap(code,obj) end end end @@ -264,9 +262,8 @@ if Manager.IsClient then for index,data in pairs(Input._InputCallbacks) do if data['Type'] == 'Ended' then if table.find(data['Keys'],obj.KeyCode) or table.find(data['Keys'],obj.UserInputType) then - Manager.wrap(function() - data['Code'](obj) - end) + local code = data['Code'] + Manager.wrap(code,obj) end end end @@ -275,9 +272,8 @@ if Manager.IsClient then UserInputService.TouchTap:Connect(function(obj,processed) if processed then return end for index,data in pairs(Input._InputTouchCallbacks) do - Manager.wrap(function() - data['Code'](obj) - end) + local code = data['Code'] + Manager.wrap(code,obj) end end) end diff --git a/src/Interface/init.lua b/src/Interface/init.lua index 9e568fd..1c47e14 100644 --- a/src/Interface/init.lua +++ b/src/Interface/init.lua @@ -103,23 +103,22 @@ local Interface = {} Interface.__index = Interface Interface._Name = string.upper(script.Name) -Interface._Error = '['.. Interface._Name ..']: ' Interface._ComponentCode = {} Interface._ComponentCache = {} Interface._AssignSizesCache = {} Interface._AssignSizesOveride = false setmetatable(Interface,Interface) -local Loader = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) -local Manager = Loader('Manager') -local Input = Loader(script:WaitForChild('Input')) -local Components = Loader(script:WaitForChild('Components')) -local Animator = Loader(script:WaitForChild('Animator')) -local Workspace = Loader['Workspace'] -local GuiService = Loader['GuiService'] -local Players = Loader['Players'] -local UserInputService = Loader['UserInputService'] -local CollectionService = Loader['CollectionService'] +local require = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) +local Manager = require('Manager') +local Input = require(script:WaitForChild('Input')) +local Components = require(script:WaitForChild('Components')) +local Animator = require(script:WaitForChild('Animator')) +local Workspace = game:GetService('Workspace') +local GuiService = game:GetService('GuiService') +local Players = game:GetService('Players') +local UserInputService = game:GetService('UserInputService') +local CollectionService = game:GetService('CollectionService') local Camera = Workspace.CurrentCamera local Container diff --git a/src/Manager.lua b/src/Manager.lua index 215c19e..722403c 100644 --- a/src/Manager.lua +++ b/src/Manager.lua @@ -128,7 +128,6 @@ Manager._Timers = {} Manager._Bouncers = {} Manager._LastIteration = nil Manager._Name = script.Name -Manager._Error = '['.. string.upper(Manager._Name) ..']: ' local Compression = {} Compression.Dictionary = {} @@ -145,12 +144,12 @@ local Settings = {} Settings.Debug = false Settings.RunService = 'Stepped' -local Loader = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) -local Workspace = Loader['Workspace'] -local CollectionService = Loader['CollectionService'] -local HttpService = Loader['HttpService'] -local RunService = Loader['RunService'] -local TweenService = Loader['TweenService'] +local require = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) +local Workspace = game:GetService('Workspace') +local CollectionService = game:GetService('CollectionService') +local HttpService = game:GetService('HttpService') +local RunService = game:GetService('RunService') +local TweenService = game:GetService('TweenService') --[=[ Remove escape characters and return the translation @@ -419,7 +418,7 @@ function Manager.debug(label: string?): nil if not timer then timer = os.clock() else - warn(Manager._Error..label,'took:',os.clock() - timer..'ms') + warn(label,'took:',os.clock() - timer..'ms') timer = nil end @@ -810,7 +809,7 @@ function Manager:Connect(code: RBXScriptConnection | table | (any) -> nil): type code:Disconnect() end) if not success and Settings.Debug then - warn(Manager._Error..err) + warn(err) end end @@ -822,7 +821,7 @@ function Manager:Connect(code: RBXScriptConnection | table | (any) -> nil): type if typeof(code) == 'function' then return Manager.wrap(code,...) else - warn(Manager._Error.."Attempted to call ':Fire' on '".. typeof(code) .."'") + warn("Attempted to call ':Fire' on '".. typeof(code) .."'") end end @@ -855,7 +854,7 @@ function Manager:ConnectKey(key: any, code: RBXScriptConnection | table | (any) end) if not success and Settings.Debug then - warn(Manager._Error..err) + warn(err) end end @@ -867,7 +866,7 @@ function Manager:ConnectKey(key: any, code: RBXScriptConnection | table | (any) if typeof(code) == 'function' then return Manager.wrap(code,...) else - warn(Manager._Error.."Attempted to call ':Fire' on '".. typeof(code) .."'") + warn("Attempted to call ':Fire' on '".. typeof(code) .."'") end end diff --git a/src/Network.lua b/src/Network.lua index 32b316a..32d23c4 100644 --- a/src/Network.lua +++ b/src/Network.lua @@ -88,16 +88,15 @@ Network._Functions = {} Network._Bindables = {} Network._Invocables = {} Network._Name = string.upper(script.Name) -Network._Error = '['.. Network._Name ..']: ' Network.Enums = { ['Event'] = 1; ['Function'] = 2; } -local Loader = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) -local Manager = Loader('Manager') -local Players = Loader['Players'] -local ReplicatedStorage = Loader['ReplicatedStorage'] +local require = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) +local Manager = require('Manager') +local Players = game:GetService('Players') +local ReplicatedStorage = game:GetService('ReplicatedStorage') local Container = ReplicatedStorage:FindFirstChild(Network._Name..'_FOLDER'); do if Manager.IsServer and not Container then local Folder = Instance.new('Folder') @@ -388,7 +387,6 @@ end @return nil ]=] function Network:FireAllClients(name: string, ...): nil - assert(typeof(name) == 'string') assert(Manager.IsServer) local remote = GetRemote(name,Network.Enums.Event) @@ -404,8 +402,6 @@ end @return nil ]=] function Network:FireAllClientsExcept(name: string, player: Player, ...): nil - assert(typeof(name) == 'string') - assert(typeof(player) == 'Instance' and player:IsA('Player')) assert(Manager.IsServer) local remote = GetRemote(name,Network.Enums.Event) @@ -440,8 +436,18 @@ end function Network:InvokeClient(name: string, player: Player, ...): any? assert(Manager.IsServer) + local data = {...} local remote = GetRemote(name) - return remote:InvokeClient(player,...) + + local success,response = pcall(function() + return remote:InvokeClient(player,table.unpack(data)) + end) + + if success then + return response + end + + return success end --[=[ diff --git a/src/Roblox.lua b/src/Roblox.lua index bd975ef..0fbd282 100644 --- a/src/Roblox.lua +++ b/src/Roblox.lua @@ -95,14 +95,14 @@ Roblox._SetCoreTypes = { ['PostNotification'] = 'SendNotification'; } -local Loader = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) -local Manager = Loader('Manager') -local Players = Loader['Players'] -local StarterGui = Loader['StarterGui'] -local TextService = Loader['TextService'] -local SocialService = Loader['SocialService'] -local TeleportService = Loader['TeleportService'] -local ContentProvider = Loader['ContentProvider'] +local require = require(game:GetService('ReplicatedStorage'):WaitForChild('Loader')) +local Manager = require('Manager') +local Players = game:GetService('Players') +local StarterGui = game:GetService('StarterGui') +local TextService = game:GetService('TextService') +local SocialService = game:GetService('SocialService') +local TeleportService = game:GetService('TeleportService') +local ContentProvider = game:GetService('ContentProvider') --[=[ Prompt a friend request to another Player diff --git a/src/init.lua b/src/init.lua index e540a99..5c618d6 100644 --- a/src/init.lua +++ b/src/init.lua @@ -16,11 +16,9 @@ Listed below is a quick glance on the API, visit the link above for proper documentation. Loader(module) - Loader[service] Loader.require(module) Loader.server(module) Loader.client(module) - Loader.import(service) Loader.enum(name,members) Loader.VERSION() @@ -45,8 +43,6 @@ │ └─ Redirects & returns __server() ├─ .client(module) │ └─ Redirects & returns __client() - ├─ Loader[service] | .import(service) - │ └─ validates the service & returns it ├─ .enum(name,members) │ └─ create a custom enum on shared ├─ .__version() and .VERSION Returns the current version @@ -76,72 +72,45 @@ SOFTWARE. ]=] +local Chat = game:GetService('Chat') +local Players = game:GetService('Players') +local Geometry = game:GetService('Geometry') +local RunService = game:GetService('RunService') +local ServerStorage = game:GetService('ServerStorage') +local ReplicatedFirst = game:GetService('ReplicatedFirst') +local ReplicatedStorage = game:GetService('ReplicatedStorage') +local ServerScriptService = game:GetService('ServerScriptService') + +local IsStudio = RunService:IsStudio() and 'Studio' +local IsServer = RunService:IsServer() and 'Server' +local IsClient = RunService:IsClient() and 'Client' + local Loader = {} Loader._ModuleCache = {} -Loader._ServiceCache = {} -Loader._Timeout = 0.5 -Loader._Initialized = false -Loader._Filter = false Loader._Name = string.upper(script.Name) -Loader._Error = '['.. Loader._Name ..']: ' Loader._Containers = {'PlayerScripts','PlayerGui','Backpack'}; +Loader._Services = { + ['Client'] = {ReplicatedFirst}; + ['Server'] = {ServerStorage, ServerScriptService}; + ['Shared'] = {ReplicatedStorage, Chat, Geometry}; +} Loader._Version = { ['MAJOR'] = 1; ['MINOR'] = 1; - ['PATCH'] = 0; -} -Loader._Services = { - ['Client'] = {'ReplicatedFirst'}; - ['Server'] = {'ServerScriptService','ServerStorage'}; - ['Shared'] = {'ReplicatedStorage','Chat','Lighting'}; + ['PATCH'] = 2; } -setmetatable(Loader,Loader) - -Loader.MaxRetryTime = 5 - -local Services = setmetatable({}, {__index = function(cache, service) - cache[service] = game:GetService(service) - return cache[service] -end}) - -local RunService = Services['RunService'] -local IsStudio = RunService:IsStudio() and 'Studio' -local IsServer = RunService:IsServer() and 'Server' -local IsClient = RunService:IsClient() and 'Client' - ---[=[ - Validates a module script instance - - @param module ModuleScript | string | number -- provided module type - @return boolean - @private -]=] -local function IsValidModule(module: ModuleScript | string | number): boolean - if typeof(module) == 'Instance' then - if not module:IsA('ModuleScript') then - return false - end - - return true - elseif typeof(module) == 'string' or typeof(module) == 'number' then - return true - end - - return false -end --[=[ - Validates and returns a Roblox service + Loaders settings - @param service string -- String to check for a service - @return boolean - @private + Defaults: + Loader.MaxRetryTime = 5 + Loader.Timeout = 0.5 + Loader.Filter = false ]=] -local function IsValidService(service: string): boolean - return pcall(function() - return game:FindService(service) - end) -end +Loader.MaxRetryTime = 5 +Loader.Timeout = 0.5 +Loader.Filter = false --[=[ Safely require a module like the Roblox require function works @@ -153,9 +122,9 @@ end ]=] local function SafeRequire(module: ModuleScript, requirer: Script): table? local time = os.clock() - local event; event = Services['RunService'].Stepped:Connect(function() - if os.clock() >= time + Loader._Timeout then - warn(string.format(Loader._Error..'%s -> %s is taking too long',tostring(requirer),tostring(module))) + local event; event = RunService.Stepped:Connect(function() + if os.clock() >= time + Loader.Timeout then + warn(string.format('%s -> %s is taking too long',tostring(requirer),tostring(module))) if event then event:Disconnect() event = nil @@ -170,14 +139,14 @@ local function SafeRequire(module: ModuleScript, requirer: Script): table? if not success then if type(loaded) == 'nil' and string.find(response,'exactly one value') then - error(Loader._Error.."Module did not return exactly one value: " .. module:GetFullName(), 3) + error("Module did not return exactly one value: " .. module:GetFullName(), 3) else - error(Loader._Error.."Module " .. module:GetFullName() .. " experienced an error while loading: " .. response, 3) + error("Module " .. module:GetFullName() .. " experienced an error while loading: " .. response, 3) end end if event then - event:disconnect() + event:Disconnect() event = nil end @@ -195,7 +164,7 @@ end local function DeepSearch(name: string, list: table): ModuleScript? for count,asset in ipairs(list) do if not asset:IsA('ModuleScript') then continue end - if Loader._Filter and asset.Parent:IsA('ModuleScript') then continue end + if Loader.Filter and asset.Parent:IsA('ModuleScript') then continue end if string.lower(asset.Name) == name then return asset @@ -234,8 +203,7 @@ function Loader.__require(module: ModuleScript, requirer: Script): table? end for index,service in pairs(Loader._Services.Shared) do - local container = Services[service] - local sharedModule = DeepSearch(name,container:GetDescendants()) + local sharedModule = DeepSearch(name,service:GetDescendants()) if sharedModule then Loader._ModuleCache[name] = SafeRequire(sharedModule,requirer) @@ -262,7 +230,7 @@ function Loader.__require(module: ModuleScript, requirer: Script): table? RunService.Heartbeat:Wait() end - assert(Loader._ModuleCache[name],Loader._Error.."attempted to require a non-existant module") + assert(Loader._ModuleCache[name],"attempted to require a non-existant module: '"..name.."'") return Loader._ModuleCache[name] end @@ -282,8 +250,7 @@ function Loader.__server(module: ModuleScript, requirer: Script): table? end for index,service in pairs(Loader._Services.Server) do - local container = Services[service] - local serverModule = DeepSearch(name,container:GetDescendants()) + local serverModule = DeepSearch(name,service:GetDescendants()) if serverModule then Loader._ModuleCache[name] = SafeRequire(serverModule,requirer) @@ -311,7 +278,7 @@ function Loader.__client(module: ModuleScript, requirer: Script, __disabled: boo end while not Loader._ModuleCache[name] and os.clock() - clock < Loader.MaxRetryTime do - local player = Services['Players'].LocalPlayer + local player = Players.LocalPlayer for index,container in pairs(player:GetChildren()) do if not table.find(Loader._Containers,container.Name) then continue end @@ -325,8 +292,7 @@ function Loader.__client(module: ModuleScript, requirer: Script, __disabled: boo end for index,service in pairs(Loader._Services.Client) do - local container = Services[service] - local clientModule = DeepSearch(name,container:GetDescendants()) + local clientModule = DeepSearch(name,service:GetDescendants()) if clientModule then Loader._ModuleCache[name] = SafeRequire(clientModule,requirer) @@ -334,9 +300,7 @@ function Loader.__client(module: ModuleScript, requirer: Script, __disabled: boo end end - if __disabled then - break - end + if __disabled then break end end return Loader._ModuleCache[name] @@ -360,7 +324,7 @@ end @return RequiredModule? ]=] function Loader.server(module: ModuleScript | string | number): table? - assert(IsServer,Loader._Error.."Attempted to access .server from the client") + assert(IsServer,"Attempted to access .server from the client") local requirer = getfenv(2).script return Loader.__server(module,require()) @@ -373,27 +337,12 @@ end @return RequiredModule? ]=] function Loader.client(module: ModuleScript | string | number): table? - assert(IsClient,Loader._Error.."Attempted to access .client from the server") + assert(IsClient,"Attempted to access .client from the server") local requirer = getfenv(2).script return Loader.__client(module,requirer) end ---[=[ - Import a Roblox service - - @param service string -- Roblox service name - @return RobloxService? -]=] -function Loader.import(service: string): Instance - if Loader._ServiceCache[service] then - return Loader._ServiceCache[service] - end - - Loader._ServiceCache[service] = game:GetService(service) - return Loader._ServiceCache[service] -end - --[=[ Create a custom enum library on 'shared' @@ -402,7 +351,7 @@ end @return table ]=] function Loader.enum(name: string, members: table): table - assert(shared[name] == nil,Loader._Error.."Error claiming enum '"..name.."': already claimed") + assert(shared[name] == nil,"Error claiming enum '"..name.."': already claimed") local proxy = {} @@ -425,19 +374,6 @@ function Loader:__call(module: ModuleScript | string | number): table? return Loader.__require(module,requirer) end ---[=[ - Quickly import services by indexing Loader - Redirects to Loader.import() - - @param service string -- Roblox service name - @return RobloxService? -]=] -function Loader:__index(service: string): Instance - if IsValidService(service) then - return Loader.import(service) - end -end - --[=[ Provides the Loader version when called tostring() @@ -474,4 +410,4 @@ do end end -return Loader \ No newline at end of file +return setmetatable(Loader,Loader) \ No newline at end of file