Please review this small community resource I made

A while back, I made a resource which ran a for loop through a specified target and appended the IDs to a table corresponding to its class and it did pretty well for such a small resource, but I’m wondering if there’s any optimizations or formatting to make it better. Please leave feedback!
Code:

local ModuleDictionary = {}
local DecalDictionary = {}
local TextureDictionary = {}
local SoundDictionary = {}
local MeshDictionary = {}
local AnimationDictionary = {}
local VideoDictionary = {}
local ImageLabelDictionary = {}
local ImageButtonDictionary = {}
local ShirtDictionary = {}
local PantsDictionary = {}

--//functions

local function AddToTable(Target)
	for index = 1, #Target do
		local Cases = {
			["Decal"] = function ()
				table.insert(DecalDictionary, Target[index].Texture)
			end,
			["Texture"] = function ()
				table.insert(TextureDictionary, Target[index].Texture)
			end,
			["Sound"] = function ()
				table.insert(SoundDictionary, Target[index].SoundId)
			end,
			["Mesh"] = function ()
				table.insert(MeshDictionary, Target[index].MeshId)
			end,
			["Animation"] = function ()
				table.insert(AnimationDictionary, Target[index].AnimationId)
			end,
			["ImageLabel"] = function ()
				table.insert(ImageLabelDictionary, Target[index].Image)
			end,
			["ImageButton"] = function ()
				table.insert(ImageButtonDictionary, Target[index].Image)
			end,
			["VideoFrame"] = function ()
				table.insert(VideoDictionary, Target[index].Video)
			end,
			["Shirt"] = function ()
				table.insert(ShirtDictionary, Target[index].ShirtTemplate)
			end,
			["Pants"] = function ()
				table.insert(PantsDictionary, Target[index].PantsTemplate)
			end,
		}
		--print(Target[index], Target[index].ClassName)
		local success, err = pcall(function()
			Cases[Target[index].ClassName]()
		end)
		if not success then
			warn("Instance is not supported. Expected a downloadable or supported asset, got "..tostring(Target[index].ClassName))
		end
	end
end



function ModuleDictionary:GetDictionary(Target: Instance, Descendants: boolean?, DeleteTarget: boolean?, Sort: boolean?, Reverse: boolean?, Print: boolean?)

	Descendants = Descendants or false
	DeleteTarget = DeleteTarget or false
	Sort = Sort or true
	Reverse = Reverse or true
	Print = Print or false

	if Descendants == false then
		AddToTable(Target:GetChildren())
	elseif Descendants == true then
		AddToTable(Target:GetDescendants())
	elseif typeof(Descendants) ~= "boolean" then
		error("GetDictionary expects \"Descendants\" to be a boolean, got "..tostring(Descendants), 2)	
	end


	local function ReverseTable(ID1, ID2)
		return ID1 > ID2
	end


	if Reverse == false and Sort == true then
		table.sort(DecalDictionary)
		table.sort(TextureDictionary)
		table.sort(SoundDictionary)
		table.sort(MeshDictionary)
		table.sort(AnimationDictionary)
		table.sort(ImageLabelDictionary)
		table.sort(ImageButtonDictionary)
		table.sort(VideoDictionary)
		table.sort(ShirtDictionary)
		table.sort(PantsDictionary)
	elseif Reverse == true and Sort == true then
		table.sort(DecalDictionary, ReverseTable)
		table.sort(TextureDictionary, ReverseTable)
		table.sort(SoundDictionary, ReverseTable)
		table.sort(MeshDictionary, ReverseTable)
		table.sort(AnimationDictionary, ReverseTable)
		table.sort(ImageLabelDictionary, ReverseTable)
		table.sort(ImageButtonDictionary, ReverseTable)
		table.sort(VideoDictionary, ReverseTable)
		table.sort(ShirtDictionary, ReverseTable)
		table.sort(PantsDictionary, ReverseTable)
	elseif typeof(Reverse) ~= "boolean" then
		error("GetDictionary expects \"Reverse\" to be a boolean, got "..tostring(Reverse), 2)
	elseif typeof(Sort) ~= "boolean" then
		error("GetDictionary expects \"Sort\" to be a boolean, got "..tostring(Sort), 2)	
	end

	--//inserting

	ModuleDictionary.DecalDictionary = DecalDictionary
	ModuleDictionary.TextureDictionary = TextureDictionary
	ModuleDictionary.SoundDictionary = SoundDictionary
	ModuleDictionary.MeshDictionary = MeshDictionary
	ModuleDictionary.AnimationDictionary = AnimationDictionary
	ModuleDictionary.ImageLabelDictionary = ImageLabelDictionary
	ModuleDictionary.ImageButtonDictionary = ImageButtonDictionary
	ModuleDictionary.VideoDictionary = VideoDictionary
	ModuleDictionary.ShirtDictionary = ShirtDictionary
	ModuleDictionary.PantsDictionary = PantsDictionary


	if DeleteTarget == true then
		Target:Destroy()
	elseif typeof(DeleteTarget) ~= "boolean" then
		error("GetDictionary expects \"DeleteTarget\" to be a boolean or nil, got "..tostring(DeleteTarget), 2)
	end

	if Print == true then
		print("Decals:", DecalDictionary)
		print("Textures:", TextureDictionary)
		print("Sounds:", SoundDictionary)
		print("Meshes:", MeshDictionary)
		print("Animations:", AnimationDictionary)
		print("Image Labels:", ImageLabelDictionary)
		print("Image Buttons:", ImageButtonDictionary)
		print("Videos:", VideoDictionary)
		print("Shirts:", ShirtDictionary)
		print("Pants:", PantsDictionary)
	elseif typeof(Print) ~= "boolean" then
		error("GetDictionary expects \"Print\" to be a boolean or nil, got "..tostring(Print), 2)
	end
