parent $utilities
object $has_messages
var $root dbref 'has_messages
var $root child_index 1
var $root fertile 1
var $root manager $has_messages
var $root owned [$has_messages]
var $root owners [$]
var $root writable []
var $root readable ['parameters, 'methods, 'code]
var $root inited 1
var $has_messages messages 0
var $has_messages message_info 0
method add_message
arg name;
var mess;
// name is the name of the message
// def is the def value of the message.
.perms(sender(), 'writer);
if (type(name) != 'string)
throw(~type, "Name must be a string");
.set_message_info(name, [$base_evaluator, $compile_evaluator, $uncompile_evaluator, []]);
mess = (| messages[this()] |) || #[];
mess = dict_add(mess, name, $message_class.new(#[]));
if (!messages)
messages = #[];
messages = dict_add(messages, this(), mess);
.
method message_info
arg [name];
if (name) {
catch ~keynf {
return message_info[name[1]];
} with handler {
throw(~messagenf, ("Message " + (name[1])) + " is not defined here.");
}
} else {
return message_info || #[];
}
.
method set_message_info
arg name, value;
if ((value[1]) && (type(value[1]) != 'dbref))
throw(~type, "The first value should be the evaluator.");
if ((value[2]) && (type(value[2]) != 'dbref))
throw(~type, "The second value should be the compiler.");
if ((value[3]) && (type(value[3]) != 'dbref))
throw(~type, "The third value should be a the uncompiler.");
if ((value[4]) && (type(value[4]) != 'list))
throw(~type, "The fourth value should be a list of strings.");
if (!message_info)
message_info = #[];
message_info = dict_add(message_info, name, value);
.
method del_message_part
arg name, old_part;
var current, parts, p, k, kids;
current = .message_info(name);
parts = current[4];
if (old_part in parts)
parts = delete(parts, old_part in parts);
.set_message_info(name, replace(current, 4, parts));
kids = [this()];
while (kids) {
k = kids[1];
.debug(k);
kids = sublist(kids, 2);
k._del_message_part(name, old_part);
kids = [@kids, @k.children()];
}
.
method message_parts
arg name;
return (| (message_info[name])[4] |) || [];
.
method evalutor
arg name;
return (defined_messages[name])[1];
.
method set_evaluator
arg name, evaluator;
var current;
.perms(sender(), 'writer);
current = defined_messages[name];
current = replace(current, 1, evaluator);
.set_message_info(name, current);
.
method defines_message
arg name;
var n;
// returns 1 if the message <name> is defined here.
if (message_info) {
for n in (dict_keys(message_info)) {
if (match_begin(name, n))
return 1;
}
}
return 0;
.
method del_message
arg name;
var mess, kids;
.perms(sender(), 'writer);
message_info = dict_del(message_info, name);
._del_message(name);
kids = .children();
while (kids) {
(| (kids[1])._del_message(name) |);
kids = [@sublist(kids, 2), @(kids[1]).children()];
}
.
method local_messages
return messages || #[];
.
method messages
var all_messages, a, a_messages, d_messages, d, m, my_d;
// return all messages set on this() or parents
// a : on eancestor
// all_messages: the sum total of message
// a_messages: messages from ancestor a
// d: the definer of a message
// d_messages: messages from ancestor a, defined on d
// m: a specific message
// my_d: messags from definer d that have already been found.
all_messages = #[];
for a in (.ancestors()) {
if (a.has_ancestor(definer())) {
a_messages = a.local_messages();
for d in (dict_keys(a_messages)) {
d_messages = a_messages[d];
my_d = (| all_messages[d] |) || #[];
for m in (dict_keys(d_messages)) {
if (!(m in dict_keys(my_d)))
my_d = dict_add(my_d, m, d_messages[m]);
}
all_messages = dict_add(all_messages, d, my_d);
}
}
}
return all_messages;
.
method local_message
arg name, [definer];
var d;
if (messages) {
if (!definer) {
for d in (dict_keys(messages)) {
catch ~keynf {
return (messages[d])[name];
}
}
} else {
catch ~keynf {
return (messages[definer[1]])[name];
}
}
}
throw(~messagenf, "Message was not found.");
.
method prep_evalutor
arg name;
.perms(sender(), 'writers);
return (.messaage_info(name))[2];
.
method message
arg name, [definer];
var a;
if (definer)
definer = definer[1];
else
definer = ._find_message_definer(name);
// Umm, ._find_message_definer already loops ancestors (-Brandon)
// for a in (.ancestors()) {
catch ~messagenf, ~methodnf {
// return a.local_message(name, definer);
return definer.local_message(name, definer);
}
// }
throw(~messagenf, ("Message " + name) + " not found.");
.
method set_message
arg name, message, [definer];
var mess;
.perms(sender(), 'writers);
if (type(name) != 'string)
throw(~type, "Name must be a string");
if (!definer)
definer = ._find_message_definer(name);
if (definer.message_parts(name)) {
if (type(message) == 'dict)
message = $message_class.new(message, (.message_info(name, definer))[2]);
if ((type(message) != 'frob) || (class(message) != $message_class))
throw(~type, "message must be a $message_class, a dict");
} else {
if (type(message) == 'string)
message = $ctext_class.new(message, (.message_info(name, definer))[2]);
if ((type(message) != 'frob) || (class(message) != $ctext_class))
throw(~type, "message must be a $ctext_class or a string");
}
if (!messages)
messages = #[];
mess = (| messages[definer] |) || #[];
mess = dict_add(mess, name, message);
messages = dict_add(messages, definer, mess);
.
method set_message_part
arg name, message, [definer];
var mes, part, pos, m;
if (definer)
definer = definer[1];
else
definer = ._find_message_definer(name);
pos = $string.rindex(name, ".");
part = substr(name, pos + 1);
name = substr(name, 1, pos - 1);
m = (| .message(name, definer) |) || ($message_class.new(#[], (.message_info(name, definer))[2]));
if (!(part in (definer.message_parts(name))))
throw(~partnf, (("Invalid part: " + part) + " for message: ") + message);
m = m.add_entry(part, message);
if (!messages)
messages = #[];
mes = (| messages[definer] |) || #[];
messages = dict_add(messages, definer, dict_add(mes, name, m));
.
method local_matching_messages
arg name, [definer];
var n, matches, d;
matches = [];
if (definer) {
for n in (dict_keys(messages[definer])) {
if (match_begin(n, name))
matches = [@matches, n];
}
} else {
for d in (dict_keys(messages)) {
for n in (dict_keys(messages[d])) {
if (match_begin(n, name))
matches = [@matches, n];
}
}
}
return matches;
.
method matching_messages
arg name;
var matches, a, local, d, n;
//returns a list of all messages set that match name
matches = #[];
for a in (.ancestors()) {
if (a.has_ancestor(this())) {
local = a.local_matching_message(name);
for d in (dict_keys(local)) {
for n in (dict_keys[d]) {
if (!(((local[d])[n]) in (matches[d])))
matches = dict_add(matches, d, [@matches[d], n]);
}
}
}
}
return #[];
.
method _del_message
arg name;
var mess;
mess = messages[sender()];
mess = dict_del(mess, name);
messages = dict_add(messages, sender(), mess);
.
method _find_message_definer
arg name;
var a;
for a in (.ancestors()) {
catch ~methodnf {
if (a.defines_message(name))
return a;
}
}
throw(~definernf, ("Could not find definer for " + name) + ".");
.
method add_message_part
arg name, [new_parts];
var current, parts, p;
.perms(sender(), 'writer);
current = .message_info(name);
parts = current[4];
for p in (new_parts) {
if (!(p in parts))
parts = [@parts, p];
}
.set_message_info(name, replace(current, 4, parts));
.
method eval_message
arg name, vars, [definer];
if (definer)
definer = definer[1];
else
definer = ._find_message_definer(name);
vars = dict_add(vars, 'evaluator, (definer.message_info(name))[1]);
return (.message(name, definer)).eval_ctext(vars);
.
method uninit_has_messages
messages = 0;
defined_messages = 0;
.
method _del_message_part
arg name, part;
var m, mess;
.debug(sender(), name, part);
if (messages && (sender() in dict_keys(messages))) {
mess = messages[sender()];
.debug(mess);
if (name in dict_keys(mess)) {
m = mess[name];
.debug(m);
m = m.del_entry(part);
.debug(m);
mess = dict_add(mess, name, m);
messages = dict_add(messages, sender(), mess);
}
}
.