• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Assassinbeast

is class templates made in gamedevelopment?

9 posts in this topic

Hello smile.png

 

I just learned templates, and i know quite abit right now.

 

So i just wanted to ask if there is any situation where you want to make your own class template. Becasue vectors already exist, and i cant really imagine when you should even need to define your own class templates.

 

But i know defining your own function templates are very useful in alot of kinds situations

0

Share this post


Link to post
Share on other sites
I don't fully understand templates, but I do know that they are agnostic of the purpose of your code. Game development or otherwise, if a part of your code will benefit from their use, use them. They are commonly used in resource management in game development.

Just make sure to use them where they make sense and for their intended purpose. Overuse is bad. Just because you can, doesn't mean you should. Edited by MarkS
1

Share this post


Link to post
Share on other sites

I'm working on some right now (IDE open in another window), wrapping boost::any and creating a Property type for config files.

 

Here's one from a 2d API called SFML:

[code]template <typename Type> struct Point2D //Actually it's called 'Vector', but it's a math vector not an array vector. {       Type x;       Type y; };   typedef Point2D<int> Point2i; //Integer point. typedef Point2D<float> Point2f; //Float point.[/code]

(This is a bad example, because it might lead someone to think all their classes should template-define their member variable types - but SFML actually has a reason for doing this)

 

Don't go template-crazy, but they definitely have their uses. Most classes don't need to be templates, but some do. Most functions don't need to be templates (and should rather be overloaded functions), but some do.

 

A few months ago I wrote a resizable templated container similar to std::vector but 2D, and that supports negative positions as well as positive.

 

templates are also used for meta-programming in C++ (C++11 added alot of meta-programming helper classes), where you can write code that runs and does calculations during compilation instead of during the program's execution, which has benefits as well.

2

Share this post


Link to post
Share on other sites

Templates can come in handy when you want to create a resource manager that can manage different type of resources. That is what i did in my engine. I have a ResourceManager class which is templated and the i have ResourceManager<Shader>, ResourceManager<Texture> for example.

0

Share this post


Link to post
Share on other sites

We use templates for a lot of different things.  I am going to (mostly) focus on how templates can prevent you from making errors in your code.  I think this is a frequently overlooked when people considers templates.

 

1) Data Structures.  Just because the STL provides some doesn't mean it has all of the data structures you need.  In addition, very few commercial game companies use the STL (and you should atleast know why).  One simple one that you could write would be a range checking array.  If the operator [] functions are inlined a good compiler will optimize it out completely.  However, in debug builds you can throw in an assert that will catch these out of range errors that will save you a lot of debugging time.  To get you started:

template <typename TYPE, int ARRAY_SIZE>
class RangeArray {
public:
     STATIC_ASSERT(ARRAY_SIZE > 0);
     TYPE& operator[](int idx) { Assert(idx >= 0 && idx < ARRAY_SIZE); return m_array[idx]; }
private:
    TYPE m_array[ARRAY_SIZE];
};
RangeArray<int, 5> myArray;
printf("%d\n", myArray[0]);
int someIndex = 2 * 2 * 2;
int i = myArray[someIndex]; // this will compile, but it will not fail silently at runtime

2) Static assertions are very useful for catching bad code at compile time.  If you want to limit the overloads to a certain type by providing all of the possible overloads and throwing a static assertion into the main templated function.  Or not even define it at all, just declare it.  If you can catch the error at compile time it is a lot better than at runtime.  Especially since assertions often aren't of the fatal variety if you are working on a large project.  Here's a somewhat practical example, with a Vector3.  The range and size of the structure is known and constant, so we can use non type template parameters.

class Vector3 {
public:
    // If the index is not 0, 1, or 2 it is known to be invalid!
    template <int idx> float getElem() const { STATIC_ASSERT_FAIL_MSG("Invalid element index!"); } 
    template <> float getElem<0>() const { return x; }
    template <> float getElem<1>() const { return y; }
    template <> float getElem<2>() const { return z; }
private:
    float x, y, z;
};
Vector3 someVec;
float atElem0 = someVec.getElem<0>(); // OK
float atElem4 = someVec.getElem<5>(); // ERROR will not compile

3) Compilers can inline templates and the optimizations made possible with inlining can be quite remarkable.  It is what makes them superior to function pointers (and is largely why std::sort trumps qsort).  It's also extremely useful in the form of delegates and functors.  Even if you use the stl, you will need to define your own functors all the time to process your custom data.  

 

