parent $utilities
object $has_settings
var $root dbref 'has_settings
var $root child_index 0
var $root fertile 1
var $root manager $has_settings
var $root owned [$has_settings]
var $root owners [$]
var $root writable []
var $root readable ['parameters, 'methods, 'code]
var $root inited 1
var $has_settings settings #[]
var $has_settings setting_types #[]
var $has_settings setting_data #[]
method _find_setting
arg spec, definer, ancestors;
if (definer) {
if (definer in dict_keys(settings)) {
if (spec in (settings[definer]))
return (settings[definer])[spec];
}
}
for definer in (dict_keys(settings)) {
if (spec in (settings[definer]))
return (settings[definer])[spec];
}
while (ancestors) {
if ((ancestors[1]).has_ancestor($settings))
return (ancestors[1])._find_setting(spec, definer, sublist(ancestors, 2));
else
ancestors = sublist(ancestors, 2);
}
throw(~settingnf, "A matching setting could not be found");
.
method uninit_has_settings
settings = 0;
setting_types = 0;
setting_data = 0;
.
method get_setting
arg name, definer, [args];
var info;
if (!definer)
definer = ._find_definer(name);
info = definer.get_setting_info(name);
if (args)
args = [@info['get_args], @args];
else
args = info['get_args];
args = ._build_args(args, #[['name, name], ['definer, definer]]);
return .(info['get])(@args);
.
method _build_args
arg arg_list, values;
var key, output;
output = [];
for key in (arg_list) {
if (key in dict_keys(values)) {
output = [@output, values[key]];
values = dict_del(values, key);
} else {
output = [@output, key];
}
}
return output;
.
method _find_definers
arg name, count, [begin];
var a, matches;
// Find a definer for <name>
// <count> is a number
// 1 finds the first possible definer
// 0 finds all
// If <begin> is given cound a match_begin as a match
matches = [];
for a in (ancestors()) {
if (a.has_ancestor($has_settings)) {
if (a.defines_setting(name, begin)) {
switch (count) {
case 0:
matches = [@matches, a];
case 1:
return [@matches, a];
default:
matches = [@matches, a];
count = count - 1;
}
}
}
}
return matches;
.
method set_setting
arg name, definer, value, [args];
var info, data;
if (!definer)
definer = ._find_definers(name, 1);
if (definer)
definer = definer[1];
else
throw(~definernf, "Definer not found.");
info = definer.get_setting_info(name);
if (.(info['check])(value)) {
data = #[['name, name], ['definer, definer], ['style, 'set], ['value, value]];
if (args)
args = [@info['set_args], @args];
else
args = info['set_args];
args = ._build_args(args, data);
.(info['set])(@args);
return 1;
} else {
return 0;
}
.
method add_setting
arg name, [args];
var values, key;
// .add_setting("name",#['type,'check,'get,'set,'del])
.perms(sender(), 'writers);
values = (| .get_setting_info(name) |) || (.default_setting_info());
if (args)
args = args[1];
else
args = #[];
if (type(args) != 'dictionary)
throw(~type, "args must be a dictionary");
for key in (dict_keys(args))
values = dict_add(values, key, args[key]);
if (type(name) != 'string)
throw(~type, "name must be a string");
if (type(values['type]) != 'string)
throw(~type, "Type must be a string");
if (type(values['check]) != 'symbol)
throw(~type, "Check must be a symbol");
if (type(values['set]) != 'symbol)
throw(~type, "set must be a symbol");
if (type(values['get]) != 'symbol)
throw(~type, "get must be a symbol");
if (type(values['del]) != 'symbol)
throw(~type, "del must be a symbol");
if (!setting_types)
setting_types = #[];
setting_types = dict_add(setting_types, name, values);
return 1;
.
method defines_setting
arg name, [begin];
var n;
// returns 1 if the setting <name> is defined here.
// if begin is given do a match begin instead of an exact match
if (setting_types) {
if (begin) {
for n in (dict_keys(setting_types)) {
if (match_begin(name, n))
return 1;
}
} else {
return name in dict_keys(setting_types);
}
}
return 0;
.
method find_matching_settings
arg name, definer;
var n, a, matches, sets;
// find all settings that match name
// return a list of [[$definer, "name"],...]
// A setting matches name if name matches the begining of the setting name.
// If definer is not "" limit to the search to settings form definer.
matches = [];
for a in (.ancestors()) {
if (a.has_ancestor($has_settings)) {
if (!definer) {
sets = a.setting_types();
for n in (dict_keys(sets)) {
if (match_begin(name, n))
matches = [@matches, [this(), n]];
}
} else if (a.has_ancestor(definer)) {
sets = a.setting_types();
for n in (dict_keys(sets)) {
if (match_begin(name, n))
matches = [@matches, [this(), n]];
}
}
}
}
return matches;
.
method del_setting
arg name;
var kid, method;
.perms(sender(), 'manager);
setting_types = dict_del(setting_types, name);
method = (.get_setting_info(name))['del];
.(method)(name);
for kid in (.children())
(| kid.(method)(name) |);
.
method is_anything
arg [args];
return 1;
.
method is_boolean
arg spec, value, [args];
if ((args[1]) == 'boolean) {
if (value in [0, 1])
return 1;
}
return 0;
.
method is_integer
arg spec, value, args;
if (type(value) == 'integer)
return 1;
if ((type(value) == 'string) && (value.is_numeric()))
return 1;
return 0;
.
method is_string
arg spec, value, args;
if (type(value) == 'string)
return 1;
return 0;
.
method setting_data
return setting_data;
.
method get_inherited_setting
arg spec, definer, args;
var fname, a, sets;
fname = ._to_fullname(spec, definer);
if (fname in dict_keys(setting_data))
return setting_data[fname];
for a in (.ancestors()) {
if ((a.has_ancestor($settings)) && (a.has_ancestor(definer)))
sets = a.setting_data();
if (fname in dict_keys(sets))
return sets[fname];
}
return 0;
.
method get_indirect_setting
arg name, definer, args;
var fname, val;
fname = ._to_fullname(name, definer);
if (fname in dict_keys(setting_data)) {
val = setting_data[fname];
if (type(val) == 'dbref)
return (setting_data[fname]).get_setting(spec, definer, args);
else
return setting_data[fname];
} else {
return (definer.setting_data())[fname];
}
.
method default_get_setting
arg name, definer, [args];
catch ~keynf, ~methoderr {
return (setting_data[definer])[name];
} with handler {
return 0;
}
.
method default_set_setting
arg name, definer, value, args;
var sets;
.perms(sender(), this());
sets = (| setting_data[definer] |) || #[];
sets = dict_add(sets, name, value);
setting_data = dict_add(setting_data, definer, sets);
.
method del_direct_setting
arg name;
var definer_set;
definer_set = (| setting_data[sender()] |) || 0;
if (definer_set)
definer_set = dict_del(definer_set, name) || definer_set;
setting_data = dict_add(setting_data, sender(), definer_set);
.
method _del_setting
var spec, definer;
if (definer != sender())
throw(~perm, "Only the definer of a setting can delete it.");
setting_data = (| dict_del(setting_data, spec) |) || setting_data;
.
method _to_fullname
arg spec, definer;
return ((definer.dbref()) + ":") + spec;
.
method matching_settings
arg name, [begin];
var n, matches;
//returns a list of all settings defined that match name
// if begin is true, does a match begin instead of exact match
if (setting_types) {
matches = [];
if (name == " ")
return dict_keys(setting_types);
for n in (dict_keys(setting_types)) {
if ((name == n) || (begin && match_begin(n, name)))
matches = [@matches, n];
}
return matches;
}
return [];
.
method all_matching_settings
arg name, definers, [begin];
var a, matches, local_matches;
//returns a list of setting that match <name>
//if begin is true, does a match_begin
//if definers is not "", limit searches to definer
if (type(definers) != 'list)
throw(~type, "definers must be a list of dbrefs");
matches = [];
if (definers == []) {
for a in (.ancestors()) {
if (a.has_ancestor($has_settings)) {
local_matches = a.matching_settings(name, begin);
if (local_matches)
matches = [@matches, [a, local_matches]];
}
}
return matches;
}
if (listlen(definers) > 1) {
for a in (ancestors()) {
if (union(a.ancestors(), definers)) {
local_matches = a.matching_settings(name, begin);
if (local_matches)
matches = [@matches, [a, local_matches]];
}
}
} else {
for a in (ancestors()) {
if (a.has_ancestor(definers)) {
local_matches = a.matching_settings(name, begin);
if (local_matches)
matches = [@matches, [a, local_matches]];
}
}
}
return matches;
.
method setting
arg name, [args];
var info, definer;
if (args) {
definer = args[1];
args = delete(args, 1);
}
if (!definer) {
definer = ._find_definers(name, 1);
if (definer)
definer = definer[1];
else
return 0;
// throw(~definernf,"Could not find a definer for "+name);
}
info = definer.get_setting_info(name);
if (args)
args = [@info['get_args], @args];
else
args = info['get_args];
args = ._build_args(args, #[['name, name], ['definer, definer]]);
return .(info['get])(@args);
.
method default_setting_info
return #[['type, "string"], ['check, 'is_anything], ['get, 'get_direct_setting], ['set, 'set_direct_setting], ['del, 'del_direct_setting], ['set_args, ['name, 'definer, 'value, 'style]], ['get_args, ['name, 'definer]]];
.
method setting_types
return setting_types;
.
method get_direct_setting
arg name, definer, [args];
catch ~keynf, ~methoderr, ~type {
return (setting_data[definer])[name];
} with handler {
return 0;
}
.
method get_setting_info
arg name;
return (| setting_types[name] |) || (.default_setting_info());
.
method set_direct_setting
arg name, definer, value, [args];
var sets;
.perms(sender(), this());
if (!setting_data)
setting_data = #[];
sets = (| setting_data[definer] |) || #[];
sets = dict_add(sets, name, value);
setting_data = dict_add(setting_data, definer, sets);
.