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

Author Topic: LuaSFG/MoonSFG (WIP)  (Read 2480 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
LuaSFG/MoonSFG (WIP)
« on: November 30, 2013, 01:53:54 am »
Yes, SFGUI bound to Lua. ;)
It's not a full binding, it just binds widgets and allows for signals in Lua.
It doesn't allow defining styles but it lets you set class and id of widget so you can use a css file with it too.
It's more work in progress than SFGUI's docs. (So quite rough for now) :P

Here is the repo with everything tucked into /src/:
https://github.com/FRex/LuaSFG
This is where code is in /src/, grouped into files, not fully ready but ok-ish state already, this will be just the base c++ code, in separate files. Ideally there might be cmake/premake file, /include/ and /src/ directories and import/export macros in code but oh.. well.. use MoonSFG if you're desperate already..

Here is MoonSFG repo, with monolithic .hpp and .cpp:
https://github.com/FRex/MoonSFG
I just cat'd files together and removed some includes, it compiled but it's stupid and dirty as hell.. I'll have to make a script for generating this two in a saner way from LuaSFG.
This is also the repo that will (ideally) contain examples in both languages, the script used to build monolithic files, lua script to remove explicit casting(see thread and example lua code to see what I mean) and so on.


Monolithic hpp and cpp is what you'd download right now if you want to test it, you link your own Lua, you link your own SFML and you link your own SFGUI. Then add these two to your project and call ee::openLuaSFG(L); No linking, no Lua C/c++ issues, you provide all includes and link and it'll work.

There is example right now of guess my number on official SFG forum: http://sfgui.sfml-dev.de/forum/post1513.html#p1513

There might be bugs, crashes, leaks, errors, typos, things are missing, but it's mostly complete etc.

Strings are passed to/from Lua as ASCII, they'll be UTF-8 later.

The ee namespace is what I use for myself and I didn't plan to share until it got a bit long and just went with it so it might change to something like luasfg or LuaSFGUI or something.
Back to C++ gamedev with SFML in May 2023

ChronicRat

  • Sr. Member
  • ****
  • Posts: 327
  • C++ programmer
    • View Profile
    • My blog
Re: LuaSFG/MoonSFG (WIP)
« Reply #1 on: February 02, 2014, 02:40:49 pm »
Big work. As you know, i'm still using OOLua for Lua bindings. But i refused wrappers, and using now OOLua with support of std::shared_ptr, it became much easier. For example:
This is controls that are required and used now. If i need new control, i'm just adding it to the end.

Code: [Select]
namespace OOLUA
{
   typedef sfg::Signal            sfgSignal;
   typedef sfg::Misc            sfgMisc;
   typedef sfg::Object            sfgObject;
   typedef sfg::Widget            sfgWidget;
   typedef sfg::Bin            sfgBin;
   typedef sfg::Container         sfgContainer;
   typedef sfg::Fixed            sfgFixed;
   typedef sfg::Alignment         sfgAlignment;
   typedef sfg::Adjustment         sfgAdjustment;
   typedef sfg::Separator         sfgSeparator;
   typedef sfg::Box            sfgBox;
   typedef sfg::Frame            sfgFrame;
   typedef sfg::Window            sfgWindow;
   typedef sfg::ScrolledWindow      sfgScrolledWindow;
   typedef sfg::Button            sfgButton;
   typedef sfg::Entry            sfgEntry;
   typedef sfg::Label            sfgLabel;

} // namespace OOLUA


DECLARE_LUA_SINGLETON(GuiManager)

OOLUA_PROXY(GuiManager, Singleton<GuiManager>)
   OOLUA_TAGS(No_public_constructors)
   OOLUA_MFUNC(Add)
   OOLUA_MFUNC(Remove)
   OOLUA_MFUNC(RemoveAll)
   OOLUA_MFUNC_CONST(GetScreenSize)
   OOLUA_SFUNC(ApplyStyle)
   OOLUA_SFUNC(ApplyStyleFromFile)
OOLUA_PROXY_END



OOLUA_PROXY(VoidCallback)
   OOLUA_TAGS(Abstract)
OOLUA_PROXY_END



OOLUA_PROXY(sfgSignal)
   OOLUA_TAGS(Abstract)
   OOLUA_MFUNC(Connect)
   OOLUA_MFUNC(Disconnect)
   OOLUA_SFUNC(GetGUID)
OOLUA_PROXY_END



OOLUA_PROXY(sfgMisc)
   OOLUA_TAGS(Abstract)

   OOLUA_MFUNC_CONST(GetAlignment)
   OOLUA_MFUNC(SetAlignment)
OOLUA_PROXY_END



