Easily fixing the EndFrame function

A third, mercifully brief post on an alternate way to fix the EndFrame – upgrade the compiler! Spike posted that the daily builds of fteqcc fix this issue, and they’ve been hidden away at:

http://triptohell.info/moodles/fteqcc/

Apart from fixing the assign to field issues from the last post there seem to be some new features like type checking on function assignments, so go check it out. This lets us get rid of a lot of the workarounds from the bug investigation post, but since one of the bugs was in my code, the full working EndFrame code follows…

We have to modify existing code to implement all of this so it ends up spread out between files. Firstly replace the definition of spawn in defs.qc with

entity() spawn_builtin                = #14;
entity() spawn; //to be defined later

Then in world.qc add the following to the top

entity backstop;
void() EndFrame =
{
    // set ourselves up to think again next frame
    self.nextthink = 0.05;
    // prevent accidental modification of the backstop
    self = world;
    
   // demonstrate the function
   bprint("EndFrame call at time ");
   bprint(ftos(time));
   bprint("\n&");
}
entity() spawn =
{
    local entity e;
    e = spawn_builtin();
    if(nextent(e) != world)
        return e;
    // e is now the last entity on the list
    // so we need to swap it with the backstop
    local entity f;
    f = backstop;
    f.think = e.think;
    f.nextthink = e.nextthink;
    f.classname = e.classname;
    
    e.think = EndFrame;
    e.nextthink = 0.05;
    e.classname = "backstop";
    backstop = e;
    
    return f;
}
void() CreateBackstop =
{
    local entity e, f, head;
//begin our list with the temp backstop
    e = f = head = backstop;
// spawn() already contains the code to make a backstop
// so we just burn off enough entities that one appears
// at the back
    do
    {
        f = spawn();
        e.chain = f;
        e = e.chain;
    }
    while(nextent(backstop) != world);
    while(head != f)
    {
        e = head;
        head = e.chain;
        remove(e);
    };
}

Two modifications need to be made to existing functions. Firstly, at the very top of worldspawn() add backstop = spawn_builtin();. Because spawn() modifies the current backstop entity while initializing a new one, we will cause a crash if backstop is the world entity. Note that we haven’t yet initialized the backstop, because all of the map loaded entities are yet to spawn – we’re just preventing the crash if one of the spawnfunctions calls spawn() immediately. To perform the initialisation, add the following to the bottom of StartFrame():

    if(framecount == 1)
        CreateBackstop();

   bprint("StartFrame call at time ");
   bprint(ftos(time));
   bprint("\n");
Advertisements

2 thoughts on “Easily fixing the EndFrame function

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s