Tuesday, July 3, 2012

Changing the name of an XCode project

A hit a small snag today when trying to rename an XCode project.
Pro tip: Don't change the name of your XCode project from anywhere outside of XCode.

Apparently XCode has some magic behind the scenes when it renames a project, which probably changes some references to the project internally. If you rename your project file from outside of XCode you will no longer be able to run your project.

To rename the project from within XCode, simply click on the project from the file view in the XCode IDE, and it will allow you to change the name, and additionally will give you the option to save a snapshot of the change in case you want to roll back.

Friday, June 8, 2012

Performance function/scope timers, for Windows

In my last post I showed you have to create an easy-to-use timer for Mac OSX programs that would calculate the time it took a function or scope to execute. Here's the Windows version I promised.

Here's the main.cpp:
// main.cpp
#include <iostream>

#include "PerfTimer.h"

void someFcn()
{
    CreateFcnTimer;
    
    for (unsigned int i = 0; i < 10000000; ++i )
    {
        int j = 5;
        ++j;
    }
}

int main(int argc, const char * argv[])
{
    {
        ScopeTimer("MyCustomScope");
        
        someFcn();
    }
    
    return 0;
}

And here's the timer class itself.
// PerfTimer.h
#pragma once
 
#include <iostream>
#include <windows.h>
 
class PerfTimer
{
public:
    PerfTimer(const char* timerName)
    {
        m_name = std::string(timerName);

 QueryPerformanceFrequency(&m_frequency);
         
        // Start the timer
        QueryPerformanceCounter(&m_startTime);
    }
     
    ~PerfTimer()
    {
        LARGE_INTEGER endTime;
 QueryPerformanceCounter(&endTime);
         
        // Output timer duration in milliseconds
        std::cout << m_name.c_str() << ": " << ((endTime.QuadPart - m_startTime.QuadPart) * 1000.0 / m_frequency.QuadPart) << std::endl;
    }
     
private:
    LARGE_INTEGER m_startTime;
    LARGE_INTEGER m_frequency;
    std::string m_name;
};
 
#ifndef SHIPPING_BUILD
 
    #define CreateFcnTimer PerfTimer __FUNCTION__timer(__FUNCTION__)
 
    // The 'x' in 'xtimer' is replaced by whatever string is passed into the scope timer
    // but the quotations are removed. So if the calling code is ScopeTimer("stuff")
    // then 'xtimer' becomes 'timerstuff'. This makes sure every timer name is unique
    // within the scoe it is used.
    #define ScopeTimer(x) PerfTimer xtimer(x)
 
#else
    // The timers can be shut off in shipping builds by replacing their standard
    // macros with these.
    #define CreateFcnTimer ((void)0)
    #define ScopeTimer(x) ((void)0)
 
#endif

The only difference between this Windows version and the Mac version is that you need to include Windows.h, and you have to query the frequency using QueryPerformanceFrequency, and factor the frequency into your calculations.

High performance function/scope timers, and some more macro love (Mac OS X)

Looking for a Windows version of this timer? It's in the following post, click here to go to it.

In my last post I talked about the fact that macros aren't always evil, and that reminded me of a function/scope timer I made for LEGO Universe, which took advantage of some fun macros. So today I'll show you how to create that timer.

This timer outputs its elapsed time whenever it leaves scope, so by using one at the beginning of your functions your can output how long a function call takes. Or you can use one anywhere else where a scope if defined.

Below is the main.cpp:

// main.cpp
#include <iostream>
#include <math.h>

#include "PerfTimer.h"

void someFcn()
{
    CreateFcnTimer;
    // someFcn timer is now in scope
    
    for (unsigned int i = 0; i < 10000000; ++i )
    {
        int j = sqrt(5);
        ++j;
    }
}

int main(int argc, const char * argv[])
{
    {
        ScopeTimer("MyCustomScope");
        // MyCustomScope timer is now in scope

        someFcn();
        // someFcn timer created by 'CreateFcnTimer' is now out of scope
    }
    // MyCustomScope timer is now out of scope
    
    return 0;
}

Inside of someFcn()you see a simple macro call: CreateFcnTimer; 
This macro creates a timer for us that will automatically output the name of the function and the time it took to execute it, it prints this information when the timer goes out of scope, which is immediately after the function is done executing.

Inside of main()you see a set of brackets used to create a scope, and within that scope we call a macro named ScopeTimer, and this time we give it whatever name we'd like, in this case it's "MyCustomScope". This timer goes out of scope when the scope that we defined with the brackets ends. You can use this technique to subdivide larger sections of code and time how long they take to execute.

The output from this program, when I ran it on my iMac was:

someFcn: 101.953
MyCustomScope: 102.08

The output is in milliseconds, but the timer is accurate down to 1 microsecond (1/1000th of a millisecond). You can see here that someFcn() was called within the unnamed scope we created in main(), and the timer within someFcn went out of scope after someFcn() finished executing, and then "MyCustomScope" went out of scope soon after. The results here show us that it takes about 102.08 milliseconds to loop 10 million times and create an integer on the stack, set it to the square root of 5, increment it, then remove it from the stack, during each loop. The results from the scope timer show that someFcn()'s code took up most of the time, and the remaining 0.127 milliseconds was for the call to someFcn(), the function timer within, and then exit someFcn(). We can deduce this because the 102.08 milliseconds recorded by the function timer began after the function timer was already created and the call to someFcn had been made and was already in progress. 0.127 seems like a lot, most of that time is in the creation of the timer within someFcn and the outputting of timer info to the console, not for the function call. If function calls took 0.127 milliseconds then computers would be performing like they were about 35 years ago.

