Let's do this, say you want to draw a box and of course you want to draw the box. You could store the full 32 bit color and have the user choose the color out of the 4 billion choices or you could set it up so they are limited to a simpler palette using bit flags.
Code: Select all
enum ColorFlags
{
BLACK = 0x0,
RED = 0x1,
GREEN = 0x2,
BLUE = 0x4,
WHITE = 0x8
};
struct Box
{
int x, y, w, h;
char color_flags;
};
Code: Select all
void Graphics::DrawBox( Box const& box )
{
unsigned int add_white = ( box.color_flags & ColorFlags::WHITE ) != 0 ? 128 : 0;
unsigned int red = add_white, green = add_white, blue = add_white;
if( box.color_flags != 0 )
{
if( add_white != 0 )
{
red += ( box.color_flags & ColorFlags::RED ) != 0 ? 128 : 0;
green += ( box.color_flags & ColorFlags::GREEN ) != 0 ? 128 : 0;
blue += ( box.color_flags & ColorFlags::BLUE ) != 0 ? 128 : 0;
}
}
unsigned int color = ( 255 << 24 ) | ( red << 16 ) | ( green << 8 ) | blue;
for(int y = box.y; y < box.y + box.h; ++y )
{
for( int x = box.x; x < box.x + box.w; ++x )
{
PutPixel( x, y, color );
}
}
}
if the WHITE flag is not set, then you could get black, dark red, dark yellow, dark green, dark cyan, dark blue and purple.
If WHITE is set you could get gray, red, yellow, green, cyan, blue, magenta or white.
You as the developer save some time by not having to type out or make enums for each of the different colors and you save 3 bytes per box object by not storing the 4 bytes of color per box object. By not creating the 15-16 enums, you also don't have to write a switch statement to convert each flag into a color though there would be a lot less thought needed. Sounds like a win on some level, but what about performance? What if these flags had a different meaning? What if some combination of flags didn't make sense?
Now, let's say you wanted to have the behavior of an object be decided on flags.
Code: Select all
enum ActionFlags
{
IDLE = 0x1,
WALK = 0x2,
RUN = 0x4
};
struct Character
{
ActionFlags action = ActionFlags::IDLE;
};
So why do I bring this up? Surely people don't do this do they?
Well, they do. Just take a look through the Win32 API. There are a metric shit ton of flags and in some cases ( probably most cases ) certain flags don't make sense to be combined and the function call will fail if you try. I know the Win32 API is outdated and can't be changed. I know from a certain point of view it's easier to just create a bunch of flags to change the behavior of an object instead of just creating different versions of the object. I'm sure in each one of those functions they have a chain of if statements checking to make sure the users ( us ) don't try anything stupid and even more if statements to direct the behavior in the way we intended it to behave.
IF THIS FLAG IS SET DO THIS
ELSE IF THIS FLAG IS SET DO THIS
ELSE IF THIS FLAG IS SET DO THIS UNLESS THIS OTHER FLAG IS SET THEN FAIL
I think it also pretty lazy to write a EnableThis() function passing in a bool ( or BOOL in C ) to determine if it should be enabled. Why not write EnableThis() and DisableThis(), nope they write a
Code: Select all
EnableThis( BOOL bIsEnabled )
{
if( is_enabled != bIsEnabled )
is_enabled = bIsEnabled;
}
THE C LANGUAGE NEEDS TO DIE AT THIS POINT!!!
Anyway, that's my rant for the month I hope.