Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
Extending Gideros - Gideros Forum

Extending Gideros

ar2rsawseenar2rsawseen Maintainer
edited October 2012 in Suggestions & requests
Hello all,

based on this thread http://www.giderosmobile.com/forum/discussion/1777/comparison-report-battle-of-the-lua-game-engines#Item_5
got an idea to create small init.lua file which would load different hacks and extensions to Gideros objects we all have used before. I'm not talking about plugins, but pure lua based extensions, and even not about lua classes as Button class or TextWrap, but extensions to current classes, which would enhance the usability of Gideros. Basically some abstraction to mainly used functionality

Here are some things I have in mind: So what do you find relevant, what should be needed and what you have up on your sleeves to share? :)
And if someone wants to get their hands dirty, here's a bunch of stuff you can research and provide code for, that would help us a lot.

Some tasks

Show child behind the parent or not inherit alpha
Explanation:
Shadows for TextField is implemented making real textfield act as shadow and it's child as real displayable text, making shadow the parent of real text. This gives two disadvantages, a little more complex to implement, but we handled that, and inability to set alpha transparency to shadow, because real text automatically inherits it.
So what could be the solution to this: making shadow child of a real text, but make it appear and real text, not on top of it or do not let real text inherit alpha from parent.
I thought of other possible implementations, as adding shadow as a brother of textfield (setting it before textfield) under same parent, but this raised many unwanted scenarios, where original textfield changes z-index, or parent, which would require a lot of additional code to bypass this scenarios. But I'll hear any ideas you might have ;)

Determine the font type
Explanation:
To implement shorthand for TextField similar to Bitmap, there is a need to understand if user wants to load Font or TTFont object. In ideal situtions only one parameter should be passed, as value "tahoma". Then maybe inside constructor we could check if file tahoma.txt available, then it's a Font, if tahoma.ttf is available, then it's a TTFont. What would be the most efficient way to do it and what filetypes are supported by which object

Chain everything
Explanation:
Right now most of the methods are chained, meaning they return they object (if not returning anything else) for shorter code writing. But still not all possible methods are chained. So the task is, either come up with set of keywords inside methods' name, that would cover up most of the methods (but will not cover methods that actually return something) and chain others manually.
Or come up with different approach how this can be done, for example, checking bytecode in function body for return command

RGB to hex conversion and vice versa
Explanation:
Now this might be to obvious thing to do, but I'm too tired right now to try and figure it out, so I'll post it here.
If we want to, for example, support HSL color model, there is a need to be able to convert 255, 255, 255 to 0xffffff and back, since Gideros accepts color in 0xffffff format.

Taking and implementing any feature of the list
Explanation:
There are features list in the first post, that should be included in init.lua. Implement them, share the code, or extend existing features ;)

Test, test, test
Explanation:
While writing I do some initial test if this works at all or not. But more thorough testing is needed. For example, including this init.lua should not only provide additional functionality, which works properly, but also not to mess up with existing code, aka, provide full backwards compatibility

Provide feedback
Explanation:
Provide feedback on existing implementations, if many of you say something is needed, it will be included, if many says it's not needed it can be removed. But that's not all. Also consider function names, optimizations and other aspects, for example, creating abstraction layer for physics, in many cases I need to think for user and make decisions for them, just to make code shorter and easier. I'm not a dictator and don't want to make decision for all, let's make it more democratic and let's hear your thoughts

Suggest new features
Explanation:
This lib will be as good as there are features in it. If there is something you use, or something you think would ease the development or simply some functionality that would have helped you, please post. Provide idea and we will be grateful, provide also a code and you will be my hero (@atilim already is :) )

TLDR; aka GimmeDaCode: Github Repo
+1 -1 (+7 / -1 ) Share on Facebook
«13456