Here's the version of the performance timer that will run on Mac OSX. In my next post I will post the code for Windows. I'm not trying to draw this out into two posts, it's just really late and I haven't written and tested the Windows version yet (the difference will be only in the timer class internally used).


// PerfTimer.h
#pragma once

#include <iostream>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <unistd.h>

class PerfTimer
{
public:
    PerfTimer(const char* timerName)
    {
        m_name = std::string(timerName);
        
        // Start the timer
        m_startTime = mach_absolute_time();
    }
    
    ~PerfTimer()
    {
        uint64_t endTime = mach_absolute_time();
        uint64_t elapsed = (endTime - m_startTime);
    
        static mach_timebase_info_data_t sTimebaseInfo;
        if ( sTimebaseInfo.denom == 0 )
        {
            mach_timebase_info(&sTimebaseInfo);
        }
        
        uint64_t elapsed_nano = elapsed * sTimebaseInfo.numer / sTimebaseInfo.denom;
        
        // Output timer duration in milliseconds
        std::cout << m_name.c_str() << ": " << elapsed_nano / 1000000.0 << " milliseconds" << std::endl;
    }
    
private:
    uint64_t m_startTime;
    std::string m_name;
};

#ifndef SHIPPING_BUILD

    #define CreateFcnTimer PerfTimer __func__timer(__func__)

    // The 'x' in 'xtimer' is replaced by whatever string is passed into the scope timer
    // but the quotations are removed. So if the calling code is ScopeTimer("stuff")
    // then 'xtimer' becomes 'timerstuff'. This makes sure every timer name is unique
    // within the scoe it is used.
    #define ScopeTimer(x) PerfTimer xtimer(x)

#else
    // The timers can be shut off in shipping builds by replacing their standard
    // macros with these.
    #define CreateFcnTimer ((void)0)
    #define ScopeTimer(x) ((void)0)

#endif
First I'll explain how the timer itself works, then how the macros work. When the timer is constructed it records the name passed into the constructor so we can output it later, and then records the exact system time. Then, when it destructs it queries the system time, and then outputs the difference between the time it was constructed and destructed. The timer is basically a simple object that records when it is created and when it leaves scope or is destructed. The CreateFcnTimer macro works by creating a PerfTimer instance, and it names the variable the function name followed by the word 'timer'. This ensures that the name of the timer variable is fairly unique so it's unlikely to have collisions with other times you might use within the same scope. Also, the name of the function is the name passed into the constructor, and when the timer destructs it's that name that will output next to the time elapsed. The MyCustomScope macro is similar to CreateFcnTimer except that it does not use the function name automatically so you can name it whatever you choose. Similarly to CreateFcnTimer, it uses the name you pass into the macro to generate the name of the timer instance variable, so you would only have a conflict when using this macro if you happened to create another timer with the exact same name in the same scope.

And if you notice, I've used the technique from my previous post to ensure that these timers will not run on a shipping build, which would slow down your program a good amount with the creation of the timers and especially the console output of them.

Saturday, June 2, 2012

C++ Macros aren't completely evil, I promise

As a C++ programmer you'll undoubtedly hear of many macro horror stories. Macros can be easily abused, can bloat your program, and can be a debugging nightmare. But, macros are not completely evil, when used properly they can be clean and useful.

