Library globals

Source modules . canvas_efis . efis-canvas.nas

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
#------------------------------------------
# efis-canvas.nas - Canvas EFIS framework
# author:       jsb
# created:      12/2017
#------------------------------------------

#--  EFISCanvas - base class to create canvas displays / pages --
# * manages a canvas
# * can load a SVG file and create clipping from <name>_clip elements
# * allows to register multiple update functions with individual update intervals
# * update functions can be en-/disabled by a single property that should
#   reflect the visibility of the canvas
# * several listener factories for common animations

var EFISCanvas = {
    # static members
    _instances: [],
    unload: func() {
        print("-- Removing EFISCanvas instances --");
        foreach (var instance; EFISCanvas._instances) {
            print("  - "~instance.name);
            instance.del();
        }
        EFISCanvas._instances = [];
    },

    # destructor
    del: func() {
        me._canvas.del();
        foreach (var timer; me._timers) {
            timer.stop();
        }
        me._timers = [];
    },

    colors: canvas.colors,
    canvas_settings: EFIS.defaultcanvas_settings,

    new: func(name) {
        var obj = {
            parents: [me, canvas.SVGCanvas.new(name, me.canvas_settings)],
            _id: size(EFISCanvas._instances), # internal ID for EFIS window mgmt.
            id: 0,                            # instance id e.g. for PFD/MFD
            name: name,
            svg_keys: [],
            # for reload support while efis development
            _timers: [],
            updateN: nil,       # to be used in update() to pause updates
            _instr_props: {},
        };
        append(EFISCanvas._instances, obj);
        var n = props.Node.makeValidPropName(name);
        obj.updateCountN = EFIS_root_node.getNode("update/count-"~n, 1);
        obj.updateCountN.setIntValue(0);
        obj.debugN = EFIS_root_node.getNode("debug/"~n, 1);
        obj.debugN.setBoolValue(0);
        return obj;
    },


    #set node that en-/dis-ables canvas updates
    setUpdateN: func(n) {
        me.updateN = n;
    },

    # register an update function with a certain update interval
    # f: function 
    # f_me: if there is any "me" reference in "f", you can set "me" with this
    #       defaults to EFISCanvas instance calling this method, useful if "f" 
    #       is a member of the EFISCanvas instance
    addUpdateFunction: func(f, interval, f_me = nil) {
        if (!isfunc(f)) {
            logprint(DEV_ALERT, "EFISCanvas.addUpdateFunction: argument is not a function.");
            return;
        }
        interval = num(interval);
        f_me = (f_me == nil) ? me : f_me;
        if (interval != nil and interval >= 0) {
            var timer = maketimer(interval, me, func {
                if (me.updateN != nil and me.updateN.getValue()) {
                    var err = [];
                    call(f, [], f_me, nil, err);
                    if (size(err))
                        debug.printerror(err);
                    # debug/performance monitoring
                    me.updateCountN.increment();
                }
            });
            append(me._timers, timer);
            return timer;
        }
    },

    # start all registered update functions
    startUpdates: func() {
        foreach (var t; me._timers)
            t.start();
    },

    # stop all registered update functions
    stopUpdates: func() {
        foreach (var t; me._timers) {
            t.stop();
        }
    },

    # getInstr - get props from /instrumentation/<sys>[i]/<prop>
    # creates prop node objects for efficient access
    # sys: the instrument name (path) (me.id is appended as index!!)
    # prop: the property(path)
    getInstr: func(sys, prop, default=0, id=nil) {
        if (me._instr_props[sys] == nil)
            me._instr_props[sys] = {};
        if (me._instr_props[sys][prop] == nil) {
            if (id == nil) { id = me.id; }
            me._instr_props[sys][prop] =
                props.getNode("/instrumentation/"~sys~"["~id~"]/"~prop, 1);
        }
        var value = me._instr_props[sys][prop].getValue();
        if (value != nil) return value;
        else return default;
    },
};