Page 1 of 2
delay not working as expected
Posted: Tue Apr 01, 2025 6:36 pm
by solo
i expected the 2 sec delay to happen between drawing circles.
instead it pauses 2 sec before window opens and draws both circles. what did i do wrong?
Code: Select all
OpenWindow(0, 200, 100, 1000, 600, " timer test")
CreateImage(0, DesktopScaledX(1000), DesktopScaledY(600))
ImageGadget(0, 0, 0, 0, 0, ImageID(0))
StartDrawing(ImageOutput(0))
Circle(100,200,5,RGB(0,0,255))
Delay(2000)
Circle(300,500,5,RGB(0,0,255))
StopDrawing()
ImageGadget(0, 0, 0, 0, 0, ImageID(0))
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow ; If the user has pressed on the window close button
End
Re: delay not working as expected
Posted: Tue Apr 01, 2025 6:42 pm
by miso
Stopdrawing is needed to finish the draw.
Code: Select all
OpenWindow(0, 200, 100, 1000, 600, " timer test")
CreateImage(0, DesktopScaledX(1000), DesktopScaledY(600))
StartDrawing(ImageOutput(0))
Circle(100,200,5,RGB(0,0,255))
StopDrawing()
ImageGadget(0, 0, 0, 0, 0, ImageID(0))
Delay(2000)
StartDrawing(ImageOutput(0))
Circle(300,500,5,RGB(0,0,255))
StopDrawing()
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow ; If the user has pressed on the window close button
End
Re: delay not working as expected
Posted: Tue Apr 01, 2025 6:45 pm
by solo
already tried that. same result.
Re: delay not working as expected
Posted: Tue Apr 01, 2025 6:47 pm
by Fred
You need to process the event to have graphical refresh. Just use a timer set to 2000 to draw to the second image
Re: delay not working as expected
Posted: Tue Apr 01, 2025 6:48 pm
by STARGĂ…TE
Wellcome to PureBasic and our forum.
For a working window, the event-loop have to be called, without (Wait)WindowEvent(), no update on the window.
Further, the drawing is only displayed, when StopDrawing() is called, finishing the drawing.
And for real-time drawing, you have to use a CanvasGadget, because the ImageGadget is not updated, event if you draw on the image.
ImageGadget() shows a copy of the passed image.
Here a working example:
Code: Select all
OpenWindow(0, 200, 100, 1000, 600, " timer test")
AddWindowTimer(0, 0, 500) ; create a timer for the drawing
CanvasGadget(0, 0, 0, 1000, 600)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #PB_Event_Timer
Select EventTimer()
Case 0
If StartDrawing(CanvasOutput(0))
Circle(Random(1000),Random(600),50,RGB(0,Random(255),Random(255)))
StopDrawing()
EndIf
EndSelect
EndSelect
ForEver
Re: delay not working as expected
Posted: Tue Apr 01, 2025 6:51 pm
by solo
so, delay is broken and PD doesn't have a timer command?
Re: delay not working as expected
Posted: Tue Apr 01, 2025 6:52 pm
by jacdelad
No, it is not broken. You just need to follow the basic programming rules. Two people already answered you how to do it...
Re: delay not working as expected
Posted: Tue Apr 01, 2025 7:46 pm
by NicTheQuick
solo wrote: Tue Apr 01, 2025 6:51 pm
so, delay is broken and PD doesn't have a timer command?
Are you trying to do April fools?
Re: delay not working as expected
Posted: Tue Apr 01, 2025 10:31 pm
by solo
doesn't work, no circles get drawn:
Code: Select all
s=0
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #PB_Event_Timer
Select EventTimer()
Case 0
If StartDrawing(CanvasOutput(0))
Circle(Random(1000),Random(600),50,RGB(0,Random(255),Random(255)))
StopDrawing()
EndIf
EndSelect
EndSelect
s=s+1
Until s=10
Re: delay not working as expected
Posted: Wed Apr 02, 2025 5:47 am
by normeus
PS
this is just too much
Norm
Re: delay not working as expected
Posted: Wed Apr 02, 2025 7:37 am
by miso
Code: Select all
OpenWindow(0, 200, 100, 1000, 600, " timer test")
AddWindowTimer(0, 0, 500) ; create a timer for the drawing
CanvasGadget(0, 0, 0, 1000, 600)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #PB_Event_Timer
Select EventTimer()
Case 0
If s<10
s+1
If StartDrawing(CanvasOutput(0))
Circle(Random(1000),Random(600),50,RGB(0,Random(255),Random(255)))
StopDrawing()
EndIf
EndIf
EndSelect
EndSelect
ForEver
Re: delay not working as expected
Posted: Wed Apr 02, 2025 7:57 am
by Marc56us
Delay stops the whole program, so if you want to use it, you'll have to set it after the complete image has been generated.
(so
not between StartDrawing and StopDrawing)
Code: Select all
OpenWindow(0, 200, 100, 1000, 600, " timer test")
CreateImage(0, DesktopScaledX(1000), DesktopScaledY(600))
ImageGadget(0, 0, 0, 0, 0, ImageID(0))
Repeat
; 1. Tracing the image
StartDrawing(ImageOutput(0))
Circle(Random(1000, 0), Random(600, 0), 50, RGB(0,0,255))
StopDrawing()
; 2. Assign image to object
SetGadgetState(0, ImageID(0))
; 3. Wait
Delay(1000)
Until WaitWindowEvent = #PB_Event_CloseWindow

