factor the MP aircraft monitoring code out of the dialog class and let
the dialog use it. Other services need the same functionality and it should only be done once.
This commit is contained in:
parent
c795f30862
commit
65e4b71406
1 changed files with 125 additions and 97 deletions
|
@ -161,7 +161,6 @@ var handle_key = func(key)
|
|||
# multiplayer.dialog.show() -- displays the dialog and starts the update loop
|
||||
|
||||
var PILOTSDLG_RUNNING = 0;
|
||||
var METER_TO_NM = 0.0005399568034557235;
|
||||
|
||||
var dialog = {
|
||||
init: func(x = nil, y = nil) {
|
||||
|
@ -173,29 +172,22 @@ var dialog = {
|
|||
me.toggle_unit(); # set to imperial
|
||||
#
|
||||
# "private"
|
||||
var font = { name: "FIXED_8x13" };
|
||||
me.header = [" callsign", "model", "brg", func { dialog.dist_hdr }, func { dialog.alt_hdr ~ " " }];
|
||||
me.columns = [
|
||||
{property:"callsign", format:" %s", label: "-----------", halign:"fill" },
|
||||
{property:"model-short", format:"%s", label: "--------------",halign:"fill" },
|
||||
{property:"bearing-to", format:" %3.0f",label: "----", halign: "right",font:{name:"FIXED_8x13"}},
|
||||
{property:func {dialog.dist_node}, format:" %8.2f",label: "---------",halign: "right",font:{name:"FIXED_8x13"}},
|
||||
{property:func {dialog.alt_node}, format:" %7.0f",label: "---------",halign: "right",font:{name:"FIXED_8x13"}}
|
||||
{property:"bearing-to", format:" %3.0f",label: "----", halign: "right", font: font },
|
||||
{property:func {dialog.dist_node}, format:" %8.2f",label: "---------",halign: "right", font: font },
|
||||
{property:func {dialog.alt_node}, format:" %7.0f",label: "---------",halign: "right", font: font }
|
||||
];
|
||||
me.name = "who-is-online";
|
||||
me.namenode = props.Node.new({"dialog-name" : me.name });
|
||||
me.dialog = nil;
|
||||
me.mp = props.globals.getNode("/ai/models");
|
||||
|
||||
me.listeners=[];
|
||||
append(me.listeners, setlistener("/sim/startup/xsize", func { me._redraw_() }));
|
||||
append(me.listeners, setlistener("/sim/startup/ysize", func { me._redraw_() }));
|
||||
append(me.listeners, setlistener("/ai/models/model-added", func(n) { me._multiplayer_update_(n) }));
|
||||
append(me.listeners, setlistener("/ai/models/model-removed", func(n) { me._multiplayer_update_(n) }));
|
||||
},
|
||||
getloc : func (p) {
|
||||
var ploc = geo.Coord.new();
|
||||
ploc.set_xyz(p.getNode("global-x").getValue(), p.getNode("global-y").getValue(), p.getNode("global-z").getValue());
|
||||
return ploc;
|
||||
append(me.listeners, setlistener("/sim/startup/xsize", func me._redraw_()));
|
||||
append(me.listeners, setlistener("/sim/startup/ysize", func me._redraw_()));
|
||||
append(me.listeners, setlistener("/sim/signals/multiplayer-updated", func me.update()));
|
||||
},
|
||||
create: func {
|
||||
if (me.dialog != nil)
|
||||
|
@ -203,6 +195,7 @@ var dialog = {
|
|||
|
||||
me.dialog = gui.Widget.new();
|
||||
me.dialog.set("name", me.name);
|
||||
me.dialog.set("dialog-name", me.name);
|
||||
if (me.x != nil)
|
||||
me.dialog.set("x", me.x);
|
||||
if (me.y != nil)
|
||||
|
@ -224,7 +217,7 @@ var dialog = {
|
|||
titlebar.addChild("text").set("label", "Pilots: ");
|
||||
|
||||
var p = titlebar.addChild("text");
|
||||
p.node.setValues({label: "---", live: 1, format: "%d", property: me.mp.getPath() ~ "/players"});
|
||||
p.node.setValues({label: "---", live: 1, format: "%d", property: "ai/models/num-players"});
|
||||
titlebar.addChild("empty").set("stretch", 1);
|
||||
|
||||
var w = titlebar.addChild("button");
|
||||
|
@ -248,67 +241,44 @@ var dialog = {
|
|||
col += 1;
|
||||
}
|
||||
row += 2;
|
||||
var children = me.mp.getChildren("multiplayer");
|
||||
var mp_vec=[];
|
||||
foreach(var c; children) {
|
||||
if(c.getNode("callsign") != nil and c.getNode("valid").getValue()) {
|
||||
append(mp_vec, { callsign:string.lc(c.getNode("callsign").getValue()), index:c.getIndex()});
|
||||
}
|
||||
}
|
||||
var sorted=sort(mp_vec, func(a,b) { return cmp(a.callsign,b.callsign) });
|
||||
foreach(var s; sorted) {
|
||||
var c = children[s.index];
|
||||
var odd = 0;
|
||||
foreach (var mp; model.list) {
|
||||
var col = 0;
|
||||
foreach (var column; me.columns) {
|
||||
var w = content.addChild("text");
|
||||
w.node.setValues(column);
|
||||
var p = typeof(column.property) == "func" ? column.property() : column.property;
|
||||
w.node.setValues({row: row, col: col, live: 1, property: c.getPath() ~ "/" ~ p});
|
||||
var odd = math.mod(row, 2);
|
||||
w.node.setValues({row: row, col: col, live: 1, property: mp.path ~ "/" ~ p});
|
||||
w.setColor(me.fg[odd][0], me.fg[odd][1], me.fg[odd][2], me.fg[odd][3]);
|
||||
col += 1;
|
||||
}
|
||||
odd = !odd;
|
||||
row +=1;
|
||||
}
|
||||
|
||||
me.update();
|
||||
fgcommand("dialog-new", me.dialog.prop());
|
||||
fgcommand("dialog-show", me.namenode);
|
||||
fgcommand("dialog-show", me.dialog.prop());
|
||||
},
|
||||
update: func {
|
||||
var children = me.mp.getChildren("multiplayer");
|
||||
var loc = geo.aircraft_position();
|
||||
var players = 0;
|
||||
foreach(var c; children) {
|
||||
if ( c.getNode("valid") == nil or !c.getNode("valid").getValue())
|
||||
continue;
|
||||
players+=1;
|
||||
var ploc = me.getloc(c.getNode("position"));
|
||||
var ploc_course = loc.course_to(ploc);
|
||||
var ploc_dist = loc.distance_to(ploc);
|
||||
var altitude_m = c.getNode("position/altitude-ft").getValue()*FT2M;
|
||||
var self = geo.aircraft_position();
|
||||
foreach(var mp; model.list) {
|
||||
var n = mp.node;
|
||||
var ac = geo.Coord.new().set_xyz(
|
||||
n.getNode("position/global-x").getValue(),
|
||||
n.getNode("position/global-y").getValue(),
|
||||
n.getNode("position/global-z").getValue());
|
||||
var distance = self.distance_to(ac);
|
||||
|
||||
var pathN = c.getNode("sim/model/path");
|
||||
if (pathN != nil)
|
||||
var path = pathN.getValue();
|
||||
else
|
||||
var path="";
|
||||
|
||||
var name = split("/", path)[-1];
|
||||
var pos = find("-model", name);
|
||||
if (pos >= 0)
|
||||
name = substr(name, 0, pos);
|
||||
if (substr(name, -4) == ".xml")
|
||||
name = substr(name, 0, size(name) - 4);
|
||||
if (substr(name, -3) == ".ac")
|
||||
name = substr(name, 0, size(name) - 3);
|
||||
|
||||
c.setValues({"model-short":name, "bearing-to": ploc_course,
|
||||
"distance-to-km":ploc_dist/1000.0, "distance-to-nm":ploc_dist*METER_TO_NM,
|
||||
"position/altitude-m":altitude_m });
|
||||
n.setValues({
|
||||
"model-short": mp.model,
|
||||
"bearing-to": self.course_to(ac),
|
||||
"distance-to-km": distance / 1000.0,
|
||||
"distance-to-nm": distance * M2NM,
|
||||
"position/altitude-m": n.getNode("position/altitude-ft").getValue() * FT2M,
|
||||
});
|
||||
}
|
||||
me.mp.getNode("players", 1).setIntValue(players);
|
||||
if (PILOTSDLG_RUNNING)
|
||||
settimer( func { me.update() }, 0.4, 1);
|
||||
settimer( func me.update(), 0.4, 1);
|
||||
},
|
||||
_redraw_: func {
|
||||
if (me.dialog != nil) {
|
||||
|
@ -316,11 +286,6 @@ var dialog = {
|
|||
me.create();
|
||||
}
|
||||
},
|
||||
_multiplayer_update_ : func(node) {
|
||||
var name = split("/", node.getValue())[-1];
|
||||
if(substr(name, 0, 11) == "multiplayer")
|
||||
me._redraw_()
|
||||
},
|
||||
toggle_unit: func {
|
||||
me.unit = !me.unit;
|
||||
if(me.unit)
|
||||
|
@ -341,7 +306,7 @@ var dialog = {
|
|||
}
|
||||
},
|
||||
close: func {
|
||||
fgcommand("dialog-close", me.namenode);
|
||||
fgcommand("dialog-close", me.dialog.prop());
|
||||
},
|
||||
del: func {
|
||||
PILOTSDLG_RUNNING=0;
|
||||
|
@ -351,8 +316,7 @@ var dialog = {
|
|||
delete(gui.dialog, "\"" ~ me.name ~ "\"");
|
||||
},
|
||||
show: func {
|
||||
if(!PILOTSDLG_RUNNING)
|
||||
{
|
||||
if (!PILOTSDLG_RUNNING) {
|
||||
PILOTSDLG_RUNNING=1;
|
||||
me.init(-2, -2);
|
||||
me.create();
|
||||
|
@ -364,6 +328,70 @@ var dialog = {
|
|||
me.show();
|
||||
else
|
||||
me.del();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
# Autonomous singleton class that monitors multiplayer aircraft,
|
||||
# maintains a data hash and a list (sorted by callsign), and raises
|
||||
# signal "/sim/signals/multiplayer-updated" whenever an aircraft
|
||||
# joined or left. Both multiplayer.model.data and multiplayer.model.list
|
||||
# contain hash entries of this form:
|
||||
#
|
||||
# {
|
||||
# callsign: "bimaus",
|
||||
# model: "bo105", # model name without suffixes (xml, ac, -anim, -model)
|
||||
# node: {...}, # node as props.Node hash
|
||||
# path: "/ai/models/multiplayer[4]",
|
||||
# }
|
||||
#
|
||||
#
|
||||
var model = {
|
||||
init: func {
|
||||
me.L = [];
|
||||
me.list = [];
|
||||
append(me.L, setlistener("ai/models/model-added", func(n) me.update(n.getValue())));
|
||||
append(me.L, setlistener("ai/models/model-removed", func(n) me.update(n.getValue())));
|
||||
me.update();
|
||||
},
|
||||
update: func(n = nil) {
|
||||
if (n != nil and props.globals.getNode(n, 1).getName() != "multiplayer")
|
||||
return;
|
||||
|
||||
me.data = {};
|
||||
foreach (var n; props.globals.getNode("ai/models", 1).getChildren("multiplayer")) {
|
||||
if (!n.getNode("valid", 1).getValue())
|
||||
continue;
|
||||
|
||||
if ((var callsign = n.getNode("callsign")) == nil or !(callsign = callsign.getValue()))
|
||||
continue;
|
||||
|
||||
var model = n.getNode("sim/model/path").getValue();
|
||||
model = split(".", split("/", model)[-1])[0];
|
||||
model = me.remove_suffix(model, "-model");
|
||||
model = me.remove_suffix(model, "-anim");
|
||||
|
||||
var path = n.getPath();
|
||||
me.data[path] = { node: n, callsign: callsign, model: model, path: path };
|
||||
}
|
||||
|
||||
me.list = sort(keys(me.data), func(a, b) string.icmp(me.data[a].callsign, me.data[b].callsign));
|
||||
forindex (var i; me.list)
|
||||
me.list[i] = me.data[me.list[i]];
|
||||
|
||||
setprop("ai/models/num-players", size(me.list));
|
||||
setprop("sim/signals/multiplayer-updated", 1);
|
||||
},
|
||||
remove_suffix: func(s, x) {
|
||||
var len = size(x);
|
||||
if (substr(s, -len) == x)
|
||||
return substr(s, 0, size(s) - len);
|
||||
return s;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
setlistener("sim/signals/nasal-dir-initialized", func model.init());
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue