cosmos 4.0.3-java → 4.1.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +12 -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
|