ON TIMER substitute

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
v1ctor
Site Admin
Posts: 3798
Joined: May 27, 2005 8:08
Location: SP / Bra[s]il
Contact:

ON TIMER substitute

Postby v1ctor » Mar 09, 2006 2:16

Code: Select all

'' timer.bi
#ifndef __timer_bi__
#define __timer_bi__

#ifdef __FB_DOS__
# error "Unsupported platform, switch to a real OS"
#endif

#inclib "timer"

type TIMER_CALLBACK as sub( byval userdata as integer )

declare function timercreate            ( _
                                         byval interval as integer, _
                                         byval callback as TIMER_CALLBACK, _
                                         byval userdata as integer = 0 _
                                   ) as integer

declare sub     timeron               ( _
                                   byval id as integer _
                                 )

declare sub     timeroff               ( _
                                   byval id as integer _
                                 )

declare sub     timerdestroy            ( _
                                   byval id as integer _
                                 )


#endif


Code: Select all

'' timer.bas
''
'' simple timer library using threads
'' (note: to use this library *always* compile the client using the -mt option for threading safety)
''
'' to compile: fbc timer.bas -lib
''

option explicit

#include once "timer.bi"

enum TIMER_STATES
   TIMER_STATE_KILLED
   TIMER_STATE_RUNNING
   TIMER_STATE_STOPPED
   TIMER_STATE_EXITING
end enum

type TIMER_CTX
   state      as TIMER_STATES
   interval   as integer
   callback   as TIMER_CALLBACK
   userdata   as integer
   cond      as integer
   thread      as integer
end type

'':::::
private sub timer_thread( byval ctx as TIMER_CTX ptr )
       
   do
      select case ctx->state
      case TIMER_STATE_EXITING
         exit do
      
      case TIMER_STATE_STOPPED
         condwait( ctx->cond )
      
      case TIMER_STATE_RUNNING
         dim interval as integer
         
         interval = ctx->interval
         do
            sleep iif( interval <= 100, interval, 100 ), 1
            
            if( ctx->state <> TIMER_STATE_RUNNING ) then
               exit do
            end if
            
            interval -= 100
         loop while( interval > 0 )
         
         if( interval <= 0 ) then
            ctx->callback( ctx->userdata )
         end if
      end select
   loop
       
end sub

'':::::
function timercreate( _
                  byval interval as integer, _
                 byval callback as TIMER_CALLBACK, _
                 byval userdata as integer = 0 _
               ) as integer
   
   dim as TIMER_CTX ptr ctx
   
   ctx = allocate( len( TIMER_CTX ) )
   
   ctx->state     = TIMER_STATE_STOPPED
   ctx->interval = interval
   ctx->callback = callback
   ctx->userdata = userdata
   ctx->cond     = condcreate( )
   ctx->thread   = threadcreate( @timer_thread, cint( ctx ) )
   
   function = cint( ctx )

end function

'':::::
sub timeron( _
           byval id as integer _
         )
   
   dim ctx as TIMER_CTX ptr = cast( TIMER_CTX ptr, id )
   
   if( ctx = 0 ) then
      exit sub
   end if
   
   if( ctx->state = TIMER_STATE_KILLED ) then
      exit sub
   end if
      
   ctx->state = TIMER_STATE_RUNNING
   condsignal( ctx->cond )

end sub

'':::::
sub timeroff( _
           byval id as integer _
         )
   
   dim ctx as TIMER_CTX ptr = cast( TIMER_CTX ptr, id )
   
   if( ctx = 0 ) then
      exit sub
   end if

   if( ctx->state = TIMER_STATE_KILLED ) then
      exit sub
   end if

   ctx->state = TIMER_STATE_STOPPED

end sub

'':::::
sub timerdestroy( _
               byval id as integer _
             )
   
   dim ctx as TIMER_CTX ptr = cast( TIMER_CTX ptr, id )
   
   if( ctx = 0 ) then
      exit sub
   end if

   if( ctx->state = TIMER_STATE_KILLED ) then
      exit sub
   end if

   ctx->state = TIMER_STATE_EXITING
   
   condsignal( ctx->cond )
   threadwait( ctx->thread )         
   conddestroy( ctx->cond )
   
   ctx->state = TIMER_STATE_KILLED
   
   deallocate( ctx )
   
end sub


Code: Select all

'' test.bas
''
'' test for the timer library
''
'' to compile: fbc test.bas -mt
'' (compile timer.bas first, of course)
''

option explicit

#include once "timer.bi"

declare sub timer_handler ( byval id as integer )

   dim t1, t2, t3
   
   print "starting.."
   
   t1 = timercreate( 500, @timer_handler, 1 )
   t2 = timercreate( 5000, @timer_handler, 2 )
   t3 = timercreate( 10000, @timer_handler, 3 )
   
   timeron t1
   timeron t2
   timeron t3
   
   do
      print "(main loop)"
      sleep 1000
    loop until len( inkey ) > 0

   print "exiting.."
   
   timeroff t3
   timeroff t2
   timeroff t1
   timerdestroy t3
   timerdestroy t2
   timerdestroy t1
   
   end