OOLUA_PROXY(sfgObject)
   OOLUA_TAGS(Shared, Abstract, No_public_constructors)
   OOLUA_MFUNC(GetSignal)
OOLUA_PROXY_END



OOLUA_PROXY( sfgWidget, sfgObject)
   OOLUA_TAGS(Shared, Abstract, Register_class_enums)

   OOLUA_ENUMS
   (
      OOLUA_ENUM(NORMAL)
      OOLUA_ENUM(ACTIVE)
      OOLUA_ENUM(PRELIGHT)
      OOLUA_ENUM(SELECTED)
      OOLUA_ENUM(INSENSITIVE)
   )

   OOLUA_MFUNC(Show)
   OOLUA_MFUNC(SetAllocation)
   OOLUA_MFUNC(SetPosition)
   OOLUA_MFUNC(SetState)
   OOLUA_MFUNC(SetId)
   OOLUA_MEM_FUNC_0(void, SetActiveWidget)
   //OOLUA_MFUNC(SetActiveWidget)
   OOLUA_MEM_FUNC_0(void, GrabFocus)
   //OOLUA_MFUNC(GrabFocus)
   OOLUA_MFUNC_CONST(Invalidate)
   OOLUA_MFUNC_CONST(GetAllocation)
   OOLUA_MFUNC_CONST(GetState)
   OOLUA_MFUNC_CONST(GetId)
   OOLUA_MFUNC_CONST(IsGloballyVisible)
   OOLUA_MFUNC_CONST(IsLocallyVisible)
   OOLUA_MEM_FUNC_CONST_0(bool, HasFocus)
   //OOLUA_MFUNC_CONST(HasFocus)
   OOLUA_MEM_FUNC_CONST_0(bool, IsActiveWidget)
   //OOLUA_MFUNC_CONST(IsActiveWidget)

OOLUA_PROXY_END



OOLUA_PROXY( sfgAdjustment, sfgObject)
   OOLUA_TAGS(Shared, Abstract)
OOLUA_PROXY_END



OOLUA_PROXY( sfgContainer, sfgWidget )
   OOLUA_TAGS(Shared, Abstract)

   OOLUA_MFUNC(Add)
   OOLUA_MFUNC(Remove)
   OOLUA_MFUNC(RemoveAll)
   OOLUA_MFUNC(Refresh)
   OOLUA_MFUNC_CONST(IsChild)

OOLUA_PROXY_END



OOLUA_PROXY( sfgBin, sfgContainer )
   OOLUA_TAGS(Shared, No_public_constructors)
   OOLUA_MFUNC_CONST( GetChild )
OOLUA_PROXY_END



OOLUA_PROXY( sfgFixed, sfgContainer )
   OOLUA_TAGS(Shared, No_public_constructors)
   OOLUA_MFUNC( Put )
   OOLUA_MFUNC( Move )
   OOLUA_SFUNC(Create)
OOLUA_PROXY_END



OOLUA_PROXY( sfgAlignment, sfgBin, sfgMisc)
   OOLUA_TAGS(Shared, No_public_constructors)
   OOLUA_MFUNC( SetScale )
   OOLUA_MFUNC_CONST( GetScale )
   OOLUA_SFUNC(Create)
OOLUA_PROXY_END



OOLUA_PROXY( sfgFrame, sfgBin, sfgMisc)
   OOLUA_TAGS(Shared, No_public_constructors)
   OOLUA_MFUNC( SetLabel )
   OOLUA_MFUNC_CONST( GetLabel )
   OOLUA_SFUNC(Create)
OOLUA_PROXY_END



OOLUA_PROXY( sfgBox, sfgContainer )
   OOLUA_TAGS(Shared, No_public_constructors, Register_class_enums)

   OOLUA_ENUMS
   (
      OOLUA_ENUM(HORIZONTAL)
      OOLUA_ENUM(VERTICAL)
   )

   OOLUA_MFUNC(Pack)
   OOLUA_SFUNC(Create)
OOLUA_PROXY_END



OOLUA_PROXY( sfgSeparator, sfgWidget )
   OOLUA_TAGS(Shared, No_public_constructors, Register_class_enums)

   OOLUA_ENUMS
   (
      OOLUA_ENUM(HORIZONTAL)
      OOLUA_ENUM(VERTICAL)
   )

   OOLUA_MFUNC_CONST(GetOrientation)
   OOLUA_SFUNC(Create)
OOLUA_PROXY_END



