Advertisement

is there a brighter way to check a variable if it's bit is set?...

Started by May 16, 2002 12:15 PM
13 comments, last by mickey 22 years, 5 months ago
i was thinking about the functions in windows on how they do it..., ie,

#define ACTIVATEA 1
#define ACTIVATEB 2
#define ACTIVATEC 4

void Activate(DWORD flags)
{ 
   switch(flags)
   {
   case 1: ... // activatea
   case 2: ... // activateb
   case 3: ... // activate a and b
   case 4: ... 
   case 5: ... 
   case 6: ... 
   case 7: ...
   }
}

[code/]

well, what if i get over a dozen of defines to be flagged....? 

thanks, 
  
    
http://www.dualforcesolutions.comProfessional website designs and development, customized business systems, etc.,
if(flags & ACTIVATEA)...// 1 set 


Forever trusting who we are
And nothing else matters
- Metallica
Forever trusting who we areAnd nothing else matters - Metallica
Advertisement
Your goal should be to make each bit its own flag.

BYTEs have 8, INTs have 16, LONGs have 32.

Examples:

#define AFFECTED_BY_GRAVITY 1
#define LIGHT_SOURCE 2
#define ON_GROUND 4

// Setting flags
object.flag = AFFECTED_BY_GRAVITY | ON_GROUND
(the | operator is and OR operation, allowing you to set multiple bits at once)

// Testing flags with some pseudocode:
// If object is affected by gravity and is NOT on the ground, apply gravity to it
if ((object.flag & AFFECTED_BY_GRAVITY) && !(object.flag & ON_GROUND))
IterateGravity(object);
(& is the AND operator, tests if bits are set)

Does that help at all? Feel free to expand on it, anyone

[edited by - Waverider on May 16, 2002 1:32:50 PM]
It's not what you're taught, it's what you learn.
no guys, what i did is also the same with you guys, actually waverider, i think you''ve made it more longer and more err.., unclean,

what am trying to ask is, is there a brighter way to do this because, what if i gave all the 32 bits a value., okey for example, 3 bits can have err., 7 combinations right? the more bits the more combinations obviously, now if i used all the bits in a DWORD, that would be tremendous amount of combination right? so is there a brighter way around what i did?

thanks!
http://www.dualforcesolutions.comProfessional website designs and development, customized business systems, etc.,
seeing as you need to define the action of each case, it seems impossible to avoid a separate line defining the action of each case. however, in determining which case to take, that can be done in one line.

i''m not sure what your activation is for, but if it''s in determining which game state to go in, this may be useuful.

consider an array of function pointers. first you define each case as a function. then in your function pointer array (let''s call it State), you just go State[statetype](); And it''ll go into the appropriate function of the desired case.

to resolve #defining a whole bunch of state IDs, you can use an enum. this way, you won''t have to worry about accidentally defining two IDs with the same number. However, if you are later saving these state id''s in a file [for whatever reason], be careful, as it''ll change if you delete one of the ids from the enum list.

umm.. it sounds like a lot of work, but if you''re skeptical consider this.... you have to define each case in your switch-case statement anyways.. so the setup in assinging the function pointers is comparable... however, in the lookup, this function-pointer-array scheme may work better as you are not doing however many if statements to check whether you have the correct case (even your switch-case does that).. .it will only take one set of instructions to go to the correct case. in other words, as the amount of cases grows, the cost of finding the correct case does not.

but then again, you can argue about cache hits and misses, but i won''t.

hope it helps
~queasy
Jonathan Makqueasy gamesgate 88[email=jon.mak@utoronto.ca]email[/email]
quote: Original post by mickey
no guys, what i did is also the same with you guys, actually waverider, i think you''ve made it more longer and more err.., unclean,


There is a subtle difference between what you wrote and what Waverider wrote. He has a series of ifs which check specific bits, you have a big switch statement which checks every possible value. The difference is, to catch every possible flag combination in a 32 bit int, Waverider''s technique requires 32 if statements. Your approach would require somewhere in the region of 4 billion switch cases. Given that fact, I think Waverider''s approach is slightly cleaner

Queasy''s approach is probably the cleanest, you could just loop through all the bits, and call a function pointer depending on whether a given bit is defined or not.

You could probably also do with templates, but we won''t go into that here....

Advertisement
quote: Original post by Sandman