The other day I was updating a logging system. For those that don't know, a logging system (or logger) is usually a system created along side a program or engine that allows programmers to log messages, or errors, and to stream their output in different ways, like to a debug console, or to a file, or even an email in some rare cases (like a critical program failing in a bad way and a live product team needs to know immediately). Anyway, I was updating a logging system, and I needed two things that it did not yet offer:
  • I needed the parameters being logged to have no expense within the shipped product (the product that was in the customer's hands). 
    • Without macros there are ways people try to limit logging commands:
      • Multiple function definitions for your logging commands, the shipped version of these do nothing when called.
        #define SHIPPING_BUILD
        #include <iostream>
        
        


namespace logging


        {
        

#ifndef SHIPPING_BUILD
            void print( int i )


            {


                std::cout << i;


            }
        

#else


            void print ( int i ) { }
        

#endif
        

}
        
        


int expensiveFcnReturningAnInt()


        {
            // The compiler would actually optimize this so it would


            // be extremely cheap to call, but you get the idea, this


            // function would be something you don't want to happen


            // in a shipping build if used only for logging.

 
            return 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1;


        }
        
        


int main(int argc, const char * argv[])


        {


            logging::print( expensiveFcnReturningAnInt() );


        
            return 0;


        }
      • In the above example the expense of the logging itself is removed, there is nothing logged to the debug console, or written to a log file. But the main issue here, is that expensiveFcnReturningAnInt() was still called, which is expensive, completely unnecessary, and useless
    • With macros you can affect the code at compile time. In this example the logging statement will no longer even exist in the program for shipping builds.
      • #define SHIPPING_BUILD
        #include <iostream>
        
        #ifndef SHIPPING_BUILD
            #define INTERNAL_PRINT(x) logging::print(x)
        #else
            #define INTERNAL_PRINT(x) ((void)0)
        #endif
        
        namespace logging
        {
            void print( int i )
            {
                std::cout << i;
            }
        }
        
        int expensiveFcnReturningAnInt()
        {
            // The compiler would actually optimize this so it would
            // be extremely cheap to call, but you get the idea, this
            // function would be something you don't want to happen
            // in a shipping build if used only for logging.
            return 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1;
        }
        
        int main(int argc, const char * argv[])
        {
            INTERNAL_PRINT( expensiveFcnReturningAnInt() );
            
            return 0;
        }
        
    • In this sample, the call inside of main() to INTERNAL_PRINT is completely optimized out of the program when SHIPPING_BUILD is defined.
  • I needed a simple, one-line logging command that accepted a stream of information, just like an std::stringstream.
    • Without a macro, you would be forced to make an entire class to try and get you close to this functionality, and even then you might not get it. 
    • With a macro you can have exactly what you want:
    • #define SHIPPING_BUILD
      #include <iostream>
      
      #ifndef SHIPPING_BUILD
      #include <sstream>
      
      #define PRINT_STREAM(x) \
          { \
              std::stringstream strStream; \
              strStream << x; \
              logging::print(strStream.str().c_str()); \
          } 
      #else         
          #define PRINT_STREAM(x) ((void)0) 
      #endif
      
      namespace logging
      {
          void print( const char* message )
          {
              std::cout << message;
          }
      }
      
      int expensiveFcnReturningAnInt()
      {
          // The compiler would actually optimize this so it would
          // be extremely cheap to call, but you get the idea, this
          // function would be something you don't want to happen
          // in a shipping build if used only for logging.
          return 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1;
      }
      
      int main(int argc, const char * argv[])
      {
          PRINT_STREAM( "Expensive fcn result is: " << expensiveFcnReturningAnInt() );
          
          return 0;
      }
I would recommend splitting your logging stuff into its own header, or class even. The examples above have everything in the same file/snippet to keep things easier to read for this blog.

Friday, April 20, 2012

C++11: Strongly-typed enum

Enums have always been a useful feature of C++, allowing the programmer to easily make a list of values that are related to one another, with names that are easy to understand. In fact, enums are at the heart of the messaging system I talk about in this post. However, the classic C++ enum is subject to many issues as well that make it less useful than it could be, and this is why in C++11 they have introduced a strongly-typed enum, called an  enum class.

1.) Implicit conversion to an integer.
Enums are not type-safe. They do prevent you from directly assigning one type of enum value to another, but there is nothing stopping you from casting an integer directly to an enum type.

enum PrimaryColor
{
    Red = 0,
    Blue,
    Yellow
};

enum FavoriteColor
{
    Green = 0,
    Orange,
    Purple
};

PrimaryColor pC = Red;
FavoriteColor fC = Orange;

pC = fC;    // Error, you cannot assign one enum value directly to another.

pC = Green; // Same error

bool primaryColorIsGreater = (pC >= Green);   // Bad! This is allowed, but probably isn't intended.

Notice on the final line we are able to make a comparison between a primary color and a favorite color. Green isn't even a primary color, so this is probably not intended.

If you want something type safe, the enum class comes to the rescue!

enum class PrimaryColor
{
    Red = 0,
    Green,
    Blue
};

enum class FavoriteColor
{
    Green = 0, 
    Orange,
    Purple
};

PrimaryColor pC = Red;
FavoriteColor fC = Orange;

pC = fC;    // Error, you cannot assign one enum value directly to another.

pC = Green; // Same error

bool primaryColorIsGreater = (pC >= FavoriteColor::Green);  // Error, you cannot directly compare types from different enums.


2.) Scope
Enums are not strongly scoped. The enumerators of an enum have scope in the same scope as the enum itself. For example, what if in the example above we wanted FavoriteColor to have some of the colors as PrimaryColor?

enum PrimaryColor
{
    Red = 0,
    Blue,
    Yellow
};

enum FavoriteColor
{
    Green = 0,
    Red,   // Error, 'Red' is already defined in the PrimaryColor enum
    Blue   // Error, 'Blue' is already defined in the PrimaryColor enum
};

We're not able to do this with standard enums because they're not strongly scoped, however, the new enum class will let us do this.

enum class PrimaryColor
{
    Red = 0,
    Green,
    Blue
};

enum class FavoriteColor
{
    Green = 0, 
    Red,    // Ok
    Blue    // Ok
};

3.) Inability to specify underlying type
The underlying type of an enum is not portable, because different compilers will use different underlying types for an enum. For example, if you're using an enum directly in a packet of information, the sender and receiver may have a different perception of what size that enum value takes.

enum Version
{
    Version1 = 1,
    Version2 = 2,
    Version3 = 3
};

struct Packet
{
    Version version;     // Bad! This size can vary by implementation.
    
    // More data here
}

You can workaround this, but it's not ideal (hence calling it a 'workaround'):
struct Packet
{
    unsigned char version;     // This works, but requires casting
    
    // More data here
}

The workaround is ugly, we shouldn't have to store a version number as a char, and require the user on the other end to understand what type of data is stored in that char, and force them to cast it back to a integer (or unsigned integer). The enum class solves this issue for us, by allowing us to specify the underlying type of the enum, so we can guarantee what size it will be.

enum class Version : unsigned
{
    Version1 = 1,
    Version2 = 2,
    Version3 = 3
};

