Hi Demivec. Some excellent points, but based on some wrong premises.
Demivec wrote:...a callback is called for every event.
A callback that takes too long to execute can lead to a backlog of events...
True, but the events that it handles would invariably trigger some action. Here is where the logic collapses.
In PureBasic, unless a separate thread is spawned to handle these actions, the triggered code would execute synchronously. This means that until it completes, all event processing is essentially suspended;
regardless of whether it is running in the callback or anywhere else.
Here's a modification of Danilo's code to illustrate this:
Code: Select all
Procedure.q Ackermann(m, n)
If m = 0
ProcedureReturn n + 1
ElseIf n = 0
ProcedureReturn Ackermann(m - 1, 1)
Else
ProcedureReturn Ackermann(m - 1, Ackermann(m, n - 1))
EndIf
EndProcedure
Procedure windowCallback(hWnd, uMsg, WParam, LParam)
Select uMsg
Case #WM_COMMAND
Select (wParam >> 16) & $ffff
Case #BN_CLICKED
Select (wParam & $ffff)
Case 2
SetGadgetText(0, "calculating...")
Ackermann(3, 9)
EndSelect
EndSelect
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure normalProcedure()
SetGadgetText(0, "calculating...")
Ackermann(3, 9)
EndProcedure
Procedure Timer()
Static Value : Value + 1
SetGadgetText(0, StrU(Value, #PB_Integer))
EndProcedure
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
If OpenWindow(0, 0, 0, 400, 100, "Callback Example", wFlags)
TextGadget(0, 150, 15, 100, 25, "", #PB_Text_Center)
ButtonGadget(1, 10, 50, 180, 30, "click handled by procedure")
ButtonGadget(2, 210, 50, 180, 30, "click handled by callback")
AddWindowTimer(0, 123, 50)
BindEvent(#PB_Event_Timer, @Timer())
SetWindowCallback(@windowCallback())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
appQuit = 1
Case #PB_Event_Gadget
Select EventGadget()
Case 1
normalProcedure()
Case 2
;handled by windowCallback
EndSelect
EndSelect
Until appQuit = 1
EndIf
Should we avoid blocking routines? Ideally -
yes. Practically -
not always possible. But that purely boils down to coding quality;
not just because it is executed within a callback.
Demivec wrote:Making a user interface more responsive and leaving as much time for procedures and code that is not part of the user interface to execute and to actually get something accomplished is a very logical idea.
That statement sounds great, but does not quite meld.
These
procedures and code that you mentioned are almost always triggered by some UI action, which is usually nothing more than a key stroke or a mouse click. Ultimately, in a synchronous environment, UI responsiveness hinges directly on these
procedures and code themselves,
regardless of where they may be executed. In this respect, the two are not exclusive.
So, unfortunately, the logic of the original statement in question still does not stand.
