generic image
Processing...
  • Games
  • Catalog
  • Develop
  • Robux
  • Search in Players
  • Search in Games
  • Search in Catalog
  • Search in Groups
  • Search in Library
  • Log In
  • Sign Up
  • Games
  • Catalog
  • Develop
  • Robux
   
ROBLOX Forum » Game Creation and Development » Scripters
Home Search
 

Re: make a newproxy + metatable obj's parent settable?

Previous Thread :: Next Thread 
NotAshley is not online. NotAshley
Joined: 16 Jan 2014
Total Posts: 14257
02 Jul 2015 07:22 PM
If I have a fake newproxy object where the metatable's index returns realObject[key], how can I make it so "fakeObj.Parent = realInstance" doesn't throw an error?
Report Abuse
TickerOfTime is not online. TickerOfTime
Joined: 02 Sep 2012
Total Posts: 2030
02 Jul 2015 07:24 PM
Here is something you might find helpful, idk if you are doing it this way, maybe not.

Object={
new=function()
local obj=newproxy(true)
getmetatable(obj).__index={Color=nil,Name='',Random=0}
getmetatable(obj).__newindex=function(S,K,V) return rawset(getmetatable(S).__index,K,V) end
return obj
end
}

-Ticker of da Tocks | Scripter's Forum Breakfast Club
Report Abuse
TickerOfTime is not online. TickerOfTime
Joined: 02 Sep 2012
Total Posts: 2030
02 Jul 2015 07:25 PM
Actually, can you post the code and the error it throws?

-Ticker of da Tocks | Scripter's Forum Breakfast Club
Report Abuse
NotAshley is not online. NotAshley
Joined: 16 Jan 2014
Total Posts: 14257
02 Jul 2015 07:27 PM
@TickerOfTime Thanks. Does that fix this issue? I'm not familiar with __newindex
Report Abuse
NotAshley is not online. NotAshley
Joined: 16 Jan 2014
Total Posts: 14257
02 Jul 2015 07:28 PM
Oh, sure. Here:

attempt to index local 'fakeObject' (a userdata value)

I can access properties n' stuff, and I can even print the parent, but trying to set the parent throws this.
Report Abuse
TickerOfTime is not online. TickerOfTime
Joined: 02 Sep 2012
Total Posts: 2030
02 Jul 2015 07:29 PM
Post your wrapper code please. I need to know how you are setting it up.

-Ticker of da Tocks | Scripter's Forum Breakfast Club
Report Abuse
NotAshley is not online. NotAshley
Joined: 16 Jan 2014
Total Posts: 14257
02 Jul 2015 07:33 PM
local addMethods = function(obj, methods)
local isInstance = function(obj) -- thanks to eLunate for this
if type(obj) == "userdata" then
local s, e = pcall(game.GetService, game, obj);
return s and not e;
end
return false
end
if isInstance(obj) then
local wrappedObj = newproxy(true)
local metatable = getmetatable(wrappedObj)
metatable.__index = function(_, key)
if methods[key] ~= nil then
return function(...)
return methods[key](obj, ...)
end
elseif type(obj[key]) == "function" then
return function(...)
return obj[key](obj, ...)
end
else
return obj[key]
end
end
metatable.__tostring = function()
return obj.Name or obj;
end;
return wrappedObj
else
return obj
end
end

local methods = {
lol = function(self, ...)
print(tostring(self).." is bae!")
end
}

local test = addMethods(workspace.BasePlate, methods)

wait(.1)

test:lol() -- works

print(test.Parent) -- works

test.Parent = game.ServerStorage -- errors
Report Abuse
AgentFirefox is not online. AgentFirefox
Top 100 Poster
Joined: 20 Jun 2008
Total Posts: 22404
02 Jul 2015 07:34 PM
"rawset(getmetatable(S).__index,K,V)"

That would error.
The __metatable field of all objects' metatables in Roblox are set to "The metatable is locked" so you can't do that. You're better off just firing the __newindex metamethod by using S[K] = V instead.
Report Abuse
TickerOfTime is not online. TickerOfTime
Joined: 02 Sep 2012
Total Posts: 2030
02 Jul 2015 07:37 PM
@Agent It doesn't error, I've used this before. Granted, it was with Parent being a string, but whatevs.

-Ticker of da Tocks | Scripter's Forum Breakfast Club
Report Abuse
TickerOfTime is not online. TickerOfTime
Joined: 02 Sep 2012
Total Posts: 2030
02 Jul 2015 07:38 PM
Now, it doesn't work with __metatable being set, but that is an easy fix.

-Ticker of da Tocks | Scripter's Forum Breakfast Club
Report Abuse
TickerOfTime is not online. TickerOfTime
Joined: 02 Sep 2012
Total Posts: 2030
02 Jul 2015 07:42 PM
K, lemme test this and I'll post it in a second.

