/
MinimalCore-1.0/
MinimalCore-1.0/src/
// ------------------------------------------------------------------
// Root Object

object $root

var $root child_index 0
var $root child 0
var $root inited 1
var $root objname 'root

private initialize: nooverride
    var ancestors, ancestor, pos, len, method;
  
    if (inited)
        throw(~perm, "Already initialized.");
    ancestors = ancestors();
    len = ancestors.length();
    for pos in [0 .. len - 1] {
        ancestor = ancestors[len - pos];
        method = tosym("init_" + tostr(ancestor.objname('symbol)));
        catch ~methodnf {
            if (find_method(method) != ancestor) {
                throw(~perm, "Initialization method for " + ancestor.objname()
                             + " in wrong place("
                             + find_method(method).objname() + ")");
            }
            .(method)();
        }
    }
    inited = 1;
    child = 1;
.

private uninitialize: nooverride
    var ancestor, p;
    
    for ancestor in (ancestors()) {
       method = tosym("uninit_" + tostr(ancestor.objname('symbol)));
        catch ~methodnf {
            if (.find_method(method) != ancestor)
                throw(~perm, "UnInitialization method for " +
                             ancestor.objname() + " in wrong place (" +
                             .find_method(method).objname() + ")");
            .(method)();
        }
    }
    for p in (.parameters())
        .del_parameter('p);
.

public spawn: nooverride
    arg [other_parents];
    var base, obj, name;

    if (child)
        throw(~perm, "Attempt to spawn a non-defining object.");
    name = .objname('symbol);
    base = tostr(name);
    while ((| get_dbref(name) |)) {
        child_index = child_index + 1;
        name = tosym(base + "_" + tostr(child_index));
    }
    obj = (> create([this()] + other_parents) <);
    catch any {
        (> obj.initialize() <);
    } with handler {
        .log($parse.traceback(traceback()));
        if (!(| obj.destroy() |))
            throw(~ack, "Unable to destroy aborted attempt", traceback());
        rethrow(error());
    }
    (> add_objname(name, obj) <);
    obj.change_objname(name);
    return obj;
.

public destroy: nooverride
    if (!child)
        throw(~perm, "Attempt to destroy a defining parent.");
    (| .uninitialize() |);
    (| del_objname(name) |);
    destroy(this());
.

public add_objname: nooverride
    arg name;
    var regexp;

    if (type(name) != 'symbol)
        throw(~perm, "Name is not a symbol.");
    name = tostr(name);
    regexp = "[a-z0-9_]*".match_regexp(name);
    if (regexp[1][2] != name.length())
        throw(~invname, "Names may only contain alphanumeric characters or \"_\".");
    name = tosym(name);
    (> add_objname(name) <);
    objname = name;
.

public change_objname: nooverride
    arg name;
    var old;

    if (objname) {
        old = objname;
        (| .del_objname(old) |);
    }
    catch any {
        (> .add_objname(name) <);
    } with handler {
        (| .add_objname(old) |);
    }
.

public del_objname: nooverride
    arg name;

    (> del_objname(name) <);
    if (name == objname)
        clear_var('objname);
.

public objname: nooverride
    arg [args];

    if (args)
        return objname;
    if (objname)
        return "$" + tostr(objname);
    return toliteral(this());
.

public parents: nooverride
    return parents();
.

public children: nooverride
    return children();
.

public descendants: nooverride
    disallow_overrides;
    var kids, i, c;
  
    kids = children();
    while ((| c = kids[i = i + 1] |))
        kids = union(kids, c.children());
    return kids;
.

public debug: nooverride
    arg [what];
    var l, line;

    line = "";
    for l in (what)
        line = line + " " + (type(l) == 'string ? l | $parse.unparse(l));
    log("DEBUG: " + $parse.unparse(what));
.

public log: nooverride
    arg what;
    var line;

    if (type(what) == 'string) {
        log(what);
    } else if (type(what) == 'list) {
        for line in (what)
            .log(line);
    } else {
        throw(~invarg, "Log must be called with a string or a list of strings");
    }
.

    
// ------------------------------------------------------------------
// System Object

parent $root
object $sys

var $root inited 1
var $root objname 'sys
var $sys startup [$login_daemon]

driver startup
    arg [args];
    var obj, hmm, l;

    for obj in (startup) {
        catch any {
            log("Calling " + obj.objname() + ".startup()");
            (> obj.startup() <);
        } with handler {
            for l in ($parse.traceback(traceback()))
                log(l);
        }
    }
    set_heartbeat(5);
.

driver signal
    arg [args];
.