Enum Madness!

Last time I wrote a class for a bitfield and a macro that allowed us to automatically size the bitfield storage based on size of flag set and platform storage sizes.  And that’s great and all, but we only went from something like Bitflag<unsigned int> m_flags to something like Bitflag<BITFLAG_SIZE(28)> m_flags.  It’s better from the perspective of what I was writing about in that last post, but you still have a hardcoded 28 sitting there, completely detached from the flag set it is trying to describe.  Wouldn’t it be great if you could feed your flag set directly into the BITFLAG_SIZE macro, and then changes to the flag set automatically change the macro, which changes the type?  Why, yes, yes it would.

So, can we do it?  Absolutely!  But, before we get to that answer, we’re going to take a detour through enums.

I love enums.  Especially unscoped enums wrapped inside of their own namespaces.  I use them all the time.  Most of that usage is to describe entries in a statically sized array, along the lines of this:

namespace CommandListLayers
{
  enum Layer
  {
    Read,
    Pivot,
    Write,
    NumberOf
  };
}

I have a system that uses an array of 3 command lists to move render data between the game thread and the render thread; the read layer, the write layer, and the pivot layer.  I can initialize the array with CommandListLayers::NumberOf, and any code I write can deal with each of the layers via the associated enumerator.  It’s clean and it’s easy.  I really like the NumberOf trick, but it’s also kind of tedious to always insert it at the end.  Or, being the stupid human that I am, maybe I forget to do it.  Who knows!  So, one day I came up with this dumb macro.

#define ARRAY_ENUM_BUILDER(name1, name2, ...) \
  namespace name1 { \
    enum name2 { \
      __VA_ARGS__, \
      NumberOf \
    }; \
  }

And that allows the enum declaration to look like this.

ARRAY_ENUM_BUILDER(
  CommandListLayers, Layer, 
  Read,
  Pivot,
  Write
)

So, I declared the namespace and enum name, all enumerator entries, and the NumberOf gets tacked onto the end with the correct value.  Great!  So, what does this have to do with my Bitflag class and the BITFLAG_SIZE macro?  Well, given the enum stuff I was already doing in my code, the next logical step was to do something like this.

namespace ProcessToggleFlags
{
  enum Flags
  {
    Lighting = (1 << 0),
    DepthOfField = (1 << 1),
    Wireframe = (1 << 2),
    DebugLines = (1 << 3),
    DebugText = (1 << 4),
    NumberOf = 5
  };
}

So, this is a little less great.  I have to manually assign a value to NumberOf since it would otherwise take the next integral value beyond (1 << 4), which isn’t 5, which is what I would want NumberOf to be in this case.  So, the macro as it exists for building enums that describe arrays isn’t going to cut it.  That’s where this template code comes in!

namespace enum_helpers
{
  template <unsigned long long T>
  struct enum_size
  {
    static const unsigned long long count = enum_size<(T >> 1)>::count + 1;
  };

  template <>
  struct enum_size<0>
  {
    static const unsigned long long count = 0;
  };
}

Using that template code, I can now create a new macro specifically to build enums for bitfields.  And that macro looks like this.

#define BITFLAG_ENUM_BUILDER(name1, name2, ...) \
  namespace name1 { \
    enum name2 : unsigned long long { \
      __VA_ARGS__, \
      Last, \
      NumberOf = enum_helpers::enum_size<Last - 1>::count \
    }; \
  }

Which allows my enum to becomes this.

BITFLAG_ENUM_BUILDER(
  ProcessToggleFlags, Flags, 
  Lighting = (1 << 0),
  DepthOfField = (1 << 1),
  Wireframe = (1 << 2),
  DebugLines = (1 << 3),
  DebugText = (1 << 4)
)

It works more or less the same as the ARRAY_ENUM_BUILDER macro, but it tacks on a Last entry with the sole purpose of being the parameter into the enum_size template, giving us the correct value for NumberOf when dealing with bit flags.  So, that’s great, right?  Now we can move from Bitflag<BITFLAG_SIZE(28)> m_flags to Bitflag<BITFLAG_SIZE(ProcessToggleFlags::NumberOf)> m_flags.  And that’s definitely better.  More or less where I want to be with this.

However, there are still some things I’d like to improve.  It would be nice if I could get the element count from __VA_ARGS__ or iterate over the contents.  Then I could generate the type of the enum, insert the shift values, and any necessary suffixes on the 1’s from inside the macro.  And it isn’t like it’s completely undoable, but it moves into the realm of really gross macro code.  Code I will probably end up writing for myself, but it’s not overly scaleable so I didn’t want to include it here.