struct Packet
{
    Version version;    // This is now safe to do, we know that 'version' is an unsigned int.
    
    // More data here
}

Also, because the size of a standard enum differs by implementation, using values that assume signed or unsigned can be unsafe. Take, for example, the enum below:

enum MyEnum
{
   Value1 = 1,
   Value2 = 2,
   ValueBig = 0xFFFFFFF0U
};

Note that the last value has been explicitly set to an unsigned int. Because of the differing implementations of enums by different compilers, the resulting value of ValueBig also differs depending on what you're compiling with. This means that your code is not longer portable, and will only work as intended in some compilers. For compilers that treat enums as unsigned ValueBig will be 4294967280, for those that treat is as signed ValueBig will be -16. Even worse, there are compilers that treat ValueBig as 4294967280, but when comparing it against -1 will tell you that ValueBig is less than -1. The enum class solves this problem by allowing the programmer to specify the type. If we want 'ValueBig' to be 0xFFFFFFF0U then we just make sure that our  enum class  is specified to be an unsigned int:

enum class MyEnum : unsigned
{
   Value1 = 1,
   Value2 = 2,
   ValueBig = 0xFFFFFFF0U   // ValueBig is now guaranteed to be 4294967280
};

In Visual Studio 2011 the enum class is signed by default. I'm willing to bet that the C++11 standard defines this to be the required default, to prevent issues like what occurred with the basic enum.

enum class MyEnum     // We do not specify the value
{
   Value1 = 1,
   Value2 = 2,
   ValueBig = 0xFFFFFFF0U   // ValueBig in VS2011 is -16
};

Some IDEs are helpful and will show you what your values are going to be so there are no surprises.











Sources:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf

Thursday, April 19, 2012

C++11: Range-based for-loops and auto

One of the downsides to using C++ in recent years has been how verbose it is compared to some other languages, such as Java, C#, or Scala, just to name a few. One of the goals of the new C++11 standard was to allow for code that is more terse, and I must say, I love it.

One of the things about using STL in C++ that has always bothered me was how bulky it is. Let's take for example, iterating over a vector of strings, using the standard C++03 for-loop.

std::vector<std::string> words;
words.push_back("Hello");
words.push_back("World");
words.push_back("...and good morning!");

std::vector<std::string>::const_iterator wordItr;
for (wordItr = words.begin(); wordItr != words.end(); ++wordItr)
{
    std::cout << (*wordItr).c_str() << " ";
}

That's a lot of code just to loop through the words and print each one. In C++11 they have introduced a new keyword: auto. auto assumes the type of whatever is assigned to it, making it less verbose when the type would be especially long, such as std::vector::const_iterator. Let's see if we can clean up the code a bit using the auto keyword.

std::vector<std::string> words;
words.push_back("Hello");
words.push_back("World");
words.push_back("...and good morning!");

for (auto word = words.cbegin(); word != words.cend(); ++word)
{
   std::cout << (*word).c_str() << " ";
}

That's a fair amount better. We didn't have to spend an entire line of code just creating our iterator variable, auto saved so much room we we able to do it inline within the for-loop. However, we still have to initialize to begin(), and compare against end(), and increment the iterator. Those things are so standardized, it would be great if the for loop could take care of that for us. And it can! C++11 introduces range-based for-loops to do just that.

std::vector<std::string> words;
words.push_back("Hello");
words.push_back("World");
words.push_back("...and good morning!");

for (auto word: words)
{
    std::cout << word.c_str() << " ";
}

auto takes care of the type for us so we don't have to type out the entire iterator, and the range-based for-loop takes care of the initialization, comparison, and incrementing of the variable. On top of that, the range-based for-loop takes care of giving us the value pointed to by the iterator itself, so we don't have to dereference the iterator to get the string it points to. This means instead of (*word).c_str() we can just do word.c_str().

Also, for those of you who use Visual Studio, the good news is that Visual Studio 11 will have support for range-based for-loops. It was reported in September that it would not have support for it, but after people complained for months about it, it looks like Microsoft decided to put some more work into their compiler. If you would like to try it out in Visual Studio the VS11 Beta is out and supports it: http://blogs.msdn.com/b/vcblog/archive/2012/02/29/10272778.aspx

I have noticed however that the IDE doesn't properly recognize it, and will give you warnings if you hover over parts of the for-loop, but it does compile and run. I'm sure this is something they'll have fixed in the final version. Regardless, VS11 does not support nearly as much of C++11 as other compilers like GCC, which are free, and I'm not sure I could restrict myself to a compiler that would restrict my learning and development as a programmer. But, I sure do love the IDE of Visual Studio, and I'm going to miss that.

Saturday, February 11, 2012

Game Engine Architecture, C#

