Thank you @Flinx to try to resolve this puzzle and taking time to experiment, your example is working but I have a couple of observations about my previous example's loop
The For/Next that executes the
RunCallback() is not blocking, it just put the callback functions into the event's queue, infact look at this piece of code executed when the button is pressed:
Code: Select all
Case "go"
;--testFunc()
f=Function(msg) DebugPrint("--> ", msg.userdata) Wait(50,#MILLISECONDS) moai.DoMethod("lv", "insert", GetTime(True) .. ": " .. "Hello!\n", "bottom") EndFunction
fm=Function(msg) moai.DoMethod("lv", "insert", GetTime(True) .. ": " .. "Hello!\n", "bottom") EndFunction
For n = 0 To 10
DebugPrint(f,fm)
RunCallback(fm,n)
RunCallback(f,n)
Next
DebugPrint(f,fm) prints all the stuff in one go because the For/Next is executed in no time and the
RunCallback() commands put the function's calls in the event queue, then the control is returned to the
WaitEvent().
Now the system should call the functions placed on the events stack, alternatining the f() and the fm() function calls, infact in the debug window the
DebugPrint() of the f() function prints some text but the fm() function does not trigger the listview update which is updated only at the end of the event's queue. That's the question: are widgets updated only when all events has been served? Looking at your example seems that the answer is no because you are calling a calback function that never returns calling itself recursively.
I'm not sure why your example works, using recursion like you did is ok but what happens if the recursion goes deep like 30000 times? Stack overflow?
I want to expose my real case for which I want to show some user feedback.
I'm building an utility to calculate checksums & hashes of some files: the user drops the files to process into a list view then, when ready, he push a button and the program starts the calculations. Well, it was an epic fail

I'm not able to update the listview while the files are being processed or better: I'm not able to force the listview to show what I've added to it.
About implementing this stuff using recursion.. well, maybe it could work, but I think it's unneeded overcomplication that could lead to stack overflows, I don't know how many files the user wants to calculate, he could ask for the sha1 of his entire disk.
There should be a legal/elegant way to implement such stuff without involving sorceries like transforming a simple loop into a recursive loop
Any ideas?
Flinx wrote: ↑Fri Feb 02, 2024 4:37 pm
The problem with the last example is that there is also a For loop that does not pass control to the main loop, so all RunCallback calls are executed at once.
I have converted your previous example into a recursive function that only executes one action and then calls itself for the next one via RunCallback.
The start value is passed as simulated userdata on the first call.
Code: Select all
@REQUIRE "RapaGUI"
Function testFunc(msg)
moai.DoMethod("lv", "insert", ToString(msg.userdata).." " .. GetTime(True) .. ": " .. "Hello!\n", "bottom")
;moai.DoMethod("lv", "jump", "bottom")
moai.DoMethod("lv", "redraw")
Wait(20, #MILLISECONDS)
DebugPrint("Added item " .. msg.userdata)
If msg.userdata<100 Then RunCallback(testFunc,msg.userdata+1)
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"
testFunc({["userdata"] =1})
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