/* Do not remove the headers from this file! see /USAGE for more info. */ /* ** flags.c ** ** Standard flag (bit) handling system. Provides arbitrary sets ** of flags for subclasses to define and use. Sets may be ** configured to save/restore or be "non-persistent". ** ** All flags come in sets of 32 bits. The flags are keyed with ** single integer values composed with the MakeFlag() macro ** found in /include/flags.h. See that header for more info. ** ** Flag sets default to zero-values that WILL be saved/restored. ** The configure_set() function may be used to define a function ** that is invoked after any flag has been changed. ** ** 961209 Deathblade Trimmed back unneeded functionality. ** 940929 Deathblade Created. */ #include <flags.h> private class flag_set_info { int is_non_persistent; function change_func; } /* ** Defines the sets of flags. Maps a set key to a flag_set_info. */ private nosave mapping flag_sets; /* ** Stores the persistent and non-persistent flags */ private nosave mapping non_persist_flags; private mapping persist_flags; #define BITMASK(w) (1 << ((w) & 0x1F)) private void init_vars() { flag_sets = ([ ]); non_persist_flags = ([ ]); persist_flags = ([ ]); } //:FUNCTION get_flags // //get_flags(set_key) returns the flags associated with the key 'set_key' //Any 'get' function for the flag set is also used. nomask int get_flags(int set_key) { class flag_set_info set_info; if ( !flag_sets ) init_vars(); set_info = flag_sets[set_key]; if ( !set_info ) set_info = new(class flag_set_info); if ( set_info->is_non_persistent ) return non_persist_flags[set_key]; return persist_flags[set_key]; } //:FUNCTION set_flags // //set_flags(which, state) sets the flag specified by 'which', which includes //both flag set and information about which bit, to 1 if state is nonzero //and 0 if state is zero. The secure, set, and change functions are also //called. private void set_flags(int which, int state) { int set_key; class flag_set_info set_info; int value; if ( !flag_sets ) init_vars(); set_key = FlagSet(which); set_info = flag_sets[set_key]; if ( !set_info ) set_info = flag_sets[set_key] = new(class flag_set_info); value = get_flags(set_key); if ( state ) value |= BITMASK(which); else value &= ~BITMASK(which); /* ** Use the set_closure if provided; otherwise, set the flags ** in the appropriate in the appropriate mapping. */ if ( set_info->is_non_persistent ) non_persist_flags[set_key] = value; else persist_flags[set_key] = value; /* ** Call the change notification function */ if ( set_info->change_func ) evaluate(set_info->change_func, which, state); } //:FUNCTION configure_set //configure_set allows one to specify whether a flag set is persistent, //and a function that can be called when a flag changes. varargs nomask void configure_set( int set_key, int is_non_persistent, function change_func ) { if ( !flag_sets ) init_vars(); flag_sets[set_key] = new(class flag_set_info, is_non_persistent : is_non_persistent, change_func : change_func); } //:FUNCTION test_flag // //test_flag(which) returns 1 if a flag is set, and zero if not. 'which' //includes information both about which flag set and which bit. nomask int test_flag(int which) { return (get_flags(FlagSet(which)) & BITMASK(which)) != 0; } //:FUNCTION set_flag // //set_flag(which) sets a given flag to 1. 'which' //includes information both about which flag set and which bit. nomask void set_flag(int which) { set_flags(which, 1); } //:FUNCTION clear_flag // //clear_flag(which) sets a given flag to 0. 'which' //includes information both about which flag set and which bit. nomask void clear_flag(int which) { set_flags(which, 0); } //:FUNCTION assign_flag // //assign_flag(which, state) sets a given flag to 1 if state is //nonzero and 0 if state is zero. 'which' includes information //both about which flag set and which bit. nomask void assign_flag(int which, int state) { set_flags(which, state); } void create() { init_vars(); }