> Sometimes events happen in C++-Land that require an update of a GUI
> element. I figured that the most sensible way of doing this is to call
> IupPostMessage from C++ territory, in whatever thread context this
> happens to be, and thus cause a Lua callback to be called in the context
> of the GUI main loop the next time it comes around.
>

Yes, this is the quintessential example case of why IupPostMessage
exists. My personal most frequent use cases for this have been:
- Downloading data over the network on a background thread and then
needing to update the UI when finished.
- Audio playback event callbacks on background threads (and needing to
update UI)
- Computation that takes a long time and I don't want to block the
main UI thread, so I thread it but need to update the GUI state when
it is finished.


I don't know Sol2, but breaking down your situation into the most
basic building blocks, I would just look at this as a classic C/C++
callback pattern. Since C is mostly valid C++, let's just simplify
this further.
Warning: This is typed in email and untested, so there may be bugs:


struct MyAppData
{
        lua_State* luaState;
        Ihandle* someWidget;
        char* callbackString;
        
};

// This is some hypothetical function that gets invoked when something
happened.
// It is expected to happen on a background thread.
// Presumably, this function will pass you back some information
associated with this event.
// For simplicity, I pretend char* some_string is that data.
// In classic callback function patterns, you also get passed a handle
to some data which you setup earlier, so you can access your
application state without globals.
void SomeCppFunctionOnABackgroundThread(char* some_string, void* user_data)
{
        struct MyAppData* app_data = (struct MyAppData*)user_data;
        app_data->callbackString = some_string; // Just for show. Maybe we
need to make a deep copy depending on how your APIs work.
        IupPostMessage(app_data->someWidget, NULL, 0, 0.0, app_data);
}


// This is the main thread callback for IupPostMessage
void MyCppIupPostMessageMainThreadCallback(Ihandle* ih, char* s, int
i, double d, void* p)
{
        struct MyAppData* app_data = (struct MyAppData*)p;      
        
        // Invoke Lua to do something.

        lua_getglobal(app_data->luaState, "MyLuaIupPostMessageCallback");
        lua_pushstring(lua_state, app_data->callbackString);
        // You could push other arguments to Lua here too, but for this
example, I will just push the string data.
        /* do the call (1 arguments, 0 results) */
        if(lua_pcall(lua_state, 0, 5, 0) != 0)
        {
                printf("Error running function: %s", lua_tostring(lua_state, 
-1));
                lua_pop(L, 1);
        }
}

/*
In Lua somewhere, you could have a global function called
MyLuaIupPostMessageCallback

function MyLuaIupPostMessageCallback(string_data)
        print("string_data", string_data)
        -- Maybe you have global data to access your Iup widgets.
        -- Or maybe you can use IupGetHandle to get the handles by string name.

end

*/


Finally, considering how to integrate Sol2, I would envision that you
have some state for Sol2 that you put into your user_data pointer.
So instead of manually invoking a Lua callback in
MyCppIupPostMessageMainThreadCallback, pull out your Sol2 data
structures from the user_data pointer, and then use Sol2 to invoke the
Lua callback.

-Eric


_______________________________________________
Iup-users mailing list
Iup-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/iup-users

Reply via email to