/
ColdCore-3.0a9.02/
ColdCore-3.0a9.02/src/
new object $heart: $utilities;

var $heart heart_failures = [];
var $heart hearts = [[$lag_watcher, 872013847], [$world, 872014008]];
var $heart info = #[[$world, [600, 872013408]], [$lag_watcher, [14, 872013833]]];
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root inited = 1;
var $root managed = [$heart];
var $root manager = $heart;

private method ._add_heartbeat() {
    arg obj, delay;
    var when, h, values;
    
    // Only one heartbeat per object
    ._del_heartbeat(obj);
    when = delay + time();
    info = dict_add(info, obj, [delay, time()]);
    for h in [1 .. listlen(hearts)] {
        if (((hearts[h])[2]) >= when) {
            hearts = insert(hearts, h, [obj, when]);
            return;
        }
    }
    hearts += [[obj, when]];
};

private method ._del_heartbeat() {
    arg obj;
    var x, pos;
    
    if (info.contains(obj))
        info = info.del(obj);
    for x in [1 .. listlen(hearts)] {
        if (((hearts[x])[1]) == obj) {
            hearts = delete(hearts, x);
            return 1;
        }
    }
    return 0;
};

public method .add_heartbeat() {
    arg @delay;
    
    [(delay ?= 60)] = delay;
    ._add_heartbeat(sender(), delay);
};

root method .core_heart(): nooverride  {
    var h;
    
    for h in (hearts) {
        if (!valid(h[1]))
            ._del_heartbeat(h[1]);
    }
};

public method .del_heartbeat() {
    if (!(._del_heartbeat(sender())))
        throw(~objnf, ("Sender (" + sender()) + ") does not have a heartbeat.");
};

public method .hearts() {
    return hearts;
};

public method .pulse() {
    var heart, h, x, new;
    
    for heart in (hearts) {
        if ((heart[2]) > time())
            break;
        if (!valid(heart[1]))
            ._del_heartbeat(heart[1]);
        catch any
            (> (heart[1]).pulse() <);
        with
            (| ((heart[1]).manager()).tell_traceback(traceback()) |);
        ._add_heartbeat(heart[1], (info[heart[1]])[1]);
    }
};