end

--//memory freeing functions

function ModuleDictionary:ClearTable(Table: string)
	if typeof(Table) == "string" then
		local cases = {
			["Decal"] = function()
				table.clear(DecalDictionary)
				ModuleDictionary.DecalDictionary = nil
			end;
			["Texture"] = function()
				table.clear(TextureDictionary)
				ModuleDictionary.TextureDictionary = nil
			end;
			["Sound"] = function()
				table.clear(SoundDictionary)
				ModuleDictionary.SoundDictionary = nil
			end;
			["Mesh"] = function()
				table.clear(MeshDictionary)
				ModuleDictionary.MeshDictionary = nil
			end;
			["Animation"] = function()
				table.clear(AnimationDictionary)
				ModuleDictionary.AnimationDictionary = nil
			end;
			["ImageLabel"] = function()
				table.clear(ImageLabelDictionary)
				ModuleDictionary.ImageLabelDictionary = nil
			end;
			["ImageButton"] = function()
				table.clear(ImageButtonDictionary)
				ModuleDictionary.ImageButtonDictionary = nil
			end;
			["Video"] = function()
				table.clear(VideoDictionary)
				ModuleDictionary.VideoDictionary = nil
			end;
			["Shirt"] = function()
				table.clear(ShirtDictionary)
				ModuleDictionary.ShirtDictionary = nil
			end;
			["Pants"] = function()
				table.clear(PantsDictionary)
				ModuleDictionary.PantsDictionary = nil
			end;
		}
		local success, err = pcall(function()
			cases[Table]()
		end)
		if not success then
			error("ClearTable expects the string to be a supported asset, got "..Table, 2)
		end
	else
		error("ClearTable expects \"Table\" to be a string, got ".. tostring(Table), 2)
	end
end

function ModuleDictionary:ClearAllTables() --//no arguments needed, and will only clear asset dictionary tables.
	table.clear(DecalDictionary)
	table.clear(TextureDictionary)
	table.clear(SoundDictionary)
	table.clear(MeshDictionary)
	table.clear(AnimationDictionary)
	table.clear(ImageLabelDictionary)
	table.clear(ImageButtonDictionary)
	table.clear(ShirtDictionary)
	table.clear(PantsDictionary)
	ModuleDictionary.DecalDictionary = nil
	ModuleDictionary.TextureDictionary = nil
	ModuleDictionary.SoundDictionary = nil
	ModuleDictionary.MeshDictionary = nil
	ModuleDictionary.AnimationDictionary = nil
	ModuleDictionary.ImageLabelDictionary = nil
	ModuleDictionary.ImageButtonDictionary = nil
	ModuleDictionary.ShirtDictionary = nil
	ModuleDictionary.PantsDictionary = nil
end

return ModuleDictionary

Here’s the documentation for it if you’re confused:

The code is probably messy lol

3 Likes

I just got ghosted by an entire forum :sob:

2 Likes

Hello, first of all having many variables like this is bad practice. It should be a single table, e.g:

local Dictionary = {
	Module = {},
	Decal = {},
	Texture = {},
	-- ...
}

This way, you can simplify all the sort statements:

for i, AssetDict in pairs(Dictionary) do
	table.sort(AssetDict)
end

Type checking boolean parameters is unnecessary:

elseif typeof(Reverse) ~= "boolean" then

Especially since you’re using type annotations already!

Default values using or cannot be used on booleans:

Reverse = Reverse or true --This will prevent false as well as nil

The ClearTable function can be simplified using the first improvement:

function ModuleDictionary:ClearTable(Table: string)
	if Dictionary[Table] then
		table.clear(Dictionary[Table]) --May also be redundant
		Dictionary[Table] = nil
	else
		error("ClearTable expects the string to be a supported asset, got '"..tostring(Table).."'", 2)
	end
end

ClearAllTables can also be simplified:

function ModuleDictionary:ClearAllTables()
	for i, AssetDict in pairs(Dictionary)
		table.clear(AssetDict)
		Dictionary[i] = nil
	end
end

With all the above in mind, I created the following. It’s untested.

local module = {}

module.Dictionary = {}

local AssetProperties = {
	Decal = "Texture",
	Texture = "Texture",
	Sound = "SoundId",
	Mesh = "MeshId",
	Animation = "AnimationId",
	ImageLabel = "Image",
	ImageButton = "Image",
	VideoFrame = "Video",
	Shirt = "ShirtTemplate",
	Pants = "PantsTemplate"
}

local function AddToDictionary(self, InstanceList : {Instance})
	for i, value in ipairs(InstanceList) do
		local Class = value.ClassName
		local Property = AssetProperties[Class]
		if not Property then
			error("Instance is not supported. Expected a downloadable or supported asset, got "..Class)
		end
		self.Dictionary[Class] = value[Property]
	end
end

type GetIdsConfigType = {Descendants: boolean?, DeleteTarget: boolean?, Sort: boolean?, Reverse: boolean?, Print: boolean?}

local function module:GetIdsInChildren(Target: Instance, Config: GetIdsConfigType)
	if Config.Descendants == nil then Config.Descendants = false end
	if Config.DeleteTarget == nil then Config.DeleteTarget = false end
	if Config.Sort == nil then Config.Sort = false end
	if Config.Reverse == nil then Config.Reverse = true end
	if Config.Print == nil then Config.Print = false end
	
	if Config.Descendants then
		AddToDictionary(self, Target.GetDescendants())
	else
		AddToDictionary(self, Target:GetChildren())
	end
	
	if Config.Sort then
		if Config.Reverse then
			table.sort(self.Dictionary, function(a, b) return a > b end)
		else
			table.sort(self.Dictionary)
		end
	end
	
	if Config.DeleteTarget then
		Target:Destroy()
	end
	
	if Config.Print then
		for k, v in self.Dictionary do
			print(k..": "..v)
		end
	end
	
	return self.Dictionary
end

local function module:ClearAsset(Asset: string)
	if self.Dictionary[Asset] then
		table.clear(self.Dictionary[Asset])
	else
		error("Expected Asset to be a supported asset, got '"..tostring(Asset).."'")
	end
end

local function module:ClearAllAssets()
	for i, AssetDict in pairs(self.Dictionary) do
		table.clear(AssetDict)
	end
end

return module
3 Likes

harlow, sorry for the late reply! is this better (i did not change certain things since i wanted to keep the structure somewhat similar):

local ModuleDictionary = {}
ModuleDictionary.Dictionaries = {
	DecalDictionary = {};
	TextureDictionary = {};
	SoundDictionary = {};
	MeshDictionary = {};
	AnimationDictionary = {};
	VideoDictionary = {};
	ImageLabelDictionary = {};
	ImageButtonDictionary = {};
	ShirtDictionary = {};
	PantsDictionary = {};
}


--//functions

local function AddToTable(Target)
	for index = 1, #Target do
		local Cases = {
			["Decal"] = function ()
				table.insert(ModuleDictionary.Dictionaries.DecalDictionary, Target[index].Texture)
			end,
			["Texture"] = function ()
				table.insert(ModuleDictionary.Dictionaries.TextureDictionary, Target[index].Texture)
			end,
			["Sound"] = function ()
				table.insert(ModuleDictionary.Dictionaries.TextureDictionary, Target[index].SoundId)
			end,
			["Mesh"] = function ()
				table.insert(ModuleDictionary.Dictionaries.MeshDictionary, Target[index].MeshId)
			end,
			["Animation"] = function ()
				table.insert(ModuleDictionary.Dictionaries.AnimationDictionary, Target[index].AnimationId)
			end,
			["VideoFrame"] = function ()
				table.insert(ModuleDictionary.Dictionaries.VideoDictionary, Target[index].Video)
			end,
			["ImageLabel"] = function ()
				table.insert(ModuleDictionary.Dictionaries.ImageLabelDictionary, Target[index].Image)
			end,
			["ImageButton"] = function ()
				table.insert(ModuleDictionary.Dictionaries.ImageButtonDictionary, Target[index].Image)
			end,
			["Shirt"] = function ()
				table.insert(ModuleDictionary.Dictionaries.ShirtDictionary, Target[index].ShirtTemplate)
			end,
			["Pants"] = function ()
				table.insert(ModuleDictionary.Dictionaries.PantsDictionary, Target[index].PantsTemplate)
			end,
		}
		--print(Target[index], Target[index].ClassName)
		local success, err = pcall(function()
			Cases[Target[index].ClassName]()
		end)
		if not success then
			warn("Instance is not supported. Expected a downloadable or supported asset, got "..tostring(Target[index].ClassName))
		end
	end