But, that’s it.  This template and 2 macros make my life a lot easier.  Hopefully it will do the same for someone else.  Here is the download link if you want all of the source: EnumHelpers.hpp.  And if anyone has suggestions for improvements (especially for doing the things I mentioned in the previous paragraph!), I’d love to hear those.

Until next time!

Oh, Hey There: The Return (Also, I Do Things With Templates And Bitfields That May Or May Not Be Dumb)

Going long periods between blog posts has always been fairly par for the course for me, but this last break was pretty excessive even by my standards.  Two years is really just too long!  Of course, shortly after that last post I ended up getting a job at 343 Industries (which is, incidentally, amazing!) and I can’t really blog about what I do at work, which lead to said hiatus.  What are you going to do?  Go two years between blog posts, apparently.

Anyway, the last two years have predominantly been writing HLSL, and that’s been great and I love my job, but recently I’ve been starting to worry that my C++ is getting rusty.  Can’t let that happen, how would I feel superior to other programmers if I’m not pro at C++?  Right?  Right!  So, with Halo 5 shipped I’ve had a little more free time and a thought occurred to me that got me jump started back into writing some “real” code.  It’s a little bit of utility around a bitfield class, and I think that it’s useful, but I also couldn’t find any real reference to anyone else having done it.  That either means that I’m an absolute genius or there are very legitimate reasons why no one does what I’m about to show and I’m just not seeing them.  Which feels pretty likely, but you tell me!

So, I started with a bitfield class that just used an unsigned int as storage and had pretty basic bit and bulk getters and setters.  Nothing super fancy, but effective for what I was doing with it.  The next logical step was to template the storage type, and that was easy, which gave me the following code.

template <typename t_field>
class Bitflag
{
public:
  //Default Constructor
  Bitflag() : m_flags(0) {}

  //Initial Value Constructor
  Bitflag(t_field pFlags) : m_flags(pFlags) {}

  //Bit Get
  bool Get(t_field pIndex) const {
    return ((m_flags & pIndex) == 0) ? false : true;
  }

  //Bulk Get
  t_field Get() const {
    return m_flags;
  }

  //Bit Set
  void Set(t_field pIndex, bool pState) {
    // Optimized based on information found at 
    // https://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching
    // Safe to squelch this warning

    #pragma warning(push)
    #pragma warning(disable : 4804)

    m_flags = (m_flags & ~pIndex) | (-pState & pIndex);

    #pragma warning(pop)
  }

  //Bulk Set
  void Set(t_field pFlags) {
    m_flags = pFlags;
  }
private:
  t_field   m_flags;
};

And for the purpose of what I’m actually blogging about, the Bitflag class never actually gets any fancier or more complicated.  Instead, I looked at what I had, and I realized that rather than really using the flexibility of the templated type to optimize storage size for the class, I just got lazy and slapped every usage with unsigned int.  Which just took me back to where I was before I even templated the class.  The hell, right?  This lead me to the question, “Could I write code that, given the size of the flag set I want to be able to store in a Bitflag, would always set the templated type to the smallest appropriate type?”  And if the answer was yes, then it could serve a few purposes; actually optimize my storage size, automatically change if necessary as the size of the represented flag set changed, automatically change if necessary as I compiled on other platforms where storage sizes might be different.  That sounded great, so I dove into it, and it turns out that the answer is indeed yes.

I’ll start with the code that I ended up writing, and then I’ll explain what it’s doing, why I had it do that, and where it might go next.

#define BITFLAG_SIZE(val) BitflagHelpers::bitflag_type_selector<val>::value_type

namespace BitflagHelpers
{
  static const int g_bits_per_byte        = 8;

  static const int g_undefined_ushort     = -1;
  static const int g_undefined_uint       = -2;
  static const int g_undefined_ulong      = -3;
  static const int g_undefined_ulonglong  = -4;

  template <int t>
  struct bitflag_type
  {
    typedef int type;
  };

  // Be careful with this case when it comes to serialization
  template <>
  struct bitflag_type<sizeof(unsigned char) * g_bits_per_byte>
  {
    typedef unsigned char type;
  };

  // We protect from doubled specialization in the case that a type is 
  // the same size as the previous type by setting that instantiation 
  // to a negative global value.  Remove the warning for specing a 
  // signed value into an unsigned type.  Do something better later?
  #pragma warning(push)
  #pragma warning(disable : 4309)

  template <>
  struct bitflag_type<(sizeof(unsigned short) != sizeof(unsigned char)) 
    ? (sizeof(unsigned short) * g_bits_per_byte) : (g_undefined_ushort)>
  {
    typedef unsigned short type;
  };

