STClass - UISystem

Hello, today I will introduce to you a Module that supports GUI scripting!

:warning: Warn :warning:

This topic is for programmers and people who want to improve their programming skills by reading source code.
STClass.rbxm (1.9 KB)
Note: you need to put these two modules in the same parent!
So what is it used for? It will force your tasks to work one after another to avoid conflicts using thread blocking construct:

if on then return end
on= true
----something!
on = false

I used it for my game!

Using

  1. require() module
  2. Use them similar to Instances
  3. ex
local UISystemService= require(script.Parent.UISystemService)
local UISystem= require(script.Parent.UISystem)

local newSystem:UISystem= UISystem.new('Test')
newSystem:Bind(workspace,'ChildAdded',function(child)
	print(child)
end)

local testSystem:UISystem= UISystemService:Find('Test')
--testSystem== newSystem

Source Code

UISystemService
export type UISystemService={
	Enabled:boolean,
	Stop:boolean,
	child:table
}

local UISystemService = {}
UISystemService.__index= UISystemService
-------------------------contructor-----------------------------
function UISystemService.new():UISystemService
	local self= setmetatable({},UISystemService)
	self.Enabled= true
	self.Stop= false
	self.child={}
	return self
end
-------------------------method-----------------------------------
function UISystemService:Find(name:string):UISystem?
	return self.child[name]
end
function UISystemService:Wait(name:string,timeOut:number?):UISystem?
	local s= tick()
	while true do
		task.wait()
		if self.child[name] then
			return self.child[name]
		end
		if  timeOut and  (tick()-s)> timeOut then
			return 
		end
	end
end
return UISystemService.new()

UISystem
export type UISystem={
	Enabled:boolean,
	on:boolean,
	child:table
}
export type UIPara={
	connect:RBXScriptConnection,
	func:func,
	call:func
}

local UISystemService= require(script.Parent:WaitForChild("UISystemService"))

local UISystem={}
UISystem.__index= UISystem
---------------------------contructor--------------------
function UISystem.new(name:string)
	if UISystemService.child[name] then
		return UISystemService.child[name]
	end
	local self= setmetatable({},UISystem)
	self.Enabled= true
	self.on= false
	self.child={}
	
	UISystemService.child[name]= self
	return self
end
-----------------------------method-------------------------

function UISystem:Bind(obj:Instance,evName:string,call:func)
	if not self.child[obj] then
		self.child[obj]= {}
	end
	if not self.child[obj][evName] then
		self.child[obj][evName]={}
	end
	if self.child[obj][evName][call] then
		local para:UIPara= self.child[obj][evName][call]
		if not para.connect.Connected then
			para.connect= obj[evName]:connect(para.func)
		end
		return para.connect
	end
	local para:UIPara= {}
	local function func(...)
		if (UISystemService.Stop and UISystemService.Enabled) or 
			(UISystemService.Enabled and self.Enabled and self.on) then
			return
		end
		self.on= true
		local s,e= pcall(call,...)
		self.on= false
		if not s then
			error(e)
		end
	end
	para.call= call
	para.func= func
	para.connect= obj[evName]:connect(func)
	self.child[obj][evName][call]= para
	return para.connect
end

function UISystem:Unbind(obj:Instance,evName:string,call:func)
	if (not self.child[obj]) or  
		(not self.child[obj][evName]) or
		(not self.child[obj][evName][call]) or
		(not self.child[obj][evName][call].connect.Connected)
	then
		return false
	end
	local para:UIPara= self.child[obj][evName][call]
	para.connect:disconnect()
	return true
end

function UISystem:Reset()
	self.on= false
end

return UISystem

API Reference

  1. UISystemService

Properties

Enabled:boolean define blocking of all UISystem
Stop:boolean when set to true, all tasks are blocked!

Methods

Find(name:string):UISystem? find a UISystem by name.
Wait(name:string,timeOut:number?):UISystem? wait a UISystem by name and timeOut

  1. UISystem

Contructor

UISystem.new(name:string):UISystem
create if UISystem is not already created

Properties

Enabled define blocking of UISystem

Methods

Bind(obj:Instance,evName:string,call:func):RBXScriptConnection
bind call on event of obj
Unbind(obj:Instance,evName:string,call:func)
unbind call on event of obj
Reset() allows one more task to be performed!

Thanks! I will be providing more! :grinning:

3 Likes

what’s wrong with binding directly and not going thru an unnecessary wrapper

1 Like

Basically it will save you writing many times:

if on then return end
on= true

on= false

and the problem of having too many return
And that thing is just an example of how to write!

??? How will an unnecessary bind function solve that?

1 Like

I first use thread blocking(on) construct
then call the attached function. And whatever happens, it never fails!

if your code fails to run you shouldn’t wrap it in a pcall, but listen to whatever error you got.

If an error is encountered, of course the task must stop, but the error warning will still be there!

ok but a error inside of a connection callback won’t stop the whole script, plus why are you even doing a custom error handler anyway? it’ll have the same (if not worse) effect than the default error handler

Definitely worse! I just don’t want the errors to go away! It would be bad if you didn’t know the game had bugs.

??? you would spot a obvious bug quickly even without your unnecessary wrapper