'':::::
sub timer_handler ( byval id as integer )
   
   print "(timer:" & id & " handler)"
   
end sub
rdc
Posts: 1713
Joined: May 27, 2005 17:22
Location: Texas, USA
Contact:

Postby rdc » Mar 09, 2006 3:06

Ah, very cool and very useful too.
D.J.Peters
Posts: 7694
Joined: May 28, 2005 3:28

Postby D.J.Peters » Mar 09, 2006 3:34

Where are condcreate, condwait, condsignal , conddestroy documented?
I know only about mutex in FreeBASIC.

Joshy
v1ctor
Site Admin
Posts: 3798
Joined: May 27, 2005 8:08
Location: SP / Bra[s]il
Contact:

Postby v1ctor » Mar 09, 2006 5:17

Indeed, they are not documented yet, i didn't see that.

There's also CondBroadcast, may Angelo could give a description about each cond* function, they are that simple to use thanks to him.
yetifoot
Posts: 1710
Joined: Sep 11, 2005 7:08
Location: England
Contact:

Postby yetifoot » Mar 09, 2006 8:19

I was going to ask a couple of days ago what cond* where for, i saw them in the keyword list, but had never seen them in action.
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Postby JohnB » Mar 09, 2006 10:25

type TIMER_CALLBACK as sub( byval userdata as integer )


I do not understand the above line of code. Is this for 0.16. Can someone explain.

Thanks

JohnB
Antoni
Posts: 1393
Joined: May 27, 2005 15:40
Location: Barcelona, Spain

Postby Antoni » Mar 09, 2006 11:17

It's a pointer to a function, it has always been there...
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Mar 09, 2006 13:26

JohnB wrote:
type TIMER_CALLBACK as sub( byval userdata as integer )


I do not understand the above line of code. Is this for 0.16. Can someone explain.

Thanks

JohnB


heres a simpler application:

http://www.freebasic.net/forum/viewtopi ... highlight=
v1ctor
Site Admin
Posts: 3798
Joined: May 27, 2005 8:08
Location: SP / Bra[s]il
Contact:

Postby v1ctor » Mar 09, 2006 18:25

TYPE symbol AS datatype is used to create new types as typedef does in C, it can also handle forward declarations http://www.freebasic.net/wiki/wikka.php?wakka=KeyPgTypeDef.
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Postby JohnB » Mar 10, 2006 1:40

Thanks for the help and information. I keep looking in my local docs and not the FBWiki.

JohnB
DB1BMN
Posts: 3
Joined: Mar 08, 2006 21:17
Location: Germany
Contact:

Postby DB1BMN » Mar 11, 2006 21:46

Hm ok,

I`ve made it now to compile it. Seems to work.
But some things I do not understand. The main programm is so far clear, but why has the timer.bi to be included? Why can´t it be included while compiling the timer.bas?
But then, in the programm timer.bi, why there stands in line 9 #inclib "timer"? Why can a a programm, that ist compiled, include itself?
And why can´t it be run in "real" DOS-mode?

Sorry for my stupid-questions but I worked only with the MS QB.

bye, Marek
VirusScanner
Posts: 775
Joined: Jul 01, 2005 18:45

Postby VirusScanner » Mar 12, 2006 0:21

This timer example uses threads, something that DOS can't do apparently.

But then, in the programm timer.bi, why there stands in line 9 #inclib "timer"?

You shouldn't be compiling timer.bi, it's an include file not a program (bi = BASIC include)
Sisophon2001
Posts: 1702
Joined: May 27, 2005 6:34
Location: Cambodia, Thailand, Lao, Ireland etc.
Contact:

Postby Sisophon2001 » Mar 12, 2006 2:47

The code above is designed to be compiled as a library. Notice in the file timer.bas

'' to compile: fbc timer.bas –lib

This creates a library.

Timer.bas needs the types and defines from timer.bi, so it must be included. The linker directive to link the library

#inclib "timer"

is ignored when creating the library because when you create a library there is no linking anyway.

To use the library, you just need to but the library file where the linker will find it, and include the timer.bi file in the user code. You then have access to the functions in the timer library. When you compile the end user code, the new library will be linked correctly because of the #inclib "timer"

v1ctors half-joke about DOS is because DOS does not support multithreading, and therefore does not qualify as a modern OS.

Garvan
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Sep 03, 2008 2:16

Please see http://therealcha0s.net/fb/fb.timer.zip for an updated version of this library.
DesignDevil
Posts: 12
Joined: Aug 17, 2009 18:22
Contact:

Postby DesignDevil » Apr 14, 2010 20:21

Is there anywhere a update for this timer library?

The download adress ist not working and i can not compile the above version (i use Version 0.20.0 Beta)

thanks in advice

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 1 guest