Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Lua SFGUI Loader  (Read 7070 times)

0 Members and 1 Guest are viewing this topic.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Lua SFGUI Loader
« on: April 21, 2013, 08:04:58 pm »
I wonder why Lua highlighting works but isn't selectable from the combo box when writing..
https://github.com/FRex/Lua-SFGUI-Loader
So, I made a LuaTable class and an InterfaceLoader class that change this:
-- this file has been proudly written in gvim ;)
win1 = {type="Window",
        x=200,
        y=100,
        colspacing=8.0,
        rowspacing=8.0,
        shadow=true,
        background=true,
        titlebar=true,
        caption="The Fu*k Java SFGUI Example",
        resize=true,
        widgets={
                {
                        type="Label",
                        text="Is c++ better?",
                        spanx=3
                },
                {
                        type="Button",
                        text="Naturally",
                        y=1
                },
                {
                        type="Button",
                        text="Of Course",
                        x=1,y=1
                },
                {
                        type="Button",
                        text="Yes!",
                        x=2,y=1,
                        OnLeftClick="correct"
                }
        }
}
 
Into this:


All you can do is get is a window with a table in it and you can place widgets in it, that's it.. no limit on number of widgets or windows, though.
Only supported so far to place in that table:
-entry
-spinner
-spinbutton
-image
-label
-progressbar
-scale
-scrollbar
-button
-togglebutton
-checkbutton
-combobox

Notice there is no radio button(edit: now there is), I'm still thinking how to handle the fact they are grouped.

It requires the change of delegates to std function that I posted few weeks back in SFGUI thread.
It may be buggy, Tank will probably release his yaml gui loader tomorrow anyway and it'll be 10x better(because f. my life  ;)). Also it depends on std::bind from c++11,Lua, SFGUI,SFML(duh..) and there are two line that use PhysicsFS but it can be easily replaced to use whatever you want. There are two std::function callbacks: creation and message, OnXXX props in widgets send the widget and the string to message callback, creation callbacks gets sent entire luatable of the widget and the widget pointer.
Also LuaTable class is pretty neat I'd say. If anyone is still interested after seeing all the disadvantages, I can share the code but neither loader nor lua table are fully ready imo.

Here's exe demo, you can play around with it, it got both callbacks set to std::cout the type of widget in creation or the message string in message callbacks.
https://docs.google.com/file/d/0B8dEkQw1a4Wvb1QzR0wyaEt2aWs/edit?usp=sharing
type can be "sfg_label" "sfg_entry" etc. for labels, entries and buttons there's text property that is string to show, for button, toggle button and image there is image which is path to image to load etc. figure it out or ask what exactly you're looking for. Things that don't matter for that widget get ignored, and almost always some sane defaults are set. Syntax is : window is global variable of type sfg_window, and it contains table of tables called wigets, in which each table has type and some other vars. I'd say it's pretty intuitive and works ok for quick menus/guis that don't require critical speed.
« Last Edit: April 22, 2013, 12:52:50 am by FRex »
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Lua SFGUI Loader
« Reply #1 on: April 21, 2013, 09:50:14 pm »
Quote
I wonder why Lua highlighting works but isn't selectable from the combo box when writing..
The mod can handle many languages, but I selected only the most relevant in the combobox.
Laurent Gomila - SFML developer

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Lua SFGUI Loader
« Reply #2 on: April 21, 2013, 09:58:40 pm »
Lua is now sad. :'(
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Lua SFGUI Loader
« Reply #3 on: April 21, 2013, 10:02:56 pm »
Is it happier now? :P
Laurent Gomila - SFML developer

foobarbaz

  • Jr. Member
  • **
  • Posts: 53
    • View Profile
Re: Lua SFGUI Loader
« Reply #4 on: April 21, 2013, 10:36:41 pm »
Looks cool! I'm definitely going to give this a try. Looks soooooooo much less tedious than hardcoding my GUI together.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Lua SFGUI Loader
« Reply #5 on: April 21, 2013, 11:20:03 pm »
Quote
Is it happier now? :P
Very. I just selected Lua for code highlight below. So boss of it to be there. 8)

Quote
Looks cool! I'm definitely going to give this a try.
Remember you need visual 2010 or another std::bind capable compiler and you'll need to modify your SFGUI a little(like 4 lines in one file), but it doesn't break any old code using signals.

I added radio buttons too now. Radio button specific syntax, just like check button + get's group string:
{
type="RadioButton",
text="whatever",
down=true,
group="one"
}
 
I'll try put it all on github sometime soon. It might have circular references(but I made bindings to messages use weak ptr) and other bugs I might have missed..

I guess I made it so OP you can ignore message callback and just throw away the edy::gui::InterfaceLoader instance away since you get to keep shared pointers to windows and get shown each widget just after it's creation and can attach whatever callbacks then. ;D You don't get adjustments though, message for them via callback works(there is only OnChange callback for them anyway, nothing big) and you can have them in spin button, scale and scrollbar(I'll maybe post examples later and you can look in the code anyway after it's up).
« Last Edit: April 22, 2013, 12:53:12 am by FRex »
Back to C++ gamedev with SFML in May 2023

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Lua SFGUI Loader
« Reply #6 on: April 21, 2013, 11:25:53 pm »
Good idea! Lua is quite nice for such stuff, I have already used it for configuration tables, too.

