Corona SDK how to add custom method to displayobject

I want to add custom method to display object something like the prebuilt methods for example “setFillColor”

i wrote the following code which is not working; however, it explains what i need

function display:foo(bar) print(bar) end local myRectangle = display.newRect( 0, 0, 150, 50 ) myRectangle:foo("something to be printed")

i want the “foo” method to be ready for all DisplayObjects not only myRectangle?

 

 

here is my question in stackoverflow

http://stackoverflow.com/questions/24597457/corona-sdk-how-to-add-custom-method-to-displayobject

thats not quite how it works, to do that you will need to create a seperate modular class . Jonathan does a great tutorial on how to do one here http://coronalabs.com/blog/2011/09/29/tutorial-modular-classes-in-corona/

edit: my bad, i’m wrong, it is possible … (feeling embarrassed)

Example below. Untested but should work. Then it will be available to all newRect calls. You would have to do this for all display.* calls that you wish to use however.

@lemonade, it is possible :wink:

local oldNewRect = display.newRect function display.newRect( ... ) local rect = oldNewRect( ... ) function rect:foo() print( "hello" ) end return rect end -- usage local rect = display.newRect( 0, 0, 40, 40 ) rect:foo() -- prints "hello"

Okay, I’m not totally sure this is a good idea. The problem is it might work now, but it might not in future. 

Example ; my Bitmap Font library ; I wanted an equivalent to display.newText, display.newBitmapText which was as near as possible functionally identical. So this involves adding a newBitmapText method to the display object in much the same way that Gremlin writes above.

The problem with this decoration is that you and I don’t own the definition of the parent object, Corona does. They may decide to do their own version of display.newBitmapText in which case my version will blat the new one.

I sometimes see code which accesses Corona’s internal structures to clear listeners. This is a baaad idea for the same reasons, Corona might change it to something functionally identical but implemented differently.

In answer to your question, a less pretty but more robust version is to use a factory function e.g.

function getRectangle(...) local rect = display.newRect(...) rect.printHello = function() print("Hello !!!!") end end 

which creates a rectangle and decorates it with a method “printHello”. Here you are working on the instances of the rectangle rather than the base object. If you are an OOP guy you can subclass the display.newRect object as well, which will achieve much the same effect.

It is still possible this might not work. You might overwrite a method that is used by another method, in which case all he*l might break loose.

Fundamentally, don’t, and if you must, do it very carefully and in a contained fashion. 

The classic example is Windows. I’m old enough to have worked on Windows 3. (actually I’m older). Up until the 32 bit versions of windows, you had to allocate memory using a GlobalAlloc() method and then lock it with a GlobalLock() method, then you could actually do something with it (and when you finished you GlobalUnlock() it then finally GlobalFree() it). It was to stop memory being moved about by the virtual memory system (this was the days of 640k and 80286 processors)

Microsoft, cluelessly, encouraged people initially to do this not using the actual methods, but by casting the handle provided by GlobalAlloc to a pointer in C, something like (void *)((long)handle << 16), I can’t remember exactly. 

Whether this was for the marginal speed advantage or they were just completely incompetent, I don’t know.

It worked. For a bit. Until later versions of Windows came along, and then it was a total mess.

thats not quite how it works, to do that you will need to create a seperate modular class . Jonathan does a great tutorial on how to do one here http://coronalabs.com/blog/2011/09/29/tutorial-modular-classes-in-corona/

edit: my bad, i’m wrong, it is possible … (feeling embarrassed)

Example below. Untested but should work. Then it will be available to all newRect calls. You would have to do this for all display.* calls that you wish to use however.

@lemonade, it is possible :wink:

local oldNewRect = display.newRect function display.newRect( ... ) local rect = oldNewRect( ... ) function rect:foo() print( "hello" ) end return rect end -- usage local rect = display.newRect( 0, 0, 40, 40 ) rect:foo() -- prints "hello"

Okay, I’m not totally sure this is a good idea. The problem is it might work now, but it might not in future. 

Example ; my Bitmap Font library ; I wanted an equivalent to display.newText, display.newBitmapText which was as near as possible functionally identical. So this involves adding a newBitmapText method to the display object in much the same way that Gremlin writes above.

The problem with this decoration is that you and I don’t own the definition of the parent object, Corona does. They may decide to do their own version of display.newBitmapText in which case my version will blat the new one.

I sometimes see code which accesses Corona’s internal structures to clear listeners. This is a baaad idea for the same reasons, Corona might change it to something functionally identical but implemented differently.

In answer to your question, a less pretty but more robust version is to use a factory function e.g.

function getRectangle(...) local rect = display.newRect(...) rect.printHello = function() print("Hello !!!!") end end 

which creates a rectangle and decorates it with a method “printHello”. Here you are working on the instances of the rectangle rather than the base object. If you are an OOP guy you can subclass the display.newRect object as well, which will achieve much the same effect.

It is still possible this might not work. You might overwrite a method that is used by another method, in which case all he*l might break loose.

Fundamentally, don’t, and if you must, do it very carefully and in a contained fashion. 

The classic example is Windows. I’m old enough to have worked on Windows 3. (actually I’m older). Up until the 32 bit versions of windows, you had to allocate memory using a GlobalAlloc() method and then lock it with a GlobalLock() method, then you could actually do something with it (and when you finished you GlobalUnlock() it then finally GlobalFree() it). It was to stop memory being moved about by the virtual memory system (this was the days of 640k and 80286 processors)

Microsoft, cluelessly, encouraged people initially to do this not using the actual methods, but by casting the handle provided by GlobalAlloc to a pointer in C, something like (void *)((long)handle << 16), I can’t remember exactly. 

Whether this was for the marginal speed advantage or they were just completely incompetent, I don’t know.

It worked. For a bit. Until later versions of Windows came along, and then it was a total mess.