Andy Gilbert Posted March 8, 2013 Share Posted March 8, 2013 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 Quote 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 More sharing options...
AggrorJorn Posted March 8, 2013 Share Posted March 8, 2013 Something like this? float float timer = 0; float eventTime = 5 //Main loop or update Update() { //Update timer timer += Time::GetSpeed(); //If the time is higher than the event time, trigger event and reset timer. if(time > eventTime) { DoEvent(); timer = 0; } } Quote Link to comment Share on other sites More sharing options...
Andy Gilbert Posted March 8, 2013 Author Share Posted March 8, 2013 Thanks Aggror, simple when you know how. Ill give this a go. Andy Quote 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 More sharing options...
Rick Posted March 8, 2013 Share Posted March 8, 2013 I'm thinking you might want to use Time::Millisecs() instead of Time::GetSpeed(). Quote Link to comment Share on other sites More sharing options...
AggrorJorn Posted March 8, 2013 Share Posted March 8, 2013 Ah yes that is what you need to use. GetSpeed is used to create the same value, no matter what the frames per second are. Quote Link to comment Share on other sites More sharing options...
Chris Vossen Posted March 9, 2013 Share Posted March 9, 2013 The Time class contains many handy functions. I'd use Time::GetCurrent local nextoccurrence = Time:GetCurrent() + 6000 (6000 milliseconds aka 6 seconds) if Time:GetCurrent() > nextoccurrence then nextoccurrence = Time:GetCurrent() + 6000 Do the function that you want every 6 seconds here end Quote Link to comment Share on other sites More sharing options...
Mumbles Posted March 9, 2013 Share Posted March 9, 2013 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 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; } Quote LE Version: 2.50 (Eventually) Link to comment Share on other sites More sharing options...
Mumbles Posted March 9, 2013 Share Posted March 9, 2013 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. Quote LE Version: 2.50 (Eventually) Link to comment Share on other sites More sharing options...
Recommended Posts
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.