/* 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();
}