This'll be short for now, as it seems I've come down with a cold, and I need to work on getting some rest and trying to knock this sickness out cold. My first day, I'll be attending the Advanced Visual Affects with DirectX 11 Summit, which runs from 10am to 6pm. The second day, I'll presumably be attending the AI Summit, which also runs from 10am to 6pm. I've never been to GDC before, so I'm not sure if one usually stays at one of these for the whole time or not.

I should also ideally be doing some networking, however, perhaps that's better saved for later in the week when I'm hopefully better from my cold. So if that's what I plan on doing, then maybe I'll work on finishing my inverse kinematics code so I have some cool stuff to show off. XD

Anyway, I'll certainly be excited to meet some new people who are also passionate about game programming; if you're in the area, please feel free to drop me a line! Also, feel free to email be to try to more quickly get in contact at: leetNightshade [at] gmail [dot] com Emails to this account, as long as they're not flagged as spam, should trigger a notification on my phone. Look forward to meeting you guys! :D

So if you're somewhat familiar with C++ you know you can't easily implement a nice generic delegate that works for both static classes and member functions of all classes.  However, with some research and thought, you will realize it's not as hard as you think!

First, I would like to share this article that inspired me and caused me to gain hope in that delegates are possible in a nice flexible way!  Here it is, on: Code Project.

Okay, let's first think about this, we want a delegate to hide away the C++ syntax so we can call any kind of function, pass in certain parameters and get something back.  To make this flexible, it makes sense to have the base delegate class be a template, so you can define what types you want to use.  So here is the base class, which I'll call IDelegate, as in Interface Delegate.

// Interface for a Delegate class, for dispatching a lookup function call.
// R is the return type
// P is the parameter type
template <typename R,typename P>
class IDelegate
{
public:
virtual ~IDelegate(){}

virtual R Invoke(P) = 0;
};

You could also just as easily use an operator overload instead of Invoke:

virtual R operator()(P) = 0;

Now we just need to worry about creating a subclass so we can use these Delegates! So, we'll start with the Static Delegate since it'll be the simplest to create. To create a Static Delegate, we'll need a StaticDelegate class that accepts a static function pointer, and that's all it needs. So we have that below:

// This class is for attaching a Static Function Pointer to an IDelegate
// R is the return type
// P is the parameter type
template <typename R,typename P>
class StaticDelegate<typename R,typename P>
	: public IDelegate<R,P>
{
	typedef R (*funcPtr)(P);

protected:
	funcPtr _funcPtr;

public:
	StaticDelegate(funcPtr functionPointer)
		: _funcPtr( functionPointer )
	{
	}

	R Invoke(P param)
	{
		return _funcPtr(param);
	}
};

For those of you who don't know, this is a Static Function Pointer:

typedef R (*funcPtr)(P);

And also in case you didn't know, you can in fact define functions with parenthesis around the name, it is valid syntax.

Okay, so what we have here is really simple to use:

void PrintInt(int num)
{
	std::cout << num << endl;
}
typdef StaticDelegate<void,int> SDelegate;

IDelegate<void,int> delegate = SDelegate(&PrintInt);

I do encourage you to use typedefs to make your life easier, this becomes more obvious why you might want to do that when you're working with Class Member Function Pointers. In an event system, to be as flexible as possible, I do suggest trying to stick with one type of delegate.

Okay, the above shows you what you need to do to get a Static Function working with an IDelegate, now we need to get something to encapsulate a Member Function Pointer. For lack of a better name, I'll be using Type Delegate, as you do have to specify a class type that the member function belongs to.

// This class is for attaching a Member Function Pointer to an IDelegate
// R is the return type
// T is the Class of this Member Function Pointer
// P is the parameter type
template <typename R,typename T,typename P>
class TypeDelegate
	: public IDelegate<R,P>
{
	typedef R (T::*funcPtr)(P);// this is a function pointer definition
protected:
	funcPtr _funcPtr;
	T& _objPtr;

public:
	TypeDelegate(T& objPtr, funcPtr functionPointer)
		: _objPtr( objPtr )
		, _funcPtr( functionPointer )
	{
	}

	R Invoke(P param)
	{
		return (_objPtr.*_funcPtr)(param);
	}
};

Okay, so to create a TypeDelegate you need to pass in an object of the class you specified, and a function pointer to the class. So you can try this:

class Object1
{
public:
	typedef TypeDelegate<void,PhysicsObject,Object_Event::ENUM> TDelegate;

	Object1(){}

	void CatchEvent(Object_Event::ENUM eventID)
	{
		//...
	}
};
//  Somewhere in your code...
Object1 obj1 = Object1();

