templates everywhere

I want to say Great Job, Casey, it is so surprising how compelling viewing it is to watch you code up your game. Keep it up, we appreciate the mammoth effort you put in.

As I've been watching Casey tap away at his keyboard, I get this tingling in my fingertips, wondering how I might have gone about the coding.

Hi, my name is Peter, and I'm a c++ addict. :)

Having some free time this weekend, I chased down some of the things I'd been thinking about. The results are at

https://github.com/Raxfale/HandmadeHero

The code there implements an asset loader similar to the one Casey uses. I guess I'd say this is full on c++, not necessarily for the unfamiliar.

But for those who may be interested in the stl and other c++ features, you might pick up some titbits.

Cheers all.

And please, no c++ flamewar. I like c++, others don't. No-one here needs to defend themselves.
Casey often mentioned that one (but not he) might do the vector classes as templates.

For those interested in details, I've added one such implementation to the above repo. (lml.h and vector.h)
raxfale
Casey often mentioned that one (but not he) might do the vector classes as templates.

For those interested in details, I've added one such implementation to the above repo. (lml.h and vector.h)


What do your templated vectors offer over a simple implementation?

If I was to make a templated vector, I would do something like this:

[code=cpp]
template <typename T>
struct Vector2
{
union
{
struct { T x, y; };
struct { T r, g; };
struct { T s, T; };
};
};

template <typename T>
struct Vector3
{
union
{
struct { T x, y, z; };
struct { T r, g, b; };
struct { T s, t, p; };

Vector2<T> xy;
Vector2<T> rg;
Vector2<T> st;
};
};
// etc.
// And their needed functions
[/code]

Your generalization is just over kill and you ain't gonna need it.

Templates can be very useful but do not over use them.

Think about what you need; not what you think you will need.
His implementation avoids reimplementing for each Vector type functions like dot, length, lerp and all kind of operators +, -, etc... They all are same for Vector2, Vector3 and Vector1024. And you need such methods.
Yes, as Martins says, there are a lot of benefits to a metaprogrammed vector type. The problem with templatizing a vector class is not that metaprogramming linear algebra is bad, but rather just that C++ sucks. If C++ had good metaprogramming functionality, I would always parameterize my linear algebra routines. But my opinion on it is generally that C++'s metaprogramming is so bad that you are better off just writing your own code generator if you want to go that route, and that is why I advocate against the use of templates.

- Casey
gingerBill
If I was to make a templated vector, I would do something like this:

That is not generally how one templatizes a linear algebra vector. Typically you parameterize not only on the type of the element, but also on the number of elements, and then you write the operators as geometric algebra operators so that they work in arbitrary dimensions. This allows you to work in, say, 4D when you're writing Miegakure, or 2D when you're writing Braid, or whatever, and the math "just works".

Again, C++ is super shitty, so unfortunately it doesn't let you do what you want which is write the code cleanly once regardless of the vector types involved and whether or not they are compile-time or run-time sized. This is not all that hard to do in regular metaprogramming but it becomes an epic exercise in frustration in C++.

For something like Handmade Hero, where we are 2D/3D everywhere, it is pretty easy to just not templatize things, so I didn't, because the costs outweigh the benefits. But in other scenarios it is much nicer to metaprogram your linear algebra types and I would never discourage anyone from doing so, which is one of the reasons I explicitly mentioned people might want to do it on the stream.

- Casey
Could anyone point me to a write up about why Casey thinks C++ is so bad, I mean really specifically why? Not that I disagree; I'm coming to realize after 20 years of programming (basically all in C++) that I and trending towards going "back to C". But I would really like to understand the specific points that Casey might have.

Historically I would have this (in an RTS game):

class Tank;
Tank tank;
tank.draw3d();
tank.drawOnMinimap();

About ten years ago (still heavily mired in OOP) I started getting heavily into any and all permutations of "Model-View-Controller" in order to, in the above example, get away from "binding" all the various ways I might visualize something to the class / object, but after a while I realized that very many things that OOP / Design Patterns / yadayada tries to "solve" are a direct result of the bundling of "state and behavior" that classes / objects give you.

Conversely, in C (and I'm sure many other languages) data is "just data" and functions are "just functions", and hence you don't have to invoke a bunch of hand-wavey high level conceptual garbage like calling things MVC.

As I understand things now I would:

struct Tank;
Tank tank;
draw3d(tank);
drawOnMinimap(tank);

One might not think that is a big change, but for me it is fundamental.

A little bit after that realization I saw the Casey's original wonderfully ranty video on IMGUI, and it completely blew me away (I had coded tons of Microsoft Foundation Classes stuff). After a while I realized that it's the same principal all over again as the MVC thing; Casey specifically complains about OOPy widget systems storing tons of redundant STATE.

Nowadays it seems to me that everything is about carefully managed state, and really trying hard to never cache things (which OOP tends to make you do without thinking about it) or otherwise be redundant in what you are storing in memory unless you REALLY need to for performance reasons. Thinking about it that way it reminds me of relational theory (third normal form).

I guess the use of OOP or not is more beside the point, but it seems to me that using plain C really gets you into a more productive mindset (where data is data and functions are functions).

For example, in the 90s I always wondered how John Carmack could be so much "better" than myself and / or all the programmers I was working with. I eventually saw the Doom and Quake sources, and reflected immediately on the fact that the code didn't look at all like the code that we were producing (it was C, dammit, and isn't C++/OOP better!?!?!). I firmly believe that the style evidenced in these codebases is DIRECTLY related to productivity; it's just simply more to the point and gets stuff done.
I cannot believe I am saying this but one good thing about MatLab is its builtin math. It does have the problem that each element is a double but that's another issue. MatLab does perform better than an optimized C++ for generalized linear algebra but that is not surprising since that is what MatLab is built for and C++ templates are not brilliant.

I am not saying we should use MatLab as I think it is one the worst programming languages ever. It is a very good tools though is you just was linear algebra.

For general game development, I've never needed more than Vector6 Matrix6x6 etc. for general math but saying that, I not saying you should not templatize code if it worked well.

Again, this is all personal opinion, I personally will only write the code I will need now and not what I think I will need. If I know I will need a VectorN, then I will program that.
gingerBill

What do your templated vectors offer over a simple implementation?

Your generalization is just over kill and you ain't gonna need it.

Templates can be very useful but do not over use them.

Think about what you need; not what you think you will need.


Sure, I won't argue. I guess it comes down to what you think you think you need :)

In this vein, I'd like to point out that the ability to have functionally identical but discrete types is something I find important.

In HH, I would consider it an advantage to have a Color4 type that is discrete from a Vec4. Is there any functional difference? Perhaps not. I'd argue that they are conceptually different, but that isn't a practical difference. It would allow the compiler to catch when you passed a position to a colour argument.

Complete judgement call on whether you consider it worth the extra typing.

Would Casey agree ? I'm sure he will voice an opinion, but it is quite likely he just wasn't ready/too time constrained to type out another set of vector operations. A template solves that.