OOLUA_PROXY( sfgWindow, sfgBin )

   OOLUA_TAGS(Shared, No_public_constructors, Register_class_enums)

   OOLUA_ENUMS
   (
      OOLUA_ENUM(NO_STYLE)
      OOLUA_ENUM(TITLEBAR)
      OOLUA_ENUM(BACKGROUND)
      OOLUA_ENUM(RESIZE)
      OOLUA_ENUM(SHADOW)
      OOLUA_ENUM(TOPLEVEL)
   )

   OOLUA_MFUNC(SetTitle)
   OOLUA_SFUNC(Create)
OOLUA_PROXY_END



OOLUA_PROXY( sfgScrolledWindow, sfgContainer )
   OOLUA_TAGS(Shared, No_public_constructors)
OOLUA_PROXY_END

namespace OOLUA
{
   int sfgScrolledWindow_Static_Create(lua_State* vm);
   int sfgScrolledWindow_Static_Create_With_Adjustments(lua_State* vm);
}


OOLUA_PROXY( sfgButton, sfgBin )
   OOLUA_TAGS(Shared, No_public_constructors)
   OOLUA_SFUNC(Create)
OOLUA_PROXY_END



OOLUA_PROXY( sfgEntry, sfgWidget )
   OOLUA_TAGS(Shared, No_public_constructors)
   OOLUA_SFUNC(Create)
OOLUA_PROXY_END



OOLUA_PROXY( sfgLabel, sfgWidget, sfgMisc )
   OOLUA_TAGS(Shared, No_public_constructors)
   OOLUA_SFUNC(Create)
OOLUA_PROXY_END


But all this not very useful without a little extension. Binding Lua functions and sounds to sfgui signals:


Code: [Select]
struct GuiEnum
{
enum GuiSignal
{
signalOnStateChange, //!< Fired when state changed.
signalOnGainFocus, //!< Fired when focus gained.
signalOnLostFocus, //!< Fired when focus lost.


signalOnExpose, //!< Fired when widget is being rendered.


signalOnSizeAllocate, //!< Fired when widget's allocation changed.
signalOnSizeRequest, //!< Fired when size was requested.


signalOnMouseEnter, //!< Fired when mouse entered widget.
signalOnMouseLeave, //!< Fired when mouse left widget.
signalOnMouseMove, //!< Fired when mouse moved over widget.
signalOnMouseLeftPress, //!< Fired when left button pressed.
signalOnMouseRightPress, //!< Fired when right button pressed.
signalOnMouseLeftRelease, //!< Fired when left button released.
signalOnMouseRightRelease, //!< Fired when right button released.


signalOnLeftClick, //!< Fired when left button clicked.
signalOnRightClick, //!< Fired when right button clicked.


signalOnKeyPress, //!< Fired when a key is pressed while State == Active.
signalOnKeyRelease, //!< Fired when a key is released while State == Active.
signalOnText, //!< Fired when text is entered while State == Active.
signalNum
};
}; // struct GuiEnum








///////////////////////////////////////////////////////////////////////////////




class IExtended
{
protected:
static sfg::Signal::SignalID* sSignals[GuiEnum::signalNum];
};






