Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
overriding class methods? — Gideros Forum

overriding class methods?

jack0088jack0088 Member
edited August 2012 in General questions
How to override class methods? Is it possible to extend a method or redefine it completely? How about constructors - say I would want to extend the Sprite.init?
Owltwins. Smart design and creative code.
»Gideros Illustrator« - [svg|xml] scene designer using Adobe Illustrator®™ Within one line of code!

Comments

  • ar2rsawseenar2rsawseen Maintainer
    edited August 2012
    Gideros class system is very felxible.

    You can both overwrite/redefine methods or extend any existing class

    Here's example of overriding Bitmap class to save reference to the texture it was created with
    --save new method as some other method
    Bitmap.__new = Bitmap.new
     
    --redefine new method
    function Bitmap.new(texture)
    	--create real Bitmap instance
    	self = Bitmap.__new(texture)
    	--save texture as property
    	self.texture = texture
    	return instance
    	return self
    end
     
    --additional method to return texture
    function Bitmap:getTexture()
    	return self.texture
    end
    And here's of extending Bitmap class with new constructor:
    --extend new class from Bitmap
    newBitmap = Core.class(Bitmap)
     
    --define new constructor (should accept atleast same arguments)
    function newBitmap:init(texture)
    	--Bitmap constructor is automatically called here
    	--so this class will have all standard methods and properties
    	--of parent class
    	--we only need to add new ones
    	self.texture = texture
    end
     
    --and define method to return texture
    function newBitmap:getTexture()
    	return self.texture
    end
    Hope that helps ;)
  • jack0088jack0088 Member
    edited August 2012
    ähm, yes, I was looking for something like the first example.. but I can't get it to work.
    What's wrong here?
    do
    	local spriteInit = Sprite.new --cache
     
    	function Sprite.new()
    		local instance = spriteInit() --call default class behavior
    		instance.coordinate = {       --extend class by a table
    			x = 0,
    			y = 0
    		}
    		return instance
    	end
    end
    Sprite.coordinate doesn't exist after calling Sprite.new()


    EDIT:
    Also tried this way, which I think is the same:
    Sprite.__new = Sprite.new
     
    function Sprite.new()
    	self = Sprite.__new()
    	self.coordinate = {
    		x = 0,
    		y = 0
    	}
    	return self
    end
    Owltwins. Smart design and creative code.
    »Gideros Illustrator« - [svg|xml] scene designer using Adobe Illustrator®™ Within one line of code!
  • It works for me:
    do
    	local spriteInit = Sprite.new --cache
     
    	function Sprite.new()
    		local instance = spriteInit() --call default class behavior
    		instance.coordinate = {       --extend class by a table
    			x = 0,
    			y = 0
    		}
    		return instance
    	end
    end
     
    local sprite = Sprite.new()
    print(sprite.coordinate.x)
    print(sprite.coordinate.y)
    If you want Sprite class and not instance) to have coordinates, then it's easy, you could have done it simply:
    Sprite.coordinate = {       --extend class by a table
    			x = 0,
    			y = 0
    		}
  • jack0088jack0088 Member
    edited August 2012
    But then Sprite doesn't propagate this value to it's instances.. at least I thought so?!

    PS: If I extend the Sprite class with this table, WHY the Shape class doesn't has it too, when a call Shape.new()?
    Owltwins. Smart design and creative code.
    »Gideros Illustrator« - [svg|xml] scene designer using Adobe Illustrator®™ Within one line of code!
  • But then Sprite doesn't propagate this value to it's instances.. at least I thought so?!
    What do you mean?
    PS: If I extend the Sprite class with this table, WHY the Shape class doesn't has it too, when a call Shape.new()?
    Because Shape class extends Sprite class somewhere internally, much before you modify Sprite class

  • jack0088jack0088 Member
    edited August 2012
    Because Shape class extends Sprite class somewhere internally, much before you modify Sprite class
    I'm still a stupid noob to Gideros, maybe because I aint work regularly with the SDK.
    The whole FAQ was due to my anchorPoint dilemma some time before, where I asked you about manipulating the getPosition() output.
    I wanted to rewrite/modify the Sprite class and have the anchorPoints working for all the classes inherited from the Sprite (e.g. Shape). BUT as you pointed out - I have a problem now. To get it work with Sprite, Shape, etc. I have to do it for every class separately, am I right?

    Ufff... maybe I should forget about development. Maybe I'm just not the right guy for this stuff.
    Owltwins. Smart design and creative code.
    »Gideros Illustrator« - [svg|xml] scene designer using Adobe Illustrator®™ Within one line of code!
  • No, don't get frustrated. Everyone makes the mistakes while in learning phase.

    So what do you do, if you are not a developer? :)

    But to answer your question, yes basically, you'll need to implement setAnchorPoint for every class you want to have it. And it's quite easy to do that.

    You can create simple function (I can't remember implementation of anchor point from the top of my head so I'll use what you had):
    function implementAnchorpoint(anyClass)
    	local newInit = anyClass.new --cache
     
    	function anyClass.new()
    		local instance = newInit() --call default class behavior
    		instance.coordinate = {       --extend class by a table
    			x = 0,
    			y = 0
    		}
    		return instance
    	end
    end
     
    --apply to all needed classes
    implementAnchorpoint(Sprite)
    implementAnchorpoint(Shape)
    --etc

    Likes: talis, jack0088

    +1 -1 (+2 / -0 )Share on Facebook
  • jack0088jack0088 Member
    edited August 2012
    oh my god.. the solution is elegant and seems now to be so obvious... thank you @ar2rsawseen for being here! Ok. I try my best.

    PS: I'm actually designer. But a few years ago I did some web development in php, mysql, html, css and all that stuff. Then I dropped because of the army.. now I'm trying to find my niche.
    Owltwins. Smart design and creative code.
    »Gideros Illustrator« - [svg|xml] scene designer using Adobe Illustrator®™ Within one line of code!
  • Considering the fact that you find the solution elegant means you have a good taste in coding.
    Meaning you'll be fine, just keep learning ;)

    Likes: techdojo

    +1 -1 (+1 / -0 )Share on Facebook
  • jack0088jack0088 Member
    edited August 2012
    I written it down, and I think it should work correctly but somehow it doesn't. Why?
    Here is my class for AnchorPoints functionality.
    local function AnchorPoint( Class )
     
    	Class.__new = Class.new --cache
     
    	function Class.new()
     
    		local instance = Class.__new() --call default class behavior
     
     
    		--add AnchorPoint methods...
     
    		instance.anchorPoint = {
    			x = 0,
    			y = 0,
    			offsetX = 0,
    			offsetY = 0,
    		}
     
     
    		instance.__setX = Class.setX
    		instance.__setY = Class.setY
    		instance.__getX = Class.getX
    		instance.__getY = Class.getY
     
     
    		function instance:getOffsetX()
    			return self:getWidth()  * self.anchorPoint.x
    		end
     
    		function instance:getOffsetY()
    			return self:getHeight() * self.anchorPoint.y
    		end
     
     
    		function instance:setAnchorPoint( cx, cy )
    			self.anchorPoint.x, self.anchorPoint.y = cx, cy
    			self:setPosition( self.__getX(self), self.__getY(self) ) --refresh
    		end
     
    		function instance:getAnchorPoint()
    			return self.anchorPoint.x, self.anchorPoint.y
    		end
     
     
    		function instance:setX( x )
    			self.anchorPoint.offsetX = self:getOffsetX()
    			self.__setX( self, x - self.anchorPoint.offsetX )
    		end
     
    		function instance:setY( y )
    			self.anchorPoint.offsetY = self:getOffsetY()
    			self.__setY( self, y - self.anchorPoint.offsetY )
    		end
     
     
    		function instance:getX()
    			local x = self.__getX(self) + self.anchorPoint.offsetX
    			self.anchorPoint.offsetX = 0
    			return x
    		end
     
    		function instance:getY()
    			local y = self.__getY(self) + self.anchorPoint.offsetY
    			self.anchorPoint.offsetY = 0
    			return y
    		end
     
     
    		function instance:setPosition( x, y )
    			self:setX(x)
    			self:setY(y)
    		end
     
    		function instance:getPosition()
    			print("#", self:getX(), self:getY()) --returns (0,0)!
    			return self:getX(), self:getY()
    		end
     
     
    		return instance
     
    	end
     
    end
     
     
    --apply to classes
    AnchorPoint( Sprite )
    AnchorPoint( Shape  )
    If I create a Shape and call :getPosition() I somehow reach the original behavior not my modified class function.
    local rect = Primitive.new() --equivalent to Shape.new()
    rect:newRect(0,0, 101,101) --method of Primitive; 101x101px at screen origin
    rect:setAnchorPoint(.5, 0)
    print("R",rect:getPosition()) --returns (-59,0)???
    My function should have nulled it out by "+self.anchorPoint.offsetX"...
    Owltwins. Smart design and creative code.
    »Gideros Illustrator« - [svg|xml] scene designer using Adobe Illustrator®™ Within one line of code!
  • ar2rsawseenar2rsawseen Maintainer
    Accepted Answer
    Well hard to tell without deeper debugging. (BTW you can debug by putting print function inside new added/overwritten methods, to see if everything happens how it's expected.)

    Will try to check it deeper, but first comment would be, try not to use reserved variables. As variable Class is a global variable for extendind/creating new classes ;)
  • jack0088jack0088 Member
    edited August 2012
    I tried to cache the original functions locally for example like:
    local __setX = Class.setX
    local __setY = Class.setY
    local __getX = Class.getX
    local __getY = Class.getY
    But same result. Also I used your suggested method of debugging at the instance:getPosition() method above.
    print("#", self:getX(), self:getY()) --returns (0,0)!
    This print() gives me the correct value of (0,0), but inside the main.lua it returns a different value of (-59,0)
    print("R",rect:getPosition()) --returns (-59,0)???
    If you'll have some time to check this, maybe you can get it to work in a better manner?
    Owltwins. Smart design and creative code.
    »Gideros Illustrator« - [svg|xml] scene designer using Adobe Illustrator®™ Within one line of code!
  • Ok I think I've figured it out.

    First thing I noticed, that this value changes. If you comment out print function inside instance:getPosition()

    And instead you'll call print("R",rect:getPosition()) --returns (-59,0)??? like you did in the in the end of the code it returns 0,0 coordinate.

    Now try calling print("R",rect:getPosition()) two times. First one will return 0,0 and second one will return -59,0

    It is because inside getX and getY methods you reset self.anchorPoint.offsetX = 0
    So next time you call it anchorPoint is zero again

    ;)
  • jack0088jack0088 Member
    edited August 2012
    double post
    Owltwins. Smart design and creative code.
    »Gideros Illustrator« - [svg|xml] scene designer using Adobe Illustrator®™ Within one line of code!
  • I think I got it to work. Thank you again many times! The only think I have to add is setRotation. And test Sprite inheritance..
    Owltwins. Smart design and creative code.
    »Gideros Illustrator« - [svg|xml] scene designer using Adobe Illustrator®™ Within one line of code!
  • jack0088jack0088 Member
    edited August 2012
    Waaahh.. I'm going crazy! @ar2rsawseen I've modified the class and it seems working now, but I can't get the :setRotation method to work! Could you be so good and help me out again? PLEASE!
    I've prepared the project for you:
    zip
    zip
    anchorPoint.zip
    192K
    Owltwins. Smart design and creative code.
    »Gideros Illustrator« - [svg|xml] scene designer using Adobe Illustrator®™ Within one line of code!
  • jack0088jack0088 Member
    edited August 2012
    I figured out where the issue lies... After the Object was rotated, the rotation point is shifted a little, because the overall shape changed (width, height). So anyone any idea how to get this shifted length?
    Untitled-1.jpg
    126 x 128 - 26K
    Owltwins. Smart design and creative code.
    »Gideros Illustrator« - [svg|xml] scene designer using Adobe Illustrator®™ Within one line of code!
  • ar2rsawseenar2rsawseen Maintainer
    edited August 2012
    Well mathematical solution to this problem:
    local dx = self:getAnchorPointOffsetX()
    local dy = self:getAnchorPointOffsetY()
    local cosine = math.cos(math.rad(n))
    local sine = math.sin(math.rad(n))
    local newX = dx - (dx*cosine - dy*sine)
    local newY = dy - (dy*cosine + dx*sine)
    self:setPosition(self:getX() + newX, self:getY() + newY)
    But is does not work as I expected.
    It still misses about 10px for 15deg and 20px for 30deg on both axis.
    Don't know where they come form, or what I'm not taking into consideration.

    Getting too late here, maybe I should leave it to other evening ;)
  • ar2rsawseenar2rsawseen Maintainer
    edited August 2012 Accepted Answer
    Ok got it with the help of my wife.

    You don't need to reset anchor point to 0 to rotate and then put it back. It can stay in same anchor, somehow I missed that.

    So here's a working project:
    http://appcodingeasy.com/anchorPointFixed.zip

    Now it's definitely good night for me ;)

    Edited:
    Don't know why I couldn't upload the file to forum. It always ended up as 0byte file
    +1 -1 (+2 / -0 )Share on Facebook
  • haha:)))) you and your wife are geniuses! :D

    Likes: chipster123

    Owltwins. Smart design and creative code.
    »Gideros Illustrator« - [svg|xml] scene designer using Adobe Illustrator®™ Within one line of code!
    +1 -1 (+1 / -0 )Share on Facebook
Sign In or Register to comment.