A Fuse Powered Company

Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Luoop - Lua oop library
Started by engel.teddy Oct 21 2013 02:20 PM

- - - - -
14 replies to this topic
lua oop objectoriented library
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

engel.teddy

[GLOBAL: userInfoPane.html]
engel.teddy
  • Pro
  • PipPip
  • 18 posts
  • Member

Hello guys,

In my game project i have an extensive need for object oriented capabilities and all the existing libraries that i found for Lua were either too complicated to fiddle with them, or lacked some features that i needed, so in the end i crafted my own.
I shared it on github as an open-source project called Luoop, so just thought i would mention it in here just in case it can be of use to anyone :)
I'm still expanding the possibilities slowly and could definitely value some external feedback :)

Here is the link:
https://github.com/TeddyEngel/Luoop

Cheers,
Teddy
@Teddy_Engel



[TOPIC: post.html]
#2

LairdGames

[GLOBAL: userInfoPane.html]
LairdGames
  • Pro
  • PipPipPipPipPipPip
  • 963 posts
  • Jedi

@Teddy,

 

THANKS for the share! it is nice to see some OOP news. I wish Corona had implemented something like this. In any event, how would you use this library to deal with say visual objects (like images) and more importantly event listeners? Say I have a HUD in the game which shows #lives, points and so on. What about event like object collisions? I am using Storyboard and not sure really how to use this library for those basic game elements (display objects or event listeners)? 

 

The example you show are good but I think people will probably need a more beefy example to apply. Of course just a suggestion:)

 

In any event, thank you again for sharing. I think we need a simple a Corona OOP infrastructure like Gideros and Moai SDK's

Cheers,

 

Mo 



[TOPIC: post.html]
#3

engel.teddy

[GLOBAL: userInfoPane.html]
engel.teddy
  • Pro
  • PipPip
  • 18 posts
  • Member

@Teddy,

 

THANKS for the share! it is nice to see some OOP news. I wish Corona had implemented something like this. In any event, how would you use this library to deal with say visual objects (like images) and more importantly event listeners? Say I have a HUD in the game which shows #lives, points and so on. What about event like object collisions? I am using Storyboard and not sure really how to use this library for those basic game elements (display objects or event listeners)? 

 

The example you show are good but I think people will probably need a more beefy example to apply. Of course just a suggestion:)

 

In any event, thank you again for sharing. I think we need a simple a Corona OOP infrastructure like Gideros and Moai SDK's

Cheers,

 

Mo 

Hello Mo !

Thanks for your interest, it's great indeed to hear some feedback :)
A few things have been added to the library since i originally posted it, it's highly iterative work since i'm basically adding to it when i encounter a case for which i need an additional development in my game project.

Your question is very very accurate actually, and in my personal case i have also recoded a whole director / event / listener implementation, as well as encapsulated the 'native' corona display objects into my own ones.
Main reasoning behind all this is that i wanted my events to work not only with physics / display objects, but basically anything and that's pretty much a requirement in the game i'm working on.
Same thing with display objects, i found out that it was probably cleaner to encapsulate native display objects so that i am
a ) secured against api changes (such as in the graphics 2.0 update) because i only need a few changes in my 'facade' display layer
b ) able to craft easily reusable components. Basically i just wanted to be able to call almost new Clock() for example and create a clock object easily.

I think however that once i'm done with the current project i'll share all the event side of the implementation since it can definitely be useful to other projects.

In your specific case, a display object that can handle native corona events try this:
 


-----------------------------------------------------------------------------------------
--
-- Control.lua
--
-----------------------------------------------------------------------------------------
require (gsPathLuoop.."luoop") -- sClass system

--- Constructor ---
local function new(self, nX, nY, nWidth, nHeight, oReferencePoint)
    -- public members
    self._nX = nX
    self._nY = nY
    self._nWidth = nWidth
    self._nHeight = nHeight
    self._oReferencePoint = oReferencePoint

    -- private members
    self._sFamily = sFamily
    self._sId = sId
    self._oDisplayObject = nil
end

-- A class
Control = class(new)

--- Destructor ---
function Control:destroy()
    self._nX = nil
    self._nY = nil
    self._nWidth = nil
    self._nHeight = nil
    self._oReferencePoint = nil
    self._oDisplayObject = nil
end

function Control:type()
    return 'Control'
end

-- Getters / setters
function Control:_getX()
    return self._nX
end

function Control:getX()
    return self:_getX()
end

function Control:setX(nX)
    self._nX = nX

    -- Updating display object if needed
    local oDisplayObject = self:_getDisplayObject()

    if oDisplayObject ~= nil then oDisplayObject.x = nX end
end

function Control:_getY()
    return self._nY
end

function Control:getY()
    return self:_getY()
end

function Control:setY(nY)
    self._nY = nY

    -- Updating display object if needed
    local oDisplayObject = self:_getDisplayObject()

    if oDisplayObject ~= nil then oDisplayObject.y = nY end