Comments

  • gorkemgorkem Maintainer
    This is something @Atilim is also really interested in to get implemented by community - a pure Lua based abstraction layer (coming with distribution?) that could help devs easily get their hands dirty.

    It can come with Gideros Community Libs [1] I think (when Atilim had packaged the latest version, I forgot to remind him that it'll be included in the package).

    Your initial list can get longer easily, so I propose to open a wiki page that includes a table with responsibility matrix. This way, anyone can step up and say "I am taking eg HSL color format support and here's the code". Especially the physics wrapper that helps programmers develop physics based games using fewer lines of code would really be great.

    Many items in your list can be coded and documented in a couple of hours I think, so why dont we get the ball running? :)

    [1] https://github.com/gideros/gideros-community-libs
  • Sure, @gorkem, can you set up a Wiki page on Gideros that I could edit/update?
  • atilimatilim Maintainer
    @ar2rsawseen that's great. And you can remove the "Mouse Touch event cross compatibility" item :)

    Likes: fxone

    mouse-touch.png
    446 x 400 - 19K
    +1 -1 (+1 / -0 ) Share on Facebook
  • Nooo, that was my "main event" :D
    I think many features would be removed when Gideros implements them internally and that is completely OK :)

    Likes: atilim

    +1 -1 (+1 / -0 ) Share on Facebook
  • ar2rsawseenar2rsawseen Maintainer
    edited September 2012
    @atilim one question, I thought it would be cool to position elements as
    sprite:setPosition("left", "bottom")

    So I thought that I should rewrite Sprite.set method as Sprite.setX/Sprite.setY and Sprite.setPosition use it internally, but it seems that they still require a number as argument.

    So do I have to override all of these methods, or is there another way?
  • atilimatilim Maintainer
    I think overriding these functions is the only way. As you know, you just need to store the original setX/setY/setPosition somewhere else. I usually prefer to store them as a field of Sprite:
    Sprite._setX = Sprite.setX
     
    function Sprite:setX(x)
        if type(x) == "string" then
            -- do as you wish
        else
            Sprite._setX(self, x)
        end
    end
  • Yes, that's the way I was doing it ;)
    Thank you
  • gorkemgorkem Maintainer
    @ar2rsawseen I'll name them "Gideros helper functions" - and will include the following:

    - Name of function
    - What it does
    - Link to source code
    - Author

    Is that ok? Any other good name you can think of?
  • ar2rsawseenar2rsawseen Maintainer
    edited September 2012
    I was actually thinking of implementing them all in one file.

    Here's what I've got so far:
    https://github.com/ar2rsawseen/GiderosInit

    Of course this all needs more thorough testing.

    But combining it all in one project would make it possible to create separate scenes as test cases and to show how this works.

    Will add sprite anchorpoint, curves for shapes and some other stuff soon. It's getting late here, where I am :)

    But about wiki, then it stays the same, we should list all additional functionalities provided, so yes it is ok. ;)

    Likes: atilim

    +1 -1 (+1 / -0 ) Share on Facebook
  • paul_k_clarkpaul_k_clark Member
    edited September 2012
    @ar2rsawseen that looks awesome. Just one point should the flip horizontal and flip vertical be the negative value of the current x or y scale? This would allow flipping of objects that have a scale value other than 1 and allow them to be flipped over and over again.
  • @ar2rsawseen, I'm not sure what approach you're using for mouse/touch event compatibility but what I've been doing is this:
    function BhButton:onMouseDown(event)
    	-- Fake a touch event with id 0, this allows buttons to work in the simulator
    	-- that doesn't normally understand touch events.	
    	event.touch={ x=event.x, y=event.y, id=0}
    	self:onTouchesBegin(event)	
    end
     
    function BhButton:onMouseMove(event)
    	-- Fake a touch event with id 0, this allows buttons to work in the simulator
    	-- that doesn't normally understand touch events.	
    	event.touch={ x=event.x, y=event.y, id=0}
    	self:onTouchesMove(event)	
    end
     
    etc
    That is, I install handlers to mouse events that simply fake up a touch (with finger id=0) and pass control to the appropriate touch handlers. Seems to work well and using a touch.id of zero means that one can distinguish these events if one needs to do so.

    best regards
  • ar2rsawseenar2rsawseen Maintainer
    edited September 2012
    @paul_k_clark great idea, thanks ;)

    @bowerhandy but then you need to modify every mouse event handler. I was doing it the same way before @atilim suggested implementation I used. But it does not really matter, because it will be removed, cause it will be implemented in next version of Gideros

    Got couple of other ideas:
    • Setters return self for chaining
    • Shorthand for creating Bitmaps (create texture inside constructor)
    • Recursive print for tables print_r
    Anything else? :)
  • Updated repo with chaining, print_r and Bitmap shorthand

    I really hope someone will come up with better chaining implementation, right now I'm simply rewriting methods by hand, can't come up with anything better for now, if anyone has any suggestions, I'm all ears ;)
  • OZAppsOZApps Guru
    edited September 2012
    @andy, am I your first follower on Twitter? Mate tweet something...
    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
  • bowerandybowerandy Guru
    edited September 2012
    OFFTOPIC: @OZApps, thanks. However, I put the wrong Twitter account in my sig. That one, "thebowerhaus" is intended for general marketing stuff if I every get round to releasing some games. The developer tweets will go to "insidebowerhaus".

    Still, I haven't sent anything there yet either. I'll try an think up something soon.

    best regards
  • bowerandybowerandy Guru
    edited September 2012
    @ar2rswaseen, great initiative, thanks for putting it together.

    Are you really sure the chaining of functions is worth it? Seems to add a lot of code for not much gain. Still, I guess you've done all the hard work now but it is an extra level of function call for virtually every method in the system.

    BTW, you're welcome to take anything you want out of BhHelpers". In particular, isVisibleDeeply is quite useful, I think.
    function Sprite:isVisibleDeeply()
    	-- Answer true only if the sprite and all it's a parents are visible. Normally, isVisible() will
    	-- return true even if a sprite is actually not visible on screen by wont of one of it's parents
    	-- being made invisible.
    	--
    	local try=self
    	while (try) do
    		if  not(try:isVisible() and try:getAlpha()>0) then
    			return false
    		end
    		try = try:getParent()
    	end
    	return true
    end
    There are a few generic table and math helper methods at the bottom but these aren't Gideros specific so it may not be appropriate to take them, I don't know.

    best regards
  • @bowerandy Thanks I will definitely check it
    About chaining methods, well it just so much easier to write with them, but if I won't find better implementation for them, then it is possible that chaining won't be included. Just need some time to think now. How would it be possible to define class method dynamically from string, if only something like this
    function Class:["mymethod"]()
    end
    would work. But it doesn't. :-?
  • atilimatilim Maintainer
    edited September 2012
    first! :)
    Class["mymethod"] = function(self) end
  • atilimatilim Maintainer
    edited September 2012
    Also your idea about changing all set functions automatically is simply genius! (You need to use string.sub to test if the function name begins with "set" and use ... to pass parameters automatically)
  • atilimatilim Maintainer
    edited September 2012
    uhm... sorry @ar2rsawseen I couldn't resist myself :)
    function changeAllSetFunctions(class)
    	for k,v in pairs(class) do
    		if type(v) == "function" and k:sub(1, 3) == "set" then
    			class["_"..k] = v
    			class[k] = function(self, ...)
    				class["_"..k](self, ...)
    				return self
    			end
    		end
    	end
    end
     
    changeAllSetFunctions(Sprite)
     
    local sprite = Bitmap.new(Texture.new("box.png"))
    sprite:setX(10):setY(20):setColorTransform(1, 0, 0, 1)
    stage:addChild(sprite)
    +1 -1 (+2 / -0 ) Share on Facebook
  • OverRideMethod function looks like just another nanotechnology from Skolkovo - I realized it only after the third reading =)

    Is not it easier to use the following syntax?:
    Colors = {
    ["Black"] = 0x000000,
    ["Blue"] = 0x0000ff,
    ....}
    application: setBackgroundColor (Colors.Black)

    When you add another function that takes color parameter, you will not need to override this function, as it will have to do in your case.
  • ar2rsawseenar2rsawseen Maintainer
    edited September 2012
    @atilim That's it! I'm buying a ticket to Turkey, just to give you a hug for this. :D
    I was totally missing part of passing instance as an argument

    @asakharov agree you'll need to override another method, but you do it only once, but otherwise you will have to write a longer color name every time.
    But in this configuration, I see no reason why we could not do it both ways :)

  • Actually, with @atilim's method it is possible to automatically override all methods, that has, for example, word color in them. So it can make all this process so much easier :)
  • atilimatilim Maintainer
    edited September 2012
    @ar2rsawseen the idea was yours. let's meet in the middle :)

    edit: forget about middle. we want to visit Latvia. :)
  • @atilim, sure if you can handle over 8000 feature squeakers and take another holiday :D

    To cover even more methods I've added also keywords "add", "remove" and "clear" to auto chaining method. Need to check other keywords to cover more methods, but not accidentally override methods that actually returns something :)

    Which get's me to other idea. Maybe it is possible to check function's body for return keyword, to check if method returns anything :))

  • atilimatilim Maintainer
    edited September 2012
    @ar2rsawseen I can bring my laptop :)

    You can use string.dump http://pgl.yoyo.org/luai/i/string.dump to get binary representation of a function and the value of opcode RETURN is.. uhmm.. just kidding :-\"

  • I'll always remember RET as C9 sigh!

    Cheers

    evs

    Likes: atilim, OZApps

    +1 -1 (+2 / -0 ) Share on Facebook
  • bowerandybowerandy Guru
    edited September 2012
    @atilim, @ar2rsawseen, when I saw you were doing this chaining stuff, my initial thought *was* to look for a return bytecode in the method (would that actually be a bad idea)?

    @evs, yes. And I think my keyboard input routine was at CD 00 OA :-)
  • ar2rsawseenar2rsawseen Maintainer
    edited September 2012
    @bowerandy Well I don't know from a performance point of view, but we might as well just try it. What byte code should I look for? :)

    BTW @atilim
    is it legit to modify table you are looping in?
    for k,v in pairs(class) do
        class["_"..k] = v
    end
    cause not all methods seem to get chained and I think that this might be the case, but I'm not sure
Sign In or Register to comment.