Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Making sure duplicate objects do not muck up an Instance Wrapper? + Weird function bug? O.o

So basically, I have created a RBX.Lua Instance Wrapper. It is a module. It works perfectly- however, it depends off of object names, because I made it automatically wrap the Parent property and the FindFirstChild, WaitForChild, Children, and GetChildren methods. Why? Because I wanted to cover all possibilities, with the least amount of code. However, to do this, my WrappedObjects table depends on names. How can I make it depend on something that will never be identical to another object?

Also, even if it doesn't pertain to my question, I would love suggestions/criticism for the wrapper as a whole (or other bits)!

Table definition:

local WrappedObjects = {}

Some relevant snippets using it:

--\\Snippet 1

WrappedObjects[Thing.Name] = NewInstance

--\\Snippet 2

elseif (Key == "Parent") then
	local RealParent = Thing.Parent
	local WrappedObject = WrappedObjects[RealParent.Name]
	if WrappedObject then
		return WrappedObject
	else
		return RealParent
	end

And so on for the other methods I auto-wrapped as well.

Full code:

local WrappedObjects = {}

return(function(Thing, Fakes)
	local Type = type(Thing)
	if (Type == "userdata") then
		local IsWrappedObject = pcall(function()
			return Thing.WrappedCheck
		end)
		if IsWrappedObject then
			return Thing
		else
			local NewInstance = newproxy(true)
			WrappedObjects[Thing.Name] = NewInstance
			local MetaTable = getmetatable(NewInstance)
			MetaTable.__index = function(Self, Key)
				local KeyLower = Key:lower()
				local Fake = Fakes[Key]
				if (Key == "WrappedCheck") then
					return ("This object has been wrapped!")
				elseif (Key == "Parent") then
					local RealParent = Thing.Parent
					local WrappedObject = WrappedObjects[RealParent.Name]
					if WrappedObject then
						return WrappedObject
					else
						return RealParent
					end
				elseif ((Key == "children") or ("GetChildren")) then
					return(function()
						local Children = {}
						for Index, Child in next, Thing:GetChildren() do
							local WrappedObject = WrappedObjects[Child.Name]
							if WrappedObject then
								Children[#Children + 1] = WrappedObject
							else
								Children[#Children + 1] = Child
							end
						end
						return Children
					end)
				elseif (KeyLower == "findfirstchild") then
					return(function(ChildName)
						local Child = Thing:FindFirstChild(ChildName)
						if Child then
							local WrappedObject = WrappedObjects[Child.Name]
							if WrappedObject then
								return WrappedObject
							else
								return Child
							end
						end
					end)
				elseif (KeyLower == "waitforchild") then
					return(function(ChildName)
						repeat
							local Child = Thing:FindFirstChild(ChildName)
							if Child then
								local WrappedObject = WrappedObjects[Child.Name]
								if WrappedObject then
									return WrappedObject
								else
									return Child
								end
							end
							wait(0.1)
						until nil
					end)
				elseif Fake then
					return Fake
				else
					local Success, Variant = pcall(function()
						return Thing[Key]
					end)
					if Success then
						return Variant
					end
				end
			end
			MetaTable.__newindex = function(Self, Key, Value)
				pcall(function()
					Thing[Key] = Value
				end)
			end
			MetaTable.__metatable = "The meta-table has been locked!"
			return NewInstance
		end
	end
end)

ALSO: Bug #2 is that with the following code:

local WrapInstance = require(game.ReplicatedStorage:WaitForChild("InstanceWrapper"))

workspace = WrapInstance(workspace, {})
game = WrapInstance(game, {gameIsWrapped = true})

print(game.gameIsWrapped)
print(workspace.Parent.gameIsWrapped)

It prints: function (0xSTUFF) for some reason, a memory address. It should be printing true. WTH!!

Help very much so appreciated!!

1 answer

Depend on objects
It's like DNA for code

Objects all have an identity, and are completely unique - One object may not have the same identity as another object, and this makes them suitable for holding information about themselves.


As you are writing a wrapper, I would like to take this moment to mention that your method of wrapping seems very primitive and flawed. You wrap statically and certainly not functionally, and the wrapper looks like it's going to have issues dealing with wrapped/unwrapped values in the wrong places.

You might want to consider taking a look at Freya's BaseLib and LiteLib, as they are both wrappers.

This discussion is preserved as it was. New answers, comments, and votes are closed.