He has a series of ifs which check specific bits, you have a big switch statement which checks every possible value. The difference is, to catch every possible flag combination in a 32 bit int, Waverider''s technique requires 32 if statements. Your approach would require somewhere in the region of 4 billion switch cases.


er., ain''t my code is the same? say for example if ''flags == ACTIVATEA | ACTIVATEB'' then ''case 3:'' would be executed right? so it''s the same as, ''if(flags & (ACTIVATEA | ACTIVATEB))''... so every identifier i included in my switch-case statements are all valid? so why would i have a whole lot more than his, it should absolutely be equal...

okey sorry for not being clear with my activate word, it means initialize this and that etc.., the flags should be used to identify what dx component that i''ll be using, so then i''ll have around 7 or so combinations which will be a lot of lines of codes if i can''t come up with a same solution but shorter lines,

anyway, pls see if i did get you guys, say i have 7 kinds of init flags right? so i should make myself an array[7] in which each element pertains to each of the flags, so in my functions... say forexample i used ACTIVATEA and ACTIVATEC, so i''ll start my search first with array[0]... okey match found.., then array[1], no match then array[2], match found again.., etc.., wow kewl thanks this is really really a hell lot shorter pls faster..,

btw, do you think in DX, say forexample in Creating a surface in which you combine multiple flags in a single statements(ie, ddsd.dwcaps.ddscaps.orsomething = flaga|flagb|flagc) right? how do you think they parse this?

thanks guys i''ll go and try this thing out now, but pls if i misunderstood correct me, many thanks again,
http://www.dualforcesolutions.comProfessional website designs and development, customized business systems, etc.,
No, your code is not the same. In Case 1 you check if the parameter passed to the function is the number 1. This will not be the case if you have combined several flags. ACTIVATEA|ACTIVATEB=00000000000000000000000000000011b=3. The compiler can't see that 3 is a combination of 1 and 2. You have to check the individual bits like Waverider did.

Am I making any sense?

--
So Long To Red Dye #2

[edited by - pafcu on May 17, 2002 11:28:58 AM]
-- So Long To Red Dye #2
A couple of things.

First, if you have a lot of defines, then enumerate them!
Example:

enum{
GRAVITY,
MOVE_LEFT,
MOVE_RIGHT,
MOVE_JUMP,
ANI_WALK,
ANI_JUMP,
ANI_FALL,
ANI_CLIMB,
ANI_IDLE,
};

The first enumeration is zero by default, and the rest increment up by 1.

Another Idea is to catagorize the flags with a flag in the upper WORD that you could use to presort, and then the lower word would have the value you would act on:

enum{
MOVE_LEFT = 1<<16,
MOVE_RIGHT,
MOVE_JUMP,
};

enum{
ANI_WALK = 2<<16,
ANI_JUMP,
ANI_FALL,
ANI_CLIMB,
ANI_IDLE,
};

That''s a 1 bitshifted into the upperword.

To presort, I would do a switch stucture like this:

switch (HIWORD(FLAG))
{
case 1:
{
MoveSortorDispatch(FLAG);
}
case 2:
{
AniSortorDispatch(FLAG);
}
}

This is somewhat like a proto-messaging system.

Also, there are various ways of checking bits,
Check out these keywords: HIWORD, LOWORD, HIBYTE, LOBYTE, enum
guys!

there's no loop involved here!

const int NUM_OF_STATES 256;
void (*StateFn[NUM_OF_STATES])(); // this is your array of states

enum {
STATE1,
STATE2,
STATE3
};

void State1() {
//do state1 stuff
}

void State2() {
//do state2 stuff
}

void State3() {
//do state3 stuff
}

void InitStates() {
StateFn[STATE1]=State1;
StateFn[STATE2]=State2;
StateFn[STATE3]=State3;
}

void RunState(int flag) {
StateFn[flag](); // this is where it chooses a state to run.
}

void main() {
InitStates();

// do whatever you want to figure out which state you are in.
RunState(flag);
}


//sorry for bad formatting, i don't know how to tab in this thing


i hope it's clearer now.
-j

[edited by - queasy on May 17, 2002 2:52:00 PM]
Jonathan Makqueasy gamesgate 88[email=jon.mak@utoronto.ca]email[/email]

This topic is closed to new replies.

Advertisement