IDelegate delegate = TDelegate(&obj1,&Object1::CatchEvent);

//or inside of obj1:
delegate = TDelegate(*this,&Object1::CatchEvent);

Again, please feel free to use typedefs as it'll leave you with less code to type. I also suggest using this one system for all your delegate needs, no matter if you need parameters or not. I think this system is beautiful as it is because it's so simple, flexible, and it's not hard to tell what it does and didn't require a mess to get working like I thought might have to happen. If you want to use this type of delegate with no params, you can define an empty class like this:

// use as a Parameter type instead of void inside of IDelegate, as you'll get a compiler error
class Void
{
public:
	Void(){}
};

Yes, as I indicated in the comment, if you try to use "void" as the parameter type for the IDelegate sub classes, you will get a compiler error. So, as an alternative, use "Void", and pass in Void() as the args for the delegate; or, just use a "void*" and set it to NULL I guess (or a Void* or whatever you want); just make it obvious to functions using the delegate know that it's a void type.

So, as I suggested for keeping the delegate system simple, when you want to use multiple parameters, just use a struct with them defined. One reason I prefer this: if you didn't use a single struct, you'd have to expect every function variable to be properly named to know what it does. In this case, if you're using a struct, the variables names are what you define them to be, so this will help for documentation purposes when someone wants to find out what it does, they just need to look in one place: the struct definition.

 

[UPDATE:]
Source Files: C++ Delegates.

So I've noticed there are a lack of Direct X tutorials or posts, specifically with 10. So I'll make some posts, specifically starting with creating and drawing sprites in DirectX 10, either using the built in ID3DX10Sprite system, or creating your own quads.

So I've got a basic render system setup with windows classes so you can use them in a small game engine. I'll be making posts diving into more details behind the PlasmaTech engine I'm helping work on for Foundations of 2D graphics, as long as it's okay with everyone else. This is the first school project I've worked on where we're paying attention to memory management, and I'm setting up memory allocators for the different game systems.

I've realized the importance of content management, though only finally writing a robust one that abstracts as much of the work as possible. Another thing I like that I'm doing in this, is error checking and handling, which is going to make the process of making this game easier. If the game fails to startup, you will get an error message indicating what went wrong. Though I'm still fleshing out how we want to handle displaying errors from subsystems. Also going to look into using a persistent log system, I have a class I can use to write formatted rtf files, so we can use colors and other formatting to make reading the logs easier.  So, the thing I like about this new engine, is that when things break, it will fail with grace.

I also did research into dumping an error report upon an unknown crash or exception; what I've got is a mini-dump file being written, and used with the .pdb debug information we can look at a stack trace and see what the error was. One step further from this, I want to setup a system where upon this game crash, it'll upload the mini-dump file to your game server for further analysis so the game devs can make a patch for their game. I got this idea from hearing about how Steam works, and that upon crash Steam automatically sends a bug report to the game devs, and thought this was a beautiful system. I don't like the idea of using try and catch blocks over the whole game, in-fact, that is a HORRIBLE idea; but, there is a windows function that basically acts like one global catch handler; I'll get into detail with that when I make the block post on writing a mini-dump file. Since we're working on PC's, we have to worry about maintaining support across a wide array of hardware platforms and variety of different operating systems and system setups.

I also bought a number of potentially great books, though one of them is arguable, as it's just a book for class and I had trouble finding something considerably better. So maybe there isn't a great book on animation algorithms and systems, but I think the one I got should get me by. So here's the list of books I just recently bought:

Computer Animation, Second Edition: Algorithms and Techniques: Amazon link.

Real-Time Collision Detection: Amazon link.

Game Physics, Second Edition: Amazon link.

Physically Based Rendering, Second Edition: From Theory To Implementation: Amazon link.

I'll be sure to give some of these books a good read over my Christmas break, and if you have any other recommendations, feel free to let us know in the comments section.

Looking to do Multithreaded programming? In order to do that you're going to need a Mutex to prevent threads from accessing data at the same time! There are different techniques of preventing threads from accessing the same data, but they can't guarantee problems won't happen, it has to be implemented on the hardware side and exposed through the OS or what have you. Luckily, we can do this using some code from the Windows header files, using what's called Critical Section Objects, which works between threads on the same process, and is apparently a, "slightly faster, more efficient mechanism for mutual-exclusion synchronization." Sweeet!

Mutex_win32.h:

#ifndef w_Mutex_win32
#define w_Mutex_win32

#include <windows.h>

