how do you create a timer?

Just starting out? Need help? Post your questions and find answers here.
josku_x
Addict
Addict
Posts: 997
Joined: Sat Sep 24, 2005 2:08 pm

how do you create a timer?

Post by josku_x »

hello!

I need help to wait for some time and to continue a function.

I simply want to do this:

Code: Select all

If WaitServer
 Wait 100 Milliseconds
 MessageRequester("Continue", "Program will continue...")
 WaitServer=0
EndIf
The problem is, I have many gadgets that need to be refreshed to show new data, and if I use Delay() or ElapsedMilliseocnds(), everything gets reezed until the wait-time is finished. So, how do I achieve this? I want that a function waits for the specified time without disturbing other stuff.

Thanks!
If this isn't clear, please let me know
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I sometimes use something like:

Code: Select all

If WaitServer 
for i = 0 to 100
  delay(1)
  WindowEvent() ;This allows gadgets to be refreshed etc.
next
 MessageRequester("Continue", "Program will continue...") 
 WaitServer=0 
EndIf
Alternatively, perhaps use a thread, or a Windows timer is very easy to set up.
I may look like a mule, but I'm not a complete ass.
josku_x
Addict
Addict
Posts: 997
Joined: Sat Sep 24, 2005 2:08 pm

Post by josku_x »

That trick with the windowEvent() looks pretty cool!
Thanks srod!
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Of course, you will not get an exact time of delay with this method. Mind you, the same is true with a Window's timer as that depends very much upon an application's use of the message queue etc. :D
I may look like a mule, but I'm not a complete ass.
josku_x
Addict
Addict
Posts: 997
Joined: Sat Sep 24, 2005 2:08 pm

Post by josku_x »

OK. I was thinking of a BitTorrent client and a time delay before reconnecting is a standard feature every BT client needs to have.
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

srod wrote:I sometimes use something like:

Code: Select all

If WaitServer 
for i = 0 to 100
  delay(1)
  WindowEvent() ;This allows gadgets to be refreshed etc.
next
 MessageRequester("Continue", "Program will continue...") 
 WaitServer=0 
EndIf
Alternatively, perhaps use a thread, or a Windows timer is very easy to set up.
This is really not the way to do it. :p

Here is an example of a repeating call to a procedure:

Code: Select all

Procedure Echo(Text.s)
	Debug Text
EndProcedure

RepeatTime.l = 1000
StartTime.l = ElapsedMilliseconds()

Repeat
	If ElapsedMilliseconds() > StartTime + RepeatTime
		Echo("I am being repeated every second")
		StartTime.l = ElapsedMilliseconds()
	EndIf
	Delay(1)
ForEver
And here is how to wait for a bit without halting the event queue:

Code: Select all

