Jump to content
  • Advertisement
too_many_stars

Algorithm Limited life time object from a function

Recommended Posts

Good Afternoon Everyone,

I am reading over "Game Engine Architecture" by Jason Gregory and my question involves the Debug example on page 377.

In the book, there's a class like so...

class DebugDrawManager{

	void AddLine( /*normal line params*/, float duration);


};

g_DebugDrawMgr; //global access to debug draw manager

And the example is used thus

void Vehicle::Update(){

	g_debugDrawMgr.AddLine(/*line params*/, 1000.0f /*duration now is 1000 ms*/);

}

My question is, since a game runs in an infinite while loop, how is it possible to draw a line, say with a duration of 1000 ms, and then upon the next frame, in the same update function, not push_back another instance of another line with a duration of 1000ms.

In another piece of code, we might have something like this

void Person::Update(){

	g_debugDrawMgr.AddLine(/*line params*/, 50000.0f /*duration now is 50000 ms*/);

}

We have the same problem. Some kind of line struct is getting pushed every update step with a life duration of 5000ms.

Does anyone know how such a function works under the hood?

Thanks again,

Mike

Share this post


Link to post
Share on other sites
Advertisement
13 minutes ago, too_many_stars said:

My question is, since a game runs in an infinite while loop, how is it possible to draw a line, say with a duration of 1000 ms, and then upon the next frame, in the same update function, not push_back another instance of another line with a duration of 1000ms.

If you're drawing a new line every frame (e.g. a line that shows which enemy your missile launcher is locked on to) then set the duration to 0. 

If you're drawing a one-off line that you want to linger for a second so that you can see it (e.g. a line that shows the path by a a bullet which exists for a single frame) then you use a large lifetime value like 1000ms.

Share this post


Link to post
Share on other sites

Thanks for the reply Hodgman. I do understand that part of it. What I don't understand is this.

Say I want render a line for 1000ms so the following happens on the main game loop...

Frame 1: g_debugDrawMgr.AddLine(/*line params*/, 1000.0f);

So on frame 1 a line object with 1000ms duration is added to (probably a vector) some batch and rendered. After 1000ms, this line object is destroyed.

The game loop continues...

Frame 2: g_debugDrawMgr.AddLine(/*line params*/, 1000.0f);

On the second frame, another line object with 1000ms duration is added to the same container, and rendered. After 1000ms, this second line object is destroyed.

As long as the game loop is running, each call to the function g_debugDrawMgr.AddLine will keeping pushing line objects without pause.

So my question is this.

How does the function g_debugDrawMgr.AddLine create a line object just once per function call with a duration without constantly creating more objects per draw call.

Mike

 

 

Share this post


Link to post
Share on other sites

At the risk of stating the obvious, is the answer not in the book, or accompanying source code?

If not, then your question should really be how do I draw a series of lines in such and such an API? There's really very little to go on here, unless someone else has read / written the book.

Share this post


Link to post
Share on other sites
2 hours ago, too_many_stars said:

How does the function g_debugDrawMgr.AddLine create a line object just once per function call with a duration without constantly creating more objects per draw call.

I assume it does create many equal line objects then, and just the timer differs.

One could use something like a hash on line coords to prevent this, but if you do as Hodgman said, there is no need for such complexity. You only know if you see the source code.

Personally i do not use timers here - i just draw every frame, so the timers are an interesting idea for me, but i don't think timers are necessary or very useful.

But i want to be able to display at least numbers within debug display. Without a need for font crap. So if anyone knows a piece of code that draws numbers in a simple fashion like primitive LCD displays from the 90s, let me know. I'm too lazy to do it myself :)

Share this post


Link to post
Share on other sites

It's now occurred, are you actually asking how to implement the timers rather than the lines (your question is unclear)?

Here is a really bad bug ridden naive unoptimal pseudo-example:

struct TimedObject
{
  void DoSomething() {print("hello\n");}
  unsigned int timeout;
}

MyVector<TimedObject> g_Objects;

void AddTimed(unsigned int uiDurationMS)
{
  TimedObject * pObj = g_Objects.Request();
  pObj->timeout = GetTime() + uiDurationMS;
}

void Update()
{
 // timed out?
 unsigned int uiTime = GetTime();
 for (int n=g_Objects.Size()-1; n>=0; n--)
 {
   if (uiTime >= g_Objects[n].timeout)
	g_Objects.DeleteItem(n);
   else
	g_Objects[n].DoSomething(); 
 }
}

Edit: This is very unoptimal, there are probably loads of cool strategies for dealing with this. E.g. keeping the list sorted by timeout, something like that to avoid lots of memcpying, or simply creating a duplicate new version of the list on each update, depending on your usage needs.

Before going any further I think OP really needs to make clearer what is the question, I can immediately see three interpretations.

