The Open-Source Game Development Pipeline

Providing the means and education to create games using free/libre open-source tools.


Leave a comment

To Thread, or Not to Thread… That is the Question

Hello, readers!

Today I’m going to discuss threading, and how it can affect the responsiveness of your application.

This topic was inspired by a comment made by a reader about my previous post. To sum it up, they wondered whether or not my game context was affected by potential latency caused by a “do/while” loop that was included inside of my audio code. Well… because of “threading”, it wasn’t!

So, what is threading… or, more importantly, what is a thread?

A thread is a unit of execution, usually containing a task (a set of instructions loaded into the computer’s memory) to be executed by the CPU. A thread is also a “scheduling” mechanism, which means that it is used to interface with an operating system’s scheduler. Threading guarantees that any task encapsulated by one will be added to the processor’s queue for immediate execution (sometimes simultaneously, which we call “concurrency”).

Tying this back into why it would be necessary for a “do/while” loop… how does threading enable my application to remain responsive? Well, let’s think about it.

Given the imperative nature of programs (A before B, B before C, etc.), if the application became stuck inside of a do/while loop, it would remain there until the loop finally exited. This would normally be true in a single-threaded environment.

If the function encapsulating the do/while loop were threaded, however, the application would be allowed to continue operating as it normally would, without having to worry about the looped task. This is especially useful for when certain actions need to be performed at the same time, like a punch sound firing off when a character’s “punching animation” connected with the bounding box of an enemy unit. Concurrency allows me to have my cake, and eat it too!

So, what is an example of threading? Here’s a POSIX routine that I’m using to test my audio library.

// The below is placed within the scope of my Game class.
pthread_t thread;
const char *audioFile = "test2.wav";
pthread_create(&thread, NULL, play2DAudio, (void*)audioFile);

“play2DAudio()” is a static function which has been passed into the “pthread_create()” method as a parameter for execution. This is the task that I want to be performed asynchronously.

void *play2DAudio(void* param){
    pthread_detach(pthread_self());
    const char *fn = (const char*)param;
    const char *media = MEDIA_DIRECTORY;
    char path[100];
    strcpy(path, media);
    strcat(path, fn);
    twoDAN = new TwoDAudioNode(path);
    twoDAN->play();
    pthread_exit(NULL);
}

As you can see, “play2DAudio()” takes the audioFile character string and uses it to load an audio file inside of a static instance of the “TwoDAudioNode” class. The reason this is threaded is so that loading & playing audio files (which may take a couple of cycles depending upon the size) doesn’t interfere with the Game class’ render/update loop.

Please note that only static methods and variables (unless locally declared) are able to be utilized by POSIX threads; members won’t make the cut! 😛

I don’t think one post will be suitable for covering this topic in its entirety, so consider this a little introduction to help get you started along the path of performance optimization. 🙂

If you have any questions, don’t hesitate to ask.

Cheers!

P.S. I’m currently learning Blender and how to animate with it. Once I get further along with my knowledge of 3D graphics, I’ll have an update on my C++ game framework.


2 Comments

A Code Snippet For You

Hello!

I’ve finished adding a feature to my game engine framework that I think will be useful for other developers to see the implementation of. It pertains to fading audio out over a set duration.

The code is as follows:

void AudioNode::fadeOut(float seconds){
  ALfloat srcVolume;
  alGetSourcef(this->source[0], AL_GAIN, &srcVolume);
  double rate = srcVolume / ((double)seconds * CLOCKS_PER_SEC);
int sleepRate = srcVolume / (seconds * 1000);
  do{
    srcVolume -= rate;
    this->setVolume(srcVolume);
  }while(srcVolume > 0.0f);
}

The algorithm took me a moment to put together, but basically, what you’re doing is taking the desired duration of the fade effect (to zero gain), multiplying it by the processor clocks per second, and then using it as the divisor of the original gain of the audio source.

Note that this code is implemented in C++ and utilizing OpenAL. You’ll need to import the OpenAL headers and the “time.h” header to achieve this effect. “setVolume()” is a method that contains the OpenAL API call for setting the gain of the audio source (which should be relatively easy to look up).

Hope this was useful! 🙂

Cheers.


Leave a comment

Debian 8 “Jessie” Released

Debian 8 has finally been released by the Debian Project. You can grab the release and read about the latest changes here. In accordance with their “Toy Story” naming scheme, the “testing” branch has been renamed to “Stretch”. I don’t know when I’ll make the switch (to the new testing environment), but will probably do so when it becomes feasible.

So, go grab a blank DVD if you’ve got one, because (so far), Debian seems to be the best Linux distro I’ve used. Most of the articles I’ve written are with respect to users who are creating games within the GNU/Linux userspace.

Cheers!