-Ticker of da Tocks | Scripter's Forum Breakfast Club
Report Abuse
TickerOfTime is not online. TickerOfTime
Joined: 02 Sep 2012
Total Posts: 2030
02 Jul 2015 08:01 PM
Done! Works with Parent and Name in the same script with a Part

local addMethods = function(obj, methods)
local isInstance = function(obj) -- thanks to eLunate for this
if type(obj) == "userdata" then
local s, e = pcall(game.GetService, game, obj);
return s and not e;
end
return false
end
if isInstance(obj) then
local wrappedObj = newproxy(true)
local metatable = getmetatable(wrappedObj)
metatable.__index = function(_, key)
if methods[key] ~= nil then
return function(...)
return methods[key](obj, ...)
end
elseif type(obj[key]) == "function" then
return function(...)
return obj[key](obj, ...)
end
else
return obj[key]
end
end
metatable.__tostring = function()
return obj.Name or obj;
end;
metatable.__newindex = function(ReindexObject,Key,Value)
--print(ReindexObject,Key,Value)
--print(obj[Key])
if obj[Key] or Key=='Parent' then
local DidSet,YNot=ypcall(function() obj[Key]=Value end)
if DidSet then
obj[Key]=Value
else
error(YNot)
end
else
error('Attempt to index \''..tostring(ReindexObject)..'\' (a userdata value)')
end
end

return wrappedObj
else
return obj
end
end

local methods = {
lol = function(self, ...)
print(tostring(self).." is bae!")
end
}
local p=Instance.new'Part'
p.Name='THISISAPART'
local thing = addMethods(p,methods)
thing:lol()

print(thing.Parent)
thing.Parent=workspace
print(thing.Parent)

print(thing.Name)
thing.Name='I spawned this part via a wrapper'
print(thing.Name)


-Ticker of da Tocks | Scripter's Forum Breakfast Club
Report Abuse
NotAshley is not online. NotAshley
Joined: 16 Jan 2014
Total Posts: 14257
02 Jul 2015 08:04 PM
Thank you so much!
Report Abuse
TickerOfTime is not online. TickerOfTime
Joined: 02 Sep 2012
Total Posts: 2030
02 Jul 2015 08:06 PM
No problem!
Send me the wrapper when it's done? I wanna see it.

-Ticker of da Tocks | Scripter's Forum Breakfast Club
Report Abuse
NotAshley is not online. NotAshley
Joined: 16 Jan 2014
Total Posts: 14257
02 Jul 2015 08:08 PM
It's done, you finished it. Not making a wrapper, just easy custom methods.
Report Abuse
TickerOfTime is not online. TickerOfTime
Joined: 02 Sep 2012
Total Posts: 2030
02 Jul 2015 08:10 PM
Oh, cool! Glad I could be of service!

-Ticker of da Tocks | Scripter's Forum Breakfast Club
Report Abuse
warspyking is not online. warspyking
Joined: 15 Nov 2011
Total Posts: 13947
02 Jul 2015 09:20 PM
"It's done, you finished it. Not making a wrapper, just easy custom methods."


That's still technically a wrapper. For a learning experience take a look at this, as far as I know it SHOULD work, it allows for custom properties and of course you can include functions in these properties to make methods (it won't use the real object though, it would use the wrapped object when calling it):

function Wrap(obj, newprops)
local new = newproxy(true)
local newprops = newprops or {}
getmetatable(new).__index = function(t, k)
if obj[k] then
if type(obj[k]) == "function" then
return function(dummy, ...)
return obj[k](obj, ...)
end
else
return obj[k]
end
else
return newprops[k]
end
end
getmetatable(new).__newindex = function(t, k, v)
if obj[k] then
local success = pcall(function() obj[k] = v end)
if not success then
newprops[k] = v
end
else
newprops[k] = v
end
end
getmetatable(new).__metatable = "Attempt to modify protected metatable"
getmetatable(new).__tostring = function(t)
return obj.Name
end
return new, newprops
end
Report Abuse
warspyking is not online. warspyking
Joined: 15 Nov 2011
Total Posts: 13947
02 Jul 2015 09:32 PM
Actually could you test this for me? Try changing the value .ClassName and then print it:

function Wrap(obj, newprops)
local new = newproxy(true)
local newprops = newprops or {}
getmetatable(new).__index = function(t, k)
if obj[k] then
if type(obj[k]) == "function" then
return function(dummy, ...)
return obj[k](obj, ...)
end
else
if pcall(function obj[k] = obj[k] end) then
return obj[k]
end
end
else
return newprops[k]
end
end
getmetatable(new).__newindex = function(t, k, v)
if obj[k] then
local success = pcall(function() obj[k] = v end)
if not success then
newprops[k] = v
end
else
newprops[k] = v
end
end
getmetatable(new).__metatable = "Attempt to modify protected metatable"
getmetatable(new).__tostring = function(t)
return obj.Name
end
return new, newprops
end


