Showing posts with label macros. Show all posts
Showing posts with label macros. Show all posts

Monday, January 25, 2010

Macros really are evil... :(

I knew my property system macros were fragile, and I ran into a fun one the other day when adding properties for the new level generators.  When loading up some test data my structure was getting turned into garbage, which I eventually tracked down to the second property in the struct having an invalid offset.  Thankfully Visual Studio's debugger is badass, and was able to find that I had accidentally setup a string property (12 bytes) into a string pointer (4 bytes), doh!

struct LevelPopulatorCreatureInfo
{
    TString* CreatureName;   // this shouldn't be a pointer, and throws off all other offsets by 8
    ...
}

ADD_PROPERTY(CREATE_PROPERTY_CUSTOM(LevelPopulatorCreatureInfo,String,CreatureName));

The question now is to add some verification asserts to the already convoluted macros, or should I bite the bullet and refactor the system to make the compiler do the type checking?  This might be a fun post to look back on in a couple months....

Monday, January 11, 2010

Macros are evil...

For some reason I thought it would be clever (and elegant) to wrap my property system declarations in some simple macros, which of course worked decently for simple cases...

DEFINE_PROPERTY_STRUCT(ACreatureClass,Range_Int,BaseXpValue));
DEFINE_PROPERTY(ACreatureClass,float,BaseEvasion));

The macro handles creating a new Property class instance and adding it to the DataType's list of properties, etc etc. Now recently I find myself add a new Property_Array class (now that I'm actually creating a game I have need of data driven lists), which worked out fairly well initially

#define DEFINE_PROPERTY_ARRAY(ClassType,PropType,PropName) Type->Properties.Add( new Property_Array(#PropName,GET_OFFSET(ClassType,PropName)) );

Which worked great for my test case for array of integers, but quickly fell apart once I wanted to make an array of enums (or for more pain, an array of structs of arrays...). I've since refactored the macros to support embedding of property creation within the array property creation macro, but it's turned into a real mess that I'm not proud of...

ADD_PROPERTY(CREATE_PROPERTY_ARRAY_EXT(ACreatureClass,ItemBodySlot,BodySlots,CREATE_PROPERTY_ENUM(ACreatureClass,ItemBodySlot,BodySlots,NumItemBodySlots,ItemBodySlots,ItemBodySlotNames)));

And with the (ab)use of the temporary LastProperty it's a pretty frail system, where any bit of manual monkeying when defining properties could very easy cause bad things. Alas I've resisted the temptation to refactor the entire system altogether for now (got to make a game you see!), but at least there's a nice juicy comment admitting the problems with the approach. As if that somehow makes it okay to write bad code....