Here's the same architecture as my last two posts, but this time in C# (the last two were in Scala and C++).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MessagingInCSharp
{
    class Program
    {
        static void Main( string[] args )
        {
            // Create a scene manager
            SceneManager sceneMgr = new SceneManager();

            // Have scene manager create an entity for us, which
            // automatically puts the object into the scene as well
            Entity myEntity = sceneMgr.CreateEntity();

            // Create a render component
            RenderComponent renderComp = new RenderComponent();

            // Attach render component to the entity we made
            myEntity.AddComponent(renderComp);

            // Set 'myEntity' position to (1, 2, 3)
            MsgSetPosition msgSetPos = new MsgSetPosition(myEntity.uniqueID, 1.0f, 2.0f, 3.0f);
            sceneMgr.SendMessage(msgSetPos);
            Console.WriteLine("Position set to (1, 2, 3) on entity with ID: " + myEntity.uniqueID);

            Console.WriteLine("Retreiving position from entity with ID: " + myEntity.uniqueID);

            // Get 'myEntity' position to verify it was set properly
            MsgGetPosition msgGetPos = new MsgGetPosition(myEntity.uniqueID);
            sceneMgr.SendMessage(msgGetPos);
            Console.WriteLine("X: " + msgGetPos.x);
            Console.WriteLine("Y: " + msgGetPos.y);
            Console.WriteLine("Z: " + msgGetPos.z);
        }
    }

    public enum MessageType
    {
        SetPosition,
        GetPosition
    }

    public class Vector3
    {
        public float x = 0.0f;
        public float y = 0.0f;
        public float z = 0.0f;
    }

    public class BaseMessage
    {
        public int destEntityID;
        public MessageType messageType;

        protected BaseMessage( int destinationEntityID, MessageType messageType )
        {
            this.destEntityID = destinationEntityID;
            this.messageType = messageType;
        }
    }

    public class PositionMessage : BaseMessage
    {
        public float x;
        public float y;
        public float z;

        protected PositionMessage( int destinationEntityID, MessageType messageType,
                                   float X = 0.0f, float Y = 0.0f, float Z = 0.0f) :
            base(destinationEntityID, messageType)
        {
            this.x = X;
            this.y = Y;
            this.z = Z;
        }
    }

    public class MsgSetPosition : PositionMessage
    {
        public MsgSetPosition( int destinationEntityID, float X, float Y, float Z ) :
            base(destinationEntityID, MessageType.SetPosition, X, Y, Z)
        {}
    }

    public class MsgGetPosition : PositionMessage
    {
        public MsgGetPosition( int destinationEntityID) :
            base(destinationEntityID, MessageType.GetPosition, 0.0f, 0.0f, 0.0f)
        {}
    }

    public abstract class BaseComponent
    {
        public virtual bool SendMessage( BaseMessage msg )
        {
            return false;
        }
    }

    public class RenderComponent : BaseComponent
    {
        public override bool SendMessage( BaseMessage msg )
        {
            // Entity has a switch for any messages it cares about
            switch (msg.messageType)
            {
                case MessageType.SetPosition:
                    {
                        // Update render mesh position/translation

                        Console.WriteLine("RenderComponent handling SetPosition");
                    }
                    break;
                default:
                    return base.SendMessage(msg);
            }

            return true;
        }
    }

    public class Entity
    {
        public int uniqueID;
        public int UniqueID
        {
            get { return this.uniqueID; }
            set { this.uniqueID = value; } 
        }
        
        private Vector3 position = new Vector3();        
        private List<BaseComponent> components = new List<BaseComponent>();

        public Entity( int uniqueID )
        {
            this.uniqueID = uniqueID;
        }

        public void AddComponent( BaseComponent component )
        {
            this.components.Add(component);
        }

        public bool SendMessage( BaseMessage msg )
        {
            bool messageHandled = false;

            // Entity has a switch for any messages it cares about
            switch (msg.messageType)
            {
                case MessageType.SetPosition:
                    {
                        MsgSetPosition msgSetPos = msg as MsgSetPosition;
                        position.x = msgSetPos.x;
                        position.y = msgSetPos.y;
                        position.z = msgSetPos.z;

                        messageHandled = true;
                        Console.WriteLine("Entity handled SetPosition");
                    }
                    break;
                case MessageType.GetPosition:
                    {
                        MsgGetPosition msgGetPos = msg as MsgGetPosition;
                        msgGetPos.x = position.x;
                        msgGetPos.y = position.y;
                        msgGetPos.z = position.z;

                        messageHandled = true;
                        Console.WriteLine("Entity handled GetPosition");
                    }
                    break;
                default:
                    return PassMessageToComponents(msg);
            }

            // If the entity didn't handle the message but the component
            // did, we return true to signify it was handled by something.
            messageHandled |= PassMessageToComponents(msg);

            return messageHandled;
        }

        private bool PassMessageToComponents( BaseMessage msg )
        {
            bool messageHandled = false;

            this.components.ForEach(c => messageHandled |= c.SendMessage(msg) );

            return messageHandled;
        }
    }

    public class SceneManager
    {
        private Dictionary<int, Entity> entities = new Dictionary<int,Entity>();
        private static int nextEntityID = 0;

        // Returns true if the entity or any components handled the message
        public bool SendMessage( BaseMessage msg )
        {
            // We look for the entity in the scene by its ID
            Entity entity;
            if ( entities.TryGetValue(msg.destEntityID, out entity) )
            {
                // Entity was found, so send it the message
                return entity.SendMessage(msg);
            }

            // Entity with the specified ID wasn't found
            return false;
        }

        public Entity CreateEntity()
        {
            Entity newEntity = new Entity(SceneManager.nextEntityID++);
            entities.Add(newEntity.UniqueID, newEntity);

            return newEntity;
        }
    }
}

Game Engine Architecture, now in Scala

In my previous post I discussed game engine architecture, object<->component hierarchy, etc. Here's the sample architecture as the last post, but instead of C++ this version is written in Scala. One thing worth noting, we get identical functionality in this Scala example, with 35% less code!

package MessagingInScala

