> 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