  template <>
  struct bitflag_type<(sizeof(unsigned int) != sizeof(unsigned short))
    ? (sizeof(unsigned int) * g_bits_per_byte) : (g_undefined_uint)>
  {
    typedef unsigned int type;
  };

  template <>
  struct bitflag_type<(sizeof(unsigned long) != sizeof(unsigned int))
    ? (sizeof(unsigned long) * g_bits_per_byte) : (g_undefined_ulong)>
  {
    typedef unsigned long type;
  };

  template <>
  struct bitflag_type<(sizeof(unsigned long long) != sizeof(unsigned long))
    ? (sizeof(unsigned long long) * g_bits_per_byte) : (g_undefined_ulonglong)>
  {
    typedef unsigned long long type;
  };

  #pragma warning(pop)

  template <int t>
  struct bitflag_type_selector
  {
    typedef 
      typename std::conditional<(t <= sizeof(unsigned char) * g_bits_per_byte), 
        bitflag_type<sizeof(unsigned char) * g_bits_per_byte>::type,
      typename std::conditional<(t <= sizeof(unsigned short) * g_bits_per_byte), 
        bitflag_type<sizeof(unsigned short) * g_bits_per_byte>::type,
      typename std::conditional<(t <= sizeof(unsigned int) * g_bits_per_byte), 
        bitflag_type<sizeof(unsigned int) * g_bits_per_byte>::type,
      typename std::conditional<(t <= sizeof(unsigned long) * g_bits_per_byte), 
        bitflag_type<sizeof(unsigned long) * g_bits_per_byte>::type,
      bitflag_type<sizeof(unsigned long long) * g_bits_per_byte>::type>::type>::type>::type>::type value_type;
  };
}

So, the idea is that when you have a Bitflag variable, rather than specifying a type, you give it the BITFLAG_SIZE macro with the size of the flag set you want to be able to store.  So, instead of something like Bitflag<unsigned int> flags, you’d write something like Bitflag<BITFLAG_SIZE(28)> flags.  Under the hood, the macro uses a set of templates that take advantage of the C/C++ language standard that doesn’t define specific sizes for unsigned integral types, just relations; it says that unsigned char <= unsigned short <= unsigned int <= unsigned long <= unsigned long long.  Everything else works because of those relationships.

The bitflag_type specializations all check to make sure that any two adjacent types don’t have the same size, and set the specialization to a special value in that case to prevent double specialization, which would cause a compile failure.  In the case of Win64, unsigned int and unsigned long are both 32 bits, so the unsigned long spec ends up being -3 instead of 32.  And then it never gets used as a result, which is perfectly fine.

The final piece was the bitflag_type_selector, which makes use of std::conditional to allow the template specializations to be assigned to ranges.  Without that, it’d be pretty tedious to write all the code that’d allow anything but exact size matches to the types to be paired to the proper specialization of bitflag_type.  So, yay for std::conditional!

One thing to watch out for here is data serialization for a Bitflag that’s using an unsigned char for its storage.  Take the case of a flag mask of 33.  That will get serialized as 33 by any basic serialization scheme for an unsigned short, unsigned int, unsigned long, or unsigned long long, which is great.  But, for an unsigned char, it will see 3 and 3, which probably isn’t what you wanted.  It’s solvable for sure, but I feel it’s worth mentioning.  I did look into using uint8_t, but it turns out that this is very implementation specific, and a lot of implementations are just typedef’s of unsigned char anyway.

While not a requirement of this setup by any means, I like to store my flag sets in enumerations.  So, for me, the next step was to be able to feed the enumeration into the BITFLAG_SIZE macro and always get the right size.  I ended up doing that (with more templates), and that will be the subject of the next blog post.  One that hopefully comes sooner than this one did!  I guess we’ll see, I tend to have a problem keeping up with my desired posting schedule.

But that is the end of this post.  Hopefully you found this useful, and hopefully I’m not insane and/or stupid.  I welcome any feedback, and you are certainly welcome to use the code provided in whatever project you want.  If you do, I’d love to know about it!  Here’s the file if you just want to download it instead of copy/pasting the various blocks I posted above: Bitflag.hpp.

I’d also like to thank Brennan Conroy and Robert Francis for dealing with a full day of my inane ramblings and providing useful insight while I worked on this.  I probably wouldn’t be making this post if it wasn’t for their help.

Premake, FXC, And You

