AS3: Testing For Optional Arguments and Combinations

263 views Asked by At

I'm revisiting some old code that filters XML, but this could easily apply to the parameters of a method (the way I'm using it, it essentially is). This is a problem I feel like I run into a lot and don't know a good way around this.

So the problem is that I've got 3 arguments. They're all optional. I want to see which ones are presents and test if their values based on which ones are present (sorted according to likelihood):

var shiftDown : Boolean = false;
var controlDown : Boolean = false;

if ( "@shift" in x )
{
    shiftDown = Global.stringToBoolean( [email protected]() );
}
if ( "@control" in x )
{
    controlDown = Global.stringToBoolean( [email protected]() );
}


if ( "@code" in x && "@shift" in x && "@control" in x )
{
    if ( KeyManager.keyIsDown( KeyManager[ [email protected]().toUpperCase() ] ) && ( KeyManager.shiftKey == shiftDown ) && ( KeyManager.controlKey == controlDown ) )
    {
        ...
    }
}
else if ( "@code" in x && "@shift" in x )
{
    if ( KeyManager.keyIsDown( KeyManager[ [email protected]().toUpperCase() ] ) && ( KeyManager.shiftKey == shiftDown ) )
    {
        ...
    }       
}
else if ( "@code" in x && "@control" in x )
{
    if ( KeyManager.keyIsDown( KeyManager[ [email protected]().toUpperCase() ] ) && ( KeyManager.controlKey == controlDown ) )
    {
        ...
    }       
}       
else if ( "@code" in x )
{
    if ( KeyManager.keyIsDown( KeyManager[ [email protected]().toUpperCase() ] ) )
    {
        ...
    }   
}
else if ( "@shift" in x )
{
    if ( KeyManager.shiftKey == shiftDown )
    {
        ...
    }
}
else if ( "@control" in x )
{
    if ( KeyManager.controlKey == controlDown )
    {
        ...
    }
}

else if ("@control" in x ) && ( "@shift" in x ) )
{
    if ( ( KeyManager.shiftKey == shiftDown ) && ( KeyManager.controlKey == controlDown ) )
    {
        ...
    }
}

I feel like there has to be a shorter way to write this with so much repetition in it's current form. Can someone suggest of a cleaner and more efficient way to write this?

Thanks for your thoughts.

EDIT: The if statement order was wrong. Changed that.

This can be generalized. I'm just including my code for clarity. If the general question is still unclear, which I get the impression it is:

What is the cleanest / most efficient way to test all combinations of exclusively optional arguments?

1

There are 1 answers

0
epologee On BEST ANSWER

I'm going to make a few assumptions here. From your example, I take it you want to perform tasks based on key presses. The XML seems to contain some kind of preferences, whether you want to enable or disable certain keys. You have two determined keys, shift and control, and one wildcard key based on the key code. If these assumptions are correct, you should be able to shorten things by combining the preference test and the actual key test on one line.

var shiftIsDown:Boolean = [email protected]() ? KeyManager.keyIsDown( KeyManager [ [email protected]().toUpperCase() ] ) : false;
var controlIsDown:Boolean = [email protected]() ? KeyManager.keyIsDown( KeyManager [ [email protected]().toUpperCase() ] ) : false;
var customIsDown:Boolean =  [email protected]() ? KeyManager.keyIsDown( KeyManager [ [email protected]().toUpperCase() ] ) : false;

I think the KeyManager lines are a bit strange. I'm not aware of a KeyManager in either Flex or regular AS3, so is this custom code? If so, you could put the upper case key code matching in there via something like a customKeyIsDown() method, instead of doing all that in here. Shift and Control are fixed anyway, so no need to reverse match the XML's value, right?

var shiftIsDown:Boolean = [email protected]() ? KeyManager.keyIsDown( KeyManager.SHIFT ) : false;
var controlIsDown:Boolean = [email protected]() ? KeyManager.keyIsDown( KeyManager.CONTROL ) : false;
var customIsDown:Boolean =  [email protected]() ? KeyManager.customKeyIsDown( x.@code ) : false;

I think this is already be a bit clearer, but again, I don't know what the KeyManager does exactly. After this you still have three variables, and they're all optional. If they all need to be exclusive, that leaves you with 8 possible outcomes.

if ( shiftIsDown && controlIsDown && customIsDown ) {
    // 1
} else if ( shiftIsDown && controlIsDown ) {
    // 2    
} else if ( shiftIsDown && customIsDown ) {
    // 3    
} else if ( shiftIsDown ) {
    // 4    
} else if ( controlIsDown && customIsDown ) {
    // 5    
} else if ( controlIsDown ) {
    // 6    
} else if ( customIsDown ) {
    // 7
} else {
    // 8
}

If what you're doing based on the keys is not exclusive though, you could go back to just performing the three key based tasks

if ( shiftIsDown ) {
    // 1
}
if ( controlIsDown ) {
    // 2
}
if ( customIsDown ) {
    // 3
}

Does this help? Cheers, EP.