#include "../Definitions.h"

namespace _Warp
{
	class Mutex_win32
	{
	protected:
		CRITICAL_SECTION _critSection;

	public:
		Mutex_win32()
		{
			InitializeCriticalSection (&_critSection);
		}

		~Mutex_win32()
		{
			DeleteCriticalSection (&_critSection);
		}

		void Lock()
		{
			EnterCriticalSection (&_critSection);
		}
		void Unlock()
		{
			LeaveCriticalSection (&_critSection);
		}

		Bool TryLock()
		{
			return (Bool)TryEnterCriticalSection(& _critSection);
		}
	};
}
#endif

Now, threading problems can be hard to track down and debug, especially if you forget to Unlock the Mutex. So a Lock object is a way to help you clean up and unlock the Mutex when you're done. A Lock is created on the Stack in a local block of code, so when the program leaves the block of code the Lock gets deleted, the destructor gets called, and in the process the Mutex is automatically unlocked in the Lock destructor.

Lock.h:

#ifndef w_Lock
#define w_Lock

#include "../Data/Uncopyable.h"

#include "Mutex_win32.h"

namespace _Warp
{
	class Lock
		: private Uncopyable
	{
	protected:
		Mutex_win32* _pMutex;

	public:
		explicit Lock(Mutex_win32* pMutex);
		~Lock();
	};

	inline Lock::Lock(Mutex_win32* pMutex)
		: _pMutex( pMutex )
	{
		if(_pMutex != NULL)
		{
			_pMutex->Lock();
		}
	}

	inline Lock::~Lock()
	{
		if(_pMutex != NULL)
		{
			_pMutex->Unlock();
		}
	}
};
#endif

Here's an example of how to use a Lock and Mutex:

Mutex_win32* _pMessageListMutex = new Mutex_win32();//a mutex might typically exist in the header as a member variable
list<string> _messages = list<string>();// this 

void function()
{
	Lock lock = Lock(_pMessageListMutex);
	/* do stuff to the list */
}// when the program reaches here, the lock gets cleaned up and the _pMessageListMutex gets freed so another thread can access the _messages list without worrying about another thread accessing it at the same time

In case you didn't notice, the Lock class inherits from an "Uncopyable" class that doesn't allow the Lock to be copied or to be constructed from another Lock.  This helps prevent errors from happening, besides the fact a lock shouldn't be copied anyway; so this class ensures it can't be.  The Uncopyable class was inspired by the Boost Uncopyable class, though it wasn't the first site I ran across that showed something very similar.

Uncopyable.h:

#ifndef w_Uncopyable
#define w_Uncopyable

namespace _Warp
{
	// Inherit from this if you want a class to be unable to be copy-constructed.
	class Uncopyable
	{
	private:
		Uncopyable(const Uncopyable&);
		Uncopyable& operator=(const Uncopyable&);

	protected:
		Uncopyable(){}
		virtual ~Uncopyable(){}
	};
};
#endif

For those of you who don't know, the virtual destructor is required if any class inherits from Uncopyable, if you want it to properly be deleted. This should only be a problem if you store an object as an Uncopyable object, instead of it's own object type, and you try to delete it, the child's destructor will be properly called before the parent's destructor. Also, because the Copy constructor and copy operator aren't defined (besides the fact that they're private), you'll get a compiler error preventing you from doing anything you shouldn't be!

Both the Lock and Mutex class are pretty simple, so there isn't really much variation to them; I don't remember exactly which sites I used to lookup the Windows functions, otherwise I'd credit them for their help.  Either way, if you had trouble finding C++ Mutex and Lock classes, I hope you find these useful for your purposes!

You can download the project files here: Mutex, Lock, and necessary class files.

This is an improved Vector2 class I'm working on with suggestions from Leander Hasting, though I haven't touched upon all of them yet.  Beyond that, some of the critiques seem subjective to a point, and other professionals he pointed me to, make the same argument; and that is the argument of the use 0f non-member functions.  With intellisense working, I find using member functions to be the easiest way of doing things, as I think it is easier for other people to work with; as someone who's trying to write an engine, I understand the importance of including extra functions in a separate header file, though I think that can get messy.  So, with what is proposed you could do VectorUtil::len(vector), though having the VectorUtilthere is ugly, though without it there, how do you know that function even exists or where it's coming from?  So for starters, it's more useful to split the vector up like this, because everything doesn't need access to these functions, and it helps build times.  Though, in the end, when this engine is done, all of the information is most likely going to be included anyway;  lets say I want to add scripting support with my own version of intellisense, I want to make it as easy as possible for someone not used to my engine to be able to interactively see what they can do with a Vector by simply using "vector." and everything they have available to them pop up.  So, because the functions are accessing public members, they have no need to be member functions; so while some may claim using member functions breaks encapsulation, I think it makes it easier to open up a class to the user and what it can do.  Though it's interesting that intellisense in Visual Studio also shows private and protected functions you don't have access to...

