# Class things: var parents = [Map.Controller]; var __self__ = caller(0)[0]; Map.Controller.add("Aircraft position", __self__); #Map.df_controller = __self__; ## # encapsulate type of aircraft (main, ai, mp or ai+mp) # This is so that we can use reuse the aircraft controller also # for AI and/or MP traffic, which may use different properties # and to fix up hard-coded property references in layers like TFC var SOURCES = {}; SOURCES["main"] = { getPosition: func subvec(geo.aircraft_position().latlon(), 0, 2), getAltitude: func getprop('/position/altitude-ft'), getHeading: func getprop('/orientation/heading-deg'), }; # Layers which get updated every frame var update_instant = [ "APS", ]; # Update at a slightly lower rate, but still # unconditionally var update_quickly = [ "TFC", "FLT", ]; var new = func(map, source='main') { if (!contains(SOURCES, source)) __die("AI/MP traffic not yet supported (WIP)!"); var m = { parents: [__self__], map: map, source: SOURCES[source], # main, ai, mp or ai+mp _pos: nil, _time: nil, _range: nil, }; m.timer1 = maketimer(0, m, update_pos); m.timer2 = maketimer(0.4, m, update_layers); m.start(); m.update_pos(); return m; }; var start = func() { me.timer1.start(); me.timer2.start(); }; var stop = func() { me.timer1.stop(); me.timer2.stop(); }; var del = func(map) { if (map != me.map) die(); me.stop(); }; # Controller methods var update_pos = func { var (lat,lon) = me.source.getPosition(); me.map.setPos(lat:lat, lon:lon, hdg:me.source.getHeading(), alt:me.source.getAltitude()); foreach (var t; update_instant) if ((var l=me.map.getLayer(t)) != nil) l.update(); }; var update_layers = func { var do_all = 1; var pos = me.map.getPosCoord(); var time = systime(); var range = me.map.getRange(); if (me._pos == nil) me._pos = geo.Coord.new(pos); # Always update if range changed # FIXME: FIX doesn't update unless range is changed? elsif (range == me._range) { var dist_m = me._pos.direct_distance_to(pos); # 2 NM until we update again if (dist_m < 2 * NM2M) do_all = 0; # Update at most every 4 seconds to avoid excessive stutter: elsif (time - me._time < 4) do_all = 0; } if (!do_all) { foreach (var t; update_quickly) if ((var l=me.map.getLayer(t)) != nil) l.update(); return; } else logprint(_MP_dbg_lvl, "update aircraft position"); var (x,y,z) = pos.xyz(); me._pos.set_xyz(x,y,z); me._time = time; me._range = range; me.map.update(); }; # predicate for the draw controller var is_tuned = func(freq) { var nav1=getprop("instrumentation/nav[0]/frequencies/selected-mhz"); var nav2=getprop("instrumentation/nav[1]/frequencies/selected-mhz"); if (freq == nav1 or freq == nav2) return 1; return 0; } var get_tuned_course = func(freq) { if (freq == getprop("instrumentation/nav[0]/frequencies/selected-mhz")) return getprop("instrumentation/nav[0]/radials/selected-deg"); else return getprop("instrumentation/nav[1]/radials/selected-deg"); } var get_position = func { delete(caller(0)[0], "me"); # remove local me, inherit outer one return [ me.aircraft_source.get_lat(), me.aircraft_source.get_lon() ]; }