4) Strings.  It is a pain to support code that works with 8 bit, 16 bit, and 32 bit characters.  If you ever embark on localization or code that otherwise needs to support both at runtime the only sane way to do it (in my opinion anyways) would be with templates.  Certainly better than using the preprocessor all over the place to route it to the equivalent call.  

 

In addition, I frequently don't really know how large statically sized arrays should be when I do string concatenations on c-strings.  A frequently unknown benefit of templates is that they can take the size of the array as a parameter.  Alloca won't work here because we can't get the string sizes if they aren't constructed yet.

template <typename CHAR_TYPE, int ARRAY_SIZE>
INLINE CHAR_TYPE * string_format(CHAR_TYPE ( & dest) [ARRAY_SIZE], const CHAR_TYPE * fmt, ...) {
    va_list argp;
    ASSERT_ONLY(int numWritten =) vsprintf(dest, fmt, argp); // yes I know this will only work with char and not wchar_t...
    SLOW_ASSERT_MSG(numWritten < ARRAY_SIZE && numWritten > 0, "Array not big enough!");
    va_end(argp);
    return dest;
}
const int kStrArraySize = 256;
char strArray[kStrArraySize];
string_format(strArray, "Entity Position: %f, %f, %f\n", entPos.x, entPos.y, entPos.z);
DebugDrawString(entPos, strArray);
// if we do a bunch of string formatting on this array and make debug drawing calls and it overflows, we can // go back and change it in ONE place.  We don't have to find all of the places we passed kStrArraySize and // change that too.

This will catch an array overrun without silently thrashing memory.  Or at least without you having to check the return value on vsprintf every time yourself.

 

5) Catching errors in casting pointer types.  This can be a real lifesaver when you have a message/event system that uses base ptr data.   dynamic_cast is almost always a sign of bad design, but don't underestimate your ability to make a mistake when casting.  NOTE: dynamic_cast requires the from type has a vtable!


// this code assumes LPTR_TYPE and RPTR_TYPE are pointer types, although there is a template for that too :)
template <typename LPTR_TYPE, typename RPTR_TYPE> 
FORCE_INLINE LPTR_TYPE smart_cast(RPTR_TYPE right) { 
#if _CPPRTTI 
    Assert(!right || dynamic_cast<LPTR_TYPE>(right)); 
#endif 
    return static_cast<LPTR_TYPE>(right); 
}

This was extremely useful for pool allocated data seen in message passing and event systems.

 

6)   Also great when making assignments between numerical types with different bits of precision.  For example, lets say we have a U32 but need to pass it as U16.  

template <typename LTYPE, typename RTYPE>
LTYPE& Assign(LTYPE& assignedTo, const RTYPE assigned) {
    assignedTo = assigned;
    Assert(assignedTo == assigned); // this will fail if there weren't enough bits in LTYPE to store RTYPE
    return assignedTo;
}
   // example code that isn't really practical
   U32 src = U16_MAX + 5;
   U16 dest = 0; 
   Assign(dest, src); // this will not fail silently anymore

7) Other things I have found templates to be useful for.

    - Component Entity Systems

    - Your own RTTI system (this will usually require the preprocessor, a virtual function, and a hash code too)

    - Permutations/Shuffling in vector libraries

    - Some of my coworkers love it for serialization code.  That's not really something I can say I'm an expert on but leaving it here anyways.

    - Static Assertions themselves

    - All that metaprogramming stuff

    - enum range checking at compile time

    - avoiding virtual functions

    - a bunch of other things I haven't mentioned...

 

But don't underestimate how much time it will save you from the errors it can catch in your code.  Most of this should compile out cleanly in release builds!

Edited by l0k0
2

Share this post


Link to post
Share on other sites

Very excellent post!

 

1) Data Structures.  Just because the STL provides some doesn't mean it has all of the data structures you need.  In addition, very few commercial game companies use the STL (and you should atleast know why). 

 

Just for clarification and summary of the EASTL page that was linked to: EASTL is more directed towards development of triple-A games and to games targeting game consoles. Indie game developers for PC/Mac/Linux are perfectly fine when using the standard library.

0

Share this post


Link to post
Share on other sites
Since I'm still using VS2008 (I will update soon... Soon... Soon...) I don't have access to std::unique_ptr, which means that I have to write RAII templates for API objects that are destroyed by things other than delete.

I'm looking at YOU, COMReleasable...
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0