diff --git a/Nasal/performance_monitor/monitor.nas b/Nasal/performance_monitor/monitor.nas
new file mode 100644
index 000000000..888c9f610
--- /dev/null
+++ b/Nasal/performance_monitor/monitor.nas
@@ -0,0 +1,168 @@
+# GUI displaying FG system performance statistics
+# performance_monitor.dialog.show() -- displays pilot list dialog
+
+var PERFMON_RUNNING = 0;
+
+var dialog = {
+ init: func(x = nil, y = nil) {
+ me.x = x;
+ me.y = y;
+ me.bg = [0, 0, 0, 0.3]; # background color
+ me.fg = [[0.9, 0.9, 0.2, 1], [1, 1, 1, 1]]; # alternative active
+
+ # "private"
+ var font = { name: "FIXED_8x13" };
+ me.header = [" submodule", "min/ms", "max/ms", "mean/ms", "stddev/ms", "total/ms", "iterations" ];
+ me.columns = [
+ { type: "text", property: "name", format: " %s", label: "------------------", halign: "fill", font: font },
+ { type: "text", property: "min-ms", format: "%5.2f", label: "---------", halign: "fill", font: font },
+ { type: "text", property: "max-ms", format: "%5.2f", label: "---------", halign: "fill", font: font },
+ { type: "text", property: "mean-ms", format:" %5.2f", label: "---------", halign: "fill", font: font },
+ { type: "text", property: "stddev-ms", format:" %5.2f", label: "---------", halign: "fill", font: font },
+ { type: "text", property: "total-ms", format:" %8.2f", label: "------------", halign: "fill", font: font },
+ { type: "text", property: "count", format:" %3d", label: "------", halign: "fill", font: font },
+ ];
+ me.name = "performance-monitor";
+ me.dialog = nil;
+ me.loopid = 0;
+
+ 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("/sim/signals/reinit-gui", func me._redraw_()));
+ },
+ create: func {
+ if (me.dialog != nil)
+ me.close();
+
+ setprop("/sim/performance-monitor/enabled",1);
+
+ me.dialog = gui.dialog[me.name] = 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)
+ me.dialog.set("y", me.y);
+
+ me.dialog.set("layout", "vbox");
+ me.dialog.set("default-padding", 0);
+
+ me.dialog.setColor(me.bg[0], me.bg[1], me.bg[2], me.bg[3]);
+
+ var titlebar = me.dialog.addChild("group");
+ titlebar.set("layout", "hbox");
+
+ var w = titlebar.addChild("button");
+ w.node.setValues({ "pref-width": 32, "pref-height": 16, legend: "sort", default: 0 });
+ w.setBinding("nasal", "performance_monitor.dialog._redraw_()");
+
+ titlebar.addChild("empty").set("stretch", 1);
+ titlebar.addChild("text").set("label", "worst/average frame rate: ");
+ titlebar.addChild("text").node.setValues({ live: 1, property: "/sim/frame-rate-worst", label: "--" });
+ titlebar.addChild("text").set("label", "/");
+ titlebar.addChild("text").node.setValues({ live: 1, property: "/sim/frame-rate", label: "-- fps,", format: "%2d fps," });
+ titlebar.addChild("text").set("label", " worst frame delay: ");
+ titlebar.addChild("text").node.setValues({ live: 1, property: "/sim/frame-latency-max-ms", label: "----.-", format: "%4d ms" });
+ titlebar.addChild("empty").set("stretch", 1);
+
+ var w = titlebar.addChild("button");
+ w.node.setValues({ "pref-width": 16, "pref-height": 16, legend: "", default: 0 });
+ w.setBinding("nasal", "performance_monitor.dialog.del()");
+
+ me.dialog.addChild("hrule");
+
+ var content = me.dialog.addChild("group");
+ content.set("layout", "table");
+ content.set("default-padding", 0);
+
+ var modulelist = props.globals.getNode( "/sim/performance-monitor/subsystems", 1 ).getChildren();
+ var DataReady = size(modulelist) > 0;
+ if (!DataReady)
+ {
+ content.addChild("text").set("label", "wait...");
+ }
+ else
+ {
+ var row = 0;
+ var col = 0;
+ foreach (var h; me.header) {
+ var w = content.addChild("text");
+ var l = typeof(h) == "func" ? h() : h;
+ w.node.setValues({ "label": l, "row": row, "col": col, halign: me.columns[col].halign });
+ w = content.addChild("hrule");
+ w.node.setValues({ "row": row + 1, "col": col });
+ col += 1;
+ }
+ row += 2;
+ var odd = 1;
+ modulelist = sort (modulelist, func (a,b) a.getChild("total-ms",0,1).getValue() < b.getChild("total-ms",0,1).getValue());
+ foreach (var mp; modulelist) {
+ var col = 0;
+ var color = me.fg[odd = !odd];
+ foreach (var column; me.columns) {
+ var p = column.property;
+ var w = nil;
+ if (column.type == "text") {
+ w = content.addChild("text");
+ w.node.setValues(column);
+ }
+ w.setColor(color[0], color[1], color[2], color[3]);
+ w.node.setValues({ row: row, col: col, live: 1, property: mp.getPath() ~ "/" ~ p });
+ col += 1;
+ }
+ row += 1;
+ }
+ }
+ if (me.x != nil)
+ me.dialog.set("x", me.x);
+ if (me.y != nil)
+ me.dialog.set("y", me.y);
+
+ fgcommand("dialog-new", me.dialog.prop());
+ fgcommand("dialog-show", me.dialog.prop());
+ if (!DataReady)
+ settimer(func me.update(me.loopid+=1), 1, 1);
+ },
+ update: func(id) {
+ id == me.loopid or return;
+ if (!PERFMON_RUNNING)
+ return;
+ me._redraw_();
+ },
+ _redraw_: func {
+ if (me.dialog != nil) {
+ me.close();
+ me.create();
+ }
+ },
+ close: func {
+ if (me.dialog != nil) {
+ me.x = me.dialog.prop().getNode("x").getValue();
+ me.y = me.dialog.prop().getNode("y").getValue();
+ }
+ fgcommand("dialog-close", me.dialog.prop());
+ setprop("/sim/performance-monitor/enabled",0);
+ },
+ del: func {
+ PERFMON_RUNNING = 0;
+ me.close();
+ foreach (var l; me.listeners)
+ removelistener(l);
+ delete(gui.dialog, me.name);
+ },
+ show: func {
+ if (!PERFMON_RUNNING) {
+ PERFMON_RUNNING = 1;
+ me.init(2, 20);
+ me.create();
+ }
+ },
+ toggle: func {
+ if (!PERFMON_RUNNING)
+ me.show();
+ else
+ me.del();
+ },
+};
+
diff --git a/gui/menubar.xml b/gui/menubar.xml
index 3e0fa9247..976c9336e 100644
--- a/gui/menubar.xml
+++ b/gui/menubar.xml
@@ -709,10 +709,15 @@
-
-
+
- property-toggle
- /sim/timing-statistics/enabled
+ property-assign
+ /nasal/performance_monitor/enabled
+ true
+
+
+ nasal
+
diff --git a/preferences.xml b/preferences.xml
index 354f927ff..61dc1cc01 100644
--- a/preferences.xml
+++ b/preferences.xml
@@ -748,16 +748,16 @@ Started September 2000 by David Megginson, david@megginson.com
Golf Foxtrot Sierra
-
+
false
20.0
+ archive="n">4.0
0.0
100.0
-
+
@@ -779,6 +779,7 @@ Started September 2000 by David Megginson, david@megginson.com
property browser to configure actual directory. -->
svn
+ 10
@@ -1274,6 +1275,9 @@ Started September 2000 by David Megginson, david@megginson.com
false
+
+ false
+