Anyway, what I would like to do with my code is make it as easy as possible for anyone to use, I'm not worried that much about technicalities and hardcore programmers squirming over things I don't care about.  Though that makes me wonder, should I care about that, and perhaps just take it with a grain of salt?

Anyway, here's my Vector2 class in it's improved glory.

Vector2.h:

/*  __      __   ___     _____    ____
 *  \ \    / /  / _ \   |  __ \  |    |
 *   \ \/\/ /  / / \ \  | | / /  |  __|
 *    \_/\_/  /_/   \_\ |_| \_\  |_|
 *      Take it to the next Level
 *
 *  Copyright (c) 2009 Brian Ernst.
 */
#ifndef w_Vector2
#define w_Vector2

#ifndef FALSE
#define FALSE 0
#endif

#ifndef TRUE
#define TRUE 1
#endif

namespace _Warp
{
	typedef float Scalar;
	typedef int Bool;

	class Vector2
	{
	public:
		Scalar X;
		Scalar Y;

		Vector2();
		Vector2(Scalar x, Scalar y);

		Vector2& operator+=(const Vector2& pVector);
		Vector2& operator-=(const Vector2& pVector);
		Vector2& operator*=(Scalar num);
		Vector2& operator/=(Scalar num);

		Bool operator!=(const Vector2& vect) const;
		Bool operator==(const Vector2&; vect) const;

		friend Vector2 operator-(Vector2& vect);
		friend Vector2 operator+(const Vector2& vect1,const Vector2& vect2);
		friend Vector2 operator-(const Vector2& vect1,const Vector2& vect2);
		friend Vector2 operator*(const Vector2& vect1, Scalar value);
		friend Vector2 operator/(const Vector2& vect1, Scalar value);
		friend Vector2 operator*(const Vector2& vect1,const Vector2& vect2);
		friend Vector2 operator/(const Vector2& vect1,const Vector2& vect2);
	};

	inline Vector2::Vector2()
	{
	}

	inline Vector2::Vector2(Scalar x,Scalar y)
		: X( x )
		, Y( y )
	{
	}

	inline Bool Vector2::operator!=(const Vector2& vector) const
	{
		return X != vector.X || Y != vector.Y;
	}

	inline Bool Vector2::operator==(const Vector2& vect) const
	{
		return (*this != vect) == FALSE;
	}

	inline Vector2& Vector2::operator+=(const Vector2& pVector)
	{
		X += pVector.X;
		Y += pVector.Y;
		return *this;
	}

	inline Vector2& Vector2::operator-=(const Vector2& pVector)
	{
		X -= pVector.X;
		Y -= pVector.Y;
		return *this;
	}

	inline Vector2& Vector2::operator*=(Scalar num)
	{
		X *= num;
		Y *= num;
		return *this;
	}

	inline Vector2& Vector2::operator/=(Scalar num)
	{
		X /= num;
		Y /= num;
		return *this;
	}

	inline Vector2 operator+(const Vector2& vect1,const Vector2& vect2)
	{
		return Vector2(vect1.X + vect2.X,vect1.Y + vect2.Y);
	}

	inline Vector2 operator-(const Vector2& vect1,const Vector2& vect2)
	{
		return Vector2(vect1.X - vect2.X,vect1.Y - vect2.Y);
	}

	inline Vector2 operator-(Vector2& vect)
	{
		return vect * -1;
	}

	inline Vector2 operator*(const Vector2& vect1, Scalar value)
	{
		return Vector2(vect1.X * value,vect1.Y * value);
	}

	inline Vector2 operator/(const Vector2& vect1, Scalar value)
	{
		return Vector2(vect1.X / value,vect1.Y / value);
	}

	inline Vector2 operator*(const Vector2& vect1,const Vector2& vect2)
	{
		return Vector2(vect1.X * vect2.X,vect1.Y * vect2.Y);
	}

	inline Vector2 operator/(const Vector2& vect1,const Vector2& vect2)
	{
		return Vector2(vect1.X / vect2.X,vect1.Y / vect2.Y);
	}
}

#endif

VectorUtil.h

