@Flinx
Looking better at your code I realized that the recursive code returns immediately, it places only one callback in the stack that, when it is executed executed, it places another callback and so on... while mine places all the callbacks in the stack at once...
it's still not clear to me why my example doesn't not work... maybe my supposition is true: widget are updated only when all the events has been served
Updating listviews...
Re: Updating listviews...
----------------------------
[Allanon] Fabio Falcucci | GitHub for recent works | Support me on Patreon for Hollywood libraries | ☆★ All my links ★☆
[Allanon] Fabio Falcucci | GitHub for recent works | Support me on Patreon for Hollywood libraries | ☆★ All my links ★☆
- airsoftsoftwair
- Posts: 5446
- Joined: Fri Feb 12, 2010 2:33 pm
- Location: Germany
- Contact:
Re: Updating listviews...
Flinx is doing it the right way. I somehow missed his answer and came up with this:
As you can see, it's pretty much the same idea except I'm not calling Listview.Redraw() because this is unnecessary. This is perfectly safe. There is no recursion. It's just pushing the next callback from the callback but it won't be called until the next event loop cycle. So there is always only one callback on the stack. No risk of any overflows here. That's how it should be done, always push the next callback *from* the callback to ensure the event loop has time to refresh.
Code: Select all
@REQUIRE "RapaGUI"
Function p_Func(msg)
Local t = msg.userdata
DebugPrint("--> ", t.n)
Wait(50,#MILLISECONDS)
moai.DoMethod("lv", "insert", GetTime(True) .. ": " .. "Hello!\n", "bottom")
t.n = t.n + 1
If t.n <= t.limit Then RunCallback(p_Func, t)
EndFunction
Function msgHandler(msg)
Switch msg.action
; Parse RapaGUI events
Case "RapaGUI"
; Filter actions by attributes
Switch msg.attribute
; Check button presses
Case "Pressed"
; Check buttons
Switch msg.id
Case "go"
Local state = {n = 1, limit = 10}
RunCallback(p_Func, state)
EndSwitch
EndSwitch
EndSwitch
EndFunction
moai.CreateApp([[<?xml version="1.0" encoding="iso-8859-1"?>
<application id="app">
<menubar id="menu">
<menu title="_File">
<item id="mn_about">_About...</item>
<item/>
<item id="mn_quit">_Quit</item>
</menu>
</menubar>
<window title="TEST LV" id="window" menubar="menu">
<vgroup frame="true" frametitle="Update Test">
<texteditor id="lv" readonly="true">
</texteditor>
<button id="go">GO</button>
</vgroup>
</window>
</application>
]])
; listen to these events!
InstallEventHandler({
RapaGUI = msgHandler
})
; Welcome message
moai.DoMethod("lv", "insert", GetTime(True) .. ": " .. "Hello!\n", "bottom")
; Let's go!
Repeat
DebugPrint("Before Wait Event")
WaitEvent
DebugPrint("After Wait Event")
Forever
Re: Updating listviews...
Yup, that's fine, I've replied to myself because I saw that the code wasn't affecting the stack
I've fixed my script to work as I wanted, thank you for the help
...to be honest I don't really like this way of structuring the code to give some feedback to the user during a loop
I've fixed my script to work as I wanted, thank you for the help
...to be honest I don't really like this way of structuring the code to give some feedback to the user during a loop
airsoftsoftwair wrote: ↑Sun Feb 04, 2024 10:03 pm Flinx is doing it the right way. I somehow missed his answer and came up with this:
As you can see, it's pretty much the same idea except I'm not calling Listview.Redraw() because this is unnecessary. This is perfectly safe. There is no recursion. It's just pushing the next callback from the callback but it won't be called until the next event loop cycle. So there is always only one callback on the stack. No risk of any overflows here. That's how it should be done, always push the next callback *from* the callback to ensure the event loop has time to refresh.Code: Select all
@REQUIRE "RapaGUI" Function p_Func(msg) Local t = msg.userdata DebugPrint("--> ", t.n) Wait(50,#MILLISECONDS) moai.DoMethod("lv", "insert", GetTime(True) .. ": " .. "Hello!\n", "bottom") t.n = t.n + 1 If t.n <= t.limit Then RunCallback(p_Func, t) EndFunction Function msgHandler(msg) Switch msg.action ; Parse RapaGUI events Case "RapaGUI" ; Filter actions by attributes Switch msg.attribute ; Check button presses Case "Pressed" ; Check buttons Switch msg.id Case "go" Local state = {n = 1, limit = 10} RunCallback(p_Func, state) EndSwitch EndSwitch EndSwitch EndFunction moai.CreateApp([[<?xml version="1.0" encoding="iso-8859-1"?> <application id="app"> <menubar id="menu"> <menu title="_File"> <item id="mn_about">_About...</item> <item/> <item id="mn_quit">_Quit</item> </menu> </menubar> <window title="TEST LV" id="window" menubar="menu"> <vgroup frame="true" frametitle="Update Test"> <texteditor id="lv" readonly="true"> </texteditor> <button id="go">GO</button> </vgroup> </window> </application> ]]) ; listen to these events! InstallEventHandler({ RapaGUI = msgHandler }) ; Welcome message moai.DoMethod("lv", "insert", GetTime(True) .. ": " .. "Hello!\n", "bottom") ; Let's go! Repeat DebugPrint("Before Wait Event") WaitEvent DebugPrint("After Wait Event") Forever
----------------------------
[Allanon] Fabio Falcucci | GitHub for recent works | Support me on Patreon for Hollywood libraries | ☆★ All my links ★☆
[Allanon] Fabio Falcucci | GitHub for recent works | Support me on Patreon for Hollywood libraries | ☆★ All my links ★☆
- airsoftsoftwair
- Posts: 5446
- Joined: Fri Feb 12, 2010 2:33 pm
- Location: Germany
- Contact:
Re: Updating listviews...
I can understand that but I'm afraid there's not really a way around this because that's how modern GUIs are designed. When designing RapaGUI I really thought about this a lot but if I wanted RapaGUI to work around this, the script would have to run on its own thread and then delegate all GUI calls to the main thread but this has the potential to trigger lots of issues so it's not really a good idea.
My idea was to tie RapaGUI as closely as possible to the underlying GUI system but of course this has the consequence that some things aren't as convenient as you're used to, e.g. your feedback situation. Remember that RapaGUI is quite a beast because it also runs on systems like Android where all GUI stuff must be done in Java. This is all very complex stuff and on Android you'll also run into the very same issue because the GUI won't refresh until the main loop is hit again. It's just how those GUI systems work and I don't think it can be made more convenient without making all hell break loose
Re: Updating listviews...
Thank you for your reply, don't get me wrong, it's not a complain about how it has been implemented but instead just a feeling, but now that I got how it works I'll live with it.
Thanks again for your efforts in Hollywood-land
Thanks again for your efforts in Hollywood-land
airsoftsoftwair wrote: ↑Sun Feb 11, 2024 9:50 pmI can understand that but I'm afraid there's not really a way around this because that's how modern GUIs are designed. When designing RapaGUI I really thought about this a lot but if I wanted RapaGUI to work around this, the script would have to run on its own thread and then delegate all GUI calls to the main thread but this has the potential to trigger lots of issues so it's not really a good idea.
My idea was to tie RapaGUI as closely as possible to the underlying GUI system but of course this has the consequence that some things aren't as convenient as you're used to, e.g. your feedback situation. Remember that RapaGUI is quite a beast because it also runs on systems like Android where all GUI stuff must be done in Java. This is all very complex stuff and on Android you'll also run into the very same issue because the GUI won't refresh until the main loop is hit again. It's just how those GUI systems work and I don't think it can be made more convenient without making all hell break loose
----------------------------
[Allanon] Fabio Falcucci | GitHub for recent works | Support me on Patreon for Hollywood libraries | ☆★ All my links ★☆
[Allanon] Fabio Falcucci | GitHub for recent works | Support me on Patreon for Hollywood libraries | ☆★ All my links ★☆