Spawn 2 enemies per second in OpenGL

I’m making a game in openGL and I want to spawn 2 enemies per second on the screen. The problem is, I’m calling the spawn function inside idle:

idle
{
    // ...
    world.spawnEnemy();
}

And then, in the spawnEnemy function:


void World::spawnEnemy()
{
    Enemy newEnemy, newEnemy2;

    float start;

    start = glutGet(GLUT_ELAPSED_TIME);

    // 1/2 a second passes
    while ( (glutGet(GLUT_ELAPSED_TIME) - start) <= 500 )
    {
        ;
    }

    // create enemy
    newEnemy();
    pushToEnemyList(newEnemy);

    // another 1/2 second passes
    while ( (glutGet(GLUT_ELAPSED_TIME) - start) <= 1000 )
    {
        ;
    }

    // create enemy
    newEnemy2();
    pushToEnemyList(newEnemy2);
}

And this is not working, of course. Probably because idle is called everytime and I’m calling a function inside idle that waits for a certain amount of time to pass and then everything starts going wrong. The solution is to do the spawning in the idle function (without calling any function, doing all the logic inside idle), but I don’t like this idea. I need to do more things in a certain number of time, for example, my enemies have guns and they will have to shoot n times every second. And if I do all of these directly inside of idle it will become a mess. So, basically, how do I make this work:


idle
{
    // ...
    world.spawnEnemy();
    world.enemyShoot();
    // another functionalities that depend on time
}

instead of this:


idle
{
   // ...
   // logic of spawnEnemy directly here in the idle function
   // logic of enemyShoot directly here in the idle function
   // logic of another functionalities that depend on time directly here in the idle function
}

The simplest solution is to use glutTimerFunc().

The other approach, if you know that the idle callback will be invoked regularly, is to implement your own timers there. The main thing is that if no actions are ready to be executed, just return from the idle function; don’t busy-wait until something is ready. It’s entirely possible that the value returned by glutGet(GLUT_ELAPSED_TIME) is only updated by the event loop; if that’s the case, busy-waiting on it within the idle callback will wait for ever.