|
| 03 Aug 2016 05:26 PM |
I've defined a class (button) and a subclass (ReleaseButton) following the steps on the Lua website: https://www.lua.org/pil/16.2.html
local button={myValue=5} function button:new(o) o=o or{} setmetatable(o,self) self.__index=self return self end function button:myFunction(n) self.myValue=self.myValue+n end
And then:
local button=require(...ButtonClass) local rb=button:new() local ReleaseButton=rb:new() --was rb:new{otherValue=6} but that doesn't work ReleaseButton.otherValue=6 function ReleaseButton:otherFunction() return self.myValue+self.otherValue end
(Obviously these aren't the real scripts)
Now, if I call button:new() or ReleaseButton:new() in a Part this works fine. But if I run :new() on another Part, it doesn't create a new instance of the class: it uses the same one and binds events twice to the first button. What have I done wrong that means it's not creating a separate instance of the class? |
|
|
| Report Abuse |
|
|
TimeTicks
|
  |
| Joined: 27 Apr 2011 |
| Total Posts: 27115 |
|
|
| 03 Aug 2016 05:27 PM |
This is awful. Stop with the classes and stop with the metatables.
|
|
|
| Report Abuse |
|
|
| |
|
| |
|
|
| 04 Aug 2016 06:30 AM |
TimeTicks you're stupid.
OP here's a good read: https://www.lua.org/pil/16.3.html |
|
|
| Report Abuse |
|
|
|
| 04 Aug 2016 07:45 AM |
Thank you
I'm confused; I tried creating two buttons which each use button:new() - the real class binds touch events etc - but from Button1 and Button2 I get the error that "items" is nil in field setup() Button and ReleaseButton both have a method setup() but only ReleaseButton has the value "items"
So when ReleaseButton:new() is called, it doesn't create a new instance of ReleaseButton, it overwrites the class button(). So across the class and the subclass, and the two buttons and the two ReleaseButtons, only one instance ever exists. What is going on?
This part in button class:
function button:new(o) o=o or{} setmetatable(o,self) self.__index=self return self end
Currently only the last ReleaseButton to call new() will bind its events to both ReleaseButtons. If I change "return self" to "return o", it has the same issue, but one button will calls events for both ReleaseButtons. |
|
|
| Report Abuse |
|
|
|
| 05 Aug 2016 07:10 AM |
I've found so much conflicting information for class inheritance online (the Lua manual didn't cut it) but I've found this example that works in Roblox after being converted to module form:
--oop.lua Example of OOP and inheritance in Lua Person={ age=0, className='Person' } -- needed if needed add comparisons, operations, ... mtPerson={} mtPerson.__index={ getClassName=function(self) return self.className end, new=function(self,t) return setmetatable(t or {},{__index=self}) end, inherit=function (self,t,methods) -- This is the heart of the inheritance: It says: -- Look it up in the methods table, and if it's not there, look it up in the parrent class (her called self) -- You pass this function the parent class (with :), a table of attributes and a table of methods. local mtnew={__index=setmetatable(methods,{__index=self})} return setmetatable(t or {},mtnew) end, introduce=function(self) print(("Hi! I'm %s, I'm a %s and I'm %d years old"):format(self.instanceName,self.className,self.age)) end }
setmetatable(Person,mtPerson)
-- Wizard inherits from the class Person, and adds some default values and methods Wizard=Person:inherit({ className="Wizard", knownSpells={}, }, { listSpells=function(self) print("known spells:",self) if #self.knownSpells==0 then print'none' else for k,v in ipairs(self.knownSpells) do print(k,v) end end end } )
i1=Person:new{ inventory={'wallet'}, instanceName="John", }
i2=Wizard:new{ -- inherited method "new" inventory={'wallet','wand','cloak of invisibility'}, instanceName="Harry", age=20, knownSpells={'Avada kavedra', 'Sesame open'} }
i1:introduce() -- inherited method "introduce" notice that qge is the default value of 0 i2:introduce() --
i2:listSpells() -- method only in class 2 i1.age=26 i1:introduce() -- changed age of instance print(Person.age) -- didn't change class defaults print(Wizard.age) i1:listSpells() -- Error. |
|
|
| Report Abuse |
|
|
|
| 05 Aug 2016 07:53 AM |
Actually I don't think it was an issue with class instances at all; even though both buttons activate together, after the timed ends they return to their own respective colour, meaning they must be using separate class instances. I'm getting the same issue with this new 'Wizard' format and the original one I used.
Button makes use of this class:
local event={} event.__index=event event.new=function() return setmetatable({handlers={}},event) end function event:connect(func) table.insert(self.handlers,func) end function event:call(...) for i=1,#self.handlers do self.handlers[i](...) end end return event
But as you can see, it all depends on "self", so event:new() should create distinct instances.
I moved the events from button={value=6,OnActivate=event.new()} etc into button:new() :
new=function(self,t) self.OnActivate=event.new() self.OnSuccess=event.new(). self.OnFail=event.new() self.OnTimerEnd=event.new() return setmetatable(t or {},{__index=self}) end
So how come the events aren't separate instances for each instance of button?
Wouldn't classes/inheritance be really useful for setting up a game? Odd this isn't more of a thing |
|
|
| Report Abuse |
|
|