So something like


local workspace = Wrap(workspace)
workspace.ClassName = "NotWorkspace"
print(workspace.ClassName)



Just see what happens.
Report Abuse
cody123454321 is not online. cody123454321
Joined: 21 Nov 2009
Total Posts: 5408
02 Jul 2015 09:36 PM
Here is an abstract version.

local setmembers = function(tab1,tab2)
for i, v in pairs(tab2)do
tab1[i] = tab2[i]
end
end

local obj = {}

obj.new = function()
local this = {}
local proxy = newproxy(true)
local metatable = {
__index = this;
__newindex = function(self, i, v)
self[i] = v
end;
}

setmembers(getmetatable(proxy), metatable)
return proxy
end

return obj
Report Abuse
warspyking is not online. warspyking
Joined: 15 Nov 2011
Total Posts: 13947
02 Jul 2015 10:09 PM
HA! TAKE THAT!


Yeah I found a few wicked errors in the wrapper. Errors found in wrappers can be difficult to fix because they're underlying and under the surface. But anyhow I fixed it, you can now overwrite read-only properties, set your own properties, write to writable properties, and write to your own properties. Indexing children should also still work fine :) (Don't bother testing, tested myself :D )

function Wrap(obj, newprops)
local new = newproxy(true)
local newprops = newprops or {}
getmetatable(new).__index = function(t, k)
if pcall(function() return obj[k] end) then
if type(obj[k]) == "function" then
return function(dummy, ...)
return obj[k](obj, ...)
end
else
if pcall(function() obj[k] = obj[k] end) then
return obj[k]
else
return newprops[k]
end
end
else
return newprops[k]
end
end
getmetatable(new).__newindex = function(t, k, v)
if pcall(function() return obj[k] end) then
if not pcall(function() obj[k] = v end) then
newprops[k] = v
end
else
newprops[k] = v
end
end
getmetatable(new).__tostring = function(t)
return obj.Name
end
getmetatable(new).__metatable = "Attempt to modify protected metatable"
return new, newprops
end
Report Abuse
TickerOfTime is not online. TickerOfTime
Joined: 02 Sep 2012
Total Posts: 2030
02 Jul 2015 10:15 PM
"you can now overwrite read-only properties" What exactly is the point of writing a wrapper then?
Also, if anyone has any experience writing Script Builder type sandboxes, please let me know.

-Ticker of da Tocks | Scripter's Forum Breakfast Club
Report Abuse
NotAshley is not online. NotAshley
Joined: 16 Jan 2014
Total Posts: 14257
02 Jul 2015 10:16 PM
> Also, if anyone has any experience writing Script Builder type sandboxes, please let me know.

I'm writing a script builder and trying for the same thing. We could work together.
Report Abuse
TickerOfTime is not online. TickerOfTime
Joined: 02 Sep 2012
Total Posts: 2030
02 Jul 2015 10:19 PM
Sounds cool. How would we do that?

-Ticker of da Tocks | Scripter's Forum Breakfast Club
Report Abuse
warspyking is not online. warspyking
Joined: 15 Nov 2011
Total Posts: 13947
02 Jul 2015 10:21 PM
""you can now overwrite read-only properties" What exactly is the point of writing a wrapper then?"

Well it's to provide extra functionality on top of what's already given and to hide the underlying mechanisms so that the user does not need to worry about them.


My "wrapper" allows you to create, change, and index custom/new properties. It allows you to overwrite read-only properties (like ClassName). But any writable properties (such as Name, and Parent) would be changed before a new property is created (so no your cannot replace them).
Report Abuse
TickerOfTime is not online. TickerOfTime
Joined: 02 Sep 2012
Total Posts: 2030
02 Jul 2015 10:23 PM
@Not Maybe party me if you're serious?

-Ticker of da Tocks | Scripter's Forum Breakfast Club
Report Abuse
Previous Thread :: Next Thread 
Page 1 of 1
 
 
ROBLOX Forum » Game Creation and Development » Scripters
   
 
   
  • About Us
  • Jobs
  • Blog
  • Parents
  • Help
  • Terms
  • Privacy

©2017 Roblox Corporation. Roblox, the Roblox logo, Robux, Bloxy, and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.



Progress
Starting Roblox...
Connecting to Players...
R R

Roblox is now loading. Get ready to play!

R R

You're moments away from getting into the game!

Click here for help

Check Remember my choice and click Launch Application in the dialog box above to join games faster in the future!

Gameplay sponsored by:
Loading 0% - Starting game...
Get more with Builders Club! Join Builders Club
Choose Your Avatar
I have an account
generic image