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); .