But a timer is better, as the rest of the program can continue.
Code: Select all
OpenWindow(0, 200, 100, 1000, 600, " timer test")
AddWindowTimer(0, 1, 1000)
CreateImage(0, DesktopScaledX(1000), DesktopScaledY(600))
ImageGadget(0, 0, 0, 0, 0, ImageID(0))
Procedure Draw_Image()
; 1. Tracing the image
StartDrawing(ImageOutput(0))
Circle(Random(1000, 0), Random(600, 0), 50, RGB(0,0,255))
StopDrawing()
; 2. Assign image to object
SetGadgetState(0, ImageID(0))
EndProcedure
Repeat
Select WaitWindowEvent()
Case #PB_Event_Timer
If EventTimer() = 1 : Draw_Image() : EndIf
Case #PB_Event_CloseWindow
End
EndSelect
ForEver
In this example, the mouse cursor shows that the program is available for other actions
Re: delay not working as expected
Posted: Wed Apr 02, 2025 8:38 am
by miso
I wrote a small timer module not long ago, that also works.
Edit: Code has been fixed to give breath back to OS.
Code: Select all
;-===MODULE DESCRIPTION===
;Tiny module to create periodic tickers
;Created with PB 6.20 Beta 1
;Author: :miso
;Creation date:2025.01.31
;Purpose :for periodic tasks like sending a keepalive packet to push through nat or change frame of an animation, etc
;Scope :all platforms, but tested only on Windows 7 64 bit
;Permissions :777, do what you want, (author takes no responsibilities nor any claims)
EnableExplicit
;-===MODULE DECLARATION===
DeclareModule ticker
;-===CONSTANTS===
#TICKS_FOREVER = -10
#MAXIMUM_ALLOWED_TICKERS = 255
;-===STRUCTURES===
Structure tickerstructure
timeout.i
lasttick.i
current_tick_count.i
target_tick_count.i
alive.i
EndStructure
;-===PUBLIC PROCEDURE DECLARATIONS===
Declare.i create(ID.i,ticktime_ms.i,number_of_ticks.i=#TICKS_FOREVER)
Declare.i triggered(ID.i)
Declare.i kill(ID.i)
EndDeclareModule
;-===MODULE===
Module ticker
;-===PRIVATE GLOBALS===
Global Dim tickers.tickerstructure(#MAXIMUM_ALLOWED_TICKERS)
;-===PUBLIC PROCEDURES===
;***************************************
;Create a new ticker
;***************************************
Procedure.i create(ID.i,ticktime_ms.i,number_of_ticks.i=#TICKS_FOREVER)
If ID.i>=0 And ID.i<=#MAXIMUM_ALLOWED_TICKERS
With tickers(ID.i)
\lasttick.i = ElapsedMilliseconds()
\timeout.i = ticktime_ms.i
\current_tick_count.i = 0
\alive.i = #True
\target_tick_count = number_of_ticks.i
EndWith
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
;***************************************
;Returns the triggered status of a ticker
;***************************************
Procedure.i triggered(ID.i)
If ID.i<0 Or ID.i>#MAXIMUM_ALLOWED_TICKERS
Debug Str(ID.i) + " not exists, cant be checked"
ProcedureReturn #False
EndIf
If tickers(ID.i)\alive <> #True
ProcedureReturn #False
EndIf
If ElapsedMilliseconds()-tickers(ID.i)\lasttick<tickers(ID.i)\timeout
ProcedureReturn #False
EndIf
tickers(ID.i)\current_tick_count + 1
tickers(ID.i)\lasttick = ElapsedMilliseconds()
If tickers(ID.i)\current_tick_count = tickers(ID.i)\target_tick_count
tickers(ID.i)\alive = #False
EndIf
ProcedureReturn #True
EndProcedure
;***************************************
;Sets a ticker to be dead
;***************************************
Procedure.i Kill(ID.i)
If ID.i<0 Or ID.i>#MAXIMUM_ALLOWED_TICKERS
ProcedureReturn #False
EndIf
tickers(ID.i)\alive = #False
ProcedureReturn #True
EndProcedure
EndModule
;-===EXAMPLE USAGE===
Define mywindowevent.i
OpenWindow(0, 200, 100, 1000, 600, " timer test")
CanvasGadget(0, 0, 0, 1000, 600)
ticker::create(1,500,10) ;This can proc only ten times with 500 ms delay, then stops
Repeat
Repeat
mywindowevent=WaitWindowEvent(1)
If mywindowevent= #PB_Event_CloseWindow : End : EndIf
Until Not mywindowevent
If ticker::triggered(1)
If StartDrawing(CanvasOutput(0))
Circle(Random(1000),Random(600),50,RGB(0,Random(255),Random(255)))
StopDrawing()
EndIf
EndIf
ForEver
Re: delay not working as expected
Posted: Wed Apr 02, 2025 9:19 am
by mk-soft
Burns too much CPU power. Better with EventTimer and BindEvent.
Re: delay not working as expected
Posted: Wed Apr 02, 2025 9:44 am
by Fred
you need to change WindowEvent() with WaitWindowEvent(1)