1
0
Fork 0

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:
mfranz 2009-01-31 17:15:48 +00:00
parent c795f30862
commit 65e4b71406

View file

@ -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());