What do you guys think of my UI Handling module?

--[[
	
      
     Optimal module for handling UI efficiently. Written by SilentsReplacement

]]

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Player = Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")

local module = {}   

function module:PlaySound(sound)
	assert(sound:IsA("Sound"), "PlaySound: sound must be a Sound")
	
	if not sound.Playing then 
		sound:Play()
	end
end

function module:SetProperty(UI, property, value, tween)
	if UI:IsA("GuiBase") and type(tween) == "boolean" then
		if UI[property] ~= value then
			if not tween then
				UI[property] = value
			else
                local tweenAnimation = TweenService:Create(UI, TweenInfo.new(), {property = value}):Play()
                 
                tweenAnimation.Completed:Connect(function()
                    print(UI.Name .. ":" .. property .. " tweened to value: " .. tostring(value))
                end)
			end
        end
    else
        if not UI:IsA("GuiBase") then
            warn("SetProperty: (Invalid argument) 'UI' must be a GuiBase")
        end
        if type(tween) ~= "boolean" then
            warn("SetProperty: (Invalid Argument) 'tween' must be a boolean value")
        end
        return
	end
end

function module:CreateGuiObject(guiObject, name, parent)
    if guiObject:IsA("GuiBase") and parent then
        local newGuiObject = Instance.new(guiObject)
        guiObject.Name = name or newGuiObject.ClassName -- In case no name was given as the argument
        newGuiObject.Parent = parent
    else
        if not guiObject:IsA("GuiBase") then
            warn("CreateGuiObject: (Invalid argument) 'guiObject' must be a GuiBase")
        end
        return
    end
    print("Created guiObject: " ..guiObject.Name.. " parented to" .. parent)
end

function module:CloneGuiObject(guiObject, parent)
    if guiObject:IsA("GuiObject") and guiObject.Parent ~= parent then
        guiObject:Clone()
        guiObject.Parent = parent or PlayerGui -- In case there was no parent given as the argument
    end
end

return module

(Note that the reason I'm using : is because the code looks cleaner, it's mainly used for the self keyword)

I’m soon about to make this new module open-sourced just like any other module. Before that, I would like some review on the following:

  • Code readability
  • Functions
3 Likes

You should not use : just for readability. You should read this: Metatables | Documentation - Roblox Creator Hub

Also, I feel like there could be more things added as this is pretty simple and I would prefer to make big changes to your code if I were you.

It’s a module specifically made for handling UI

True, but is everything related to UI handled here? No.
And also:

function module:PlaySound(sound)
	assert(sound:IsA("Sound"), "PlaySound: sound must be a Sound")
	
	if not sound.Playing then 
		sound:Play()
	end
end

This is basically sound:Play() but with more checks.

: is personal preference at least for me, it just adds a keyword self.

Incorrect. I don’t think you know what self is. You first have to get your metatables working properly. If you keep using : without need for it, certainly no one will use your module and future releases.
https://developer.roblox.com/en-us/articles/Metatables

Here is an example of using : and .:

local module = {}
local mt = {
    __index = module, -- do the other methods like __div and stuff, but this is merely and example.
}

function module.new(x, y)
    local self = setmetatable({}, mt)
    self.x = x or 0
    self.y = y or 0
    return self
end

function module:PrintVector2(vc2)
    assert(vc2.x ~= nil and vc2.y ~= nil, "Given argument is not a Vector2.")

    print("X: " .. vc2.x .. " -- Y: " .. vc2.y)
end

return module

It is true that : looks cleaner but every single developer who knows what they are doing will tell you not to do that for cleanability. In programming, making the code look good doesn’t matter when the actual output is not good.

Take this for example:

So what if it looks good, it creates so much of a memory mess that there is literally a PSA from a staff. It isn’t deprecated, though. (Using it with a Frame or ImageLabel would be fine, etc.)

self can be still used if you use ., it will implicitly create the keyword self whereas using : will explicilty create the keyword self.

Ok? I literally put that in my example. The point:
If you use : for readability I don’t think people will even think about your module, just flag and their day goes on. It is kinda spam. Like, that module could be written in 5 minutes, and even though some small modules are useful, this one certainly isn’t.

1 Like

Agreed. I’ll abandon this module since handling UI is pretty much easy.

1 Like