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
:cry:

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 
:arrow: 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)