Creating a class and dispatching events from it?

I want to make a class, that holds some graphics and dispatch events from this class when a button is tapped… here is my simple code:

MyClass.lua:

local Class = {} local Class\_mt = { \_\_index = Class }    -- metatable ------------------------------------------------- -- PRIVATE FUNCTIONS ------------------------------------------------- local function tapListener( e )    -- local; only visible in this module     local event = {         name = "customEvent", myscustomvar = "this is my custom var"     }     Class:dispatchEvent( event ) end ------------------------------------------------- -- PUBLIC FUNCTIONS ------------------------------------------------- function Class.new( )    -- constructor          local rect = display.newRect( 0, 0, 50, 50 )     rect:addEventListener( "tap", tapListener )     local newClass = {         body = rect     }          return setmetatable( newClass, Class\_mt ) end ------------------------------------------------- return Class  

and then create this class and listen to some events being dispached:

local MyClass = require( "MyClass" ) local mynewclasss = MyClass.new() function myCustomEvent(e) print(e.myscustomvar) end mynewclass:addEventListener("customEvent", myCustomEvent)  

How to make it work? Any ideas?

I found a way to dispatch the event, but for me it feels kinda hacky - please enlighten me:

MyClass.lua

local Class = {} local Class\_mt = { \_\_index = Class }    -- metatable local thisObject ------------------------------------------------- -- PRIVATE FUNCTIONS ------------------------------------------------- local function tapListener( e )    -- local; only visible in this module     local event = {         name = "customEvent",         mycustomvar = "this is my custom var"     }          thisObject.body:dispatchEvent( event ) end ------------------------------------------------- -- PUBLIC FUNCTIONS ------------------------------------------------- function Class.new( )    -- constructor          local rect = display.newRect( 0, 0, 50, 50 )     rect:addEventListener( "tap", tapListener )     local newClass = {         body = rect     }          return setmetatable( newClass, Class\_mt ) end -- added this function to get reference to the object function Class:init()     thisObject = self end ------------------------------------------------- return Class  

implementation:

local MyClass = require( "MyClass" ) function myCustomEvent(e)   print(e.mycustomvar) end local myNewClass = MyClass.new() myNewClass:init() myNewClass.body:addEventListener("customEvent", myCustomEvent)  

This works… please tell me what you think - is this the right way of doing it?

I am no expert at this,  but I base what I do on Ardentkids  tutorial (found here).  He uses storyboard and makes self.view global so that it can be accessed by all classes loaded after it, this is then cleaned up by storyboard when the scene transitions.   You can dispatch events to self.view and listen to it as you want.

Hope this helps a little,  I am still not 100% sure if this is a clean way of doing it - but it works.

Craig

Ok thanks for info - I’ll check that out - meanwhile my solution seems to be working. Thanks!

What you are doing is actually dispatching and registering events on the rect.

If you want them on your class then you need to implement addEventListener, removeEventListener and dispatchEvent on your class or pass the calls to rect which will have the same effect of registering and dispatching events on the rect object.

This is the simple way of passing to the rect:

local Class = {} local Class\_mt = { \_\_index = Class } -- metatable ------------------------------------------------- -- PRIVATE FUNCTIONS ------------------------------------------------- ------------------------------------------------- -- PUBLIC FUNCTIONS ------------------------------------------------- function Class.new( ) -- constructor local rect = display.newRect( display.contentCenterX, display.contentCenterY, 50, 50 ) local newClass = { body = rect } newClass = setmetatable( newClass, Class\_mt) function newClass:addEventListener(eventName, listener) rect:addEventListener(eventName, listener) end function newClass:removeEventListener(eventName, listener) rect:removeEventListener(eventName, listener) end function newClass:dispatchEvent(event) rect:dispatchEvent(event) end local function tapListener( e ) -- local; only visible in this module local event = { name = "customEvent", mycustomvar = "this is my custom var" } newClass:dispatchEvent( event ) end rect:addEventListener( "tap", tapListener ) return newClass end return Class

Usage:

local myClass = require ("MyClass") local function myCustomEvent(e) print(e.mycustomvar) end local newClass = myClass.new() newClass:addEventListener("customEvent", myCustomEvent)

Actually implementing the event handling in your class is a bit more involved. If passing to rect is not good enough and you need it implemented in your class you can tell me and I will try to throw together a simple example.

I found a way to dispatch the event, but for me it feels kinda hacky - please enlighten me:

MyClass.lua

local Class = {} local Class\_mt = { \_\_index = Class }    -- metatable local thisObject ------------------------------------------------- -- PRIVATE FUNCTIONS ------------------------------------------------- local function tapListener( e )    -- local; only visible in this module     local event = {         name = "customEvent",         mycustomvar = "this is my custom var"     }          thisObject.body:dispatchEvent( event ) end ------------------------------------------------- -- PUBLIC FUNCTIONS ------------------------------------------------- function Class.new( )    -- constructor          local rect = display.newRect( 0, 0, 50, 50 )     rect:addEventListener( "tap", tapListener )     local newClass = {         body = rect     }          return setmetatable( newClass, Class\_mt ) end -- added this function to get reference to the object function Class:init()     thisObject = self end ------------------------------------------------- return Class  

implementation:

local MyClass = require( "MyClass" ) function myCustomEvent(e)   print(e.mycustomvar) end local myNewClass = MyClass.new() myNewClass:init() myNewClass.body:addEventListener("customEvent", myCustomEvent)  

This works… please tell me what you think - is this the right way of doing it?

I am no expert at this,  but I base what I do on Ardentkids  tutorial (found here).  He uses storyboard and makes self.view global so that it can be accessed by all classes loaded after it, this is then cleaned up by storyboard when the scene transitions.   You can dispatch events to self.view and listen to it as you want.

Hope this helps a little,  I am still not 100% sure if this is a clean way of doing it - but it works.

Craig

Ok thanks for info - I’ll check that out - meanwhile my solution seems to be working. Thanks!

What you are doing is actually dispatching and registering events on the rect.

If you want them on your class then you need to implement addEventListener, removeEventListener and dispatchEvent on your class or pass the calls to rect which will have the same effect of registering and dispatching events on the rect object.

This is the simple way of passing to the rect:

local Class = {} local Class\_mt = { \_\_index = Class } -- metatable ------------------------------------------------- -- PRIVATE FUNCTIONS ------------------------------------------------- ------------------------------------------------- -- PUBLIC FUNCTIONS ------------------------------------------------- function Class.new( ) -- constructor local rect = display.newRect( display.contentCenterX, display.contentCenterY, 50, 50 ) local newClass = { body = rect } newClass = setmetatable( newClass, Class\_mt) function newClass:addEventListener(eventName, listener) rect:addEventListener(eventName, listener) end function newClass:removeEventListener(eventName, listener) rect:removeEventListener(eventName, listener) end function newClass:dispatchEvent(event) rect:dispatchEvent(event) end local function tapListener( e ) -- local; only visible in this module local event = { name = "customEvent", mycustomvar = "this is my custom var" } newClass:dispatchEvent( event ) end rect:addEventListener( "tap", tapListener ) return newClass end return Class

Usage:

local myClass = require ("MyClass") local function myCustomEvent(e) print(e.mycustomvar) end local newClass = myClass.new() newClass:addEventListener("customEvent", myCustomEvent)

Actually implementing the event handling in your class is a bit more involved. If passing to rect is not good enough and you need it implemented in your class you can tell me and I will try to throw together a simple example.