3
\$\begingroup\$

A piece of my program allows the looping and incrementing of a targeted entity to be used in a while loop somewhere else. Here is a sample of the while loop:

while (state.World.Looping(reqComponents))
{
    TimerComponent timer = state.World.GetComponent(TimerComponent.Type);

    if (timer.IsActive)
    {
        timer.TimeLeft -= gameTime.ElapsedGameTime.TotalSeconds;

        if (timer.IsFinished)
        {
            timer.IsActive = false;
        }
    }
}

Here is the actual loop function, which increments the current entity (which is grabbed by state.World.GetComponent():

public bool Looping(ComponentType reqComponents)
{
    if (!isLooping)
    {
        isLooping = true;
        CurrentEntity = 0;
    }
    else if (stopLooping)
    {
        isLooping = false;
        stopLooping = false;

        return false;
    }
    else if (++CurrentEntity == EntityCount - 1)
    {
        stopLooping = true;
    }

    if (!HasComponents(reqComponents))
    {
        return Looping(reqComponents);
    }

    return true;
}

The very top part of the Looping() feels really ugly to me. Is there a better way to do this?

\$\endgroup\$
2
\$\begingroup\$

Basically, this code controls everything except the body of the loop: initialization, increment, and destruction. This suggests that the actual while should be inside State.World.Looping, and it should take another parameter, an Action or equivalent delegate, which the caller should pass in. For instance, the call would be rewritten:

state.World.Looping(reqComponents, () =>
{
    TimerComponent timer = state.World.GetComponent(TimerComponent.Type);

    if (timer.IsActive)
    {
        timer.TimeLeft -= gameTime.ElapsedGameTime.TotalSeconds;

        if (timer.IsFinished)
        {
            timer.IsActive = false;
        }
    }
});

and Looping itself could be modified to:

public void Looping(ComponentType reqComponents, Action loopBody)
{
    if (!HasComponents(reqComponents))
    {
       return;
    }
    CurrentEntity = 0;

    do
    {
       loopBody();
    } while (++CurrentEntity != EntityCount - 1);
}

I think I got the number of iterations right but I'm not completely sure.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I really like this approach. I'm trying to think of a way for Looping() to not stop if it doesn't have the component. The original code increments the current entity if it doesn't have a component before returning. \$\endgroup\$ – Shane Aug 10 '14 at 3:53
0
\$\begingroup\$

It looks like you want to iterate though a sequence of items (in your case, components). So do that: create a method that returns a sequence of components (IEnumerable<Component>; yield return might be useful for that) that can be iterated using foreach, not some weird version of a while loop.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.