template<class T>
class SFGExtended: public T, protected IExtended
{
typedef SFGExtended<T> ThisClass;
typedef void (ThisClass::*SignalCallback)();
SignalCallback mSignalCallbacks[GuiEnum::signalNum];


public:


virtual ~SFGExtended<T>()
{
}


void SetSignalCallback(GuiEnum::GuiSignal signal, const std::string& callback)
{
mLuaCallbacks[signal] = callback;
this->GetSignal(*sSignals[signal]).Connect( std::bind(mSignalCallbacks[signal], this) );
}


static bool SetSound(int signal, const std::string& filename);


protected:


explicit SFGExtended<T>()
{
#define STORE_CALLBACK(Name) mSignalCallbacks[GuiEnum::signal##Name] = &ThisClass::Name;
STORE_CALLBACK(OnStateChange);
STORE_CALLBACK(OnGainFocus);
STORE_CALLBACK(OnLostFocus);
STORE_CALLBACK(OnExpose);
STORE_CALLBACK(OnSizeAllocate);
STORE_CALLBACK(OnSizeRequest);
STORE_CALLBACK(OnMouseEnter);
STORE_CALLBACK(OnMouseLeave);
STORE_CALLBACK(OnMouseMove);
STORE_CALLBACK(OnMouseLeftPress);
STORE_CALLBACK(OnMouseRightPress);
STORE_CALLBACK(OnMouseLeftRelease);
STORE_CALLBACK(OnMouseRightRelease);
STORE_CALLBACK(OnLeftClick);
STORE_CALLBACK(OnRightClick);
STORE_CALLBACK(OnKeyPress);
STORE_CALLBACK(OnKeyRelease);
STORE_CALLBACK(OnText);
#undef STORE_CALLBACK
}


virtual void RunCallback(GuiEnum::GuiSignal signal)
{
LuaManager::Instance().AddCallback(mLuaCallbacks[signal], this, false);
//LuaManager::Instance().Lua().call(mLuaCallbacks[signal], this);
}


inline void PlaySound(GuiEnum::GuiSignal signal)
{
if (sSounds[signal])
{
mSound.setBuffer(*sSounds[signal]);
mSound.play();
}
}


#define DECLARE_CALLBACK(Name) \
virtual void Name() {\
PlaySound(GuiEnum::signal##Name);\
RunCallback(GuiEnum::signal##Name); }


DECLARE_CALLBACK(OnStateChange)
DECLARE_CALLBACK(OnGainFocus)
DECLARE_CALLBACK(OnLostFocus)
DECLARE_CALLBACK(OnExpose)
DECLARE_CALLBACK(OnSizeAllocate)
DECLARE_CALLBACK(OnSizeRequest)
DECLARE_CALLBACK(OnMouseEnter)
DECLARE_CALLBACK(OnMouseLeave)
DECLARE_CALLBACK(OnMouseMove)
DECLARE_CALLBACK(OnMouseLeftPress)
DECLARE_CALLBACK(OnMouseRightPress)
DECLARE_CALLBACK(OnMouseLeftRelease)
DECLARE_CALLBACK(OnMouseRightRelease)
DECLARE_CALLBACK(OnLeftClick)
DECLARE_CALLBACK(OnRightClick)
DECLARE_CALLBACK(OnKeyPress)
DECLARE_CALLBACK(OnKeyRelease)
DECLARE_CALLBACK(OnText)


#undef DECLARE_CALLBACK


private:


std::string mLuaCallbacks[GuiEnum::signalNum];
sf::Sound mSound;
static sf::SoundBuffer* sSounds[GuiEnum::signalNum];


};






template<class T>
/* static */ sf::SoundBuffer* SFGExtended<T>::sSounds[GuiEnum::signalNum] = { nullptr };






template<class T>
/* static */ bool SFGExtended<T>::SetSound(int signal, const std::string& filename)
{
return ResourceManager::Instance().GetSoundBuffer(filename,  sSounds[signal]);
}




#define DECLARE_EXTENDED(x)\
typedef SFGExtended<sfg::x> Extended##x;\
OOLUA_PROXY( Extended##x, sfg##x)\
OOLUA_TAGS(Shared, Abstract)\
OOLUA_MFUNC(SetSignalCallback)\
OOLUA_SFUNC(SetSound)\
OOLUA_PROXY_END




DECLARE_EXTENDED(Button)


#undef DECLARE_EXTENDED






class GuiButton: public ExtendedButton
{
public:
typedef std::shared_ptr<GuiButton> Ptr;
typedef std::shared_ptr<const GuiButton> PtrConst;


static Ptr Create( const std::string& label);


private:


};








OOLUA_PROXY(GuiEnum)
OOLUA_TAGS(Abstract, Register_class_enums)


OOLUA_ENUMS(
OOLUA_ENUM(signalOnStateChange)
OOLUA_ENUM(signalOnGainFocus)
OOLUA_ENUM(signalOnLostFocus)
OOLUA_ENUM(signalOnExpose)
OOLUA_ENUM(signalOnSizeAllocate)
OOLUA_ENUM(signalOnSizeRequest)
OOLUA_ENUM(signalOnMouseEnter)
OOLUA_ENUM(signalOnMouseLeave)
OOLUA_ENUM(signalOnMouseMove)
OOLUA_ENUM(signalOnMouseLeftPress)
OOLUA_ENUM(signalOnMouseRightPress)
OOLUA_ENUM(signalOnMouseLeftRelease)
OOLUA_ENUM(signalOnMouseRightRelease)
OOLUA_ENUM(signalOnLeftClick)
OOLUA_ENUM(signalOnRightClick)
OOLUA_ENUM(signalOnKeyPress)
OOLUA_ENUM(signalOnKeyRelease)
OOLUA_ENUM(signalOnText))
OOLUA_PROXY_END


OOLUA_PROXY( GuiButton, ExtendedButton)
OOLUA_TAGS(Shared, No_public_constructors)
OOLUA_SFUNC(Create)
OOLUA_PROXY_END

There are two CPP files also and ResourceManager for sounds. So, i think that OOLua is very good library to create Lua bindings. =)
PS One bad thing. OOLua not supports strongly typed enums yet. Deleting keyword 'class' solves the problem, but this is hack and ugly.
« Last Edit: February 02, 2014, 03:49:27 pm by ChronicRat »