diff --git a/README.md b/README.md index 7e900007..cf5a99cc 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # Ссылки на составные части -- [Собранные исполняемые файлы для шаблонов экспорта и редактора](https://gitea.srez.local:3000/sasha80/godot-bin) +- [Исполняемые файлы для шаблонов экспорта и редактора](https://gitea.srez.local:3000/sasha80/godot-bin) - [Проброс последовательных портов через Ethernet](http://gitea.srez.local:3000/sasha80/uart-forwarder) - [Сборка Godot из исходников](http://gitea.srez.local:3000/sasha80/godot-build) +- [Сервер карт](http://gitea.srez.local:3000/sasha80/map-tiles) # Ссылки на имитаторы @@ -24,7 +25,7 @@ приходящих на соответствующий порт. Скрипт `ip-tables-navigation.sh` выполняет необходимые для этого настройки. - Для доступа к последовательным портам расположенным на другом вычислительном модуле, - следует использовать [проброс портов](http://gitea.srez.local:3000/sasha80/uart-forwarder). + следует использовать [проброс портов](http://gitea.srez.local:3000/sasha80/uart-forwarder). # Разработка diff --git a/project.godot b/project.godot index dbe368b4..5442dace 100644 --- a/project.godot +++ b/project.godot @@ -24,7 +24,6 @@ config/map_bcs=Vector3(0.5, 1.5, 0.3) config/map_tile_size=256 config/map_minimum_zoom=5 config/map_maximum_zoom=19 -config/map_server_addr="https://b.tile.openstreetmap.org" interfer/center_offset=Vector2(200, 225) interfer/default_color0=Vector3(0.38, 0.47, 0.51) interfer/default_color1=Vector3(0.39, 0.44, 0.5) diff --git a/scenes/tilemap/tilemap.gd b/scenes/tilemap/tilemap.gd index 5eee485f..1d8b756f 100644 --- a/scenes/tilemap/tilemap.gd +++ b/scenes/tilemap/tilemap.gd @@ -17,9 +17,10 @@ class_name MercatorTileMap @export var tile_width: float = 256.0 @export var tile_height: float = 256.0 @export_range(1, 1000, 1) var max_concurrent_requests:int = 5 -@export_range(100, 100000, 1) var max_cached_tiles: int = 200 -@export_range(0, 25, 1) var max_zoom_level: int = 19 -@export_range(0, 25, 1) var min_zoom_level: int = 0 +@export_range(100, 100000, 1) var max_cached_tiles: int = 1024 +@export_range(0, 20, 1) var max_zoom_level: int = 20 +@export_range(0, 20, 1) var min_zoom_level: int = 0 +@export_range(0, 20, 1) var max_zoom_level_server: int = 20 @export_color_no_alpha() var back_color: = Color.BLACK const default_size: = 400.0 var is_centered: = false @@ -104,7 +105,13 @@ const image_load_proc_names = { set(v): image_load_proc = Callable(image, image_load_proc_names[v]) -func _ready(): +func on_map_centered(toggle_centered: bool): is_centered = toggle_centered + + +func get_marks_count(): return _marks.size() + + +func _ready() -> void: image_type = 'png' $canvas.connect('mouse_entered', func(): _rollover = true) $canvas.connect('mouse_exited', func(): _rollover = false) @@ -116,11 +123,7 @@ func _ready(): unit_nav.connect('data_received', on_data_received) -func on_map_centered(toggle_centered: bool): - is_centered = toggle_centered - - -func on_data_received(coords: Dictionary): +func on_data_received(coords: Dictionary) -> void: if not is_centered: return if coords.has_all(['latitude', 'longitude']): @@ -134,7 +137,7 @@ func _on_resize() -> void: ## Создаёт новую отметку из координат экрана -func add_mark_from_screen_pos(id: int, x: float, y: float, mark: Node): +func add_mark_from_screen_pos(id: int, x: float, y: float, mark: Node) -> bool: if _marks.has(id): return false var wrld_pos = screen_to_world(_xyz, x, y) @@ -147,19 +150,17 @@ func add_mark_from_screen_pos(id: int, x: float, y: float, mark: Node): return true -func get_marks_count(): return _marks.size() - - -func delete_mark(id: int): +func delete_mark(id: int) -> bool: if not _marks.has(id): return false _marks[id].mark.queue_free() _marks.erase(id) queue_redraw() + return true ## Создаёт новую отметку из долготы и широты -func add_mark_from_lon_lat(id: int, lon: float, lat: float, mark: Node, gap_size: float = 32): +func add_mark_from_lon_lat(id: int, lon: float, lat: float, mark: Node, gap_size: float = 32) -> bool: if _marks.has(id): return false var wrld_pos = lonlat_to_world(lon, lat) @@ -172,7 +173,7 @@ func add_mark_from_lon_lat(id: int, lon: float, lat: float, mark: Node, gap_size ## Возвращает новую позицию для точки, если она выходит из поля видимости -func fix_mark_position(dot): +func fix_mark_position(dot) -> void: if is_mark_visible(dot): return var v = 2 * tile_width * pow(2, _xyz.z) @@ -182,12 +183,12 @@ func fix_mark_position(dot): dot.position.x = _xyz.x + $canvas.size.x / v -func is_mark_visible(dot): +func is_mark_visible(dot) -> bool: var screen_pos = world_to_screen(dot.position.x, dot.position.y) return screen_pos.x > 0 and screen_pos.x < $canvas.size.x -func _input(e): +func _input(e) -> void: var lmp = get_local_mouse_position() if not _rollover: return @@ -222,7 +223,7 @@ func is_border_visible(): return screen_to_tile(0, 0, z).y != 0 -func multiply_zoom(multiplier: float, pivot: Vector2): +func multiply_zoom(multiplier: float, pivot: Vector2) -> void: var p1: = screen_to_world(_xyz, pivot.x, pivot.y) _xyz.z = clampf(_xyz.z * multiplier, min_zoom_level, max_zoom_level) var p2: = screen_to_world(_xyz, pivot.x, pivot.y) @@ -230,7 +231,7 @@ func multiply_zoom(multiplier: float, pivot: Vector2): _xyz.y -= p2.y - p1.y -func set_zoom(zoom: float, pivot=null): +func set_zoom(zoom: float, pivot=null) -> void: if pivot == null: pivot = $canvas.size / 2.0 @@ -241,7 +242,7 @@ func set_zoom(zoom: float, pivot=null): _xyz.y -= p2.y - p1.y -func _draw(): +func _draw() -> void: var lmp = get_local_mouse_position() if mouse_wheel_count > 0: @@ -275,7 +276,7 @@ func _draw(): visible_marks_count += int(dot.mark.visible) -func _clean_all(): +func _clean_all() -> void: _queue.clear() _cache.clear() _marks.clear() @@ -286,7 +287,7 @@ func _clean_all(): # get the tile from queue with the newest timestamp -func get_next_in_queue(): +func get_next_in_queue() -> Tile: var tile = null for idx in _queue: var t = _queue.get(idx) @@ -296,7 +297,7 @@ func get_next_in_queue(): # delete oldest tiles from cache -func _clean_cache(): +func _clean_cache() -> void: var overflow = _cache.size() - max_cached_tiles if overflow <= 0: return @@ -307,7 +308,7 @@ func _clean_cache(): _cache.erase(vals[i].i) -func _process(delta): +func _process(delta) -> void: now += delta # if cache is overflowing - clean it @@ -340,8 +341,7 @@ func _process(delta): emit_signal('load_completed') -# result, response_code, headers, body -func _response(result, code, _headers: Array, body: PackedByteArray, req, tile: Tile): +func _response(result, code, _headers: Array, body: PackedByteArray, req, tile: Tile) -> void: _req_count -= 1 remove_child(req) @@ -401,7 +401,7 @@ func _draw_subtile(tx: int, ty: int, tz: int, origx: int, origy: int, origz: flo return false -func _draw_tile(tx: int, ty: int, z: float): +func _draw_tile(tx: int, ty: int, z: float) -> void: var tz = floor(z) var p1 = tile_to_screen(tx, ty, z) var p2 = tile_to_screen(tx + 1, ty + 1, z) @@ -556,10 +556,12 @@ func get_tile(x: int, y: int, z: int, create: bool = true) -> Tile: var queue_size: = _queue.size() if create and (not $canvas/player.is_playing()): - tile = Tile.new(idx, x, y, z) - tile.url = base_url.replace('{x}', str(x)).replace('{y}', str(y)).replace('{z}', str(z)) - tile.t = now - _queue[idx] = tile + if not tile: + tile = Tile.new(idx, x, y, z) + tile.url = base_url.replace('{x}', str(x)).replace('{y}', str(y)).replace('{z}', str(z)) + tile.t = now + if z <= max_zoom_level_server: + _queue[idx] = tile if queue_size == 0 and _queue.size(): emit_signal('load_started') @@ -600,8 +602,8 @@ class Tile: self.y = y0 self.z = z0 - -func haversine_m(lat1, lon1, lat2, lon2): +# Возвращает расстояние в метрах между двумя точками на карте +func haversine_m(lat1: float, lon1: float, lat2: float, lon2: float) -> float: # Радиус Земли в метрах const R: = 6372795.0 # Преобразование градусов в радианы @@ -624,16 +626,17 @@ func haversine_m(lat1, lon1, lat2, lon2): return dist -func remove_closest_dot(screen_pos): +func remove_closest_dot(screen_pos: Vector2) -> bool: var closest_dot = find_at_screen_position(screen_pos) if not closest_dot: - return + return false remove_child(closest_dot.mark) closest_dot.mark.queue_free() _marks.erase(closest_dot) + return true -func find_at_screen_position(screen_pos: Vector2): +func find_at_screen_position(screen_pos: Vector2) -> Node: var closest_dot = null var closest_distance = INF for mark in _marks.values(): @@ -650,7 +653,7 @@ func clear() -> void: queue_redraw() -func set_coordinates(lon: float, lat: float): +func set_coordinates(lon: float, lat: float) -> void: var anim: Animation = $player.get_animation('goto') var new_pos = lonlat_to_world(lon, lat) anim.track_insert_key(0, 0, _xyz.x) diff --git a/scenes/tilemap/tilemap.tscn b/scenes/tilemap/tilemap.tscn index 27a42cd8..aa619a98 100644 --- a/scenes/tilemap/tilemap.tscn +++ b/scenes/tilemap/tilemap.tscn @@ -28,7 +28,9 @@ size = Vector2(400, 400) [node name="tilemap" type="CanvasGroup" groups=["gui_items"]] script = ExtResource("1_l64tp") -max_zoom_level = 21 +base_url = "http://192.168.11.105:8001/osm_tiles/{z}/{x}/{y}.png" +max_zoom_level = 15 +max_zoom_level_server = 10 az = 2.0 [node name="canvas" type="TextureRect" parent="." groups=["gui_items"]] diff --git a/scenes/настройки/настройки.gd b/scenes/настройки/настройки.gd index 5dbd0378..e73dfc40 100644 --- a/scenes/настройки/настройки.gd +++ b/scenes/настройки/настройки.gd @@ -8,56 +8,57 @@ const ALIGNMENT = [HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER] const HEADER_ROW = [TableHeader, TableHeader] const HEADER_ROW_TEXT = ['Параметр', 'Значение'] const SETTING_TABLE = [ - ['Ограниченный режим', TableEdit, TableToggle], - ['Управление элементами в ограниченном режиме', TableEdit, TableToggle], - ['Кнопка «ПД-М4»', TableEdit, TableToggle], - ['Кнопка «ПД-М2»', TableEdit, TableToggle], - ['Кнопка «ОЗП-1»', TableEdit, TableToggle], - ['Кнопка «МЧМ-1»', TableEdit, TableToggle], - ['Кнопка «ОРН-И1»', TableEdit, TableToggle], - ['Кнопка «ОРН-М2»', TableEdit, TableToggle], - ['Кнопка «ЛЧМ-1»', TableEdit, TableToggle], - ['Кнопка «ПД-М4С»', TableEdit, TableToggle], - ['Кнопка «ПД-ЧМ»', TableEdit, TableToggle], - ['Кнопка «СВ-И1»', TableEdit, TableToggle], - ['Кнопка «К1»', TableEdit, TableToggle], - ['Кнопка «СВ-М2»', TableEdit, TableToggle], - ['Кнопка «ОРН»', TableEdit, TableToggle], - ['Кнопка «JTIDS»', TableEdit, TableToggle], - ['Кнопка «КУПД»', TableEdit, TableToggle], - ['Внешнее целеуказание', TableEdit, TableToggle], - ['Кнопка «Подавление»', TableEdit, TableToggle], - ['Виртуальная клавиатура', TableEdit, TableToggle], - ['Скрыть вкладку ЭМС 2', TableEdit, TableToggle], - ['Текущая версия ПО УАРЭП', TableEdit, TableEdit ], - ['Адрес сервера карт', TableEdit, TableEdit ], - ['уарэп-яу07-частный', TableEdit, TableEdit ], - ['уарэп-яу07-общий', TableEdit, TableEdit ], - ['уарэп-капсрпб', TableEdit, TableEdit ], - ['уарэп-эмс', TableEdit, TableEdit ], - ['уарэп-яу07-2в', TableEdit, TableEdit ], - ['уарэп-яу07-2н', TableEdit, TableEdit ], - ['уарэп-яу07-2к', TableEdit, TableEdit ], - ['уарэп-яу07-4в', TableEdit, TableEdit ], - ['уарэп-яу07-4н', TableEdit, TableEdit ], - ['уарэп-яу07-4к', TableEdit, TableEdit ], - ['уарэп-яу07-1в', TableEdit, TableEdit ], - ['уарэп-яу07-1н', TableEdit, TableEdit ], - ['уарэп-яу07-1к', TableEdit, TableEdit ], - ['уарэп-яу07-3в', TableEdit, TableEdit ], - ['уарэп-яу07-3н', TableEdit, TableEdit ], - ['уарэп-яу07-3к', TableEdit, TableEdit ], - ['уарэп-5п28', TableEdit, TableEdit ], - ['уарэп-щ3', TableEdit, TableEdit ], - ['уарэп-спт25-1', TableEdit, TableEdit ], - ['уарэп-спт25-2', TableEdit, TableEdit ] - ] -const EXTERNAL_CU = 17 # Внешнее целееуказание -const SUPPRESS = 18 # Строка - Подавление -const KEYBOARD = 19 # Строка - Виртуальная клавиатура -const HIDE_EMS2 = 20 # Строка - Скрыть вкладку ЭМС 2 -const COMMIT = 21 # Строка - Версия УАРЭП -const SERVER = 22 # Строка - Сервер карт + ['Ограниченный режим', TableEdit, TableToggle, 'Ограничть возможности по постановке помех'], + ['Кнопка «ПД-М4»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ПД-М2»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ОЗП-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «МЧМ-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ОРН-И1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ОРН-М2»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ЛЧМ-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ПД-М4С»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ПД-ЧМ»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «СВ-И1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «К1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «СВ-М2»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ОРН»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «JTIDS»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «КУПД»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Внешнее целеуказание', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «Подавление»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Виртуальная клавиатура', TableEdit, TableToggle, 'Разрешить отображение экранной клавиатуры'], + ['Скрыть вкладку ЭМС 2', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Текущая версия ПО УАРЭП', TableEdit, TableEdit, 'Время сборки, версия и номер фиксации'], + ['уарэп-яу07-частный', TableEdit, TableEdit, 'IP-адрес для получения частных сообщений от ЯУ-07'], + ['уарэп-яу07-общий', TableEdit, TableEdit, 'IP-адрес для получения широковещательных сообщений от ЯУ-07'], + ['уарэп-капсрпб', TableEdit, TableEdit, 'IP-адрес для связи с КАПС-РПБ'], + ['уарэп-эмс', TableEdit, TableEdit, 'IP-адрес для связи с ЭМС'], + ['уарэп-яу07-2в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 2'], + ['уарэп-яу07-2н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 2'], + ['уарэп-яу07-2к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 2'], + ['уарэп-яу07-4в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 4'], + ['уарэп-яу07-4н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 4'], + ['уарэп-яу07-4к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 4'], + ['уарэп-яу07-1в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 1'], + ['уарэп-яу07-1н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 1'], + ['уарэп-яу07-1к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 1'], + ['уарэп-яу07-3в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 3'], + ['уарэп-яу07-3н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 3'], + ['уарэп-яу07-3к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 3'], + ['уарэп-5п28', TableEdit, TableEdit, 'IP-адрес для связи с 5П28'], + ['навигация', TableEdit, TableEdit, 'Порт назначения для получения данных от АКНГ'], + ['уарэп-щ3', TableEdit, TableEdit, 'Путь к UART-устройству для связи с прибором Щ3'], + ['уарэп-спт25-1', TableEdit, TableEdit, 'Путь к UART-устройству для связи с прибором СПТ-25 1'], + ['уарэп-спт25-2', TableEdit, TableEdit, 'Путь к UART-устройству для связи с прибором СПТ-25 2'], + ['Шаблон адреса сервера карт', TableEdit, TableEdit, 'URL-адрес сервера карт, содержащий поля \"{x}\", \"{y}\", \"{z}\" для подстановки индекса плитки'] ] +const EXTERNAL_CU = 16 ## Внешнее целееуказание +const SUPPRESS = 17 ## Строка - Подавление +const KEYBOARD = 18 ## Строка - Виртуальная клавиатура +const HIDE_EMS2 = 19 ## Строка - Скрыть вкладку ЭМС 2 +const COMMIT = 20 ## Строка - Версия УАРЭП + + +func on_checkbutton_pressed(i_row: int): on_row_pressed(i_row) ## Вызывается, когда узел впервые попадает в дерево сцены. @@ -92,8 +93,57 @@ func on_row_pressed(i_row: int): $scroll_set/table.set_row_selected(i_row, true) -func on_checkbutton_pressed(i_row: int): - on_row_pressed(i_row) +func parse_cmd_line_args(settings_data: Dictionary): + var args = OS.get_cmdline_args() + for i in range(0, args.size(), 2): + var key: String = args[i] + key = key.lstrip('\'\" ').rstrip('\'\" ').strip_edges().strip_escapes() + if not settings_data.has(key): + continue + if not ((i + 1) < args.size()): + push_error('для аргумента \"%s\" не указано значение.' % key) + break + var val0 = args[i + 1] + var val1 = settings_data[key] + val0 = val0.lstrip('\'\" ').rstrip('\'\" ').strip_edges().strip_escapes() + if typeof(val1) == TYPE_BOOL: + if val0 not in ['yes', 'true', 'да', 'no', 'false', 'нет']: + push_error('для аргумента \"%s\" указано неверное значение \"%s\".' % [key, val0]) + break + settings_data[key] = true if val0 in ['yes', 'true', 'да'] else false + elif typeof(val1) == TYPE_ARRAY: + var val0s = val0.split(',') + if val0s.size() != val1.size(): + push_error('для аргумента \"%s\" указано неверное значение \"%s\" (исходное: \"%s\").' % [key, val0, val1]) + break + for j in val0s.size(): + var val: String = val0s[j] + val = val.lstrip('\'\" ').rstrip('\'\" ').strip_edges().strip_escapes() + if tools.type_is_num(val): + val0s[j] = int(val) + elif val in ['true', 'false']: + val0s[j] = true if val == 'true' else false + else: + val0s[j] = val + elif typeof(val1) == TYPE_STRING: + settings_data[key] = val0 + + +## Загружает настройки из файла +func load_settings(settings_data: Dictionary): + var settings_file = settings.get_settings_file_path() + var file = FileAccess.open(settings_file, FileAccess.READ) + var abs_path = ProjectSettings.globalize_path(settings_file) + if file: + var read = file.get_as_text() + file.close() + var json_conv = JSON.new() + if json_conv.parse(read) == OK: + settings_data.merge(json_conv.get_data()) + else: + log.warning('Не удалось разобрать \"%s\", будут использованы настройки по умолчанию' % abs_path) + else: + log.warning('Файл \"%s\" не найден, будут использованы настройки по умолчанию' % abs_path) func setting_tab(): @@ -101,57 +151,54 @@ func setting_tab(): $heard_table.set_header_text(HEADER_ROW_TEXT) $heard_table.set_columns_min_size([600, 950]) $heard_table.set_columns_alignments(ALIGNMENT) - var settings_data = {} # Загружаем настройки из файла - var file = FileAccess.open(settings.settings_file, FileAccess.READ) - var abs_path = ProjectSettings.globalize_path(settings.settings_file) - if file: - var read = file.get_as_text() - file.close() - var json_conv = JSON.new() - if json_conv.parse(read) == OK: - settings_data = json_conv.get_data() - else: - log.warning('Не удалось разобрать \"%s\", будут использованы настройки по умолчанию' % abs_path) - else: - log.warning('Файл \"%s\" не найден, будут использованы настройки по умолчанию' % abs_path) + var settings_data = {} + load_settings(settings_data) + parse_cmd_line_args(settings_data) + for i in SETTING_TABLE.size(): - var setting_str = SETTING_TABLE[i] - var parameter = setting_str[0] - var node_label = setting_str[1] - var node_value = setting_str[2] + var tbl_row = SETTING_TABLE[i] + var param_name = tbl_row[0] + var node_label = tbl_row[1] + var node_value = tbl_row[2] + var tootip_text = tbl_row[3] $scroll_set/table.add_row([node_label, node_value]) var label_instance = $scroll_set/table.get_node2(0, i) - label_instance.text = parameter + label_instance.text = param_name + label_instance.tooltip_text = tootip_text $scroll_set/table.set_node_editable(0, i, false) var node_values = $scroll_set/table.get_node2(1, i).get_children() if node_values.size(): var child = node_values[0] if child is CheckButton: child.connect('pressed', Callable(self, 'on_checkbutton_pressed').bind(i)) - if parameter in settings_data: - child.set_pressed(settings_data[parameter]) - else: - child.set_pressed(false) - var commit_instance = $scroll_set/table.get_node2(1, COMMIT) - var server_instance = $scroll_set/table.get_node2(1, SERVER) - commit_instance.text = '%s' % commit.VCS_HEAD - server_instance.text = ProjectSettings.get('application/config/map_server_addr') + var val = settings_data[param_name] if settings_data.has(param_name) else false + child.set_pressed(val) + else: + if settings_data.has(param_name): + var val = settings_data[param_name] + if typeof(val) == TYPE_STRING: + $scroll_set/table.get_node2(1, i).text = settings_data[param_name] + $scroll_set/table.set_node_editable(1, COMMIT, false) $scroll_set/table.set_columns_min_size([600, 950]) $scroll_set/table.set_columns_alignments(ALIGNMENT) - for i in SETTING_TABLE.size(): - var setting_str = SETTING_TABLE[i] - var parameter = setting_str[0] - if parameter in settings.UnitProfiles: - var unit_data = settings.UnitProfiles[parameter] - var profiles = $scroll_set/table.get_node2(1, i) - var joined_data = '' - for j in range(unit_data[2].size()): - joined_data += str(unit_data[2][j]) - if j < unit_data[2].size() - 1: - joined_data += ',' - profiles.text = str(unit_data[1]) + ' : ' + joined_data $scroll_set/table.connect('row_pressed', Callable(self, 'on_row_pressed')) + + var commit_instance = $scroll_set/table.get_node2(1, COMMIT) + commit_instance.text = '%s' % commit.VCS_HEAD + + for i in SETTING_TABLE.size(): + var param_name = SETTING_TABLE[i][0] + if not settings.UnitProfiles.has(param_name): + continue + var unit_data = settings.UnitProfiles[param_name] + var profile = $scroll_set/table.get_node2(1, i) + var joined_data = '' + for j in unit_data[2].size(): + joined_data += str(unit_data[2][j]) + if j < unit_data[2].size() - 1: + joined_data += ',' + profile.text = '%s : %s' % [str(unit_data[1]), joined_data] button_settings() @@ -171,7 +218,7 @@ func button_settings(): func _on_btn_save_settings_pressed(): var json_data = {} - for i in range(SETTING_TABLE.size()): + for i in SETTING_TABLE.size(): var parameter = SETTING_TABLE[i][0] if parameter in settings.UnitProfiles: var profiles = $scroll_set/table.get_node2(1, i) @@ -191,16 +238,19 @@ func _on_btn_save_settings_pressed(): else: port = port.strip_edges() if port.is_valid_int(): - json_data[parameter].append(int(port)) - else: - json_data[parameter].append(port) + port = int(port) + json_data[parameter].append(port) else: var children = $scroll_set/table.get_node2(1, i).get_children() if len(children): var child = children[0] json_data[parameter] = child.is_pressed() - var file = FileAccess.open(settings.settings_file, FileAccess.WRITE) - var abs_path = ProjectSettings.globalize_path(settings.settings_file) + else: + var row = $scroll_set/table.get_row(i) + json_data[parameter] = row[1].text + var settings_file = settings.get_settings_file_path() + var file = FileAccess.open(settings_file, FileAccess.WRITE) + var abs_path = ProjectSettings.globalize_path(settings_file) if not file: log.error('Не удалось открыть файл для записи \"%s\"' % abs_path) return diff --git a/scenes/работа/работа.gd b/scenes/работа/работа.gd index 00a90f5c..75123d47 100644 --- a/scenes/работа/работа.gd +++ b/scenes/работа/работа.gd @@ -164,7 +164,7 @@ func map_threat_to_bip(th: threats.Threat, bip: Control): var sector_width = 50.0 for key in prd.FS_FREQ: var freq_range = prd.FS_FREQ[key] - var _num_values = (freq_range[1]- freq_range[0]) / sector_width + var _num_values = (freq_range[1] - freq_range[0]) / sector_width if freq_range[0] <= freq and freq <= freq_range[1]: sector_key = key break @@ -195,7 +195,7 @@ func on_interfer_new(ecm): if interfer.thrs.has(ecm.ispp): var th_id = interfer.thrs[ecm.ispp] var bip = get_node('%d' % th_id) - if bip!= null: + if bip != null: if ecm.krp!= interfer.INTERFER_OFF: bip.set_track_visible(true) if ecm.svk == 1: diff --git a/scripts/navigation.gd b/scripts/navigation.gd index a46a2a50..a5bd9170 100644 --- a/scripts/navigation.gd +++ b/scripts/navigation.gd @@ -2,7 +2,7 @@ class_name navigation extends Node ## "Протокол №120-11435-09.PDF" -const ONLINE_TIMEOUT: = 5000 ## Время ожидания пакета, милисекунды +const ONLINE_TIMEOUT: = 5000 ## Время ожидания пакета, миллисекунды const pow_2_30: = pow(2.0, 30.0) ## Источник данных навигации diff --git a/scripts/network.gd b/scripts/network.gd index ba425a94..9f3f6063 100644 --- a/scripts/network.gd +++ b/scripts/network.gd @@ -153,10 +153,7 @@ func _ready() -> void: var unit_key = settings.get_unit_key(unit_name) units[unit_key] = new_unit units_udp[unit_key] = new_unit - if len(st[2]) > 1: - dst_ports[unit_key] = st[2][1] - else: - dst_ports[unit_key] = st[2][0] + dst_ports[unit_key] = st[2][1] if len(st[2]) > 1 else st[2][0] if proto in TCP_PROTO: var unit_tcp = TCP_PROTO[proto].new(unit_name) diff --git a/scripts/settings.gd b/scripts/settings.gd index 0853dd81..3c7b4cb8 100644 --- a/scripts/settings.gd +++ b/scripts/settings.gd @@ -1,9 +1,7 @@ @tool -class_name rep_settings extends Node +class_name uarep_settings extends Node -## Параметры. - -var settings_file = ProjectSettings.get_setting('application/config/settings_path', 'user://settings.json') # Путь к файлу с настройками +## Настройки программы var settings_program: Dictionary @@ -57,6 +55,7 @@ const UM_MAX: = 55.0 func _ready() -> void: if Engine.is_editor_hint(): return + var settings_file = settings.get_settings_file_path() var abs_path = ProjectSettings.globalize_path(settings_file) log.info('Путь к файлу настроек: \"%s\"' % abs_path) var file = FileAccess.open(settings_file, FileAccess.READ) @@ -103,6 +102,13 @@ func _ready() -> void: log.info('Не удалось прочитать значение \"%s\" из файла настроек, будет использовано значение по умолчанию' % key) +## Возвращает полный путь к файлу с настройками +func get_settings_file_path(): + return ProjectSettings.get_setting( + 'application/config/settings_path', + 'user://settings.json') + + ## Возвращает ключ устройства. func get_unit_key(unit_name: String) -> Array: var item = UnitProfiles[unit_name] diff --git a/scripts/tcp5p28.gd b/scripts/tcp5p28.gd index a054cc24..02a2396b 100644 --- a/scripts/tcp5p28.gd +++ b/scripts/tcp5p28.gd @@ -1,30 +1,30 @@ class_name tcp5_p28 extends Node ## Реализация "Протокол информационного сопряжения. -## СПО АСУ изделия «МП‑550» с СПО 5П-28". - +## СПО АСУ изделия МП-550 с СПО 5П-28 const ONLINE_TIMEOUT = 5000 ## Время ожидания пакета от 5П-28, мс. const BUFFER_SIZE = 2048 ## Размер приёмного буфера для датаграмм. ## Тип модуляции для запаковки в пакет для 5П-28. -const MOD_TYPES: Array = ['', - 'am', - 'ook', - 'ask', - 'fm', - 'qpsk', - 'oqpsk', - 'pi4qpsk', - 'qam16', - 'qam32', - 'qam64', - 'qam128', - 'qam256', - 'qam512', - 'cpfsk', - 'psk', - 'ofdm',] +const MOD_TYPES: Array = [ + '', + 'am', + 'ook', + 'ask', + 'fm', + 'qpsk', + 'oqpsk', + 'pi4qpsk', + 'qam16', + 'qam32', + 'qam64', + 'qam128', + 'qam256', + 'qam512', + 'cpfsk', + 'psk', + 'ofdm' ] const CU_STATE: Dictionary = { 0: 2, # Подготовка к выполнению @@ -42,19 +42,19 @@ class TCP5P28 extends unit.Unit: const CMD_TYPE_IN: int = 3 const PR_STATE: Dictionary = { - 'уарэп-эмс': [1, 1], - 'уарэп-яу07-1н': [9, 8], - 'уарэп-яу07-1в': [5, 4], - 'уарэп-яу07-1к': [13, 12], - 'уарэп-яу07-2н': [10, 9], - 'уарэп-яу07-2в': [6, 5], - 'уарэп-яу07-2к': [14, 13], - 'уарэп-яу07-3н': [11, 10], - 'уарэп-яу07-3в': [7, 6], - 'уарэп-яу07-3к': [15, 14], - 'уарэп-яу07-4н': [12, 11], - 'уарэп-яу07-4в': [8, 7], - 'уарэп-яу07-4к': [16, 15], } + 'уарэп-эмс': [1, 1], + 'уарэп-яу07-1н': [9, 8], + 'уарэп-яу07-1в': [5, 4], + 'уарэп-яу07-1к': [13, 12], + 'уарэп-яу07-2н': [10, 9], + 'уарэп-яу07-2в': [6, 5], + 'уарэп-яу07-2к': [14, 13], + 'уарэп-яу07-3н': [11, 10], + 'уарэп-яу07-3в': [7, 6], + 'уарэп-яу07-3к': [15, 14], + 'уарэп-яу07-4н': [12, 11], + 'уарэп-яу07-4в': [8, 7], + 'уарэп-яу07-4к': [16, 15] } signal get_threats(unit: TCP5P28) ## Сигнал запрос целей. signal get_interfers(unit: TCP5P28) ## Запрос состояния выполнения целеуказания. @@ -125,7 +125,7 @@ class TCP5P28 extends unit.Unit: var data_len = 12 # длинна блока данных в байтах data.resize(data_len) data.encode_u16(0, 0) # Код ошибки - data.encode_u16(2, len(interfers)) # Количество целей + data.encode_u16(2, interfers.size()) # Количество целей data.encode_u32(4, uarep_state) # Состояние УА-РЕП data.encode_u32(8, uarep_line) # Состояние линий связи var cu_data: PackedByteArray = [] @@ -136,15 +136,11 @@ class TCP5P28 extends unit.Unit: continue var cu = ecms[id] cu_data.encode_u16(0, cu.ispp) - var state: int - if CU_STATE.has(cu.svk): - state = CU_STATE[cu.svk] - else: - state = 9 + var state: int = CU_STATE[cu.svk] if CU_STATE.has(cu.svk) else 9 cu_data.encode_u8(2, state) # Состояние выполнения команды cu_data.encode_u8(3, 0xFF) # Эффективность работы помехи data.append_array(cu_data) - var data_to_send: PackedByteArray = create_header(data_len + 4 * len(interfers)) + var data_to_send: PackedByteArray = create_header(data_len + 4 * interfers.size()) data_to_send.append_array(data) tx_stack.append(data_to_send) @@ -195,7 +191,7 @@ class TCP5P28 extends unit.Unit: func to_cp866(proto: String, th_data: PackedByteArray): var cp866_proto: PackedByteArray = proto.to_ascii_buffer() cp866_proto.resize(36) - for i in len(cp866_proto): + for i in cp866_proto.size(): th_data[28 + i] = cp866_proto[i] func set_interfer(data: PackedByteArray): diff --git a/scripts/tools.gd b/scripts/tools.gd index 8330cd5f..dca07aa5 100644 --- a/scripts/tools.gd +++ b/scripts/tools.gd @@ -35,7 +35,7 @@ func allways(val: bool, msg: String = '<не указано>'): get_tree().quit(Error.FAILED) -func _check_index(obj, index) -> bool: +func check_index(obj, index) -> bool: if obj is Dictionary: if obj.has(index): return true @@ -59,11 +59,11 @@ func get_value_by_path(obj, paths: Array, ret_val: Array): var index = paths.pop_at(0) ret_val[1] = false if paths.size(): - if _check_index(obj, index): + if check_index(obj, index): ret_val[2] += 1 get_value_by_path(obj[index], paths, ret_val) else: - if _check_index(obj, index): + if check_index(obj, index): ret_val[0] = obj[index] ret_val[1] = true