Quantcast

Jump to content

» «
Photo

C++ Timer equivalent to C#/VB Timer

13 replies to this topic
LetsPlayOrDy
  • LetsPlayOrDy

    Too fast for ya

  • Members
  • Joined: 24 Aug 2013
  • United-States

#1

Posted 19 February 2014 - 09:54 PM Edited by LetsPlayOrDy, 20 February 2014 - 03:01 AM.

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 Sub


End 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!


LordOfTheBongs
  • LordOfTheBongs

    Deceased

  • Members
  • Joined: 21 Sep 2013
  • None

#2

Posted 20 February 2014 - 03:03 AM Edited by LordOfTheBongs, 20 February 2014 - 06:06 PM.

void CustomThread::RunTick()

 

you can just override that method and use GetGameTimer


formel117
  • formel117

    Programmer

  • Members
  • Joined: 13 Jun 2013
  • None

#3

Posted 20 February 2014 - 05:05 AM

You could use GetTickCount in your C++ loop to create your own kind of timer by comparing the ticks since the last execution.


XForceP
  • XForceP

    C++ Evangelist

  • Members
  • Joined: 04 Sep 2013
  • Germany

#4

Posted 20 February 2014 - 07:54 AM Edited by XForceP, 20 February 2014 - 07:57 AM.

#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.


LetsPlayOrDy
  • LetsPlayOrDy

    Too fast for ya

  • Members
  • Joined: 24 Aug 2013
  • United-States

#5

Posted 21 February 2014 - 03:38 PM

#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. :)

LordOfTheBongs
  • LordOfTheBongs

    Deceased

  • Members
  • Joined: 21 Sep 2013
  • None

#6

Posted 21 February 2014 - 08:02 PM Edited by LordOfTheBongs, 21 February 2014 - 08:17 PM.

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


LetsPlayOrDy
  • LetsPlayOrDy

    Too fast for ya

  • Members
  • Joined: 24 Aug 2013
  • United-States

#7

Posted 24 February 2014 - 04:20 AM Edited by LetsPlayOrDy, 24 February 2014 - 04:30 AM.

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


LordOfTheBongs
  • LordOfTheBongs

    Deceased

  • Members
  • Joined: 21 Sep 2013
  • None

#8

Posted 24 February 2014 - 11:16 PM Edited by LordOfTheBongs, 24 February 2014 - 11:44 PM.

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
    }
}

LetsPlayOrDy
  • LetsPlayOrDy

    Too fast for ya

  • Members
  • Joined: 24 Aug 2013
  • United-States

#9

Posted 26 February 2014 - 05:47 PM

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
  • LordOfTheBongs

    Deceased

  • Members
  • Joined: 21 Sep 2013
  • None

#10

Posted 26 February 2014 - 06:05 PM Edited by LordOfTheBongs, 26 February 2014 - 11:46 PM.

 

 

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
    }
}

XForceP
  • XForceP

    C++ Evangelist

  • Members
  • Joined: 04 Sep 2013
  • Germany

#11

Posted 01 March 2014 - 06:18 PM

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.


LetsPlayOrDy
  • LetsPlayOrDy

    Too fast for ya

  • Members
  • Joined: 24 Aug 2013
  • United-States

#12

Posted 02 March 2014 - 04:06 AM Edited by LetsPlayOrDy, 02 March 2014 - 04:10 AM.

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++ >:)

LordOfTheBongs
  • LordOfTheBongs

    Deceased

  • Members
  • Joined: 21 Sep 2013
  • None

#13

Posted 02 March 2014 - 06:27 AM

 

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?


LetsPlayOrDy
  • LetsPlayOrDy

    Too fast for ya

  • Members
  • Joined: 24 Aug 2013
  • United-States

#14

Posted 02 March 2014 - 10:50 AM

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.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users