Public methods:
verb_templates() Get verb templates
verb_info(template) Get {method, remote}
local_verb_info(template) Get {method, remote} locally
Owner methods:
add_verb(template, method, remote) Add a verb
del_verb(method) Remove a verb
Protected methods:
verbs_changed_on_leaf() Verbs changed on leaf object
Private methods (non-overridable):
verbs_changed() Indicates verbs changed
Verbs:
list_verb @list * on %this List method
show_verb @show %this Show object
params_verb @params %this Show parameters
methods_verb @methods %this Show method names
verbs_verb @verbs %this Show verbs
parent root
object verbs
var verbs verbs 0
method init
arg ancestors;
(> pass(ancestors) <);
if (definer() in ancestors)
verbs = #[];
.
eval
.initialize();
.set_name("Generic verb-containing object");
.
method verb_templates
return dict_keys(verbs);
.
method add_verb
arg template, method, remote;
var words, pos;
if (!.is_owned_by(sender()))
throw(~perm, "Sender is not an owner.");
// Check argument types.
if (type(template) != 'string)
throw(~type, "Template is not a string.");
if (type(method) != 'symbol)
throw(~type, "Method name is not a symbol.");
if (remote != 'remote && remote != 'noremote)
throw(~type, "Remote specifier is neither 'remote nor 'noremote");
// Make sure there's exactly one "%this" in the template, as a word by
// itself.
words = explode(template);
if (words[1] == "%this" || words[1] == "*" || words[1] == "*=*")
throw(~template, "Template begins with wildcard.");
pos = "%this" in words;
if (!pos || "%this" in sublist(words, pos + 1))
throw(~template, "Template does not contain exactly one \"%this\".");
// Add the verbs to the dictionary.
verbs = dict_add(verbs, template, [method, remote]);
if (remote == 'remote)
$sys.new_remote_template(template);
else
.verbs_changed();
.
method remove_verb
arg template;
var verb_info;
if (!.is_owned_by(sender()))
throw(~perm, "Sender is not an owner.");
catch ~keynf {
verb_info = verbs[template];
verbs = dict_del(verbs, template);
if (verb_info[1] == 'remote)
$sys.removed_remote_template(template);
else
.verbs_changed();
} with handler {
throw(~verbnf, "No verb with template " + tostr(template) + ".");
}
.
method verbs_changed
disallow_overrides;
var loc, p;
if (sender() != this() || caller() != definer())
throw(~perm, "Invalid call to private method.");
// If this object has children, up the system verb consistency clock,
// forcing all users to update their command lists next time they process
// a command.
if (children()) {
for p in ($sys.connected_users())
p.invalidate_verb_cache();
}
// The verbs changed on a leaf. Delegate this to the subclasses; located
// objects will want to deal with it one way, exits another.
.verbs_changed_on_leaf();
.
method verbs_changed_on_leaf
if (sender() != this())
throw(~perm, "Sender not this.");
.
method verb_info
disallow_overrides;
arg template;
var verb_info, anc;
if (dict_contains(verbs, template))
return verbs[template];
for anc in (ancestors()) {
verb_info = (| anc.local_verb_info(template) |);
if (verb_info)
return verb_info;
}
throw(~verbnf, "No verb with template " + template);
.
method local_verb_info
disallow_overrides;
arg template;
catch ~keynf {
return verbs[template];
} with handler {
throw(~verbnf, "No verb with template " + template);
}
.