object GameMessageType extends Enumeration {
  type GameMessageType = Value

  val SetPosition = Value
  val GetPosition = Value
}
import GameMessageType._

class Vector3(var x: Float, var y: Float, var z: Float)

abstract class GameMessage (val destinationID: Int) {  
  def messageType: GameMessageType
}

abstract class PositionMessage (destinationID: Int,
                                var x: Float, var y: Float,
                                var z: Float) extends GameMessage(destinationID) {
}  

class MsgSetPosition(destinationID: Int,
                     x: Float, y: Float,
                     z: Float) extends PositionMessage(destinationID, x, y, z) {
  override val messageType = SetPosition
}
object MsgSetPosition {
  def Apply(destinationID: Int,
            x: Float, y: Float,
            z: Float) = new MsgSetPosition(destinationID, x, y, z)
}

class MsgGetPosition(destinationID: Int) extends PositionMessage(destinationID, 0.0f, 0.0f, 0.0f) {
  val messageType = GetPosition
}
object MsgGetPosition {
  def Apply(destinationID: Int) = new MsgGetPosition(destinationID)
}

abstract class BaseComponent {
  def SendMessage(message: GameMessage) = false
}

class RenderComponent extends BaseComponent {
  override def SendMessage(message: GameMessage): Boolean = {
    message.messageType match {
      case GameMessageType.SetPosition => {
        // Update render mesh position
        println("RenderComponent received SetPosition")
        true // Return value
      }
      case _ => super.SendMessage(message)
    }
  }
}

class Entity(ID: Int) {
  private var Components: List[BaseComponent] = List()
  var position: Vector3 = new Vector3(0.0f, 0.0f, 0.0f)
  val uniqueID: Int = ID

  def AddComponent(component: BaseComponent) {
    Components = component :: Components
  }

  def SendMessage(message: GameMessage): Boolean = {
    message.messageType match {
      case GameMessageType.SetPosition => {
        println("Entity received SetPosition")
        var msgSetPos: MsgSetPosition = message.asInstanceOf[MsgSetPosition]
        position.x = msgSetPos.x
        position.y = msgSetPos.y
        position.z = msgSetPos.z
        PassMessageToComponents(message) // This is also the return value
      }
      case GameMessageType.GetPosition => {
        println("Entity received GetPosition")
        var msgGetPos: MsgGetPosition = message.asInstanceOf[MsgGetPosition]
        msgGetPos.x = position.x
        msgGetPos.y = position.y
        msgGetPos.z = position.z
        PassMessageToComponents(message) // This is also the return value
      }
      case _ => PassMessageToComponents(message) // This is also the return value
    }
  }
  
  def PassMessageToComponents(message: GameMessage): Boolean = {
    var messageHandled = false
    Components.foreach(c => {
      messageHandled |= c.SendMessage(message)
    })
    
    messageHandled
  }
}

object Entity {
  var nextUUID: Int = 0  
  def apply() = new Entity(nextUUID + 1)
}

class SceneManager {
  // You don't need to type the entire HashMap path like this, I'm
  // doing this so the reader understands this is not a Java HashMap
  var entities: Map[Int, Entity] = Map.empty[Int, Entity]
  
  def SendMessage(message: GameMessage): Boolean = {
    if ( entities.contains(message.destinationID) ) {
      entities(message.destinationID).SendMessage(message)
    } else {
      false
    }
  }
  
  def CreateEntity(): Entity = {
    val newEntity: Entity = Entity()
    entities += newEntity.uniqueID -> newEntity
    newEntity
  }
}


object Main extends App {
  val sceneMgr: SceneManager = new SceneManager
  
  val testEntity = sceneMgr.CreateEntity()
  val testRenderComp = new RenderComponent
  testEntity.AddComponent(testRenderComp)
  
  val msgSetPos: MsgSetPosition = new MsgSetPosition(testEntity.uniqueID, 1.0f, 2.0f, 3.0f)
  sceneMgr.SendMessage(msgSetPos)
  println("Position set to (1, 2, 3) on entity with ID " + testEntity.uniqueID)  

  println("Retreiving position from object with ID: " + testEntity.uniqueID)

  val msgGetPos: MsgGetPosition = new MsgGetPosition(testEntity.uniqueID)
  sceneMgr.SendMessage(msgGetPos)
  println("X: " + msgGetPos.x)
  println("Y: " + msgGetPos.y)
  println("Z: " + msgGetPos.z)
}

Thursday, February 9, 2012

Game Engine Architecture, C++

I recently saw a question on Stack Overflow about engine architecture, specifically how to layout systems and communicate between them. My favorite engine architecture by far is an object<->component architecture. I posted a full working code sample as an answer to the question, along with details. Here's the link to the question, if you don't wish to follow the link, here's the full answer along with code. Enjoy!




My favorite game engine structure is the interface and object<->component model using messaging for communication between almost all parts.

You have multiple interfaces for main engine parts such as your scene manager, resource loader, audio, renderer, physics, etc.

I have the scene manager in charge of all objects in the 3D scene/world.

Object is a very atomic class, containing only a few things that are common to almost everything in your scene, in my engine the object class holds only position, rotation, a list of components, and a unique ID. Every object's ID is generated by a static int, so that no two objects will every have the same ID, this allows you to send messages to an object by its ID, rather than having to have a pointer to the object.