Edited by lawnjelly

Share this post


Link to post
Share on other sites
13 hours ago, lawnjelly said:

At the risk of stating the obvious, is the answer not in the book, or accompanying source code?

If not, then your question should really be how do I draw a series of lines in such and such an API? There's really very little to go on here, unless someone else has read / written the book.

There's no code for it in the book, the blurb says "The debug drawing API in Naughty Dog's Uncharted: Drake's Fortune engine looks something like this."

 

13 hours ago, JoeJ said:

I assume it does create many equal line objects then, and just the timer differs.

One could use something like a hash on line coords to prevent this, but if you do as Hodgman said, there is no need for such complexity. You only know if you see the source code.

Personally i do not use timers here - i just draw every frame, so the timers are an interesting idea for me, but i don't think timers are necessary or very useful.

But i want to be able to display at least numbers within debug display. Without a need for font crap. So if anyone knows a piece of code that draws numbers in a simple fashion like primitive LCD displays from the 90s, let me know. I'm too lazy to do it myself :)

I thought about the hash example. I am just not sure how efficient it would be before ever draw call to check if the object is in the map. Especially if there are hundreds or thousands of objects to debug.

12 hours ago, lawnjelly said:

It's now occurred, are you actually asking how to implement the timers rather than the lines (your question is unclear)?

Here is a really bad bug ridden naive unoptimal pseudo-example:


struct TimedObject
{
  void DoSomething() {print("hello\n");}
  unsigned int timeout;
}

MyVector<TimedObject> g_Objects;

void AddTimed(unsigned int uiDurationMS)
{
  TimedObject * pObj = g_Objects.Request();
  pObj->timeout = GetTime() + uiDurationMS;
}

void Update()
{
 // timed out?
 unsigned int uiTime = GetTime();
 for (int n=g_Objects.Size()-1; n>=0; n--)
 {
   if (uiTime >= g_Objects[n].timeout)
	g_Objects.DeleteItem(n);
   else
	g_Objects[n].DoSomething(); 
 }
}

Edit: This is very unoptimal, there are probably loads of cool strategies for dealing with this. E.g. keeping the list sorted by timeout, something like that to avoid lots of memcpying, or simply creating a duplicate new version of the list on each update, depending on your usage needs.

Before going any further I think OP really needs to make clearer what is the question, I can immediately see three interpretations.

You are right,  I did stumble through the question. My apologies.

A better way to phrase it might be "How does one create a single timed object per function call in an infinite loop."

Mike

Share this post


Link to post
Share on other sites

Typically you don't have the line drawn every frame, that was merely an example.  Typically you have the debug line triggered by another event.  So, if you say bind F5 to fire off a line showing each objects orientation or through menus is more common using something like imGUI.  It then creates the line using a set duration of time.

@lawnjelly "Game Engine Architecture" by Jason Gregory is like the go to book for reading up on engine architecture, likely hundreds if not thousands of people have read the book cover to cover 😉  Including many on this very site.  It's a very good book that I cannot recommend enough, even just for a general read if you have no intention of ever writing an engine yourself just for general knowledge of how they typically work and how the parts typically interact.  It's an overview book, not a how-to really though in my opinion.  Just an FYI.

Share this post


Link to post
Share on other sites
19 hours ago, too_many_stars said:

Say I want render a line for 1000ms so the following happens on the main game loop...

Frame 1: g_debugDrawMgr.AddLine(/*line params*/, 1000.0f);

So on frame 1 a line object with 1000ms duration is added to (probably a vector) some batch and rendered. After 1000ms, this line object is destroyed.

 The game loop continues...

 Frame 2: g_debugDrawMgr.AddLine(/*line params*/, 1000.0f);

 On the second frame, another line object with 1000ms duration is added to the same container, and rendered. After 1000ms, this second line object is destroyed.

 As long as the game loop is running, each call to the function g_debugDrawMgr.AddLine will keeping pushing line objects without pause.

So my question is this.

How does the function g_debugDrawMgr.AddLine create a line object just once per function call with a duration without constantly creating more objects per draw call.

 

If you want to add a line once (not once per frame) then you only call AddLine once (not once per frame)?

Share this post


Link to post
Share on other sites
On 2/7/2019 at 10:21 AM, too_many_stars said:

My question is, since a game runs in an infinite while loop, how is it possible to draw a line, say with a duration of 1000 ms, and then upon the next frame, in the same update function, not push_back another instance of another line with a duration of 1000ms.

On the surface this makes no sense. Are you actually using code like what you posted, and does it work as you've said, only adding one line? Why would you put code in a loop that you didn't want to be called every iteration? Seems like all the timer stuff is just a red herring here.

Share this post


Link to post
Share on other sites

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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!