end



function ModuleDictionary:GetDictionary(Target: Instance, Descendants: boolean?, DeleteTarget: boolean?, Sort: boolean?, Reverse: boolean?, Print: boolean?)
	
	if Descendants == nil then Descendants = false end
	if DeleteTarget == nil then DeleteTarget = false end
	if Sort == nil then Sort = true end
	if Reverse == nil then Reverse = true end
	if Print == nil then Print = false end
	--print(Descendants, DeleteTarget, Sort, Reverse, Print)
	
	if Descendants == false then
		AddToTable(Target:GetChildren())
	elseif Descendants == true then
		AddToTable(Target:GetDescendants())
	end


	local function ReverseTable(ID1, ID2)
		pcall(function()
			--print(ID1, ID2)
			return ID1 > ID2
		end)
	end


	if Reverse == false and Sort == true then
		for _, tables in pairs(ModuleDictionary.Dictionaries) do
			table.sort(tables)
		end
	elseif Reverse == true and Sort == true then
		for _, tables in pairs(ModuleDictionary.Dictionaries) do
			table.sort(tables, ReverseTable)
		end
	end


	if DeleteTarget == true then
		Target:Destroy()
	end

	if Print == true then
		print("Decals:", ModuleDictionary.Dictionaries.DecalDictionary)
		print("Textures:", ModuleDictionary.Dictionaries.TextureDictionary)
		print("Sounds:", ModuleDictionary.Dictionaries. SoundDictionary)
		print("Meshes:", ModuleDictionary.Dictionaries.MeshDictionary)
		print("Animations:", ModuleDictionary.Dictionaries.AnimationDictionary)
		print("Videos:", ModuleDictionary.Dictionaries.VideoDictionary)
		print("Image Labels:", ModuleDictionary.Dictionaries.ImageLabelDictionary)
		print("Image Buttons:", ModuleDictionary.Dictionaries.ImageButtonDictionary)
		print("Shirts:", ModuleDictionary.Dictionaries.ShirtDictionary)
		print("Pants:", ModuleDictionary.Dictionaries.PantsDictionary)
	end

	--//memory freeing functions

	function ModuleDictionary:ClearTable(Table: string)
		if typeof(Table) == "string" then
			local cases = {
				["Decal"] = function()
					ModuleDictionary.Dictionaries.DecalDictionary = nil
				end;
				["Texture"] = function()
					ModuleDictionary.Dictionaries.TextureDictionary = nil
				end;
				["Sound"] = function()
					ModuleDictionary.Dictionaries.SoundDictionary = nil
				end;
				["Mesh"] = function()
					ModuleDictionary.Dictionaries.MeshDictionary = nil
				end;
				["Animation"] = function()
					ModuleDictionary.Dictionaries.AnimationDictionary = nil
				end;
				["Video"] = function()
					ModuleDictionary.Dictionaries.VideoDictionary = nil
				end;
				["ImageLabel"] = function()
					ModuleDictionary.Dictionaries.ImageLabelDictionary = nil
				end;
				["ImageButton"] = function()
					ModuleDictionary.Dictionaries.ImageButtonDictionary = nil
				end;
				["Shirt"] = function()
					ModuleDictionary.Dictionaries.ShirtDictionary = nil
				end;
				["Pants"] = function()
					ModuleDictionary.Dictionaries.PantsDictionary = nil
				end;
			}
			local success, err = pcall(function()
				cases[Table]()
			end)
			if not success then
				error("ClearTable expects the string to be a supported asset, got "..Table, 2)
			end
		end
	end

	function ModuleDictionary:ClearAllTables() --//no arguments needed, and will only clear asset dictionary tables.
		for _, tables in pairs (ModuleDictionary.Dictionaries) do
			tables = nil
		end
	end
end

return ModuleDictionary
1 Like

updated the code a bit:

--!native