/*  __      __   ___     _____    ____
 *  \ \    / /  / _ \   |  __ \  |    |
 *   \ \/\/ /  / / \ \  | | / /  |  __|
 *    \_/\_/  /_/   \_\ |_| \_\  |_|
 *      Take it to the next Level
 *
 *  Copyright (c) 2009 Brian Ernst.
 */

#ifndef w_VectorUtil
#define w_VectorUtil

#include <cmath>

using std::sin;
using std::cos;
using std::sqrt;
using std::atan2;

#include "Vector2.h"

namespace _Warp
{
	class Vector2Util
	{
		static Scalar 	len(const Vector2& vect);
		static Scalar 	len2(const Vector2& vect);

		static Vector2& invert(Vector2& vect);
		static Vector2& normalize(Vector2& vect);
		static Vector2& clamp(Vector2& vect, Scalar value);
		static Vector2& setLength(Vector2& vect, Scalar value);

		static Vector2	polar		(Scalar x, Scalar y);
		static Vector2 	cartesian	(Scalar radius,	Scalar angle);
		static Scalar 	dot			(const Vector2& pVec1, const Vector2& pVec2);
		static Vector2 	rotate		(const Vector2& pVec, Scalar angle);
	};

	inline Scalar len(const Vector2& vect)
	{
		return sqrt(vect.X * vect.X + vect.Y * vect.Y);
	}

	inline Scalar len2(const Vector2& vect)
	{
		return vect.X * vect.X + vect.Y * vect.Y;
	}

	inline Vector2& invert(Vector2& vect)
	{
		return vect *= -1;
	}

	inline Vector2& normalize(Vector2& vect)
	{
		if(vect.X == 0 &amp;&amp; vect.Y == 0)
		{
			return vect;
		}

		Scalar length = len(vect);

		vect.X /= length;
		vect.Y /= length;
		return vect;
	}

	inline Vector2& clamp(Vector2& vect,Scalar value)
	{
		Scalar length = len2(vect);
		if(length &lt;= value * value)
		{
			return vect;
		}

		length = sqrt(length);

		vect.X *= value / length;
		vect.Y *= value / length;

		return vect;
	}

	inline Vector2& setLength(Vector2& vect, Scalar value)
	{
		if(vect.X == 0 &amp;&amp; vect.Y == 0)
		{
			return vect;
		}

		Scalar length = len(vect);

		vect.X *= value / length;
		vect.Y *= value / length;

		return vect;
	}

	inline Vector2 cartesian(Scalar radius,Scalar angle)
	{
		return Vector2(radius * cos(angle),radius * sin(angle));
	}

	inline Vector2 polar(Scalar x,Scalar y)
	{
		return Vector2(atan2(y,x),sqrt(x * x + y * y));
	}

	inline Scalar dot(const Vector2& pVec1,const Vector2& pVec2)
	{
		return pVec1.X * pVec2.X + pVec1.Y * pVec2.Y;
	}

	inline Vector2 rotate(const Vector2& pVec,Scalar angle)
	{
		Scalar cosResult = cos(angle);
		Scalar sinResult = sin(angle);

		//Essentially, apply a 2x2 rotation matrix to the vector
		Scalar newX = pVec.X * cosResult - pVec.Y * sinResult;
		Scalar newY = pVec.X * sinResult + pVec.Y * cosResult;

		return Vector2(newX,newY);
	}
}

#endif

Notes:

With this class, you can't do this:

Vector2 vect = 2;

This was possible with my old Vector2 class, and frankly should be an error.  If you are going to initialize the vars of a Vector2 at a later time, you can do this:

Vector2 vect = Vector2(Vector2::Uninitialized())

The reason for this is, doing this:

Vector2 vect = Vector2();

...creates a Vector2(0,0) by default. I could setup a default constructor and not use default values, however that could result in bugs from coders not properly initializing Vector2 objects. So, it is this reason the Uninitialized class is being used.

Feel free to use this improved Vector2 class, and if the c-style functions in VectorUtil bug you, feel free to make them member functions again in Vector2.

Download the Vector2 improved here: Vector2 class files.

[Update: As of 5/11/10 I noticed a typo, which I fixed, however I need to update the source files. I've also realized there are also a couple other utility functions I could "add", so will do so sometime soon; I got the idea from looking at another blog, however I realized he just named the functions to something easily understandable. For example, the dot and cross product; their names don't say anything about what the function really does, what the data represents. So, it seems useful to package up those functions to make it easier for programmers using this utility, and of course leaving the original functions in-tact (perhaps?) so other programmers looking for them won't be confused when they think they can't find them. So, more cool things to come! :) ]

Archive