The list of components on the object is what gives that objects is main properties. For example, for something that you can see in the 3D world, you would give your object a render component that contains the information about the render mesh. If you want an object to have physics you would give it a physics component. If you want something to act as a camera, give it a camera component. The list of components can go on and on.

Communication between interfaces, objects, and components is key. In my engine I have a generic message class that contains only a unique ID, and a message type ID. The unique ID is the ID of the object you want the message to go to, and the message type ID is used by the object receiving the message so it knows what type of message it is.

Objects can handle the message if they need, and they can pass the message on to each of their components, and components will often do important things with the message. For example, if you want to change and object's position you send the object a SetPosition message, the object may update its position variable when it gets the message, but the render component may need to message to update the position of the render mesh, and the physics component may need the message to update the physics body's position.

Here is a very simple layout of scene manager, object, and component, and message flow, that I whipped up in about an hour, written in C++. When run it sets the position on an object, and the message passes through the render component, then retrieves the position from the object. Enjoy!

#include <iostream>
#include <stdio.h>

#include <list>
#include <map>

using namespace std;

struct Vector3
{
public:
    Vector3() : x(0.0f), y(0.0f), z(0.0f)
    {}

    float x, y, z;
};

enum eMessageType
{
    SetPosition,
    GetPosition,    
};

class BaseMessage
{
protected: // Abstract class, constructor is protected
    BaseMessage(int destinationObjectID, eMessageType messageTypeID) 
        : m_destObjectID(destinationObjectID)
        , m_messageTypeID(messageTypeID)
    {}

public: // Normally this isn't public, just doing it to keep code small
    int m_destObjectID;
    eMessageType m_messageTypeID;
};

class PositionMessage : public BaseMessage
{
protected: // Abstract class, constructor is protected
    PositionMessage(int destinationObjectID, eMessageType messageTypeID, 
                    float X = 0.0f, float Y = 0.0f, float Z = 0.0f)
        : BaseMessage(destinationObjectID, messageTypeID)
        , x(X)
        , y(Y)
        , z(Z)
    {

    }

public:
    float x, y, z;
};

class MsgSetPosition : public PositionMessage
{
public:
    MsgSetPosition(int destinationObjectID, float X, float Y, float Z)
        : PositionMessage(destinationObjectID, SetPosition, X, Y, Z)
    {}
};

class MsgGetPosition : public PositionMessage
{
public:
    MsgGetPosition(int destinationObjectID)
        : PositionMessage(destinationObjectID, GetPosition)
    {}
};

class BaseComponent
{
public:
    virtual bool SendMessage(BaseMessage* msg) { return false; }
};

class RenderComponent : public BaseComponent
{
public:
    /*override*/ bool SendMessage(BaseMessage* msg)
    {
        switch(msg->m_messageTypeID)
        {
        case SetPosition:
            {                   
                // Update render mesh position/translation

                cout << "RenderComponent handling SetPosition\n";
            }
            break;
        default:
            return BaseComponent::SendMessage(msg);
        }

        return true;
    }
};

class Object
{
public:
    Object(int uniqueID)
        : m_UniqueID(uniqueID)
    {
    }

    int GetObjectID() const { return m_UniqueID; }

    void AddComponent(BaseComponent* comp)
    {
        m_Components.push_back(comp);
    }

    bool SendMessage(BaseMessage* msg)
    {
        bool messageHandled = false;

        // Object has a switch for any messages it cares about
        switch(msg->m_messageTypeID)
        {
        case SetPosition:
            {               
                MsgSetPosition* msgSetPos = static_cast<MsgSetPosition*>(msg);
                m_Position.x = msgSetPos->x;
                m_Position.y = msgSetPos->y;
                m_Position.z = msgSetPos->z;

                messageHandled = true;
                cout << "Object handled SetPosition\n";
            }
            break;
        case GetPosition:
            {
                MsgGetPosition* msgSetPos = static_cast<MsgGetPosition*>(msg);
                msgSetPos->x = m_Position.x;
                msgSetPos->y = m_Position.y;
                msgSetPos->z = m_Position.z;

                messageHandled = true;
                cout << "Object handling GetPosition\n";
            }
            break;
        default:
            return PassMessageToComponents(msg);
        }

        // If the object didn't handle the message but the component
        // did, we return true to signify it was handled by something.
        messageHandled |= PassMessageToComponents(msg);

        return messageHandled;
    }

private: // Methods
    bool PassMessageToComponents(BaseMessage* msg)
    {
        bool messageHandled = false;

        std::list<BaseComponent*>::iterator compIt = m_Components.begin();
        for ( compIt; compIt != m_Components.end(); ++compIt )
        {
            messageHandled |= (*compIt)->SendMessage(msg);
        }

        return messageHandled;
    }

private: // Members
    int m_UniqueID;
    std::list<BaseComponent*> m_Components;
    Vector3 m_Position;
};

class SceneManager
{
public: 
    // Returns true if the object or any components handled the message
    bool SendMessage(BaseMessage* msg)
    {
        // We look for the object in the scene by its ID
        std::map<int, Object*>::iterator objIt = m_Objects.find(msg->m_destObjectID);       
        if ( objIt != m_Objects.end() )
        {           
            // Object was found, so send it the message
            return objIt->second->SendMessage(msg);
        }

        // Object with the specified ID wasn't found
        return false;
    }