Don't you want to call the types according to SFGUI's classes, i.e. "RadioButton" instead of "sfg_radiobutton"? I think the prefixes are not very useful ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Lua SFGUI Loader
« Reply #7 on: April 21, 2013, 11:33:51 pm »
Quote
Don't you want to call the types according to SFGUI's classes, i.e. "RadioButton" instead of "sfg_radiobutton"? I think the prefixes are not very useful ;)
Well, I guess I might remove prefix and change from hacker_cpp to HelloCSharp.
Tank will be happy... :P

Major post edit:
You can grab it here:
https://github.com/FRex/Lua-SFGUI-Loader
by default using physics is OFF(you can't turn it on by commenting out define in loader's header) so you don't need any file that has Phys in it's name.
There is small but well commented main.cpp example and test.lua example. More examples will (maybe) come soon-ish. Any users/questions/comments and Nexus' constructive criticism are welcome.
Ok, now I'm kind of done for today because I keep making silly commits to fix silly typos and stuff.
If you really don't want to change SFGUI it's easy to remove that requirement, few widgets attach callback themselves, and there is a for loop for that in addCallbacks, and you could even remove std::functions from the class to make it c++98 compliant. I won't be doing any of that, making #define switch for physics is enough, I'm just sharing something others might find useful, I myself use visual 10 that has bind and function and did that small modification to my SFGUI. :P
« Last Edit: April 22, 2013, 12:43:54 am by FRex »
Back to C++ gamedev with SFML in May 2023

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: Lua SFGUI Loader
« Reply #8 on: April 22, 2013, 12:29:35 pm »
Good job on the loader, now it's "only" missing some more flexibility and good usage of layouters. ;)

Quote
Well, I guess I might remove prefix and change from hacker_cpp to HelloCSharp.
Tank will be happy...
Well, hacker_cpp makes me more happy, but it won't be consistent with SFGUI's coding style. ;)

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Lua SFGUI Loader
« Reply #9 on: April 22, 2013, 03:22:10 pm »
Quote
Good job on the loader, now it's "only" missing some more flexibility and good usage of layouters. ;)
By which you mean? ;D

Also, I'm not sure if it's all good and bug free, like getAdjustment might have kept strong shared ptr in it's std::bind call so it's kind of memory leak I think.., still waiting for Nexus' criticism. :P
« Last Edit: April 22, 2013, 04:00:23 pm by FRex »
Back to C++ gamedev with SFML in May 2023

ChronicRat

  • Sr. Member
  • ****
  • Posts: 327
  • C++ programmer
    • View Profile
    • My blog
Re: Lua SFGUI Loader
« Reply #10 on: August 29, 2013, 08:48:39 pm »
You know, i need Lua-based GUI too. Because of SharedPtr i can't just to bind Lua with SFGUI classes, but SFGUI is too good that to not use it. So my rough variant - wrappers (just for example, no full code):

(click to show/hide)

No strict order while initialisation needed. This is very first variant, no any optimisations. OOLua was used to Lua-bindings.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Lua SFGUI Loader
« Reply #11 on: August 29, 2013, 10:03:53 pm »
This is just using Lua for loading the table from/to file into std::map with semi nice syntax for accessing, iterating and modifying. I wrote it before I decided to use XML for data storage too.

A hand made API would make more sense, but it'd be a lot of typing for everything. I don't really like automatic binders and such, many people say that they make worse job than humans even, because of how different c++ and Lua are it's impossible to do it well programmaticaly, binding c++ to Lua is art. :P It's hard as hell and makes your brain turn upside down after a while.
I gave it a bit of thought(I'm not going to do it, it's not worth it at this point, SFG lacks too much IMO) in the past and it's a bit complicated and long write to explain it. :P

1. each callback has unique id from 0 to numcallbacks-1, every single one, even ones like ontext(from entry) and ontoggle(from togglebutton) can't overlap
2. have a way to turn string name of signal into number in that range(lua has support function for that actually so its just 1 call and one const char array), make const char arrays for all enums when youre at it :P
3. make metatables for each widget type, also they must have functions that go: asBase, where base is one of the bases, so toggle button has asButton and asWidget, window has asContainer and asWidget, etc. there are for downcasting
4. make global functions like ones in point 3, these will be for upcasting, one per each type of widget
5. make callback class that has ALL possible callbacks as void() functions and array of ints that is numcallbacks in size, init them all to LUA_NOREF

Creating new widget:
create full user data and new in it a struct that consists of right type of widget ptr and one int(can be template struct),
Create() the widget(optionally getting params from stack), create new user data sizeof callback class from 5., and new callback class in it, store that in registry, put the ref into the int in the first struct, return the first user data, done

