Jan 1, 2013

IntervalTimer


Introduction
When programming a game you'll depend on timers heavily. Whether you have a damage effect, that needs to be calculated every x seconds, or a visual special effect to be controlled, you'll steer all that by adding time to variable and checking it against a limit.
Like with every work that gets repetitive, you'll get sloppy and you'll make mistakes.
And it's precicely for this reason that I wrote this class.

Description
It should have a constructor where you would have to declare the timeout in milliseconds you want to measure.
Then you would have to update it every game-cycle, giving it the current gameTime object. Its update method will do the appropriate math with the appropriate values hidden in the gameTime object and return true, if the timeout has been reached.
It has some convenience-properties, which you may use to determine the percentage of time passed, to determine the time that is still left, or to reset or change the interval itself.
You may use a defaulted field in the update method, if you wish to add the excess time, that was not used after "triggering" the timer, to the next run of the timer (in case you have some sort of a cyclic timer because otherwise you would just "lose" this excess time).
 
References

Interval<T>

Introduction
When programming a game or, frankly speaking, when programming anything, you will be confronted with intervals.
I remember reaching the point, where I began thinking about a separate class, when I was working on the particle engine. I had about 30 values to track per particle (velocity, starting position, rotation, acceleration...) and each one of them had an upper- and lower boundary. As I'm not paid per line of code, I searched for a way to somehow reduce the length and improve the readability of it (int minNumberOfParticles, maxNumberOfParticles; float minRotation, maxRotation...).
The Interval class is a handy way to produce shorter and more readable code while introducing a new level of consistency and, as I will explain right now, accuracy as well.
 
Accuracy
We don't always take care about it, but intervals don't only have upper- and lower bounds. They also have the property to include or exclude both bounds as well.
And when we have to take care about that, we almost certainly treat it differently each time.
 
Think about it. What do you mean by: "Pick a number between 0 and 100!".
It could be one of the following:

Most of the time we mean to include both boundaries, but we should be able to override that behavior.
 
The requirements
So we want a generic class that you may instantiate using
  • Only an upper and lower bound (you would use that constructor most of the time) and it would default the treatment of the boundaries as inclusive.
  • A full constructor, specifying the treatment of the boundaries as well
 
It should have convenience-methods:
  • IsInBetween, that takes a value and tells us if this given value lies within the interval
  • An overload of this method, specifying the treatment of the boundaries as well, overriding the given treatment, but only for this single call.
  • We would want it to adjust the values in a way, that the interval doesn't become irregular
    Consider you built one:
Interval<int> i = new Interval(3, 8);
And now we set the lower bound to 9. That may actually happen during the lifetime of such an object and it may happen the other way round as well. Our object should, without having any other useful information, do the most sensitive thing there is to do and automatically set the upper bound to 9 as well.
 
When we think about the functionality, we should restrict the generic type-usage of this class to the interface IComparable, which allows us to do all the proper comparisons.
 
The class/struct
After writing it I saw that I used it almost everywhere and since I was programming a game at the moment, the effort for the garbage collector was some concern. So I found that I could change it from a class to a struct (= no garbage collector overhead), without any side effects.
It doesn't change the way you use it at all.
 
The consequences
After using it for a while now I found that the usage of this class helps making my code a lot leaner.
For example it reduced the LOC of my Particle class almost to half and it reduced the number of overloads for a few different classes as well .
Think about a randomizer-class, that gives you a random number between two given values (which I was very lucky to have when trying to change my code to support several multiplayer modes... Deterministic Lockstep is the keyword... But that is another story waiting to be told).
 
References