    Object* CreateObject()
    {
        Object* newObj = new Object(nextObjectID++);
        m_Objects[newObj->GetObjectID()] = newObj;

        return newObj;
    }

private:
    std::map<int, Object*> m_Objects;
    static int nextObjectID;
};

// Initialize our static unique objectID generator
int SceneManager::nextObjectID = 0;

int main()
{
    // Create a scene manager
    SceneManager sceneMgr;

    // Have scene manager create an object for us, which
    // automatically puts the object into the scene as well
    Object* myObj = sceneMgr.CreateObject();

    // Create a render component
    RenderComponent* renderComp = new RenderComponent();

    // Attach render component to the object we made
    myObj->AddComponent(renderComp);

    // Set 'myObj' position to (1, 2, 3)
    MsgSetPosition msgSetPos(myObj->GetObjectID(), 1.0f, 2.0f, 3.0f);
    sceneMgr.SendMessage(&msgSetPos);
    cout << "Position set to (1, 2, 3) on object with ID: " << myObj->GetObjectID() << '\n';

    cout << "Retreiving position from object with ID: " << myObj->GetObjectID() << '\n';

    // Get 'myObj' position to verify it was set properly
    MsgGetPosition msgGetPos(myObj->GetObjectID());
    sceneMgr.SendMessage(&msgGetPos);
    cout << "X: " << msgGetPos.x << '\n';
    cout << "Y: " << msgGetPos.y << '\n';
    cout << "Z: " << msgGetPos.z << '\n';
}

Tuesday, February 7, 2012

LINQ and Lambda in C# 4.0 for cleaner, leaner code

There are times when less is more. If you want clean and concise code, or if readability is more important than finely tuned high-performance, then LINQ and Lambda expressions might just be for you.

First let's look at a small code sample that does NOT use LINQ or Lambda that where we want to filter through some physics collision results for objects of a certain ID, and then sort our results by the lower IDs first.

struct CollisionPair : IComparable, IComparer
{
    public int first;
    public int second;

    // Since we're sorting we'll need to write our own Comparer
    int IComparer.Compare( object one, object two )
    {
        CollisionPair pairOne = (CollisionPair)one;
        CollisionPair pairTwo = (CollisionPair)two;

        if (pairOne.first < pairTwo.first)
            return -1;
        else if (pairTwo.first < pairOne.first)
            return 1;
        else
            return 0;
    }

    // ...and our own comparable
    int IComparable.CompareTo( object two )
    {
        CollisionPair pairTwo = (CollisionPair)two;

        if (this.first < pairTwo.first)
            return -1;
        else if (pairTwo.first < this.first)
            return 1;
        else
            return 0;
    }
}

static void Main( string[] args )
{           
    List&ltCollisionPair&gt collisions = new List&ltCollisionPair&gt
    {
        new CollisionPair { first = 1, second = 5 },
        new CollisionPair { first = 2, second = 3 },
        new CollisionPair { first = 5, second = 4 }
    };

    List&ltCollisionPair&gt sortedCollisionsWithFive = new List&ltCollisionPair&gt();
    foreach (CollisionPair c in collisions)
    {
        if (c.first == 5 || c.second == 5)
        {
            sortedCollisionsWithFive.Add(c);
        }
    }
    sortedCollisionsWithFive.Sort();

    foreach (CollisionPair c in sortedCollisionsWithFive)
    {
        Console.WriteLine("Collision between " + c.first +
                          "and " + c.second);
    }
}
Now let's take a look at what we can do when we use LINQ and Lambda expressions to clean things up a bit.
struct CollisionPair
{
    public int first;
    public int second;
}

static void Main( string[] args )
{           
    List&ltCollisionPair&gt collisions = new List&ltCollisionPair&gt
    {
        new CollisionPair { first = 1, second = 5 },
        new CollisionPair { first = 2, second = 3 },
        new CollisionPair { first = 5, second = 4 }
    };

    (from c in collisions 
    where ( c.first == 5 || c.second == 5 )
    orderby c.first select c).ForEach(c =&gt
        Console.WriteLine("Collision between " + c.first +
                          "and " + c.second));
}
So which part is LINQ, and which part is Lambda? Here's the LINQ part:
(from c in collisions 
    where ( c.first == 5 || c.second == 5 )
    orderby c.first select c)
This loops through 'collisions', and you can reference each element in the container by 'c'. Then it filters the list so only elements with either a first or second ID of 5 remain. Then it orders the list by the first element, and then selects all elements remaining and creates a list out of them. In this case the list may be hard to see, it's formed by wrapping the entire LINQ expression in parentheses. The sample below might make it easier to see:
// LINQ
var filteredCollisions = from c in collisions 
    where ( c.first == 5 || c.second == 5 )
    orderby c.first select c
And here is the Lambda expression:
// Lambda
ForEach(c =&gt
    Console.WriteLine("Collision between " + c.first +
                      "and " + c.second));
This performs a ForEach on a list, the list formed by the LINQ expression that comes before it in the original code. For each element in the list, it calls each element 'c', and then performs a Console.Writeline on each element. Here's the original sample, simplified a bit:
// LINQ
var filteredCollisions = from c in collisions 
    where ( c.first == 5 || c.second == 5 )
    orderby c.first select c

// Lambda
ForEach(c =&gt
    Console.WriteLine("Collision between " + c.first +
                      "and " + c.second));
If you want to use LINQ you'll want to make sure to use System.Linq:
using System.Linq;