robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 30 Apr 2015 11:10 PM |
I'm not great at OOP, I'm trying to get into the swing of using it more often, and I've been doing great, up until now. I'm trying to write a custom mouse module, that allows me to ignore instances at will without using roblox's restrictive TargetFilter property(http://wiki.roblox.com/index.php?title=API:Class/Mouse/TargetFilter). What I thought was easy turned problematic, obtaining the hit and the target of the mouse was a bit difficult, logically, and I got it to work, but not in a clean way, and it's prone to errors. I don't want to rely on loops, but the only other idea I have is to use __index and return the hit or the target using a method. I thought maybe I could use multiple metatables, and then found out if you set a metatable to a new metatable with a different __index definition, it overrides the existing metatable. Unless I'm doing something wrong and it's not supposed to behave like that(though I understand why it would, lol).
For example;
local basetable = {}
function basetable.GetHit() return "hit" end
function basetable.new() local meta = setmetatable({}, {__index = function(_, ind) if ind == "Hit" then return basetable:GetHit() --this kinda kills the .new method, i can no longer access :GetHit directly end end}) return meta end
excuse the word wall, i have no idea how to explain what i'm doing. lol
-=Robo=- |
|
|
| Report Abuse |
|
|
|
| 30 Apr 2015 11:12 PM |
"OOP question"
I see no question
ᴄσσℓɪσs :: ʙᴜɪᴅᴇʀ :: sᴄʀɪᴘᴛᴇʀ :: ᴅᴇᴠᴇʟᴏᴘᴇʀ :: ᴘʀᴏɢʀᴀᴍᴍᴇʀ |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 30 Apr 2015 11:15 PM |
"i have no idea how to explain what i'm doing" guess i left out a question, i thought i'd explained it but i forgot to
I'm trying to allow the player to call something like;
local NewMouse = mouse.new()
print(NewMouse.Hit)
>Hit's value
without relying on a loop, and using metamethods. i can't do this because i have it set to __index = NewMouse, and i'm not sure how to get around it.
-=Robo=- |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 30 Apr 2015 11:35 PM |
i see several capable people ignoring this post, can you guys tell me if i did a bad job at explaining it? i can try again xD
-=Robo=- |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 30 Apr 2015 11:38 PM |
You should do: function basetable:GetHit() to define it then do:
local meta = setmetatable({}, {__index = {hit = basetable.GetHit}}); |
|
|
| Report Abuse |
|
|
|
| 30 Apr 2015 11:41 PM |
local class = {}
local setmeta = function(tab, new) for i, v in pairs(new)do tab[i] = new[i] end end
class.new = function() local this = {} local metatable = {} local proxy = newproxy(true) this.isDead = false
this.kill = function(self) self.isDead = true end
setmeta(getmetatable(proxy), metatable) return proxy end
return class
local mod = require(script.ClassModule)
local example_class = mod.new() print(example_class.isDead) example_class:kill() print(example_class.isDead) |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 30 Apr 2015 11:41 PM |
| Why not reuse functions, be more efficient bud |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 30 Apr 2015 11:48 PM |
That's part of the problem. I was hoping there was a way I could avoid using (), it's actually why I was using metamethods in the first place. I had an idea before I posted this, of course it wouldn't work for obvious reasons but I'm kind of tired.
local basetable = {}
function basetable.GetHit() return "hit" end
function basetable.new() local meta = setmetatable({}, {__index = basetable}) meta.Hit = (function() return basetable:GetHit() end)() --only called once, obviously "doy doy doy" return
-=Robo=- |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 30 Apr 2015 11:49 PM |
Just do: meta.__index.Hit = baseplate.GetHit |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 30 Apr 2015 11:51 PM |
You can do that? wtf
-=Robo=- |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 30 Apr 2015 11:52 PM |
| Yeah, all you are doing is making Hit refer to basetable.GetHit |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 01 May 2015 12:01 AM |
i don't think you can do that man it's erroring for me lol
-=Robo=- |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 01 May 2015 12:02 AM |
| You are calling it using: meta:Hit() ? |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 01 May 2015 12:05 AM |
Oh sorry: baseplate.Hit = baseplate.GetHit;
Do that outside the functino |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 01 May 2015 12:06 AM |
is there anyway to do it without using parameters?
-=Robo=- |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 01 May 2015 12:06 AM |
| I didn't mean to add the __index, so either do ^ or meta.Hit = baseplate.GetHit |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 01 May 2015 12:08 AM |
local Meta = setmetatable( Mouse, {__index = function(table, Index) if Index == "Hit" then return Mouse:GetHit() elseif Index == "Target" then return Mouse:GetTarget() elseif Index == "X" or Index == "x" then return mouse.X elseif Index == "Y" or Index == "y" then return mouse.Y elseif Index == "Real" then return mouse elseif Index == "IgnoreNames" then return IgnoreNames elseif Index == "IgnoreInstances" then return IgnoreInstances else return Mouse[Index] end end} )
this is what i had previously. not pretty, really.
-=Robo=- |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 01 May 2015 12:08 AM |
Here:
local basetable = {}
function basetable:GetHit() return "hit" end
function basetable.new() local meta = setmetatable({}, {__index = basetable}) meta.Hit = basetable.GetHit return meta; end
Although since it will always be like that, just rename GetHit to Hit? |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 01 May 2015 12:11 AM |
err, uhh, not parameters, parentheses. I'm like, really out of it, I should probably go to bed but I wanna figure this out lol I want to do it like local hit = Mouse.Hit
and when you move the mouse like 5 seconds later and you define a new hit like
local hit2 = Mouse.Hit
hit ~= hit2 but i don't want to use a loop
does that makes sense at all? I think that's what I'm trying to say, it looks legible lol
-=Robo=- |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 01 May 2015 12:12 AM |
Oh, yeah sorry.
__index = function(self, key) if key == "Hit" then return baseplate.GetHit(self); end -- etc end;
That's one way of doing it |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 01 May 2015 12:13 AM |
say target = baseplate, and 5 seconds later, target = treestump
when you set a variable to Mouse.Target, it should THEN try to get the target, not run a continuous loop. I want to do it without using parentheses though. My previous method worked but it was kind of buggy, I want to do this with a new metatable so .new() actually has a purpose, and I can avoid having the same tables and values for different mouses. Maybe that explains more?
-=Robo=- |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 01 May 2015 12:15 AM |
well yes, but if I were trying to divide it up, all while having access to the new metatables methods(like :GetHit would still be available to use, but I could also do Mouse.Hit) setting the index to a function prevents me from allowing nil values to reference the basetable directly
-=Robo=-
-=Robo=- |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
| |
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 01 May 2015 12:19 AM |
could I maybe...
function basetable.new() local basemeta = setmetatable({}, {__index = basetable}) local newmouse = setmetatable({}, {__index = function(_, ind) if ind == "soandso" then --code, do this for all if statements end return basemeta[ind] --rely on the basemeta if no "if" statements return end}) end
would this work
-=Robo=- |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 01 May 2015 12:27 AM |
IT WOULLDD thanks guys lol
-=Robo=- |
|
|
| Report Abuse |
|
|