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;
},
};