Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]

Sending messages, calling distant functions
Started by horacebury Aug 15 2018 01:52 AM

- - - - -
1 reply to this topic
lua composer functions
This topic has been archived. This means that you cannot reply to this topic.
[TOPIC: post.html]


[GLOBAL: userInfoPane.html]
  • Corona Geek

  • 3,069 posts
  • Corona SDK

Let's say I have a button which is created within a layer, which is constructed by another layer and that by an over-arching module of my game. I want that button to call a function on a particular object (or objects!) which was created by a layer within a layer within a user interface module which was, itself, constructed by a composer scene. That's quite a distance between the caller and the receiver.


Currently, I have three options open to me to allow that function call to take place:

  1. Pass a reference to the thing I might want to call a function on around the system. The penalty here is that tidying up references can cause memory leaks after garbage collection and is just unsightly.
  2. Have the thing with the function to be called listen for an event on the current scene or Runtime object and simply remove the listener when it is finalized. This approach is handy, but lends itself to losing the connection between the items making the call and receiving the call, which makes future maintenance harder.
  3. Using a single table, perhaps returned from a dedicated module, to store a list of named functions, which can be called in a 'global' style but is more easily managed. This, too, has the flaw that tidying references up is a risk at garbage collection but that connections between caller and receiver are more obvious during maintenance and expansion.

What do you do to make distant or complex connections between components easier to manage, maintain and simply easier to see when returning to old code?

[TOPIC: post.html]


[GLOBAL: userInfoPane.html]
  • Corona Geek

  • 7,587 posts
  • Corona SDK

I use custom Runtime events.


i.e. Create a listener for some 'custom' event anywhere you need it, then dispatch it from anywhere else.


The Corona functions for this are:

  • Runtime:addEventListener()
  • Runtime:dispatchEvent()

However, I don't use them.  I have shorthand helpers in SSK that are easier to type and more efficient in signature.

-- Some code some place

local function killBill( event )
   -- do something here
end; listen( "killBill", killBill )

... can also do this:

local bill = display.newCircle( 10, 10, 10 )

function bill.killBill( self, event )
   -- do something here
end; listen( "killBill", bill )

Now anywhere else in my game I can do this (using SSK):

post( "killBill" )

-- or I can pass info in a table

post( "killBill", { reason = "He's a bad man.", when = "now" } )

The only thing to worry about is that Runtime event listeners don't self-clean. i.e. If you delete 'bill' (object above) later, you need to remove the listener.


SSK contains two helpers for this:


1. Code to catch the problem late...

-- Modified listener from above

function bill.killBill( self, event )

   -- object is invalid, clean up and get out of here
   if( autoIgnore( "killBill", self ) ) then return end 

   -- otherwise, do something here

end; listen( "killBill", bill )

2. Code to safely remove a whole set of listeners

-- alternately, I like to do this:

function bill.finalize( self )
   -- assuming I also added an enterFrame listener to 'bill'
   ignoreList( { "enterFrame", "killBill" }, self )