Sign in to follow this  
CCF

[C++] How are these function parameter done?

Recommended Posts

CCF    199
Hi there, I was wondering how a function parameter which takes multiple flags (seperated by | operator) like this works:
sprite->Begin(D3DXSPRITE_OBJECTSPACE | D3DXSPRITE_BILLBOARD | D3DXSPRITE_SORT_DEPTH_BACKTOFRONT);
I'd like to roll my own and would like some advice on how to handle all the possible combinations passed through it. The only way I could think of at the moment is to have a switch or if/else statement to handle them. Is this the right way or there's some better way to handle the multi combinations? Thanks! [smile] Quick pseudo code folllows:
enum StatusFX { POISON = 1, SLEEP = 2, CONFUSED = 4, ACID = 8, FROZEN = 16 };

void SetStatus(StatusFX flag)
{
   switch (flag)
   {
   case 1:
     // Do poison fx
   case 2:
     // Do sleep fx
   case 3:
     // Do poison and sleep fx
     .
     .
     . // Repeat with all possible combinations
     .
     .
   }
}

Share this post


Link to post
Share on other sites
feverzsj    133
look like that

#define STATE1 0x0001
#define STATE2 0x0002
#define STATE3 0x0004
#define STATE4 0x0008

int astate=STATE1|STATE2; //now astate includes STATE1 and 2
int astate=STATE1|STATE2|........ //

take them into binary form
and you'll see the key~

Share this post


Link to post
Share on other sites
yaroslavd    150
Yes, you use an if/else. But see how you set the flags using | or OR? Well, you get them using & or AND. So to see if the flag D3DXSPRITE_OBJECTSPACE was set, simply do this:

if (flag & D3DXSPRITE_OBJECTSPACE)
{
doSomething();
}

Share this post


Link to post
Share on other sites
jyk    2094
Quote:
Original post by CCF

enum StatusFX { POISON = 1, SLEEP = 2, CONFUSED = 4, ACID = 8, FROZEN = 16 };

void SetStatus(StatusFX flag)
{
switch (flag)
{
case 1:
// Do poison fx
case 2:
// Do sleep fx
case 3:
// Do poison and sleep fx
.
.
. // Repeat with all possible combinations
.
.
}
}
Generally the point of this approach is the allow multiple flags to be stored in a single integer value. You've got the first part right; the enumerated values need to be powers of two so that each corresponds to a single bit of the integer value type. The case statement doesn't make much sense though as it defeats the purpose of the bit manipulation. Here's a revised example:
enum { POISON = 1, SLEEP = 2, CONFUSED = 4, ACID = 8, FROZEN = 16 };

void SetStatus(size_t flag)
{
if (flag & POISON) { /* Do poison fx */ }
if (flag & SLEEP) { /* Do sleep fx */ }
if (flag & CONFUSED) { /* Do confused fx */ }
// And so on...
}
This is assuming that these states/values are not intended to be mutually exclusive (I infer this from your DX example above). If they are, then your original example is correct, other than that there's no particular need for the enumerated values to be powers of two.

Share this post


Link to post
Share on other sites
Anatol    178
Those flags are basically based on binary numbers.

For example
00000010
That could be a number but you could also think every digit(bit) is a boolean "flag" for something. Using your enumeration, the above 1 would signify POISON.

Now the | is the bitwise OR operator, and it does exactly that, bitwise OR.
To clarify, the following truth table is applied to every bit. (forgive the ascii art)

A | B | Output
---+-----+-------
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 1

I bet you've seen that before ;)

No when you type "CONFUSED | FROZEN" that really means 00000100 | 00010000.
Please note that this of course only works on multiples of 2, as you have quite intuitively done right in your enum.
I'm sure you can figure out the rest yourself ;)

EDIT: beaten like a punching bag

Share this post


Link to post
Share on other sites
Limitz    342
Hi,

the | operator is a binary OR. so: 0001 | 0010 = 0011
and: 0011 | 0010 = 0011

as you know 0001 = 1 and 0010 = 2, 0100 = 4 etc.
so your flag values should be powers of two.

now you can use the binary and, which is & to extract flag values.

0001 & 0001 = 0001
0010 & 0001 = 0000
0011 & 0001 = 0001
0011 & 0010 = 0010

so if you got the keys State1 = 1, State2 = 2, State3 = 4 and State4 = 8

a flag could be State1 | State3 => 0001 | 0100 = 0101;

if (flag & State1) printf("Yippie");

flag = 0101, so 0101 & 0001 = 0001, which is not 0 so is true;

flag & State2 == false


Hope i made it a bit clear ?
Greetings.

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