;]=============================================================================
;-CONSTANTS
;[=============================================================================

#APP_NAME = "Timer Test"

Enumeration
	#WINDOW_ROOT
	#BUTTON_DELAY
EndEnumeration

;]=============================================================================
;-GLOBAL FLAGS / VARIABLES / STRUCTURES / ARRAYS
;[=============================================================================

Global StartTimer.b = #False
Global StartTime.l
Global DelayTime.l = 5000

;]=============================================================================
;-PROCEDURES
;[=============================================================================

;Handle an error
Procedure HandleError(Result.l, Text.s)
	If Result = 0
		MessageRequester("Error", Text, #PB_MessageRequester_Ok)
		End
	EndIf
EndProcedure

;]=============================================================================
;-GEOMETRY
;[=============================================================================

HandleError(OpenWindow(#WINDOW_ROOT, 0, 0, 120, 120, #APP_NAME, #PB_Window_SystemMenu | #PB_Window_ScreenCentered), "Main window could not be created.")
HandleError(CreateGadgetList(WindowID(#WINDOW_ROOT)), "Gadget list for the main window could not be created.")
ButtonGadget(#BUTTON_DELAY, 10, 10, 100, 90, "Press Me")

;]=============================================================================
;-MAIN LOOP
;[=============================================================================

Repeat
	EventID.l = WindowEvent()
	If EventID
		Select EventID
			Case #PB_Event_Gadget
				Select EventGadget()
					Case #BUTTON_DELAY
						Debug "Waiting for 5 seconds"
						StartTime.l = ElapsedMilliseconds()
						StartTimer.b = #True
				EndSelect
		EndSelect
	Else
		Delay(1)
	EndIf

	If ElapsedMilliseconds() > StartTime + DelayTime And StartTimer = #True
		Debug "Five seconds has elapsed!"
		StartTimer.b = #False
	EndIf

Until EventID = #PB_Event_CloseWindow
End

;]=============================================================================
;-END
;==============================================================================


--Kale

Image
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Yes, I was just giving the general idea of how to refresh gadgets whilst forcing a delay. I take your point though; use of the ElapsedMilliseconds() command is a good idea.
I may look like a mule, but I'm not a complete ass.
josku_x
Addict
Addict
Posts: 997
Joined: Sat Sep 24, 2005 2:08 pm

Post by josku_x »

Thanks Kale, works perfectly!
inc.
Enthusiast
Enthusiast
Posts: 406
Joined: Thu May 06, 2004 4:28 pm
Location: Cologne/GER

Post by inc. »

... everything gets reezed until the wait-time is finished. So, how do I achieve this? I want that a function waits for the specified time without disturbing other stuff....

Code: Select all

Repeat
   If ElapsedMilliseconds() > StartTime + RepeatTime
      Echo("I am being repeated every second")
      StartTime.l = ElapsedMilliseconds()
   EndIf
   Delay(1)
ForEver
This makes the appl. itself wait till the loop finished if its not performed in a thread and as I understood right he wants the timer to be processed in Backgr. so his gadgets ca be refreshed fast etc.

In case of a timer best would be a callback approach like included in the winAPI:
http://msdn.microsoft.com/library/defau ... tevent.asp
This is a multimediatimer (others are available also) and could easely used also for other stuff.
I do use it for proper FPS playback of moviecontend where frames are received via the avifil32 functions.
Just set the delay in ms, the timerProc callback wich calls your intervalled routine and let it go. ;)

I do prefer the one above over the common one: http://msdn.microsoft.com/library/defau ... ttimer.asp
In PB: http://www.purebasic.fr/english/viewtop ... t=settimer
Cause this SetTimer() routine does interrupt when dragging the title bar of the window.
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

inc. wrote:

Code: Select all

Repeat 
   If ElapsedMilliseconds() > StartTime + RepeatTime 
      Echo("I am being repeated every second") 
      StartTime.l = ElapsedMilliseconds() 
   EndIf 
   Delay(1) 
ForEver 
This makes the appl. itself wait till the loop finished if its not performed in a thread
The loop here is for demonstration only purposes, if you need to use this example put this code:

Code: Select all

   If ElapsedMilliseconds() > StartTime + RepeatTime 
      Echo("I am being repeated every second") 
      StartTime.l = ElapsedMilliseconds() 
   EndIf 
in your main loop. It doesn't interfere with anything.
inc. wrote:..as I understood right he wants the timer to be processed in Backgr. so his gadgets ca be refreshed fast etc.
Which is what i've demonstrated in the other code snippet. There is no need for API usage for this simple task.
--Kale

Image
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

If you want a timer wich doesn't interfer with your main code, and is easy to use you can use a thread..!

Code: Select all

Global #timerquit

Procedure Timer1(time) ;time is in milliseconds

  Delay(time)

  Repeat
    ;YOUR REPEATED CODE
  Until #timerquit=1
  
EndProcedure

;fire the timer every second:
CreateThread(@timer1(),1000)
inc.
Enthusiast
Enthusiast
Posts: 406
Joined: Thu May 06, 2004 4:28 pm
Location: Cologne/GER

Post by inc. »

in your main loop. It doesn't interfere with anything.
missed that one ... sorry
josku_x
Addict
Addict
Posts: 997
Joined: Sat Sep 24, 2005 2:08 pm

Post by josku_x »

thefool wrote:If you want a timer wich doesn't interfer with your main code, and is easy to use you can use a thread..!

Code: Select all

Global #timerquit

Procedure Timer1(time) ;time is in milliseconds

  Delay(time)

  Repeat
    ;YOUR REPEATED CODE
  Until #timerquit=1
  
EndProcedure

;fire the timer every second:
CreateThread(@timer1(),1000)
Thanks thefool! I knew that I have to do a thread, but if I remember right, last week I tried it but failed. Thanks for the working example!
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

josku_x wrote:
thefool wrote:If you want a timer wich doesn't interfer with your main code, and is easy to use you can use a thread..!

Code: Select all

Global #timerquit

Procedure Timer1(time) ;time is in milliseconds

  Delay(time)

  Repeat
    ;YOUR REPEATED CODE
  Until #timerquit=1
  
EndProcedure

;fire the timer every second:
CreateThread(@timer1(),1000)
Thanks thefool! I knew that I have to do a thread, but if I remember right, last week I tried it but failed. Thanks for the working example!
Working example? are you joking or didn't even tried it? it doesn't work! :shock:
And you are not forced to create a thread.
Don't you like this?
http://www.purebasic.fr/english/viewtopic.php?t=17594
Last edited by Psychophanta on Fri May 26, 2006 4:41 pm, edited 1 time in total.
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

You'll need to use the debugger to kill the following:

Code: Select all

Global timerquit 

Procedure Timer1(time) ;time is in milliseconds 
  Repeat 
    Delay(time) 
    Debug 1
  Until timerquit=1 
EndProcedure 

;fire the timer every second: 
CreateThread(@timer1(),1000)

Repeat
ForEver
I may look like a mule, but I'm not a complete ass.
Post Reply