Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Thursday, February 6, 2014

C++ Build Preprocessing Thoughts

Something that's been on my mind lately is how you could automatize many otherwise tedious and repetitive programming tasks by using custom build preprocessing tools.

If you're familiar with Qt's meta object compiler (moc) then you should have a good understanding of what I'm trying to talk about in this post.

When I first thought of useful C/C++ build preprocessing steps I was adding reflection and serialization to my engine.

Serialization, for instance, was just filling out a virtual serialize() function, where each member variable of a class was written to a binary stream.

Basically it was like this:

 Example::serialize(Stream& p_Stream)  
 {  
    p_Stream << m_Value1;  
    p_Stream << m_Value2;  
    p_Stream << m_Value3;  
    //custom class  
    m_Value4->serialize(p_Stream);  
    //...and so on  
 }  

As you can imagine, this got tedious and boring pretty quick...And that was when I though about a more elegant solution for this.

A few days later, build preprocessing came to my mind.

The basic idea is to use some kind of parser-tool (clang anyone? Getting a hang of clang can be pretty tedious, but it will pay off eventually) to parse your C/C++ code and
identify variables by using custom type qualifier. The information you gather by identifying your variables like this can be used to automatically create various function (like the serialize() function in this example)
In my codebase this would look like:

 #define serializable  
 class Example  
 {  
 public:  
    Example();  
    ~Exmaple();  
 private:  
    serializable int m_Value1;  
    serializable float m_Value2;  
    serializable bool m_Value3;  
    serializable CustomClass m_Value4;  
 };  

The tool I build (in lua - still learning how to use clang) scans my codebase for variables with the custom qualifier 'serializable'. It then saves these variables and automatically creates the serialize() function with the information it gathered during the codebase parsing.

This approach saved me various hours of tedious code doublication so far :)

Some more examples I thought of that would make sense would be

  • Code reflection (again using custom qualifiers)
  • Enum <--> String conversion 

Monday, January 23, 2012

New arrivals!

Today the new books I ordered got delivered!
Including:

Unfortunately my exams are starting tomorrow. I guess I'll have to wait until my exams are over until I can start reading these books, altough I couldn't stop me to take a quick glance at the C++ book ;).

In addition, I hope the math book is good. I'm slightly starting to get to the boundries of my mathematical knowledge :-/.


Monday, January 9, 2012

Type conversion using template functions

Yesterday I came up with a new way to make type conversions prettier.
I want to explain you how that works in this post.

As you might know, I work with a component based object model in my engine (see here).
In this kind of object model, you sometimes need to modify the component of certain objects after you added them.

To do that I implement a getComponent() function, which - in the past - returned a object of the type of the component interface (called IComponent). Type conversions needed to be made afterwards to work with the desired implementation. That used to look like this:

 GameObject gameobject;  
 RenderableComponent *renderableComponent = new RenderableComponent("graphic.png");  
 gameobject.addComponent(renderableComponent);  
 //Somewhere else in the code in another function.  
 IComponent *component = gameobject.getComponent("RenderableComponent");  
 RenderableComponent *renderableComponent = static_cast<RenderableComponent*>(component);  
 //.. do stuff with renderablecomponent.  

I found that code pretty ugly and unnecessary complicated, so I thought of another idea to do that user friendlier. The first step I did was to change the getComponent() function to a template function.

The function looked like this:

 IComponent *GameObject::getComponent(const String &componentName){  
      for(std::list<IComponent*>::iterator i = this->m_components.begin();i != this->m_components.end();i++){  
           if((*i)->getType() == componentName){  
                return (*i);  
           }  
      }  
      return NULL;
 }  

With template support it now looks like this:
 template<class T>  
 T *getComponent(const String &componentName){  
      for(std::list<IComponent*>::iterator i = m_components.begin();i != m_components.end();i++){  
           if((*i)->getType() == componentName){  
                return static_cast<T*>((*i));  
           }  
      }  
      return NULL;  
 }  
