cosmos 4.0.3 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -5
- data/Manifest.txt +11 -1
- data/README.md +3 -2
- data/Rakefile +18 -4
- data/appveyor.yml +19 -0
- data/cosmos.gemspec +14 -3
- data/data/config/cmd_tlm_server.yaml +3 -0
- data/data/crc.txt +63 -60
- data/demo/config/targets/INST/cmd_tlm_server.txt +1 -0
- data/demo/config/targets/INST/cmd_tlm_server2.txt +7 -0
- data/demo/config/tools/cmd_sequence/cmd_sequence.txt +2 -0
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +8 -12
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +7 -9
- data/demo/lib/cmd_sequence_exporter.rb +52 -0
- data/demo/lib/example_background_task.rb +1 -0
- data/demo/procedures/replay_test.rb +32 -0
- data/ext/cosmos/ext/structure/structure.c +39 -3
- data/install/config/tools/cmd_tlm_server/cmd_tlm_server.txt +1 -0
- data/install/config/tools/launcher/launcher.txt +2 -0
- data/lib/cosmos/config/config_parser.rb +2 -0
- data/lib/cosmos/core_ext/io.rb +89 -60
- data/lib/cosmos/gui/qt.rb +5 -8
- data/lib/cosmos/gui/qt_tool.rb +8 -8
- data/lib/cosmos/gui/text/ruby_editor.rb +12 -12
- data/lib/cosmos/gui/utilities/script_module_gui.rb +9 -9
- data/lib/cosmos/gui/widgets/realtime_button_bar.rb +18 -17
- data/lib/cosmos/interfaces/protocols/fixed_protocol.rb +2 -2
- data/lib/cosmos/interfaces/protocols/template_protocol.rb +3 -0
- data/lib/cosmos/interfaces/udp_interface.rb +27 -14
- data/lib/cosmos/io/buffered_file.rb +0 -1
- data/lib/cosmos/io/json_drb.rb +134 -214
- data/lib/cosmos/io/json_drb_object.rb +22 -61
- data/lib/cosmos/io/json_drb_rack.rb +79 -0
- data/lib/cosmos/io/json_rpc.rb +27 -0
- data/lib/cosmos/io/udp_sockets.rb +102 -58
- data/lib/cosmos/packets/commands.rb +1 -1
- data/lib/cosmos/packets/structure.rb +1 -1
- data/lib/cosmos/packets/structure_item.rb +37 -5
- data/lib/cosmos/script/cmd_tlm_server.rb +76 -2
- data/lib/cosmos/script/replay.rb +60 -0
- data/lib/cosmos/script/script.rb +20 -2
- data/lib/cosmos/script/scripting.rb +9 -9
- data/lib/cosmos/script/tools.rb +14 -0
- data/lib/cosmos/system/system.rb +185 -92
- data/lib/cosmos/system/target.rb +1 -1
- data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +44 -4
- data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +4 -0
- data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +7 -0
- data/lib/cosmos/tools/cmd_tlm_server/api.rb +347 -20
- data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +3 -0
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +329 -111
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +13 -0
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +261 -95
- data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +46 -35
- data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +18 -8
- data/lib/cosmos/tools/cmd_tlm_server/gui/packets_tab.rb +39 -28
- data/lib/cosmos/tools/cmd_tlm_server/gui/replay_tab.rb +242 -0
- data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +24 -8
- data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +18 -6
- data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +5 -4
- data/lib/cosmos/tools/cmd_tlm_server/replay_backend.rb +375 -0
- data/lib/cosmos/tools/cmd_tlm_server/routers.rb +10 -2
- data/lib/cosmos/tools/data_viewer/data_viewer.rb +40 -5
- data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +18 -20
- data/lib/cosmos/tools/launcher/launcher_config.rb +5 -16
- data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +65 -39
- data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +19 -0
- data/lib/cosmos/tools/replay/replay.rb +5 -505
- data/lib/cosmos/tools/script_runner/script_audit.rb +1 -0
- data/lib/cosmos/tools/script_runner/script_runner.rb +3 -4
- data/lib/cosmos/tools/script_runner/script_runner_config.rb +3 -4
- data/lib/cosmos/tools/script_runner/script_runner_frame.rb +44 -23
- data/lib/cosmos/tools/test_runner/results_writer.rb +4 -0
- data/lib/cosmos/tools/test_runner/test_runner.rb +0 -3
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +6 -2
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +26 -1
- data/lib/cosmos/tools/tlm_viewer/screen.rb +24 -1
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +25 -0
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +24 -14
- data/lib/cosmos/top_level.rb +34 -24
- data/lib/cosmos/utilities/csv.rb +60 -8
- data/lib/cosmos/version.rb +5 -5
- data/spec/config/config_parser_spec.rb +10 -1
- data/spec/core_ext/socket_spec.rb +4 -2
- data/spec/gui/utilities/script_module_gui_spec.rb +102 -0
- data/spec/install/config/data/data.txt +1 -0
- data/spec/install/config/targets/INST/cmd_tlm/inst_cmds.txt +2 -0
- data/spec/interfaces/cmd_tlm_server_interface_spec.rb +1 -2
- data/spec/interfaces/protocols/template_protocol_spec.rb +72 -2
- data/spec/interfaces/serial_interface_spec.rb +1 -1
- data/spec/interfaces/udp_interface_spec.rb +14 -0
- data/spec/io/buffered_file_spec.rb +37 -0
- data/spec/io/json_drb_object_spec.rb +2 -15
- data/spec/io/json_drb_spec.rb +61 -121
- data/spec/io/udp_sockets_spec.rb +42 -2
- data/spec/packet_logs/packet_log_reader_spec.rb +5 -2
- data/spec/packets/binary_accessor_spec.rb +1 -1
- data/spec/packets/packet_item_spec.rb +1 -1
- data/spec/packets/structure_item_spec.rb +5 -6
- data/spec/script/cmd_tlm_server_spec.rb +39 -4
- data/spec/script/commands_disconnect_spec.rb +1 -1
- data/spec/script/commands_spec.rb +2 -1
- data/spec/script/scripting_spec.rb +18 -3
- data/spec/script/telemetry_spec.rb +5 -0
- data/spec/spec_helper.rb +43 -26
- data/spec/streams/tcpip_socket_stream_spec.rb +2 -2
- data/spec/system/system_spec.rb +11 -9
- data/spec/system/target_spec.rb +3 -0
- data/spec/tools/cmd_tlm_server/api_spec.rb +543 -29
- data/spec/tools/cmd_tlm_server/background_task_spec.rb +2 -2
- data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +31 -75
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +199 -66
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +85 -9
- data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +29 -127
- data/spec/tools/cmd_tlm_server/router_thread_spec.rb +10 -50
- data/spec/tools/launcher/launcher_config_spec.rb +1 -1
- data/spec/tools/table_manager/table_item_spec.rb +1 -1
- data/spec/tools/table_manager/tablemanager_core_spec.rb +4 -4
- data/spec/top_level/top_level_spec.rb +151 -3
- data/spec/utilities/csv_spec.rb +24 -5
- metadata +61 -9
- data/lib/cosmos/tools/replay/replay_server.rb +0 -91
@@ -49,10 +49,10 @@ module Cosmos
|
|
49
49
|
@running_icon = Cosmos.get_icon('running.png')
|
50
50
|
@no_icon = Qt::Icon.new
|
51
51
|
|
52
|
-
|
52
|
+
begin
|
53
53
|
ScriptRunnerConfig.new(options.config_file)
|
54
|
-
|
55
|
-
|
54
|
+
rescue => error
|
55
|
+
ExceptionDialog.new(self, error, "Error parsing #{options.config_file}")
|
56
56
|
end
|
57
57
|
|
58
58
|
@procedure_dir = System.paths['PROCEDURES'][0]
|
@@ -955,7 +955,6 @@ module Cosmos
|
|
955
955
|
options.height = 600
|
956
956
|
options.title = "Script Runner : Untitled"
|
957
957
|
options.auto_size = false
|
958
|
-
options.config_file = "script_runner.txt"
|
959
958
|
options.server_config_file = CmdTlmServer::DEFAULT_CONFIG_FILE
|
960
959
|
options.run_procedure = nil
|
961
960
|
|
@@ -11,11 +11,11 @@
|
|
11
11
|
require 'cosmos'
|
12
12
|
|
13
13
|
module Cosmos
|
14
|
-
|
15
14
|
# This class reads the Script Runner configuration file
|
16
15
|
class ScriptRunnerConfig
|
17
16
|
# Processes the config file
|
18
17
|
def initialize(filename)
|
18
|
+
return unless filename
|
19
19
|
parser = ConfigParser.new("http://cosmosrb.com/docs/tools/#script-runner-configuration")
|
20
20
|
parser.parse_file(filename) do |keyword, params|
|
21
21
|
case keyword
|
@@ -35,6 +35,5 @@ module Cosmos
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
|
-
end
|
39
|
-
|
40
|
-
end # module Cosmos
|
38
|
+
end
|
39
|
+
end
|
@@ -140,6 +140,7 @@ module Cosmos
|
|
140
140
|
# Add Realtime Button Bar
|
141
141
|
@realtime_button_bar = RealtimeButtonBar.new(self)
|
142
142
|
@realtime_button_bar.state = 'Stopped'
|
143
|
+
@realtime_button_bar.step_callback = method(:handle_step_button)
|
143
144
|
@realtime_button_bar.start_callback = method(:handle_start_go_button)
|
144
145
|
@realtime_button_bar.pause_callback = method(:handle_pause_retry_button)
|
145
146
|
@realtime_button_bar.stop_callback = method(:handle_stop_button)
|
@@ -549,13 +550,20 @@ module Cosmos
|
|
549
550
|
return nil if @cancel_instrumentation
|
550
551
|
instrumented_line = ''
|
551
552
|
if instrumentable
|
553
|
+
# Skip the segment if it's empty. Note that the segment could have
|
554
|
+
# originally had comments but they were stripped in
|
555
|
+
# ruby_lex_utils.remove_comments
|
556
|
+
next if segment.strip.empty?
|
552
557
|
# If not inside a begin block then create one to catch exceptions
|
553
558
|
unless inside_begin
|
554
559
|
instrumented_line << 'begin; '
|
555
560
|
end
|
556
561
|
|
557
562
|
# Add preline instrumentation
|
558
|
-
instrumented_line << "ScriptRunnerFrame.instance.script_binding = binding();
|
563
|
+
instrumented_line << "ScriptRunnerFrame.instance.script_binding = binding(); "\
|
564
|
+
"if ScriptRunnerFrame.instance.inline_return then ScriptRunnerFrame.instance.inline_return = nil; "\
|
565
|
+
"return ScriptRunnerFrame.instance.inline_return_params; end; "\
|
566
|
+
"ScriptRunnerFrame.instance.pre_line_instrumentation('#{filename}', #{line_no}); "
|
559
567
|
|
560
568
|
# Add the actual line
|
561
569
|
instrumented_line << segment
|
@@ -566,7 +574,8 @@ module Cosmos
|
|
566
574
|
|
567
575
|
# Complete begin block to catch exceptions
|
568
576
|
unless inside_begin
|
569
|
-
instrumented_line << "; rescue Exception => eval_error;
|
577
|
+
instrumented_line << "; rescue Exception => eval_error; "\
|
578
|
+
"retry if ScriptRunnerFrame.instance.exception_instrumentation(eval_error, '#{filename}', #{line_no}); end"
|
570
579
|
end
|
571
580
|
|
572
581
|
instrumented_line << "\n"
|
@@ -682,7 +691,16 @@ module Cosmos
|
|
682
691
|
# Implement the breakpoint callbacks from the RubyEditor
|
683
692
|
######################################
|
684
693
|
def breakpoint_set(line)
|
685
|
-
|
694
|
+
# Check for blank and comment lines which can't have a breakpoint.
|
695
|
+
# There are other un-instrumentable lines which don't support breakpoints
|
696
|
+
# but this is the most common and is an easy check.
|
697
|
+
# Note: line is 1 based but @script.get_line is zero based so subtract 1
|
698
|
+
text = @script.get_line(line - 1)
|
699
|
+
if text.strip.empty? || text.strip[0] == '#'
|
700
|
+
@script.clear_breakpoint(line) # Immediately clear it
|
701
|
+
else
|
702
|
+
ScriptRunnerFrame.set_breakpoint(current_tab_filename(), line)
|
703
|
+
end
|
686
704
|
end
|
687
705
|
|
688
706
|
def breakpoint_cleared(line)
|
@@ -874,6 +892,7 @@ module Cosmos
|
|
874
892
|
|
875
893
|
def show_debug
|
876
894
|
unless @debug_frame
|
895
|
+
@realtime_button_bar.step_button.setHidden(false)
|
877
896
|
@script.enable_breakpoints = true
|
878
897
|
if @tab_book_shown
|
879
898
|
if @tab_book.count > 0
|
@@ -946,20 +965,6 @@ module Cosmos
|
|
946
965
|
|
947
966
|
@debug_frame.addWidget(@debug_text)
|
948
967
|
|
949
|
-
@toggle_button = Qt::PushButton.new('Toggle Run/Step')
|
950
|
-
@debug_frame.addWidget(@toggle_button)
|
951
|
-
@toggle_button.connect(SIGNAL('clicked(bool)')) do
|
952
|
-
if @@step_mode
|
953
|
-
scriptrunner_puts "Debug: run_mode"
|
954
|
-
handle_output_io()
|
955
|
-
self.class.step_mode = false
|
956
|
-
else
|
957
|
-
scriptrunner_puts "Debug: step_mode"
|
958
|
-
handle_output_io()
|
959
|
-
self.class.step_mode = true
|
960
|
-
end
|
961
|
-
end
|
962
|
-
|
963
968
|
@return_button = Qt::PushButton.new('Insert Return')
|
964
969
|
@debug_frame.addWidget(@return_button)
|
965
970
|
@return_button.connect(SIGNAL('clicked(bool)')) do
|
@@ -985,11 +990,19 @@ module Cosmos
|
|
985
990
|
end
|
986
991
|
end
|
987
992
|
end
|
993
|
+
@realtime_button_bar.step_button.setHidden(true)
|
988
994
|
# Remove the debug frame
|
989
995
|
@bottom_frame.layout.takeAt(@bottom_frame.layout.count - 1) if @debug_frame
|
990
996
|
@debug_frame.removeAll
|
991
997
|
@debug_frame.dispose
|
992
998
|
@debug_frame = nil
|
999
|
+
|
1000
|
+
# If step mode was previously active then pause the script so it doesn't
|
1001
|
+
# just take off when we end the debugging session
|
1002
|
+
if @@step_mode
|
1003
|
+
pause()
|
1004
|
+
@@step_mode = false
|
1005
|
+
end
|
993
1006
|
end
|
994
1007
|
|
995
1008
|
def self.set_breakpoint(filename, line_number)
|
@@ -1442,8 +1455,18 @@ module Cosmos
|
|
1442
1455
|
true
|
1443
1456
|
end
|
1444
1457
|
|
1445
|
-
def
|
1446
|
-
scriptrunner_puts "User pressed #{@realtime_button_bar.
|
1458
|
+
def handle_step_button
|
1459
|
+
scriptrunner_puts "User pressed #{@realtime_button_bar.step_button.text.strip}"
|
1460
|
+
pause()
|
1461
|
+
@@step_mode = true
|
1462
|
+
handle_start_go_button(step = true)
|
1463
|
+
end
|
1464
|
+
|
1465
|
+
def handle_start_go_button(step = false)
|
1466
|
+
unless step
|
1467
|
+
scriptrunner_puts "User pressed #{@realtime_button_bar.start_button.text.strip}"
|
1468
|
+
@@step_mode = false
|
1469
|
+
end
|
1447
1470
|
handle_output_io()
|
1448
1471
|
@realtime_button_bar.start_button.clear_focus()
|
1449
1472
|
|
@@ -1832,7 +1855,5 @@ module Cosmos
|
|
1832
1855
|
# Oh Well
|
1833
1856
|
end
|
1834
1857
|
end
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
end # module Cosmos
|
1858
|
+
end
|
1859
|
+
end
|
@@ -116,6 +116,9 @@ module Cosmos
|
|
116
116
|
footer()
|
117
117
|
ensure
|
118
118
|
@file.close if @file and not @file.closed?
|
119
|
+
Cosmos.set_working_dir do
|
120
|
+
File.chmod(0444, @filename)
|
121
|
+
end
|
119
122
|
end
|
120
123
|
|
121
124
|
def header
|
@@ -166,6 +169,7 @@ module Cosmos
|
|
166
169
|
end
|
167
170
|
end
|
168
171
|
end
|
172
|
+
File.chmod(0444, @data_package_filename)
|
169
173
|
end
|
170
174
|
progress_dialog.close_done if progress_dialog
|
171
175
|
rescue => error
|
@@ -971,12 +971,9 @@ module Cosmos
|
|
971
971
|
|
972
972
|
def process_config(filename)
|
973
973
|
ScriptRunnerFrame.instance = @script_runner_frame
|
974
|
-
|
975
974
|
# Remember all the requires that fail and warn the user
|
976
975
|
require_errors = []
|
977
976
|
|
978
|
-
# Ensure the file exists
|
979
|
-
raise "Configuration File: #{filename} does not exist" unless test(?f, filename)
|
980
977
|
parser = ConfigParser.new("http://cosmosrb.com/docs/tools/#test-runner-configuration")
|
981
978
|
parser.parse_file(filename) do |keyword, params|
|
982
979
|
case keyword
|
@@ -18,8 +18,12 @@ module Cosmos
|
|
18
18
|
class TabbedPlotsRealtimeThread < InterfaceThread
|
19
19
|
|
20
20
|
# Create a new TabbedPlotsRealtimeThread
|
21
|
-
def initialize(tabbed_plots_config, connection_success_callback = nil, connection_failed_callback = nil, connection_lost_callback = nil, fatal_exception_callback = nil)
|
22
|
-
|
21
|
+
def initialize(tabbed_plots_config, connection_success_callback = nil, connection_failed_callback = nil, connection_lost_callback = nil, fatal_exception_callback = nil, replay_mode = false)
|
22
|
+
if replay_mode
|
23
|
+
interface = TcpipClientInterface.new(System.connect_hosts['REPLAY_PREIDENTIFIED'], nil, System.ports['REPLAY_PREIDENTIFIED'], nil, tabbed_plots_config.cts_timeout, 'PREIDENTIFIED')
|
24
|
+
else
|
25
|
+
interface = TcpipClientInterface.new(System.connect_hosts['CTS_PREIDENTIFIED'], nil, System.ports['CTS_PREIDENTIFIED'], nil, tabbed_plots_config.cts_timeout, 'PREIDENTIFIED')
|
26
|
+
end
|
23
27
|
super(interface)
|
24
28
|
|
25
29
|
@queue = Queue.new
|
@@ -63,6 +63,7 @@ module Cosmos
|
|
63
63
|
@tabbed_plots = nil
|
64
64
|
@realtime_thread = nil
|
65
65
|
@config_modified = false
|
66
|
+
@replay_mode = false
|
66
67
|
|
67
68
|
# Bring up slash screen for long duration tasks after creation
|
68
69
|
Splash.execute(self) do |splash|
|
@@ -107,6 +108,10 @@ module Cosmos
|
|
107
108
|
@file_screenshot.statusTip = tr('Screenshot of Application')
|
108
109
|
@file_screenshot.connect(SIGNAL('triggered()')) { on_file_screenshot() }
|
109
110
|
|
111
|
+
@replay_action = Qt::Action.new(tr('Toggle Replay Mode'), self)
|
112
|
+
@replay_action.statusTip = tr('Toggle Replay Mode')
|
113
|
+
@replay_action.connect(SIGNAL('triggered()')) { toggle_replay_mode() }
|
114
|
+
|
110
115
|
# Tab Menu Actions
|
111
116
|
@tab_add = Qt::Action.new(Cosmos.get_icon('add_tab.png'), tr('&Add Tab'), self)
|
112
117
|
@tab_add.statusTip = tr('Add New Tab')
|
@@ -209,6 +214,8 @@ module Cosmos
|
|
209
214
|
@file_menu.addSeparator()
|
210
215
|
@file_menu.addAction(@file_screenshot)
|
211
216
|
@file_menu.addSeparator()
|
217
|
+
@file_menu.addAction(@replay_action)
|
218
|
+
@file_menu.addSeparator()
|
212
219
|
@file_menu.addAction(@exit_action)
|
213
220
|
|
214
221
|
@tab_menu = menuBar.addMenu(tr('&Tab'))
|
@@ -265,6 +272,10 @@ module Cosmos
|
|
265
272
|
# Create a Vertical Frame for the right contents
|
266
273
|
@right_widget = Qt::Widget.new(self)
|
267
274
|
@right_frame = Qt::VBoxLayout.new
|
275
|
+
@replay_flag = Qt::Label.new("Replay Mode")
|
276
|
+
@replay_flag.setStyleSheet("background:green;color:white;padding:5px;font-weight:bold;height:30px;")
|
277
|
+
@right_frame.addWidget(@replay_flag)
|
278
|
+
@replay_flag.hide
|
268
279
|
@right_widget.setLayout(@right_frame)
|
269
280
|
@splitter.addWidget(@right_widget)
|
270
281
|
@splitter.setStretchFactor(0,0) # Set the left side stretch factor to 0
|
@@ -581,6 +592,20 @@ module Cosmos
|
|
581
592
|
@tabbed_plots.resume unless paused
|
582
593
|
end # def on_file_screenshot
|
583
594
|
|
595
|
+
def toggle_replay_mode
|
596
|
+
running = @realtime_thread ? true : false
|
597
|
+
handle_stop()
|
598
|
+
System.telemetry.reset
|
599
|
+
@tabbed_plots.reset_all_data_objects
|
600
|
+
@replay_mode = !@replay_mode
|
601
|
+
if @replay_mode
|
602
|
+
@replay_flag.show
|
603
|
+
else
|
604
|
+
@replay_flag.hide
|
605
|
+
end
|
606
|
+
handle_start() if running
|
607
|
+
end
|
608
|
+
|
584
609
|
###############################################################################
|
585
610
|
# Tab Menu Handlers
|
586
611
|
###############################################################################
|
@@ -921,7 +946,7 @@ module Cosmos
|
|
921
946
|
# Startup realtime thread
|
922
947
|
@realtime_button_bar.state = 'Connecting'
|
923
948
|
statusBar.showMessage(tr("Connecting to COSMOS Server"))
|
924
|
-
@realtime_thread = TabbedPlotsRealtimeThread.new(@tabbed_plots_config, method(:realtime_thread_connection_success_callback), method(:realtime_thread_connection_failed_callback), method(:realtime_thread_connection_lost_callback), method(:realtime_thread_fatal_exception_callback))
|
949
|
+
@realtime_thread = TabbedPlotsRealtimeThread.new(@tabbed_plots_config, method(:realtime_thread_connection_success_callback), method(:realtime_thread_connection_failed_callback), method(:realtime_thread_connection_lost_callback), method(:realtime_thread_fatal_exception_callback), @replay_mode)
|
925
950
|
end
|
926
951
|
end # def handle_start
|
927
952
|
|
@@ -21,7 +21,7 @@ module Cosmos
|
|
21
21
|
# close_all_screens is called
|
22
22
|
@@open_screens = []
|
23
23
|
|
24
|
-
attr_accessor :full_name, :width, :height, :window
|
24
|
+
attr_accessor :full_name, :width, :height, :window, :replay_flag
|
25
25
|
|
26
26
|
class Widgets
|
27
27
|
# Flag to indicate all screens should close
|
@@ -229,6 +229,7 @@ module Cosmos
|
|
229
229
|
app_style = File.join(Cosmos::USERPATH, 'config', 'tools', 'application.css')
|
230
230
|
setStyleSheet(File.read(app_style)) if File.exist? app_style
|
231
231
|
|
232
|
+
@replay_flag = nil
|
232
233
|
@widgets = Widgets.new(self, mode)
|
233
234
|
@window = process(filename)
|
234
235
|
@@open_screens << self if @window
|
@@ -277,6 +278,12 @@ module Cosmos
|
|
277
278
|
setCentralWidget(top_widget)
|
278
279
|
frame = Qt::VBoxLayout.new()
|
279
280
|
top_widget.setLayout(frame)
|
281
|
+
|
282
|
+
@replay_flag = Qt::Label.new("Replay Mode")
|
283
|
+
@replay_flag.setStyleSheet("background:green;color:white;padding:5px;font-weight:bold;")
|
284
|
+
frame.addWidget(@replay_flag)
|
285
|
+
@replay_flag.hide unless get_replay_mode()
|
286
|
+
|
280
287
|
layout_stack[0] = frame
|
281
288
|
Cosmos.load_cosmos_icon if @single_screen
|
282
289
|
when 'END'
|
@@ -498,5 +505,21 @@ module Cosmos
|
|
498
505
|
Widgets.closing_all = false
|
499
506
|
end
|
500
507
|
|
508
|
+
def self.update_replay_mode
|
509
|
+
screens = @@open_screens.clone
|
510
|
+
replay_mode = get_replay_mode()
|
511
|
+
screens.each do |screen|
|
512
|
+
begin
|
513
|
+
if replay_mode
|
514
|
+
screen.replay_flag.show if screen.replay_flag
|
515
|
+
else
|
516
|
+
screen.replay_flag.hide if screen.replay_flag
|
517
|
+
end
|
518
|
+
rescue
|
519
|
+
# Oh well
|
520
|
+
end
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
501
524
|
end
|
502
525
|
end
|
@@ -57,6 +57,8 @@ module Cosmos
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def self.load_config(filename)
|
60
|
+
raise "Configuration file #{filename} does not exist." unless filename && File.exist?(filename)
|
61
|
+
|
60
62
|
# Find all screen files so we can calculate MD5
|
61
63
|
tlmviewer_files = [filename, System.initial_filename]
|
62
64
|
additional_data = ''
|
@@ -179,6 +181,10 @@ module Cosmos
|
|
179
181
|
@file_audit.shortcut = @file_audit_keyseq
|
180
182
|
@file_audit.statusTip = tr('Create a report listing which telemetry points are not on screens')
|
181
183
|
@file_audit.connect(SIGNAL('triggered()')) { file_audit() }
|
184
|
+
|
185
|
+
@replay_action = Qt::Action.new(tr('Toggle Replay Mode'), self)
|
186
|
+
@replay_action.statusTip = tr('Toggle Replay Mode')
|
187
|
+
@replay_action.connect(SIGNAL('triggered()')) { toggle_replay_mode() }
|
182
188
|
end
|
183
189
|
|
184
190
|
def initialize_menus(options)
|
@@ -187,6 +193,7 @@ module Cosmos
|
|
187
193
|
@file_menu.addAction(@file_save)
|
188
194
|
@file_menu.addAction(@file_generate)
|
189
195
|
@file_menu.addAction(@file_audit)
|
196
|
+
@file_menu.addAction(@replay_action)
|
190
197
|
@file_menu.addSeparator()
|
191
198
|
@file_menu.addAction(@exit_action)
|
192
199
|
|
@@ -202,6 +209,11 @@ module Cosmos
|
|
202
209
|
setCentralWidget(central_widget)
|
203
210
|
top_layout = Qt::VBoxLayout.new
|
204
211
|
|
212
|
+
@replay_flag = Qt::Label.new("Replay Mode")
|
213
|
+
@replay_flag.setStyleSheet("background:green;color:white;padding:5px;font-weight:bold;")
|
214
|
+
top_layout.addWidget(@replay_flag)
|
215
|
+
@replay_flag.hide
|
216
|
+
|
205
217
|
@search_box = FullTextSearchLineEdit.new(self)
|
206
218
|
top_layout.addWidget(@search_box)
|
207
219
|
|
@@ -406,6 +418,16 @@ module Cosmos
|
|
406
418
|
Cosmos.open_in_text_editor(output_filename) if output_filename
|
407
419
|
end
|
408
420
|
|
421
|
+
def toggle_replay_mode
|
422
|
+
set_replay_mode(!get_replay_mode())
|
423
|
+
if get_replay_mode()
|
424
|
+
@replay_flag.show
|
425
|
+
else
|
426
|
+
@replay_flag.hide
|
427
|
+
end
|
428
|
+
Screen.update_replay_mode
|
429
|
+
end
|
430
|
+
|
409
431
|
# Method called by screens to notify that they have been closed
|
410
432
|
def notify(closed_screen)
|
411
433
|
screen_full_name = closed_screen.full_name
|
@@ -447,6 +469,9 @@ module Cosmos
|
|
447
469
|
|
448
470
|
def display(screen_full_name, x_pos = nil, y_pos = nil)
|
449
471
|
return unless screen_full_name
|
472
|
+
x_pos = x_pos.to_i if x_pos
|
473
|
+
y_pos = y_pos.to_i if y_pos
|
474
|
+
|
450
475
|
# Find the specified screen
|
451
476
|
screen_info = find_screen_info(screen_full_name)
|
452
477
|
|
@@ -46,6 +46,21 @@ module Cosmos
|
|
46
46
|
@invalid_items = []
|
47
47
|
end
|
48
48
|
|
49
|
+
def as_json(options = nil) #:nodoc:
|
50
|
+
{group: @group,
|
51
|
+
target_name: @target_name,
|
52
|
+
original_target_name:
|
53
|
+
@original_target_name,
|
54
|
+
name: @name,
|
55
|
+
filename: @filename,
|
56
|
+
x_pos: @x_pos,
|
57
|
+
y_pos: @y_pos,
|
58
|
+
substitute: @substitute,
|
59
|
+
force_substitute: @force_substitute,
|
60
|
+
show_on_startup: @show_on_startup
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
49
64
|
def full_name
|
50
65
|
@group ? @name : "#{@target_name} #{@name}"
|
51
66
|
end
|
@@ -96,15 +111,10 @@ module Cosmos
|
|
96
111
|
attr_accessor :completion_list
|
97
112
|
attr_accessor :tlm_to_screen_mapping
|
98
113
|
|
99
|
-
def initialize(filename = nil)
|
114
|
+
def initialize(filename = nil, skip_read_items = false)
|
100
115
|
# Handle nil filename
|
101
116
|
filename = File.join(Cosmos::USERPATH, 'config', 'tools', 'tlm_viewer', 'tlm_viewer.txt') unless filename
|
102
117
|
@filename = filename
|
103
|
-
|
104
|
-
# Ensure the file exists
|
105
|
-
raise "Telemetry Viewer configuration file #{filename} does not exist" unless test ?f, filename
|
106
|
-
|
107
|
-
# Initialize instance variables
|
108
118
|
@columns = []
|
109
119
|
@columns << {}
|
110
120
|
@screen_infos = {}
|
@@ -129,7 +139,7 @@ module Cosmos
|
|
129
139
|
screen_dir = File.join(target.dir, 'screens')
|
130
140
|
if File.exist?(screen_dir) and num_screens(screen_dir) > 0
|
131
141
|
start_target(target.name, parser)
|
132
|
-
auto_screens()
|
142
|
+
auto_screens(skip_read_items)
|
133
143
|
end
|
134
144
|
end
|
135
145
|
|
@@ -141,7 +151,7 @@ module Cosmos
|
|
141
151
|
screen_dir = File.join(target.dir, 'screens')
|
142
152
|
if File.exist?(screen_dir) and num_screens(screen_dir) > 0
|
143
153
|
start_target(target.name, parser)
|
144
|
-
auto_screens()
|
154
|
+
auto_screens(skip_read_items)
|
145
155
|
end
|
146
156
|
|
147
157
|
when 'TARGET'
|
@@ -153,7 +163,7 @@ module Cosmos
|
|
153
163
|
raise parser.error("No target defined. SCREEN must follow TARGET.") unless @current_target
|
154
164
|
parser.verify_num_parameters(1, 3, 'SCREEN <Filename> <X Position (optional)> <Y Position (optional)>')
|
155
165
|
screen_filename = File.join(@current_target.dir, 'screens', parameters[0])
|
156
|
-
start_screen(screen_filename, parameters[1], parameters[2])
|
166
|
+
start_screen(screen_filename, parameters[1], parameters[2], skip_read_items)
|
157
167
|
|
158
168
|
when 'SHOW_ON_STARTUP'
|
159
169
|
raise parser.error("No screen defined. SHOW_ON_STARTUP must follow SCREEN or GROUP_SCREEN.") unless @current_screen_info
|
@@ -179,7 +189,7 @@ module Cosmos
|
|
179
189
|
parser.verify_num_parameters(2, 4, 'GROUP_SCREEN <Target Name> <Screen Filename> <X Position (optional)> <Y Position (Optional)>')
|
180
190
|
start_target(parameters[0].upcase, parser, @current_group)
|
181
191
|
screen_filename = File.join(@current_target.dir, 'screens', parameters[1])
|
182
|
-
start_screen(screen_filename, parameters[2], parameters[3])
|
192
|
+
start_screen(screen_filename, parameters[2], parameters[3], skip_read_items)
|
183
193
|
|
184
194
|
else
|
185
195
|
# blank config.lines will have a nil keyword and should not raise an exception
|
@@ -233,7 +243,7 @@ module Cosmos
|
|
233
243
|
end
|
234
244
|
end
|
235
245
|
|
236
|
-
def start_screen(screen_filename, x_pos = nil, y_pos = nil)
|
246
|
+
def start_screen(screen_filename, x_pos = nil, y_pos = nil, skip_read_items = false)
|
237
247
|
screen_name = File.basename(screen_filename, '.txt').upcase
|
238
248
|
x_pos = x_pos.to_i if x_pos
|
239
249
|
y_pos = y_pos.to_i if y_pos
|
@@ -244,15 +254,15 @@ module Cosmos
|
|
244
254
|
@current_screen_info.force_substitute = true if @current_target.auto_screen_substitute
|
245
255
|
@current_screen_info.original_target_name = @current_target.original_name
|
246
256
|
@current_screen_info.substitute = @current_target.name if @current_target.substitute or @current_target.auto_screen_substitute
|
247
|
-
@current_screen_info.read_items
|
257
|
+
@current_screen_info.read_items unless skip_read_items
|
248
258
|
end
|
249
259
|
|
250
|
-
def auto_screens
|
260
|
+
def auto_screens(skip_read_items = false)
|
251
261
|
@current_group = nil
|
252
262
|
screen_dir = File.join(@current_target.dir, 'screens')
|
253
263
|
if File.exist?(screen_dir)
|
254
264
|
Dir.new(screen_dir).each do |filename|
|
255
|
-
start_screen(File.join(screen_dir, filename)) if valid_screen_name(filename)
|
265
|
+
start_screen(File.join(screen_dir, filename), nil, nil, skip_read_items) if valid_screen_name(filename)
|
256
266
|
end
|
257
267
|
end
|
258
268
|
end
|