end

function Control:_getWidth()
    return self._nWidth
end

function Control:getWidth()
    return self:_getWidth()
end

function Control:setWidth(nWidth)
    self._nWidth = nWidth

    -- Updating display object if needed
    local oDisplayObject = self:_getDisplayObject()

    if oDisplayObject ~= nil then oDisplayObject.width = nWidth end
end

function Control:_getHeight()
    return self._nHeight
end

function Control:getHeight()
    return self:_getHeight()
end

function Control:setHeight(nHeight)
    self._nHeight = nHeight

    -- Updating display object if needed
    local oDisplayObject = self:_getDisplayObject()

    if oDisplayObject ~= nil then oDisplayObject.height = nHeight end
end

function Control:getContentWidth()
    local nContentWidth = 0
    local oDisplayObject = self:_getDisplayObject()

    if oDisplayObject ~= nil then nContentWidth = oDisplayObject.contentWidth end
    return nContentWidth
end

function Control:getContentHeight()
    local nContentHeight = 0
    local oDisplayObject = self:_getDisplayObject()

    if oDisplayObject ~= nil then nContentHeight = oDisplayObject.contentHeight end
    return nContentHeight
end

function Control:_getReferencePoint()
    return self._oReferencePoint
end

function Control:getReferencePoint()
    return self:_getReferencePoint()
end

function Control:_setReferencePoint(oReferencePoint)
    self._oReferencePoint = oReferencePoint
end

function Control:setReferencePoint(oReferencePoint)
    self:_setReferencePoint(oReferencePoint)

    -- Updating display object if needed
    local oDisplayObject = self:_getDisplayObject()

    if oDisplayObject ~= nil then oDisplayObject:setReferencePoint(oReferencePoint) end
end

function Control:_getDisplayObject()
    return self._oDisplayObject
end

function Control:_setDisplayObject(oDisplayObject)
    self._oDisplayObject = oDisplayObject
end

--- Methods ---
function Control:refresh()
    -- Some controls require a specific routine to call when content is updated
end

function Control:render()
    -- Called when actually rendering by creating the display object and showing on screen
end


function Control:addOnTouchEvent(fctOnTouch)
    local oDisplayObject = self:_getDisplayObject()
    return oDisplayObject:addEventListener( "touch", fctOnTouch)
end

function Control:removeOnTouchEvent(fctOnTouch)
    local oDisplayObject = self:_getDisplayObject()
    return oDisplayObject:removeEventListener( "touch", fctOnTouch)
end

function Control:addOnTapEvent(fctOnTap)
    local oDisplayObject = self:_getDisplayObject()
    return oDisplayObject:addEventListener( "tap", fctOnTap)
end

function Control:removeOnTapEvent(fctOnTap)
    local oDisplayObject = self:_getDisplayObject()
    return oDisplayObject:removeEventListener( "tap", fctOnTap)
end

That's like a 'generic' control object from which you can create your inherited specific controls.
Once it's created you just have to call yourControl:addOnTapEvent(yourHandler) to add an event listener on the object.
You could also call yourControl:addOnTapEvent(yourControl.fctInternalHandler) to keep the handler internal to the object :)

The _methods are considered private methods, other public.

Feel free to contact me by pm / e-mail if you need more detail :)

Edit: Added the example on the github repository.



[TOPIC: post.html]
#4

TJHague

[GLOBAL: userInfoPane.html]
TJHague
  • Starter
  • Pip
  • 1 posts
  • Newbie

@Teddy

 

Thanks so much for posting this!

 

I've been relearning mobile programming in my (little) free time and had been debating if I wanted to use Corona because of its lack of a simple Object Oriented implementation. This looks like it does exactly what I was looking for! I'm excited to start using this :)

 

-Tyler



[TOPIC: post.html]
#5

LairdGames

[GLOBAL: userInfoPane.html]
LairdGames
  • Pro
  • PipPipPipPipPipPip
  • 963 posts
  • Jedi

Thanks Teddy for the additional example and the extra info. I appreciate it. I have to admit that because I am new to OOP, it is going to take me sometime to absorb the info but I am very grateful that you took the time the answer and that you are willing to help. I will have a lot of questions!

 

Thanks.

 

Mo



[TOPIC: post.html]
#6

engel.teddy

[GLOBAL: userInfoPane.html]
engel.teddy
  • Pro
  • PipPip
  • 18 posts
  • Member

@Tyler,
Haha i had the same "issue", it's really hard to go back to another paradigm once you are used to it :)

@Mo,
I just updated the control example and also added a 'label' class displaying a simple text so that you have a concrete example :)
Note that it's a basic example you will have to build upon it ;) But that should give you an idea of how inheritance works with luoop, and how you can call a parent method (the label:render() automatically calls the control:render() method using _parentMethod()).

Enjoy !
Teddy



[TOPIC: post.html]
#7

develephant