(Hint: If you don't know nothing about template functions, check here)

As you can see, the user determines the return type via the template type ( So there's no ugly conversion needed afterwards.)

The result is (in my opinion) much nicer source code.
The following is the above example reused with the new getComponent() template function:
  GameObject gameobject;   
  RenderableComponent *renderableComponent = new RenderableComponent("graphic.png");   
  gameobject.addComponent(renderableComponent);   
  //Somewhere else in the code in another function.   
  //IComponent *component = gameobject.getComponent("RenderableComponent");   
  //RenderableComponent *renderableComponent = static_cast<RenderableComponent*>(component);  
 RenderableComponent *renderableComponent = gameobject.getComponent<RenderableComponent>("RenderableComponent");   
  //.. do stuff with renderablecomponent.   
I don't know what about you, but I find it much nicer ;) .

Compared with a macro like:
 #define GET_COMPONENT(type)(getComponent<type>(#type))  

The example could even get more improved to look like this:
  GameObject gameobject;    
  RenderableComponent *renderableComponent = new RenderableComponent("graphic.png");    
  gameobject.addComponent(renderableComponent);    
  //Somewhere else in the code in another function.    
  //IComponent *component = gameobject.getComponent("RenderableComponent");    
  //RenderableComponent *renderableComponent = static_cast<RenderableComponent*>(component);   
  RenderableComponent *renderableComponent = gameobject.GET_COMPONENT(RenderableComponent);  
  //.. do stuff with renderablecomponent.    

Monday, December 5, 2011

Make your Engine more dynamic!


When I started to program my Engine, I wanted to create a somewhat portable Engine.
I wanted to support different libraries like OpenGL, OpenAL or DirectX to make my Engine run under Windows and other platforms.

My first attempt was to differentiate with the Preprocessor variables given by the OS
(For example _WIN32 under Windows).

That worked, but was somewhat ugly...

It was indeed so ugly that I decided to give it another try.
So I split everything into separate dynamic libraries.

At the end I had one library for every replaceable feature of my engine.
Here are some of them:

K15_GraphicModule.dll / K15_GraphicModule.so
K15_SoundModule.dll / K15_SoundModule.so
K15_InputQueueModule.dll / K15_InputQueueModule.so
They were implement as subsystems.

I'll try to explain the idea behind the subsystems by the example of the GraphicModule.

The GraphicModule is, for example, a subsystem of the Engine's GraphicManager.
The GraphicManager will try to find a "K15_GraphicModule.dll" or "K15_GraphicModule.so" (depends on the OS) in it's initialize function. When it finds the dynamic library, it loads it and tries to perform the function "createGraphicModule()" within the library.

The function createGraphicModule will return an implementation of a GraphicModule interface that is declared inside the Engine's library file.

Here's some code to clarify my example.

 GraphicManager::GraphicManager  
 {  
      typedef createGraphicModule IGraphicManagerModule* (*createGraphicModule)(void);  
      DynLib graphicLib("K15_GraphicModule") // load library (without extension...Determined by the current OS)  
      if(graphicLib.loadedSuccessful()){ //Check if library has been loaded.  
           createGraphicModule func = (createGraphicModule)graphiclib.getFuction("createGraphicModule");  
           if(func != NULL){ // function loaded?  
                this->m_subsystem = func(); //get Subsystem from dynamic library.  
           }  
      }  
 }  

This system allows me to switch between OpenGL and DirectX just by replacing the dynamic library files...Or to switch from Windows File Manager to some Unix File Manager just by replacing the library file.

I just implemented this system about a few days ago, so I don't know how well that will work in an actual game...But it's only a matter of time 'till I know it ;-)

Sunday, October 23, 2011

Friday, September 9, 2011

Using the benefits of lambda functions with a component based game object model

Hi everybody!

Today I'd like to introduce a feature of the new C++11x standard, which is implemented in the Visual C++ compiler of the 2010 edition of visual studio and newer versions of gcc.

The new feature I'd like to talk about is the Lambda Function.

A Lambda Function is an anonymous function...
What exactly that means is demonstrated in the code below.

I'm going to refer to my last blog post (Component based game objects) and take components as an example.

 class IComponent
{
public:
virtual void update(float gameTime) = 0;
virtual bool handleMessage(Event const & componentEvent) = 0;
};
This is the (simplified) interface I'm using for components.

Now think about what you would do if you have, for example, a game object which needs to respond to mouse movement events.

You really need this behaviour only for this particular object and nothing else.

So far one had to write a new IComponent implementation for this.
Think about the mass of this kind of components you'll have at the end of your project...

Fortunately the Lambda Functions will help us with the mass of implementations for this "one purpose components".

Consider the following IComponent implemention:

 typedef std::function<void(float)> UpdateFunction;
typedef std::function<bool(const Event)> HandleEventFunction;
class VersatileComponent : public IComponent
{
public:
VersatileComponent(UpdateFunction updateFunc,HandleEventFunction handleFunc){
this->m_updateFunction = updateFunc;
this->m_handleFunction = handleFunc;
}
void update(float GameTime){
m_updateFunction(GameTime);
}
bool handleEvent(const Event &gameevent){
return m_handleFunction(gameevent);
}
private:
UpdateFunction m_updateFunction;
HandleEventFunction m_handleFunction;
};

What this component does is taking 2 functions as parameters and performing them.
(for those of you who are not familiar with std::function (or std::tr1::function) check out Effective C++ (Scott Meyers has some great items in there which covers std::function) or this link.)

What you can do with the above implementation is something like this:

 bool handleMouseMovement(const Event &gameEvent){
if(gameEvent.getType() == MouseMovement){
//DoStuff
}
}
void update(float deltaTime){
//DoStuff
}
int main()
{
VersatileComponent *vComponent = new VersatileComponent(update,handleMouseMovement);
//DoStuff
}

Here we just define 2 functions which takes the same parameters and return the same types as the update and handle function of the VersatileComponent class... We just pass them as parameters so they get called in the VersatileComponent update() and handleMouseMovement() function.

(Look here if you need a refresh in function pointers)

So...That's nothing new so far, but now I'm going to use Lamda Functions (or anonymous functions, if you prefer).

I'm just going to throw this code at you, before I'll do any explanation:
 int main()
{
VersatileComponent *vComponent = new VersatileComponent([](float gameTime){
//DoUpdateStuff
},[](const Event &gameEvent)->bool{
if(gameEvent.getType() == MouseMovement){
//DoStuff
}
});
//DoStuff
}
I know this does look weird at first, but I'm just doing the same as in the previous code example...I'm passing two functions as parameters...two Lambda Functions.

As you might see, Lambda Functions are getting defined at the point where they are needed.
They don't get named (well they get internally,but you don't know the name of them), so you can't call them in other places of your code.

They also have some kind of unique initialization syntax, which you can look up here (the link also features more informations about Lambda Functions).

The benefit of this approach is, that you don't have to declare functions in other places of your code only because you need them once. (see the example with the function pointers)

With the new Lambda Functions the VersatileComponent truly gets maximum versatileness.

BTW: Just for your information : I don't get nothing for linking to Amazon items. ;)