Casing up(ie. button->widget, done in metamethods so we know type):
create full user data, new in right struct, fetch ptr and int from struct passed in as self, now set the ptr, fetch the reference and make new one to that user data you just fetched, and store it in the struct you just new'd, return it, done

Casting down(ie. widget -> container, done in global functions so we always use widget):
if sfg::DynamicPtrCast fails just return, if not, create full user data, new in right struct, etc. , set ptr and int in struct like before in up cast, done

Callbacks:
use that function from 2. to get right index of callback that you assigned in 1., then using self struct's int, get full user data, now in that user data array of ints, look up the index you just got using function from 2., if its NOREF or REFNIL create new metatable in registry and then store ref in that index, if not just fetch that table, in both cases, add the function as reference in that table, return that reference as number of full user data(to prevent changes) so it can later be used for disconnecting

Disconnecting:
similar, self struct to get user data callback class in registry, then just get the table via reference and free the passed in reference from it

This ends up with nice way to do literally everything:
button = sfg.Button.Create"blablautf-8str";
box = sfg.Box.Create"Vertical";
box:Pack(button:asWidget(),true,false);--up cast
hehe = button:ConnectCallback("OnLeftClick",function() print"hehe" end);--connecting signal
button:DisconnectCallback("OnLeftClick",hehe);--disconnecting signal
box2 = asBox(button:getParent():asWidget());--down cast
 
(Sorry for mixing two naming conventions in this small snippet :P)
When all instances of one widget, in all pointers die, then widget will die too, and it'll free callback class which will free all the tables with callbacks which in turn frees these functions

I of course left out small details like ctors, dtors, __gc meta methods themselves etc. but they are very obvious, just tedious to write.

For strings in unicode you can use UTF-8, Lua will pass them around no problem and then you can conver them to sf::String on c++ side.

Also, you should probably recompile your Lua as c++, or you're in for nasty surprises when things start leaking because Lua C default errors/'exceptions' don't call destructors.

This is kind of complicated but it's really good IMO - it allows connecting and disconnecting many signals and supports polymorphism and up and down casts. This also has nice effect that you can connect any callback to even widget and it'll work 100% well if it's there and just get silently ignore if it's not there.
Pretty much any other binding I thought of so far will have pitfalls with signals or up and down casts or something. Of course this is assuming faithful binding, not just extension of functionality.

That was long...
You need good understanding of Lua, tables, references, pseudo indices and user data to do all that.

I could actually help with Lua part if you were to try and bind entire of SFG to Lua, but it'd be really asymetric partnership(me=fun Lua API manipulations, you = writting most of tedious C wrappers for SFG methods) and you might not be happy with that. ;D
If you just want some Lua GUI you might look at lua users wiki or at cegui.
It probably wouldn't be too hard, honestly with two or three alright c++ and/or Lua programmers cooperating irl it could be done overnight, that's one of strengths of Lua flexibility and small but powerful C API, any C or c++ library can easily become Lua one.
You can PM me if interested in that way of binding or in making that binding together.
« Last Edit: August 29, 2013, 10:26:02 pm by FRex »
Back to C++ gamedev with SFML in May 2023

ChronicRat

  • Sr. Member
  • ****
  • Posts: 327
  • C++ programmer
    • View Profile
    • My blog
Re: Lua SFGUI Loader
« Reply #12 on: August 29, 2013, 10:40:41 pm »
Quote
That was long...
Yes, with my knowledge of english - that was long nightmare. =)

Quote
You need good understanding of Lua, tables, references, pseudo indices and user data to do all that.
Nope, i'm very beginner in Lua.

Quote
I could actually help with Lua part if you were to try and bind entire of SFG to Lua, but it'd be really asymetric partnership(me=fun Lua API manipulations, you = writting most of tedious C wrappers for SFG methods) and you might not be happy with that. ;D
If you just want some Lua GUI you might look at lua users wiki or at cegui.
It probably wouldn't be too hard, honestly with two or three alright c++ and/or Lua programmers cooperating irl it could be done overnight, that's one of strengths of Lua flexibility and small but powerful C API, any C or c++ library can easily become Lua one.
You can PM me if interested in that way of binding or in making that binding together.
As i said - i am beginner in Lua, and i want to know it better, much better, so i will continue my experiments myself, just for experience. Аnd the most important thing in this - i have no time to this job (i mean bindings for whole SFGUI). But thank you for the offer of help.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Lua SFGUI Loader
« Reply #13 on: August 29, 2013, 10:47:26 pm »
If you don't know much of Lua it's not understandable in any language because that binding I came up with is really Lua heavy. :P
Programming in Lua (even if the free one on site is only for 5.0) explains functions, references, tables, registry pseudo index and user data very very well(it's written by chief engineer of Lua and it influenced the language in recent years and vice versa) but it's in english. :P

As I said, depending on what you want you can find cegui or something on lua wiki better or just stick to little Lua with SFGUI.
Back to C++ gamedev with SFML in May 2023