Jump to content

C++ Timer equivalent to C#/VB Timer


Recommended Posts

I'm coding in C++, trying to make a new mod, but some things might lag because, since I am using a while() to do all of the code, if one part of the code lags, I won't be able to press buttons or do anything, because that one thing is lagging. I have searched on Google and found some things, but they are either not what I am looking for or not detailed enough. Here is what a Timer would look like in C#:

public class BasicTickExample : Script {      public BasicTickExample() {         Interval = 5000;         this.Tick += new EventHandler(this.BasicTickExample_Tick);      }      private void BasicTickExample_Tick(object sender, EventArgs e) {         //Do code      }   }

And in VB:

 

Public Class BasicTickExample   Inherits Script   Public Sub New()      Me.Interval = 5000   End Sub   Private Sub BasicTickExample_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Tick      'Do code   End SubEnd Class

Can anyone help me on finding out what the equivalent of this is in C++? Is this even possible in C++? I would greatly appreciate it an answer.

 

P.S. If you think there is a better website to post this on, could you please direct me towards it? I thought this would be a good website to post this on, because people here are very smart, and I'm going to be using this code for GTA IV mods.

 

Thanks!

Edited by LetsPlayOrDy
Link to comment
https://gtaforums.com/topic/685732-c-timer-equivalent-to-cvb-timer/
Share on other sites

#include <Windows.h>#include <stdio.h>typedef void (*Timer_Callback)();class CTimer{private:	Timer_Callback m_callback;	unsigned int m_msInterval;	HANDLE m_hThread;	bool m_bStarted;	static DWORD WINAPI InternalThread(LPVOID pParam)	{		CTimer * pTimer = (CTimer*)pParam;		if(pTimer)		{			while(true)			{				pTimer->m_callback();				Sleep(pTimer->m_msInterval); /* Not 100% accurate ~ 15ms*/			}		}		return 0;	};public:	CTimer()	{		m_hThread = 0;		m_callback = 0;		m_msInterval = 1000; /* Set default interval to 1 second */		m_bStarted = false;	}	CTimer(Timer_Callback callback, unsigned int msInterval)	{		m_callback = callback;		m_msInterval = msInterval;		m_bStarted = false;	}	~CTimer()	{		Stop();	}	void SetCallback(Timer_Callback callback)	{		m_callback = callback;	}	/* Set the interval in milliseconds */	void SetInterval(unsigned int msInterval)	{		m_msInterval = msInterval;	}	void Start()	{		if(!m_bStarted)			m_hThread = CreateThread(NULL, NULL, InternalThread, (LPVOID)this, 0, 0);		m_bStarted = true;	}	void Stop()	{		if(m_bStarted)			TerminateThread(m_hThread, 0);		m_bStarted = false;	}};DWORD lastPrint = 0;void TimerCallback(){	static int runs = 0;	runs++;	printf("Hello %i\n", GetTickCount() - lastPrint);	lastPrint = GetTickCount();}int main(){	CTimer timer(TimerCallback, 1000);	timer.Start();	getchar();	timer.Stop();	getchar();	return 1;}

I think this is what you want. In C++11 this would be easier but I dont know if your compiler supports it so this is C++98.

I just wrote this in 5 mins.

Edited by XForceP

 

#include <Windows.h>#include <stdio.h>typedef void (*Timer_Callback)();class CTimer{private:	Timer_Callback m_callback;	unsigned int m_msInterval;	HANDLE m_hThread;	bool m_bStarted;	static DWORD WINAPI InternalThread(LPVOID pParam)	{		CTimer * pTimer = (CTimer*)pParam;		if(pTimer)		{			while(true)			{				pTimer->m_callback();				Sleep(pTimer->m_msInterval); /* Not 100% accurate ~ 15ms*/			}		}		return 0;	};public:	CTimer()	{		m_hThread = 0;		m_callback = 0;		m_msInterval = 1000; /* Set default interval to 1 second */		m_bStarted = false;	}	CTimer(Timer_Callback callback, unsigned int msInterval)	{		m_callback = callback;		m_msInterval = msInterval;		m_bStarted = false;	}	~CTimer()	{		Stop();	}	void SetCallback(Timer_Callback callback)	{		m_callback = callback;	}	/* Set the interval in milliseconds */	void SetInterval(unsigned int msInterval)	{		m_msInterval = msInterval;	}	void Start()	{		if(!m_bStarted)			m_hThread = CreateThread(NULL, NULL, InternalThread, (LPVOID)this, 0, 0);		m_bStarted = true;	}	void Stop()	{		if(m_bStarted)			TerminateThread(m_hThread, 0);		m_bStarted = false;	}};DWORD lastPrint = 0;void TimerCallback(){	static int runs = 0;	runs++;	printf("Hello %i\n", GetTickCount() - lastPrint);	lastPrint = GetTickCount();}int main(){	CTimer timer(TimerCallback, 1000);	timer.Start();	getchar();	timer.Stop();	getchar();	return 1;}
I think this is what you want. In C++11 this would be easier but I dont know if your compiler supports it so this is C++98.

I just wrote this in 5 mins.

I think that is what I'm wanting. I'll have to test when I get home. I can't believe you can write that in 5 minutes XD! Thanks for your help, even if it is not what I'm looking for. I'll keep ya guys updated. :)

Tried that code. At least for me it isn't doing anything. I put a PrintStringWithLiteralStringNow in the TimerCallback function, and when I start GTA up, nothing shows up. Also I didn't put the 'CTimer timer(TimerCallback, 1000); timer.Start();' in 'int main()' because I'm coding in a class library and not a console application. I instead put it into a function that runs once at the start-up. Or maybe I'm just a noob at this and you there is 'int main()' in a class library, idk though. Am I doing something wrong? Something I need to change or something? My code is exactly the same as above (for the timer, not my whole mod) but with the above exceptions.

 

EDIT: Just changed the code. It only runs the code once I believe, any way I can change that?


oh u wanted an actual timer class, thought u just wanted to run a tick method

Forgot to reply earlier lol. No I know how to run a tick method, I just want multiple Timers (or tick methods, whatever you guys call 'em) to run at the same time. Makes it so if one thing isn't working in one timer, I'll still be able to do other stuff that is running in another. Hope that makes sense :D

Edited by LetsPlayOrDy
LordOfTheBongs

Tried that code. At least for me it isn't doing anything. I put a PrintStringWithLiteralStringNow in the TimerCallback function, and when I start GTA up, nothing shows up. Also I didn't put the 'CTimer timer(TimerCallback, 1000); timer.Start();' in 'int main()' because I'm coding in a class library and not a console application. I instead put it into a function that runs once at the start-up. Or maybe I'm just a noob at this and you there is 'int main()' in a class library, idk though. Am I doing something wrong? Something I need to change or something? My code is exactly the same as above (for the timer, not my whole mod) but with the above exceptions.

 

EDIT: Just changed the code. It only runs the code once I believe, any way I can change that?

oh u wanted an actual timer class, thought u just wanted to run a tick method

Forgot to reply earlier lol. No I know how to run a tick method, I just want multiple Timers (or tick methods, whatever you guys call 'em) to run at the same time. Makes it so if one thing isn't working in one timer, I'll still be able to do other stuff that is running in another. Hope that makes sense :D

just get the gametimer and make your own intervals... u dont need a timer class, if u want start and stop options, use a bool... if u need multiple timers, make multiple intervals, multiple start bools and multiple if blocks...

 

30 seconds :catspider: lol

uint interval = 3000;uint startGameTime;bool isRunning;void CustomThread::StartTimer(){    if (isRunning) return;    GetGameTimer(&startGameTime);    isRunning = true;}void CustomThread::StopTimer(){    isRunning = false;}void CustomThread::ResetTimer(){    GetGameTimer(&startGameTime);}void CustomThread::RunTick(){    uint currentGameTime;    GetGameTimer(&currentGameTime);     if (isRunning && currentGameTime - startGameTime > interval)    {        startGameTime = currentGameTime;       //this will run every 3 seconds about when started    }}
Edited by LordOfTheBongs

 

Tried that code. At least for me it isn't doing anything. I put a PrintStringWithLiteralStringNow in the TimerCallback function, and when I start GTA up, nothing shows up. Also I didn't put the 'CTimer timer(TimerCallback, 1000); timer.Start();' in 'int main()' because I'm coding in a class library and not a console application. I instead put it into a function that runs once at the start-up. Or maybe I'm just a noob at this and you there is 'int main()' in a class library, idk though. Am I doing something wrong? Something I need to change or something? My code is exactly the same as above (for the timer, not my whole mod) but with the above exceptions.

 

EDIT: Just changed the code. It only runs the code once I believe, any way I can change that?

 

oh u wanted an actual timer class, thought u just wanted to run a tick method

 

Forgot to reply earlier lol. No I know how to run a tick method, I just want multiple Timers (or tick methods, whatever you guys call 'em) to run at the same time. Makes it so if one thing isn't working in one timer, I'll still be able to do other stuff that is running in another. Hope that makes sense :D

 

just get the gametimer and make your own intervals... u dont need a timer class, if u want start and stop options, use a bool... if u need multiple timers, make multiple intervals, multiple start bools and multiple if blocks...

 

30 seconds :catspider: lol

 

uint interval = 3000;uint startGameTime;bool isRunning;void CustomThread::StartTimer(){    if (isRunning) return;    GetGameTimer(&startGameTime);    isRunning = true;}void CustomThread::StopTimer(){    isRunning = false;}void CustomThread::ResetTimer(){    GetGameTimer(&startGameTime);}void CustomThread::RunTick(){    uint currentGameTime;    GetGameTimer(&currentGameTime);     if (isRunning && currentGameTime - startGameTime > interval)    {        startGameTime = currentGameTime;       //this will run every 3 seconds about when started    }}

Nah you don't get it. If you have two tick methods using if's, if one of the functions takes 10 seconds to complete, all the other code is not ran until after that 10 seconds is finished. This is a problem with things that need to be done very fast. Is there another way?

LordOfTheBongs

 

 

Tried that code. At least for me it isn't doing anything. I put a PrintStringWithLiteralStringNow in the TimerCallback function, and when I start GTA up, nothing shows up. Also I didn't put the 'CTimer timer(TimerCallback, 1000); timer.Start();' in 'int main()' because I'm coding in a class library and not a console application. I instead put it into a function that runs once at the start-up. Or maybe I'm just a noob at this and you there is 'int main()' in a class library, idk though. Am I doing something wrong? Something I need to change or something? My code is exactly the same as above (for the timer, not my whole mod) but with the above exceptions.

 

EDIT: Just changed the code. It only runs the code once I believe, any way I can change that?

oh u wanted an actual timer class, thought u just wanted to run a tick method

Forgot to reply earlier lol. No I know how to run a tick method, I just want multiple Timers (or tick methods, whatever you guys call 'em) to run at the same time. Makes it so if one thing isn't working in one timer, I'll still be able to do other stuff that is running in another. Hope that makes sense :D
just get the gametimer and make your own intervals... u dont need a timer class, if u want start and stop options, use a bool... if u need multiple timers, make multiple intervals, multiple start bools and multiple if blocks...

 

30 seconds :catspider: lol

 

uint interval = 3000;uint startGameTime;bool isRunning;void CustomThread::StartTimer(){    if (isRunning) return;    GetGameTimer(&startGameTime);    isRunning = true;}void CustomThread::StopTimer(){    isRunning = false;}void CustomThread::ResetTimer(){    GetGameTimer(&startGameTime);}void CustomThread::RunTick(){    uint currentGameTime;    GetGameTimer(&currentGameTime);     if (isRunning && currentGameTime - startGameTime > interval)    {        startGameTime = currentGameTime;       //this will run every 3 seconds about when started    }}

Nah you don't get it. If you have two tick methods using if's, if one of the functions takes 10 seconds to complete, all the other code is not ran until after that 10 seconds is finished. This is a problem with things that need to be done very fast. Is there another way?

 

 

Oh no i get it ;)

 

sounds like u dont get it lol :) ...why would u block your entire script instead of allowing script to loop??

 

why would anything be delayed for 10 seconds unless u write code that only works in a straight line??

 

Again, there is a game timer and u can get the time whenever u want... u dont block your script for 10 seconds if ur script needs to do stuff... start the action that takes 10 seconds, record the start time and block only the specific action from occuring on future loops by checking game time against start time thus allowing the rest of the script to loop (exactly what my sample does and it can be edited to do this multiple times in the same tick method) ... ever wonder why while loops need waits to prevent game freezing??? So the game can process other scripts and come back to your script later because when u say to wait u tell it to block your script on future loops of the script thread for a specified amount of time :catspider: All scripts run on a single script thread apparently.

 

... u need to code your script in same way if u need stuff working while other stuff in the script is processing... when stuff needs to wait u just block it and allow script to loop just like the game blocks your script and allows other scripts to loop... This is how the game handles when u say to wait. if u sleep your script then it sleeps and that means it isnt gonna do anything until it wakes up ;)

 

the functionality i wrote could be made into it's own class but it is such a basic thing it really just needs a couple uints and a bool, then u just gotta know how to arrange code in a tick loop

 

so like i said, u want multiple timers, u do what i did multiple times... interval1,2,3 etc startGameTime1,2,3 etc isRunning1,2.3 etc

uint interval1 = 3000, interval2 = 10000, interval3 = 60000;uint startGameTime1, startGameTime2, startGameTime3;bool isRunning1, isRunning2, isRunning3; void CustomThread::StartTimer(int timer){    switch (timer)    {        case 1:            if (isRunning1) return;                GetGameTimer(&startGameTime1);            isRunning1 = true;            break;        case 2:            if (isRunning2) return;                GetGameTimer(&startGameTime2);            isRunning2 = true;            break;        case 3:            if (isRunning3) return;                GetGameTimer(&startGameTime3);            isRunning3 = true;            break;    }}void CustomThread::StopTimer(int timer){    switch (timer)    {        case 1:            isRunning1 = false;            break;        case 2:            isRunning2 = false;            break;        case 3:            isRunning3 = false;            break;    }}void CustomThread::ResetTimer(int timer){    switch (timer)    {        case 1:            GetGameTimer(&startGameTime1);            break;        case 2:            GetGameTimer(&startGameTime2);            break;        case 3:            GetGameTimer(&startGameTime3);            break;    }} void CustomThread::RunTick(){    uint currentGameTime;    GetGameTimer(&currentGameTime);    if (isRunning1 && currentGameTime - startGameTime1 > interval1)    {        startGameTime1 = currentGameTime;       //this will run every 3 seconds about when started    }    GetGameTimer(&currentGameTime);    if (isRunning2 && currentGameTime - startGameTime2 > interval2)    {        startGameTime2 = currentGameTime;       //this will run every 10 seconds about when started    }    GetGameTimer(&currentGameTime);    if (isRunning3 && currentGameTime - startGameTime3 > interval3)    {        startGameTime3 = currentGameTime;       //this will run every 60 seconds about when started    }}
Edited by LordOfTheBongs

ok I know why my code runs only once if you use it you have to keep in mind that if you create a variable CTimer timer; in a function then it will only in that function scope.

So if the functions ends the object timer will be destroyed and the timer will stop. To make it work put CTimer m_Timer as a class memeber in your class. and on startup you can

Set the callback and the interval and then start the timer. So If its a class member the scope is the livetime of the class object so it will be destroyed when the class object in which the member is will be destroyed.

ok I know why my code runs only once if you use it you have to keep in mind that if you create a variable CTimer timer; in a function then it will only in that function scope.

So if the functions ends the object timer will be destroyed and the timer will stop. To make it work put CTimer m_Timer as a class memeber in your class. and on startup you can

Set the callback and the interval and then start the timer. So If its a class member the scope is the livetime of the class object so it will be destroyed when the class object in which the member is will be destroyed.

I'm pretty sure that I did not put it in a function. I just started it in a function. I've basically given up on this. Too much C++ for me to understand anyways lol. I'm a C# guy but I like the power with C++ >:) Edited by LetsPlayOrDy
LordOfTheBongs

 

ok I know why my code runs only once if you use it you have to keep in mind that if you create a variable CTimer timer; in a function then it will only in that function scope.

So if the functions ends the object timer will be destroyed and the timer will stop. To make it work put CTimer m_Timer as a class memeber in your class. and on startup you can

Set the callback and the interval and then start the timer. So If its a class member the scope is the livetime of the class object so it will be destroyed when the class object in which the member is will be destroyed.

I'm pretty sure that I did not put it in a function. I just started it in a function. I've basically given up on this. Too much C++ for me to understand anyways lol. I'm a C# guy but I like the power with C++ > :)

 

what power does c++ have?

 

 

ok I know why my code runs only once if you use it you have to keep in mind that if you create a variable CTimer timer; in a function then it will only in that function scope.

So if the functions ends the object timer will be destroyed and the timer will stop. To make it work put CTimer m_Timer as a class memeber in your class. and on startup you can

Set the callback and the interval and then start the timer. So If its a class member the scope is the livetime of the class object so it will be destroyed when the class object in which the member is will be destroyed.

 

I'm pretty sure that I did not put it in a function. I just started it in a function. I've basically given up on this. Too much C++ for me to understand anyways lol. I'm a C# guy but I like the power with C++ > :)

 

what power does c++ have?... on GTA IV.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • 0 User Currently Viewing
    0 members, 0 Anonymous, 0 Guests

×
×
  • Create New...

Important Information

By using GTAForums.com, you agree to our Terms of Use and Privacy Policy.