When I joined Team Fizz over last summer, I was introduced to the awesomeness that is Premake.  Shortly after that, this post on Bobby Anguelov’s blog introduced me to FXC and everything awesome that it could bring to the table.  I instantly wanted to use it.  The problem then became, how I can get Premake to generate projects and include the necessary custom build steps for my shader files to be able to utilize FXC?  I figured this would be a pretty common issue for people and it would either be intuitive to setup or there would be a lot of information online on how to make it happen.  I was completely wrong on both counts and I wasn’t able to make this work until just last night.

Semi-recently, Premake added support for two features that I felt could potentially solve my issue.  The buildrule function was supposed to allow me to set a custom build rule to files based on a configuration declaration, and this sounded like it would directly be the solution I was looking for.  I could just have the shader files in my project, the configuration declaration could look for files based on extension to apply the build rule to, and everything would work.  I’m not sure if we just didn’t set it up properly (the documentation for this feature isn’t great) or it just doesn’t work right, but it didn’t do what I needed it to.

The second option was project reference through the external function.  While less optimal, the plan was to manually create a project for my shaders, set the custom build tool on each shader file to use FXC, and then have Premake just add this project into the sln when it creates and links in all other projects.  This is what ended up working for me, so I thought I would document what I did in case anyone else runs into this issue.  I know I would have appreciated it about 6 months ago.

In your build script, assuming a current enough version of Premake, you can use the external command to reference a pre-existing project into the sln being made.  Just slide the command in anywhere that you would add “project” for a project that you wanted Premake to autogenerate, and make sure that you add the name to the startup project’s links so that the proper build dependency is made.  Here is what mine looks like:

 

 

Shader is the name of my vcxproj, which is what comes after external.  It’s also in a folder named Shader at the root of my sln directory, which is what goes in location.  Setting the kind to StaticLib (and making sure you actually set the project to match) might not be necessary, but it fit the rest of the architecture of our engine.  Uuid can be found by opening your vcxproj in notepad and looking for this:

 

  <PropertyGroup Label=”Globals”>
    <ProjectGuid>{7CF9442C-12F8-4675-9CE2-D54FEC4C31D0}</ProjectGuid>
    <RootNamespace>Shader</RootNamespace>
  </PropertyGroup>

 

Once you have the project made, setup, and your buildscript ready, you just need to setup your shader files’ properties to use FXC.  The link to Bobby’s blog from earlier in this post completely details the process so I won’t repeat it here.

So, there you have it.  I won’t say this is the best way to accomplish what I wanted, or even necessarily a good way, but it’s a way and it works for me.  Hopefully if anyone finds themselves in the situation I was in, it will be helpful.  And if anyone has a better way to solve this, please let me know; I would love to get that kind of feedback and improve things.

CS380 Project 1, Having Fun Outside Of Game

Shifting gears ever so slightly, I thought I’d make a post about my first CS380 project.  CS380 is a class on game AI and the first project is to implement something inside of the provided State Machine Language framework.  The only limitations are that we have to implement at least 3 state machines, at least 15 states between them, and then at least 10 unique features from a list we were given.  Otherwise, we’re free to simulate anything we want, modify the code base to handle new graphical, audio, etc features, anything at all.

I made the choice to simulate a parody of my game team.  There are 4 programmers and 1 producer.  They all have fatigue and anger levels they have to manage.  When anyone is too fatigued, they go on break until they get rested.  When working, programmers will either fix bugs if they have any assigned to them or create bugs if not.  After either, they will do a small compile, during which they just sit there and reduce fatigue slightly.  If any bugs are unassigned, the producer will assign them out.  Otherwise, he will pick between doing scheduling or calling a meeting.  When a meeting is called, everyone drops whatever they’re doing and attends.

Now, this is where it gets good.  When scheduling, the producer increases his anger towards individual programmers based on how many outstanding bugs are assigned to them.  During meetings, programmers increase anger towards the producer, and they also incur fatigue at a doubled rate.  When a programmer reaches his anger threshold, he quits. When the producer reaches his anger threshold with a specific programmer, he fires him.  Any unemployed programmer switches state machines to “homeless bum”.  Homeless bums will either spend 20 seconds crying in the alley or go beg the producer for their job back.  And so, the simulation is highly cyclical, but each cycle typically devolves into the producer constantly calling meetings and everyone becoming very angry and unemployed.

What started as parody ended up hitting a little closer to the mark than intended as far as the average Digipen team goes.  So, it was hilariously successful.  My only regret was not starting early enough to have time to change the graphics framework to load in extra models and animations to make the visuals match the logic.  Also, this was the first school project outside of game class where I felt compelled to put in extra work to make something specific because I wanted to and not because it was worth any class credit.  It was totally worth the effort.

 

Tagged