Jump to content

simlple timer?


Andy Gilbert
 Share

Recommended Posts

I know this might come down to some simple maths, but somtimes i just cant figure somthing out and find it better to ask :)

 

In either learkers 2 or 3 (preferrably 3) how would i achive a simple timer so that "somthing" happens either a function call or variable change would happen every N seconds or minutes?

 

Thanks

Andy

The good news about computers is that they do what you tell them to do. The bad news is that they do what you tell them to do.

 

Leadwerks Game-Ready 3D Models:https://sellfy.com/gib3d

Link to comment
Share on other sites

You want a timer that automatically calls a function when it reaches zero? That's soooo simple, all you need all you need is some uh, basic knowledge of multithreading and function pointers laugh.png

 

 

Basically, I have a struct that contains:

a number of milliseconds to run for,

a control bool to abort the timer (set it to false at any time, when the timer next hits zero, it won't do anything, and will instead end the thread)

a number of timer to run the timer, (0 for unlimited)

Then a function pointer to the function it will call

and a void pointer containing the parameters to pass to the function

 

 

Then there is a function called TimerThreadFunction, but you never call this yourself. When you call StartTimerThread, that will call _beginthreadex which spawns a new thread, the entry point (like your main() is TimerThreadFunction. It uses the struct (pass is by pointer) to determine how long it would wait for, which function it should run when finished, and how many times it should run the timer.

 

When it has run enough times (or if you set the stop timer value to true in your main loop), it will end the thread.

 

 

PrintToScreen() and ChangeVarVal are two different functions that the timers can use. The way I designed it, any void function with a void * parameter can be called by the timer thread. PrintToScreen shows the timer working totally multithreaded. ChangeVarVal just changes a bool value, and we check this value in the main loop, this is more suitable if for LE 2 commands, since you cannot call them inside another thread

 

 

Finally, there is the main function, which just shows it in action. First, it does PrintToScreen multithreaded, then it does ChangeVarVal single threaded, then it does PrintToScreen multithreaded again, but with an infinite count, and the main loop aborts the timer after a short time...

 

#include <iostream>
#include <process.h>
#include <windows.h>

struct ThreadLaunchArgs
{
   unsigned int WaitMillis;
   bool StopTimer;
   unsigned int RepeatCount; //0 = infinite... can only be stopped with the above bool
   void (*FuncToCall)(void *);
   void * FuncToCallArgs;
};

unsigned __stdcall TimerThreadFunction( void * ArgList )
{
   ThreadLaunchArgs * ArgsList = ( ThreadLaunchArgs * ) ArgList;

   if( ArgsList->RepeatCount != 0)
   {
       for ( unsigned int CurrentRepeat = 0 ; CurrentRepeat < ArgsList->RepeatCount ; CurrentRepeat += 1)
       {
           Sleep( ArgsList->WaitMillis );
           if ( !ArgsList->StopTimer )
               ArgsList->FuncToCall( ArgsList->FuncToCallArgs );
           else
               CurrentRepeat = ArgsList->RepeatCount;
       }
   }
   else
   {
       while ( !ArgsList->StopTimer )
       {
           Sleep( ArgsList->WaitMillis);
           if ( !ArgsList->StopTimer )
               ArgsList->FuncToCall( ArgsList->FuncToCallArgs );
       }
   }

   _endthreadex( 0 );
   return 0;
}

HANDLE StartTimerThread(ThreadLaunchArgs * TimerArgs)
{
   HANDLE hThread;
   unsigned threadID;
   hThread = (HANDLE)_beginthreadex( NULL, 0, &TimerThreadFunction, TimerArgs, 0, &threadID );
   return hThread;
}

void PrintToScreen ( void * MillisDelay )
{
   unsigned int * Value = (unsigned int *) MillisDelay;
   std::cout << "Fire and forget timer, with delay of " << *Value << " millis has expired!\n";
   return;
}

void ChangeVarVal ( void * Flag )
{
   bool * Value = (bool *) Flag;
   *Value = true;
   return;
}

int main( int argcn, char* argv[])
{
   unsigned int NumRepeats = 10, TimerMillis = 2000;
   ThreadLaunchArgs * TimerArgs = (ThreadLaunchArgs *) malloc (sizeof (ThreadLaunchArgs));

   TimerArgs->FuncToCall = &PrintToScreen;
   TimerArgs->FuncToCallArgs = &TimerMillis;
   TimerArgs->RepeatCount = NumRepeats;
   TimerArgs->StopTimer = false;
   TimerArgs->WaitMillis = TimerMillis;

   //Fire and forget timer - will automatically call the selected function when the timer expires
   HANDLE FirstTimerThreadHandle = StartTimerThread(TimerArgs);
   Sleep(5000);//Main thread does nothing for 30 seconds - notice how the console window still fills up
   //For 20 seconds, the counter will work, then for the next 10, nothing will happen.
   //You can make things interesting by sleeping for less timer, like only 5 seconds





   //Perhaps we don't want to work multithreaded... Maybe we are calling LE 2 commands, which won't work in another thread. We'll operate psuedo single threaded instead
   //The second thread will set a flag value. We check it in this thread's loop, and when it's true, we do "stuff"

   bool * TimerFlag = new bool();
   *TimerFlag = false;

   ThreadLaunchArgs * SecondTimerArgs = (ThreadLaunchArgs *) malloc (sizeof (ThreadLaunchArgs));

   SecondTimerArgs->FuncToCall = &ChangeVarVal;
   SecondTimerArgs->FuncToCallArgs = TimerFlag;
   SecondTimerArgs->RepeatCount = NumRepeats;
   SecondTimerArgs->StopTimer = false;
   SecondTimerArgs->WaitMillis = TimerMillis;

   unsigned int CurrentRepeatCount = 0;

   //Monitored timer - will still count but it will instead set a value that we must check in this thread
   HANDLE SecondTimerThreadHandle = StartTimerThread(SecondTimerArgs);
   while( CurrentRepeatCount < 10 )
   {
       if( *TimerFlag )
       {
           *TimerFlag = false;
           CurrentRepeatCount += 1;
           std::cout << "Monitored timer, with delay of " << TimerMillis << " millis has expired!\n";
       }
   }





   //In the final example, the timer repeats forever, and we stop it ourself with the bool value

   ThreadLaunchArgs * ThirdTimerArgs = (ThreadLaunchArgs *) malloc (sizeof (ThreadLaunchArgs));

   ThirdTimerArgs->FuncToCall = &PrintToScreen;;
   ThirdTimerArgs->FuncToCallArgs = &TimerMillis;
   ThirdTimerArgs->RepeatCount = NumRepeats;
   ThirdTimerArgs->StopTimer = false;
   ThirdTimerArgs->WaitMillis = TimerMillis;

   HANDLE ThirdTimerThreadHandle = StartTimerThread(ThirdTimerArgs);

   Sleep(20000);
   ThirdTimerArgs->StopTimer = true;




   WaitForSingleObject(FirstTimerThreadHandle,INFINITE);
   CloseHandle(FirstTimerThreadHandle); //It has a return value, but if it fails, just end the process anyway...

   WaitForSingleObject(SecondTimerThreadHandle,INFINITE);
   CloseHandle(SecondTimerThreadHandle);

   WaitForSingleObject(ThirdTimerThreadHandle,INFINITE);
   CloseHandle(ThirdTimerThreadHandle);

   delete TimerFlag;

   //These three could have been done better as an array, but it's just a "simple" example
   //As could the HANDLE variables for each thread
   free(ThirdTimerArgs);
   free(SecondTimerArgs);
   free(TimerArgs);

   return 0;
}

LE Version: 2.50 (Eventually)

Link to comment
Share on other sites

Source code if you really want it, but really, everything is in the one source file. It's all in the last post, but that scroll bar makes it a bit harder to read...

 

Minor typo, but not serious. the int main has it's first value of "int argcn". It shouldn't say 'n' at the end, but there's no way I'm editing that post, otherwise I'd have to format that big block of code all over again - no thanks.

LE Version: 2.50 (Eventually)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...