114 lines
3.5 KiB
Text
114 lines
3.5 KiB
Text
# Class things:
|
|
var name = 'TFC';
|
|
var parents = [SymbolLayer.Controller];
|
|
var __self__ = caller(0)[0];
|
|
SymbolLayer.Controller.add(name, __self__);
|
|
SymbolLayer.add(name, {
|
|
parents: [SymbolLayer],
|
|
type: name, # Symbol type
|
|
df_controller: __self__, # controller to use by default -- this one
|
|
});
|
|
|
|
var model_root = props.globals.getNode("/ai/models/");
|
|
|
|
var new = func(layer) {
|
|
var m = {
|
|
parents: [__self__],
|
|
layer: layer,
|
|
listeners: [],
|
|
query_range_nm: 25,
|
|
};
|
|
# Listen to ai model events
|
|
append(m.listeners, setlistener(
|
|
model_root.getNode("model-added"), func(n) {
|
|
#printlog(_MP_dbg_lvl, "Dynamically adding model at "~n.getValue());
|
|
var node = props.globals.getNode(n.getValue());
|
|
var name = node.getName();
|
|
if (name == "aircraft" or name == "multiplayer")
|
|
if (m.in_range(node.getValue("position/latitude-deg"), node.getValue("position/longitude-deg")))
|
|
layer.onAdded(TrafficModel.new(node));
|
|
}
|
|
));
|
|
append(m.listeners, setlistener(
|
|
model_root.getNode("model-removed"), func(n) {
|
|
#printlog(_MP_dbg_lvl, "Dynamically deleting model at "~n.getValue());
|
|
var node = props.globals.getNode(n.getValue());
|
|
var name = node.getName();
|
|
if (name == "aircraft" or name == "multiplayer")
|
|
if (m.in_range(node.getValue("position/latitude-deg"), node.getValue("position/longitude-deg")))
|
|
layer.onRemoved(TrafficModel.new(node));
|
|
}
|
|
));
|
|
layer.searcher._equals = func(l,r) l.equals(r);
|
|
return m;
|
|
};
|
|
var del = func() {
|
|
#print(name~".lcontroller.del()");
|
|
foreach (var l; me.listeners)
|
|
removelistener(l);
|
|
};
|
|
var in_range = func(lat,lon,myPositionVec=nil,max_dist_m=nil) {
|
|
if (lat == nil or lon == nil) return 0;
|
|
var pos = geo.Coord.new();
|
|
pos.set_latlon(lat,lon);
|
|
var myPosition = geo.Coord.new();
|
|
# FIXME: need a Map Controller for this, and all query_range's/get_position's
|
|
if (myPositionVec == nil)
|
|
var myPositionVec = me.get_position();
|
|
myPosition.set_latlon( myPositionVec[0], myPositionVec[1]);
|
|
if (max_dist_m == nil)
|
|
var max_dist_m = me.query_range()*NM2M;
|
|
return (pos.distance_to( myPosition ) <= max_dist_m )
|
|
};
|
|
|
|
var TrafficModel = {
|
|
new: func(node, id=nil, layer=nil) {
|
|
if (id == nil) id = node.getValue("id");
|
|
var m = {
|
|
# Note: because this inherits from props.Node, Symbol.Controller.equals
|
|
# will call l.equals(r) -- the one defined below
|
|
parents: [TrafficModel, geo.Coord, node], # note we don't implement a full geo.Coord API
|
|
id: id,
|
|
node: node,
|
|
pos: node.getNode("position",1),
|
|
};
|
|
if (m.pos == nil)
|
|
m.latlon = func [nil,nil,nil];
|
|
#debug.dump(m); # why doesn't this print?
|
|
return m;
|
|
},
|
|
equals: func(other) other.id == me.id,
|
|
latlon: func() {
|
|
return [
|
|
me.pos.getValue("latitude-deg"),
|
|
me.pos.getValue("longitude-deg"),
|
|
me.pos.getValue("altitude-ft")
|
|
];
|
|
},
|
|
};
|
|
|
|
var searchCmd = func {
|
|
# TODO: this would be a good candidate for splitting across frames
|
|
#print("Doing query: "~name);
|
|
|
|
var result = [];
|
|
# FIXME: need a Map Controller for this, and all query_range's/get_position's
|
|
var myPositionVec = me.get_position();
|
|
var max_dist_m = me.query_range()*NM2M;
|
|
|
|
# AI and Multiplayer traffic
|
|
foreach (var traffic; [model_root.getChildren("aircraft"), model_root.getChildren("multiplayer")]) {
|
|
foreach(var t; traffic) {
|
|
if (me.in_range(t.getValue("position/latitude-deg"),
|
|
t.getValue("position/longitude-deg"),
|
|
myPositionVec,
|
|
max_dist_m))
|
|
append(result, TrafficModel.new(t, nil, me.layer));
|
|
}
|
|
}
|
|
|
|
#debug.dump(result);
|
|
#return [];
|
|
return result;
|
|
};
|
|
|