Why doesn't this work?

BlitzMax Forums/BlitzMax Programming/Why doesn't this work?

Sean Doherty(Posted 2006) [#1]
The following works:

Select m_kClickState
Case kSelected | kClicked 
DrawImage(m_pTClickedImage, m_iX + m_dOffsetX, m_iY + m_dOffsetY) 


The following does NOT work:

Select m_kClickState
Case kSelected | kClicked | kActive
DrawImage(m_pTClickedImage, m_iX + m_dOffsetX, m_iY + m_dOffsetY) 


Isn't the | just an or operator?

Thanks


bradford6(Posted 2006) [#2]
| is a bit wise OR.


you need to look at what your variables hold in their "bits"

example:
1 = 00000001
2 = 00000010
4 = 00000100
8 = 00001000

7 = 00000111

8|7 is the same as 8|4|2|1


| sets a bit to 1 if one or both of the corresponding bits in its operands are 1, and to 0 if both of the corresponding bits are 0.


Sean Doherty(Posted 2006) [#3]
If there another or for a case statement I can use?


H&K(Posted 2006) [#4]
| is a bit wise OR

And? Thats what or is, and more importantly what sean is trying to do

@Sean you are using Case wrong, use an If statement instead

What uou have saiod do is select the case to run on the value of m_kClickState, the or (as has been said) just changes the value of the case

se;ect m_kClickState
    case clicked
        select active
           case true
           case false



bradford6(Posted 2006) [#5]
try using a shl:

kSelected = 0
KClicked = 1
kActive = 0

Print kSelected | kClicked Shl 1 | kActive Shl 2

this will create a unique outcome for each combination.

00000001 SHL 1 = 00000010

it just shifts the bits "1" to the left.


SculptureOfSoul(Posted 2006) [#6]
you could use the OR operator - which is a logical OR.

Case kSelected OR kClicked OR kActive


What you are doing is, as Bradford said, bitwise or'ing your cases together.

So while you think you are doing something like this

Case 1 (or) 2 (or) 3 (or) 4

the program sees that as "Case 7" because
1: 00000001
2: 00000010
3: 00000011
4: 00000100
----------------

=: 00000111 = 7

The OR operator however, simply returns true when any of the conditions are true.

A handy efficiency tip is to put whatever condition is most likely to be true first in your OR sequence.

ie. Lets say you have condition 1 that is true 10% of the time, and condition 2 that is true 75% of the time. In an OR conditional statement, it is more efficient to put condition2 first, e.g.

condition2 OR condtion1

since ANY true result will cause the OR evalutation to return true. If you put condition1 first, the 90% of the time that it isn't true the program will have to check both condition1 and then condition2. Putting condition2 first will result in the OR statement ONLY checking condition2 the 75% of the time that it returns true.

The opposite is true for AND statements. Logical AND returns false when any of its test statements are false, so it's wisest to put whatever statement is most likely to return false first in the series.


SculptureOfSoul(Posted 2006) [#7]
Nevermind, you can't use a Logical OR in a case statement it seems.

I'd just switch it to an if statment.

If m_kClickState = kSelected OR kClicked OR kActive

works.


SculptureOfSoul(Posted 2006) [#8]
Of course, the solutions I proposed are assuming that the states kSelected, kClicked and kActive are all mutually exclusive.

If, on the other hand those states can exist simultaneously, you will need to use a bitwise or to see if any of them are active.

I'd do it like this

if ( (m_kClickState AND kSelected) OR (m_kClickState AND kClicked) OR (m_kClickState AND kActive))

The above will return true if any of the following are true

ClickState AND kSelected (true if the kSelected bit is set in clickstate)
ClickState and kClicked (true if kClicked bit is set in Clickstate)
ClickState and kActive (true if kActive bit is set)

Of course, this would require kSelected, kClicked and kActive all to have their own single bit identifier. e.g.

global kSelected = %00000001
global kClicked = %00000010
global kActive = %00000100


Warren(Posted 2006) [#9]
According to the BlitzMax documentation, you just have to put a comma between each one. So:

Case kSelected, kClicked, kActive

However, if you're testing bit flags then it gets more complicated and "Select/Case" probably isn't what you want to be using anyway.