niedziela, 28 sierpnia 2011

Class method as template parameter

I had an interesting problem that can be solved using a little bit tricky C++ code. Imagine a singleton that holds some pointer to a class that has many methods with identical params, but different purposes. Now, imagine you're creating some wrapper for this class in some other class (the first one was a ID3D11Device in my case, so I didn't modify it) and your code is also identical, despite this single method call. You can obviously copy paste this problem, creating n-times more lines of code. But this is an ugly solution, so below I paste the nice one. Class A is the ID3D11Device, class B is my wrapper. In my case fun1 was enough (i knew A type while implementing this), but because i find this useful - i paste code for case with unknown A type. Of course in practice, fun1 and fun2 would be big functions with this single call embedded somewhere deep.

struct A {
void a(int param) { std::cout << "a " << param << std::endl; }
void b(int param) { std::cout << "b " << param << std::endl; }
};


struct B {
template< void (A::*F)(int) >
void fun1() {
A* a = new A; // obtain A, this may be singleton or anything else
(a->*F)(1);
delete a;
}


template< typename T, void (T::*F)(int) >
void fun2(T* t) {
(t->*F)(2);
}
};


int main() {
B b;
b.fun1< &A::a >();
b.fun1< &A::b >();


A a;
b.fun2< A,&A::a >(&a);
b.fun2< A, &A::b >(&a);


return 0;
}



The only aspect that may need some explanation at the moment is how to pass ID3D11Device method marked with STDMETHODCALLTYPE as template parameter. Notice, that STDMETHODCALLTYPE is just a macro for __stdcall. We can pass this additional keyword using syntax like:


template< HRESULT (__stdcall ID3D11Device::*CreateShader)(const void*, SIZE_T, ID3D11ClassLinkage*, ID3D11VertexShader**) >
bool load_(const char* filename) {
...
}

Ok, now for the real example - the code will be a little bit more tricky, because we have to use derived template param as param for functions used as template params, blah, compliacted - look at the code :)

template< typename ShaderType >
class Shader {
protected:
ShaderType* shader;
public:
Shader() {
shader = NULL;
}


virtual ~Shader() {
if(shader) {
shader->Release();
}
}


template< HRESULT (__stdcall ID3D11Device::*CreateShader)(const void*, SIZE_T, ID3D11ClassLinkage*, ShaderType**) >
bool load_(const char* filename, const char* entryPoint, const char* shaderModel) {
...
}


template< void (__stdcall ID3D11DeviceContext::*SetShader)(ShaderType*, ID3D11ClassInstance* const*, UINT) >
void bind_() {
...
}
};


class VertexShader : public Shader< ID3D11VertexShader > {
public:
__forceinline bool load(const char* filename) {
return load_< &ID3D11Device::CreateVertexShader >(filename, "mainVS", "vs_4_0");
}


__forceinline void bind() {
bind_< &ID3D11DeviceContext::VSSetShader >();
}
};


class PixelShader : public Shader< ID3D11PixelShader > {
...
};


class GeometryShader : public Shader< ID3D11GeometryShader > {
...
};


class DomainShader : public Shader< ID3D11DomainShader > {
...
};


class HullShader : public Shader< ID3D11HullShader > {
...
};


class ComputeShader : public Shader< ID3D11ComputeShader > {
...
};


Of course you may decide to make load and bind virtuals, and to pack them into some kind of manager - this is just a design decision, whether you want to automate use of those classes. In such case design would get a little bit more complicated. My load is virtual, bind isn't. Additionally, VertexShader is strongly coupled with VertexLayout (ID3D11InputLayout), which is created while loading, so my structure looks something like this:


środa, 24 sierpnia 2011

GNOMZ the game

GNOMZ is a WiiWare multiplayer hot seat action platformer developed by QubicGames. I worked over this project as lead programmer and project manager since january till august 2011. You can read more about this game on GnomzTheGame.com. I also wrote some paper about implementing AI in GNOMZ, you can read it here.






Reviews:
  • "I would say that Gnomz is an excellent multiplayer game"
  • www.gev.com


sobota, 6 sierpnia 2011

Smart Traffic Signs

Recently, I've been traveling more than 4k km by car, and I had some time to think about stuff not connected with gamedev. In Germany I've noticed a strange sign - speed limit depending on slipperiness of the road surface. It was strange, because there were no precautions if weather is ok, so you can go 300km/h if your car can, and in case of rain you can go only 80km/h, so it's quite discrete. And than the idea came - why not measure the state of the road and show the speed limit in electronic form. For example in dense rain - 80km/h, in snow - 50km/h, in light rain - 120km/h and so on. We kept going, and on the bridge there was a sign - in case of wind, 100km/h or something like this. The idea is even better here - just measure wind speed and show appropriate limits. The method is great because the sign can measure a lot of parameters at a time, and using some heuristics it can show the speed limit, or some other information. What other info? For example - imagine a sign showing a pedestrian crossing. If you go at night you usually can't see anything, so slowing down is the only option, but even going 50km/h is too much if someone enters the crossing. The solution is simple - show some additional info, that there is someone near the crossing, so that the driver knows that he has to stop, not only slow down. It's not easy to implement, but in my opinion it's not impossible. Smart signs can also take into consideration some other stuff, like traffic - read this. In my opinion, the method has almost no limits, and would really improve safety on roads. The only question is, will politics spend money on our safety? I don't think so, they need money for PR :)


Let's go further - the speed limit also depends on the car, for example big truck should have much bigger limits. Why not implement traffic signs... in cars? Imagine a display that shows you the limit, or in extreme it can even automatically limit your speed. The idea can be really simple - all traffic signs have some transmitters attached, that broadcast restrictions at some place (some norm would be required). Receivers collect those broadcast, and analyze them, for example taking into consideration mass of the car, state of it's tires and so on. But for now this is rather science fiction, because all cars would have to implement this. Maybe it's a good moment to start such revolution, this depends on motorization brands. Remember, that such a solution doesn't have to mean that we remove all "classic" signs - they can stay, we can just add some new features to them.