local ModuleDictionary = {}
ModuleDictionary.Dictionaries = {
	DecalDictionary = {};
	TextureDictionary = {};
	SoundDictionary = {};
	MeshDictionary = {};
	AnimationDictionary = {};
	VideoDictionary = {};
	ImageLabelDictionary = {};
	ImageButtonDictionary = {};
	ShirtDictionary = {};
	PantsDictionary = {};
}
local Dictionaries = ModuleDictionary.Dictionaries

--//functions

local function AddToTable(Target)
	for index = 1, #Target do
		local Cases = {
			["Decal"] = function ()
				table.insert(Dictionaries.DecalDictionary, Target[index].Texture)
			end,
			["Texture"] = function ()
				table.insert(Dictionaries.TextureDictionary, Target[index].Texture)
			end,
			["Sound"] = function ()
				table.insert(Dictionaries.TextureDictionary, Target[index].SoundId)
			end,
			["Mesh"] = function ()
				table.insert(Dictionaries.MeshDictionary, Target[index].MeshId)
			end,
			["Animation"] = function ()
				table.insert(Dictionaries.AnimationDictionary, Target[index].AnimationId)
			end,
			["VideoFrame"] = function ()
				table.insert(Dictionaries.VideoDictionary, Target[index].Video)
			end,
			["ImageLabel"] = function ()
				table.insert(Dictionaries.ImageLabelDictionary, Target[index].Image)
			end,
			["ImageButton"] = function ()
				table.insert(Dictionaries.ImageButtonDictionary, Target[index].Image)
			end,
			["Shirt"] = function ()
				table.insert(Dictionaries.ShirtDictionary, Target[index].ShirtTemplate)
			end,
			["Pants"] = function ()
				table.insert(Dictionaries.PantsDictionary, Target[index].PantsTemplate)
			end,
		}
		--print(Target[index], Target[index].ClassName)
		local success, err = pcall(function()
			Cases[Target[index].ClassName]()
		end)
		if not success then
			warn("Instance is not supported. Expected a downloadable or supported asset, got "..tostring(Target[index].ClassName))
		end
	end
end



function ModuleDictionary:GetDictionary(Target: Instance, Descendants: boolean?, ClearTables: boolean?, DeleteTarget: boolean?, Sort: boolean?, Reverse: boolean?, Print: boolean?)

	if Descendants == nil then Descendants = false end
	if ClearTables == nil then ClearTables = true end
	if DeleteTarget == nil then DeleteTarget = false end
	if Sort == nil then Sort = true end
	if Reverse == nil then Reverse = true end
	if Print == nil then Print = false end

	if ClearTables == true then
		for _, tables in pairs(Dictionaries) do
			table.clear(tables)
		end	
	end

	if Descendants == false then
		AddToTable(Target:GetChildren())
	elseif Descendants == true then
		AddToTable(Target:GetDescendants())
	end


	local function ReverseTable(ID1, ID2)
		pcall(function()
			--print(ID1, ID2)
			return ID1 > ID2
		end)
	end


	if Reverse == false and Sort == true then
		for _, tables in pairs(Dictionaries) do
			table.sort(tables)
		end
	elseif Reverse == true and Sort == true then
		for _, tables in pairs(Dictionaries) do
			table.sort(tables, ReverseTable)
		end
	end


	if DeleteTarget == true then
		Target:Destroy()
	end

	if Print == true then
		print("Decals:", Dictionaries.DecalDictionary)
		print("Textures:", Dictionaries.TextureDictionary)
		print("Sounds:", Dictionaries. SoundDictionary)
		print("Meshes:", Dictionaries.MeshDictionary)
		print("Animations:", Dictionaries.AnimationDictionary)
		print("Videos:", Dictionaries.VideoDictionary)
		print("Image Labels:", Dictionaries.ImageLabelDictionary)
		print("Image Buttons:", Dictionaries.ImageButtonDictionary)
		print("Shirts:", Dictionaries.ShirtDictionary)
		print("Pants:", Dictionaries.PantsDictionary)
	end

	--//memory freeing functions

	function ModuleDictionary:ClearTable(Table: string)
		if typeof(Table) == "string" then
			local success, err = pcall(function()
				print(Table)
				if Table:find("Dictionary") then
					table.clear(Dictionaries[Table])
				else
					table.clear(Dictionaries[Table.. "Dictionary"])
				end
			end)
			if not success then
				error("ClearTable expects the string to be a supported asset, got "..Table, 2)
			end
		end
	end

	function ModuleDictionary:ClearAllTables() --//no arguments needed, and will only clear asset dictionary tables.
		for _, tables in pairs (Dictionaries) do
			table.clear(tables)
		end
	end
end

return ModuleDictionary
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.