How to use ASSetPropFlags in ActionScript 2.0
ASSetPropFlags lets you modify the following three flags of an object's child properties.
- Write Protection: When a child property is write protected, its value can no longer be modified.
- Delete Protection: When a child property is delete protected, it can no longer be deleted from its parent.
- Hidden: When a child property is hidden it is no longer processed in a for..in loop enumerating over its parent's children.
These flags are usually modified for one of two reasons.
- You can protect properties of an object you made to prevent user's of your code from modifying variables that should remain constant.
- You can remove restrictions on properties of libraries you are using. For example, you could disable write protection of a function such as Mouse.show() and then set it to execute a new function of your own.
Now that we've covered the purpose of ASSetPropFlags, let's take a look at the function prototype and discuss each parameter.
Prototype
function ASSetPropFlags( object, properties, setFlags, clearFlags )
Parameters
Proof
The largest confusion in the online documentation of this function surrounds the functionality of the third and fourth parameters. Given my description above, flags of a property are set (enabled) and cleared (disabled) with the third and fourth parameters. If a flag is set and cleared at the same time, the setting takes priority. We can interpret this as a two step operation: first clear the flags specified by the fourth parameter (clearFlags) and then set the flags specified by the third parameter (setFlags). We can perform these steps with the following bitwise operation to update a given property's flags.
flags = (flags & ~clearFlags) | setFlags;
You can run the below ActionScript to verify the functionality. It first tests that every desired set of flags can be applied to a newly constructed object. After verifying that this functionality works, it tests that every possible modification to every possible set of initial flags produces the expected result. If any tests do not produce the expected values, information about that permutation is traced to the output. By placing this function in the first frame of a movie and running it, you will see the following output printed to the console showing that all expected results were achieved.
START: Test setting of flags
FINISHED: Test setting of flags
START: Test modification of flags
FINISHED: Test modification of flags
//******************************************************************************
// Test functionality of setting individual flags with the third parameter of
// of ASSetPropFlags.
//******************************************************************************
function TestSetPropFlags(setFlags)
{
var foo = new Object;
foo.bar="initialValue";
// set the initial flags
ASSetPropFlags(foo, null, setFlags, 0);
// test hidden
var hidden = 1;
for( var i in foo )
{
if( i == "bar" )
hidden = 0;
}
// test write protection
foo.bar="newValue";
var writeProtected = (foo.bar == "initialValue") ? 1 : 0;
// test delete protection
delete foo.bar;
var deleteProtected = (foo.bar != null) ? 1 : 0;
// check that the resulting flags match teh expected value
var resultFlags = (writeProtected << 2) | (deleteProtected << 1) | (hidden << 0);
if( resultFlags != setFlags )
{
trace( " set:" + setFlags +
" resultFlags:" + resultFlags +
" writeProtected:" + writeProtected +
" deleteProtected:" + deleteProtected +
" hidden:" + hidden );
}
}
//******************************************************************************
// Test functionality of modifying flags using the third and forth parameters
// of ASSetPropFlags.
//******************************************************************************
function TestModifyPropFlags(initFlags, setFlags, clearFlags)
{
var foo = new Object;
foo.bar="initialValue";
// set the initial flags
ASSetPropFlags(foo, null, initFlags, 0);
// apply the change
ASSetPropFlags(foo, null, setFlags, clearFlags);
// test hidden
var hidden = 1;
for( var i in foo )
{
if( i == "bar" )
hidden = 0;
}
// test write protection
foo.bar="newValue";
var writeProtected = (foo.bar == "initialValue") ? 1 : 0;
// test delete protection
delete foo.bar;
var deleteProtected = (foo.bar != null) ? 1 : 0;
// apply the expected formula to the input values for comparison
var expectedFlags = (initFlags & ~clearFlags) | setFlags;
// check that the resulting flags match the expected value
var resultFlags = (writeProtected << 2) | (deleteProtected << 1) | (hidden << 0);
if( resultFlags != expectedFlags )
{
trace( " init:" + initFlags +
" set:" + setFlags +
" clear:" + clearFlags +
" expected:" + expectedFlags +
" resultFlags:" + resultFlags +
" writeProtected:" + writeProtected +
" deleteProtected:" + deleteProtected +
" hidden:" + hidden );
}
}
//******************************************************************************
// Declare variables.
//******************************************************************************
var initFlags;
var setFlags;
var clearFlags;
//******************************************************************************
// Run flag setting tests on every permutation
//******************************************************************************
trace("START: Test setting of flags");
for( setFlags = 0; setFlags < 8; ++setFlags )
{
TestSetPropFlags(setFlags);
}
trace("FINISHED: Test setting of flags");
//******************************************************************************
// Run flag modification tests on every permutation.
//******************************************************************************
trace("START: Test modification of flags");
for( initFlags = 0; initFlags < 8; ++initFlags )
{
for( setFlags = 0; setFlags < 8; ++setFlags )
{
for( clearFlags = 0; clearFlags < 8; ++clearFlags )
{
TestModifyPropFlags(initFlags,setFlags,clearFlags);
}
}
}
trace("FINISHED: Test modification of flags");
//******************************************************************************
// Stop the movie from looping.
//******************************************************************************
stop();
Comments