[GLOBAL: userInfoPane.html]
develephant
  • Pro
  • PipPipPipPipPipPip
  • 431 posts
  • Jedi

@engel.teddy Very cool.

 

@Mo This article might help for a better understanding of how the powerful and often simpler OOP pattern can work when building Corona apps.

 

Cheers.



[TOPIC: post.html]
#8

engel.teddy

[GLOBAL: userInfoPane.html]
engel.teddy
  • Pro
  • PipPip
  • 18 posts
  • Member

A few updates:
Since the creation, I expanded the library and added singleton support as well as parent class method calling.

Added today new clearer examples for each possible case.

I also removed the deprecated corona control examples since they weren't really relevant anymore :)

Cheers,
Teddy



[TOPIC: post.html]
#9

j_wbrown

[GLOBAL: userInfoPane.html]
j_wbrown
  • Pro
  • PipPip
  • 19 posts
  • Member

Thanks a lot Mr Teddy! - looking forward to using your library. 



[TOPIC: post.html]
#10

tartarsaucemedia

[GLOBAL: userInfoPane.html]
tartarsaucemedia
  • Starter
  • PipPip
  • 18 posts
  • Member

How would you go about inserting these child objects into a display group? 



[TOPIC: post.html]
#11

engel.teddy

[GLOBAL: userInfoPane.html]
engel.teddy
  • Pro
  • PipPip
  • 18 posts
  • Member

How would you go about inserting these child objects into a display group? 

That's the main limitation of objects you create that way.
The corona display group system will definitely "not" call your object destroy function to make sure memory is freed, and you cannot "insert" them as such since they aren't corona display objects.

In this case, it's better to consider the luoop view object as a wrapper around a corona display group.
You could hijack the removeSelf function to make it call the destructor automatically but you would still have the issue when there is a hierarchy of corona display groups / objects - parent groups seem to call an internal display cleanup function different to removeSelf()

Conclusion is: Either use a whole luoop stack and wrap your groups inside them, or use luoop for the model / controller objects only if it is an issue

 



[TOPIC: post.html]
#12

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Starter
  • PipPipPipPipPipPip
  • 454 posts
  • Jedi

I've my own entirely different system which has destructors (non automatic obviously) and I think the latter is the solution. Objects are used for game scenes, some abstract display objects, resources etc. but the actual Corona flat implementation of objects displays as is. 

 

Objects that need their displays manipulated (e.g. game scenes so the game manager can do state changes fade in/out etc.) have a getDisplayObject() method.

 

Banjaxing around with Corona SDK is generally not a good idea - I don't even recommend basic decoration because Corona could add methods to the API. 

 

I think it introduces unnecessary complexity anyway. 

 

In my system if you have an object that (say) represents a score display the actual implementation is hidden in the object, built up by the constructor and torn down by the destructor. It allows some automation - the object can be added to the scene in such a way that when the scene is destroyed its child objects are too, but the actual Corona tear-down is still done the same old fashioned way.



[TOPIC: post.html]
#13

engel.teddy

[GLOBAL: userInfoPane.html]
engel.teddy
  • Pro
  • PipPip
  • 18 posts
  • Member

I've my own entirely different system which has destructors (non automatic obviously) and I think the latter is the solution. Objects are used for game scenes, some abstract display objects, resources etc. but the actual Corona flat implementation of objects displays as is. 

 

Objects that need their displays manipulated (e.g. game scenes so the game manager can do state changes fade in/out etc.) have a getDisplayObject() method.

 

Banjaxing around with Corona SDK is generally not a good idea - I don't even recommend basic decoration because Corona could add methods to the API. 

 

I think it introduces unnecessary complexity anyway. 

 

In my system if you have an object that (say) represents a score display the actual implementation is hidden in the object, built up by the constructor and torn down by the destructor. It allows some automation - the object can be added to the scene in such a way that when the scene is destroyed its child objects are too, but the actual Corona tear-down is still done the same old fashioned way.

I see your point yep. You could still have issues with specific cases where Corona destroys a display group / object completely bypassing your whole system though and you would have to make sure that the display object's state is tracked properly / tested for validity. That's the idea though, having a getDisplayObject() method or whatever method to wrap around the "native" corona display group.



[TOPIC: post.html]
#14

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Starter
  • PipPipPipPipPipPip
  • 454 posts
  • Jedi

Can Corona delete display objects on its own ? I think StoryBoard/Composer can garbage collect stuff but I don't use that.



[TOPIC: post.html]
#15

engel.teddy

[GLOBAL: userInfoPane.html]
engel.teddy
  • Pro
  • PipPip
  • 18 posts
  • Member

Can Corona delete display objects on its own ? I think StoryBoard/Composer can garbage collect stuff but I don't use that.

Nope it can't (I hope !) unless you have inserted it in another display object / group




[topic_controls]
[/topic_controls]



Also tagged with one or more of these keywords: lua, oop, objectoriented, library