diff --git a/.gitignore b/.gitignore index a3b149b..4762b6c 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ modbus/serial/__pycache__ /scenes/pribor-prd-k/kasseta-fs-kd.tscn.bak /scenes/pribor-prd-k/pribor-prd-k.tscn.bak /scenes/pribor-prd-n/kasseta-fs-nd.tscn.bak + +*.patch diff --git a/README.md b/README.md index 0389621..aa9e039 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ - [Проброс последовательных портов через 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) -- [Генераторы PCM файлов для модулей ФС](http://gitea.srez.local:3000/danil_tim/Signals_to_the_MP-550) # Ссылки на имитаторы @@ -36,4 +35,5 @@ - После клонирования запустить скрипт `git-hooks-config.sh` - В среде **Windows** запуск скрипта `git-hooks-config.sh` производить из оболочки `git bash` -- При необходимости обновить `settings.json` +- Нужно обновить `settings.json` +- поиск циклических зависимостей diff --git a/check-graph.py b/check-graph.py new file mode 100644 index 0000000..73edca9 --- /dev/null +++ b/check-graph.py @@ -0,0 +1,164 @@ +# -*- coding: utf-8 -*- +import os +import re +import networkx as nx + +# pip install networkx plotly numpy scipy + +def build_class_graph(directory): + """Builds a directed acyclic graph of class dependencies.""" + # Create a graph to store the dependencies + graph = nx.DiGraph() + dependencies = {} + + # Find all .gd files in the directory + for root, dirs, files in os.walk(directory): + for file in files: + if not file.endswith(".gd"): + continue + + file_path = os.path.join(root, file) + # Find the class name in the file + with open(file_path, "r", encoding="utf-8") as f: + contents = f.read() + match = re.search(r"^class_name\s+(\w+)", contents, re.MULTILINE) + if not match: + continue + + class_name = match.group(1) + graph.add_node(class_name) + + # Find the dependencies of the class + for dep_match in re.finditer( + r"^\s*extends\s+(\w+)", contents, re.MULTILINE + ): + dep_name = dep_match.group(1) + graph.add_edge(class_name, dep_name) + + # Find all uses of the class name in other files + for root2, dirs2, files2 in os.walk(directory): + for file2 in files2: + if not file2.endswith(".gd"): + continue + + if file_path == os.path.join(root2, file2): + continue + + with open(os.path.join(root2, file2), "r", encoding="utf-8") as f2: + contents2 = f2.read() + if re.search(rf"\b{class_name}\b", contents2): + print( + file2.ljust(30, " "), + f"--> class_name {class_name}".ljust(50, " "), + f" from {file}", + ) + graph.add_edge(class_name, file2) + dependencies[file2] = file + + pos = nx.planar_layout(graph) + + # Set the node positions in the graph + nx.set_node_attributes(graph, pos, "pos") + + return graph, dependencies + + +def debug_graph(graph): + """Builds and visualizes a graph of class dependencies in the directory.""" + import plotly.graph_objects as go + + # Create the plotly figure + fig = go.Figure() + + # Add the nodes to the figure + for node in graph.nodes(): + x, y = graph.nodes[node]["pos"] + fig.add_trace( + go.Scatter( + x=[x], + y=[y], + text=[node], + hovertext=[f"Class: {node}"], + mode="markers", + marker=dict( + symbol="circle", size=20, line=dict(width=1, color="black"), + ), + name=node, + ) + ) + + # Add the edges to the figure + for edge in graph.edges(): + x0, y0 = graph.nodes[edge[0]]["pos"] + x1, y1 = graph.nodes[edge[1]]["pos"] + fig.add_trace( + go.Scatter( + x=[x0, x1], + y=[y0, y1], + text=[f"{edge[0]} -> {edge[1]}", ""], + hovertext=[f"Depends on: {edge[1]}", ""], + mode="lines+markers+text", + line=dict(width=2, color="black"), + marker=dict(size=0), + textposition="middle right", + showlegend=True, + ) + ) + + # Customize the layout and style of the figure + fig.update_layout( + title="Class Dependency Graph", + title_font_size=24, + margin=dict(l=20, r=20, t=50, b=20), + hovermode="closest", + plot_bgcolor="white", + showlegend=True, + ) + + # Show the figure + fig.show() + + +def find_circular_dependencies(dependencies): + """Finds circular dependencies between classes in the directory.""" + + circular_dependencies = [] + + for file, dependency in dependencies.items(): + visited = set() + path = [file] + + while dependency and dependency not in visited: + visited.add(dependency) + path.append(dependency) + dependency = dependencies.get(dependency) + + # Circular check + if dependency in path: + start_index = path.index(dependency) + circular_dependency = path[start_index:] + if circular_dependency not in circular_dependencies: + circular_dependencies.append(circular_dependency) + break + + # Convert circular_dependencies to dependency paths + dependency_paths = [] + for circular_dependency in circular_dependencies: + dependency_path = " -> ".join(circular_dependency) + dependency_paths.append(dependency_path) + + return dependency_paths + + +# Example usage +graph, dependencies = build_class_graph("./") +debug_graph(graph) +circular_deps = find_circular_dependencies(dependencies) +print("----------------------------------") +if circular_deps: + print(" Circular dependencies found!") + for dep in circular_deps: + print("\t", dep) +else: + print(" No circular dependencies found.") +print("----------------------------------") diff --git a/scenes/tabs-switch/tab-switch.tscn b/scenes/tabs-switch/tab-switch.tscn index b33b2b9..7fd6d96 100644 --- a/scenes/tabs-switch/tab-switch.tscn +++ b/scenes/tabs-switch/tab-switch.tscn @@ -5,8 +5,8 @@ [ext_resource type="PackedScene" uid="uid://lwmw4egynmd1" path="res://scenes/контроль/контроль.tscn" id="3_txp0s"] [ext_resource type="PackedScene" uid="uid://trt0q8th3bn2" path="res://scenes/журнал/журнал.tscn" id="4_cu5k8"] [ext_resource type="PackedScene" uid="uid://dab6loryocc73" path="res://scenes/эмс/эмс.tscn" id="5_u71bh"] +[ext_resource type="PackedScene" uid="uid://musb21x2u0xs" path="res://scenes/эмс2/эмс2.tscn" id="6_41d34"] [ext_resource type="PackedScene" uid="uid://bnptm4rlp60dq" path="res://scenes/настройки/настройки.tscn" id="6_i8iv3"] -[ext_resource type="PackedScene" uid="uid://musb21x2u0xs" path="res://scenes/эмс2/эмс2.tscn" id="6_rsg03"] [ext_resource type="Script" uid="uid://b5ykwyk5vpi6" path="res://scenes/tabs-switch/lbl_ready.gd" id="8_tidwt"] [ext_resource type="Script" uid="uid://roajn6c6wvc1" path="res://scenes/tabs-switch/тренаж_режим.gd" id="9_41d34"] @@ -69,7 +69,7 @@ visible = false layout_mode = 2 metadata/_tab_index = 3 -[node name="ЭМС ТГ" parent="tab_switch" instance=ExtResource("6_rsg03")] +[node name="ЭМС ТГ" parent="tab_switch" instance=ExtResource("6_41d34")] visible = false layout_mode = 2 metadata/_tab_index = 4 diff --git a/scenes/tilemap/ship_mark.tscn b/scenes/tilemap/ship_mark.tscn index 06aacfd..fbf2558 100644 --- a/scenes/tilemap/ship_mark.tscn +++ b/scenes/tilemap/ship_mark.tscn @@ -3,6 +3,5 @@ [ext_resource type="Texture2D" uid="uid://cj1f2uy6qfvki" path="res://scenes/tilemap/23900.png" id="1_v0nwa"] [node name="23900" type="Sprite2D"] -rotation = -6.28319 scale = Vector2(0.496934, 0.496934) texture = ExtResource("1_v0nwa") diff --git a/scenes/tilemap/tilemap.gd b/scenes/tilemap/tilemap.gd index e363d95..37e3ae4 100644 --- a/scenes/tilemap/tilemap.gd +++ b/scenes/tilemap/tilemap.gd @@ -147,12 +147,11 @@ func _ready() -> void: signaller.connect('map_centered', on_map_centered) if not Engine.is_editor_hint(): var unit_nav = network.get_unit_instance('навигация') - unit_nav.connect('data_received', Callable(self, 'on_data_received')) + unit_nav.connect('data_received', on_data_received) ProjectSettings.connect('settings_changed', _settings_changed) threats.connect('threat_new', Callable(self, '_on_threat_new')) threats.connect('threat_lost', Callable(self, '_on_threat_lost')) threats.connect('threat_update', Callable(self, '_on_threat_update')) - func _settings_changed(): @@ -196,7 +195,7 @@ func add_mark_from_lon_lat(id: int, lon: float, lat: float, mark: Node, gap_size if _marks.has(id): return false var wrld_pos: Vector2 = lonlat_to_world(lon, lat) - _marks[id] = {'id': id, 'position': wrld_pos, 'mark': mark, 'gap_size': gap_size} # Добавляем ID + _marks[id] = {'position': wrld_pos, 'mark': mark, 'gap_size': gap_size} add_child(mark) queue_redraw() return true @@ -294,15 +293,20 @@ func _draw() -> void: for tx in range(t1.x, t2.x): for ty in range(t1.y, t2.y): _draw_tile(tx, ty, z) + # Рисование отметок + var n: = pow(2, z) + var dx: = n * tile_width var c: Vector2 = $canvas.size / 2.0 var r: float = c.length() visible_marks_count = 0 for dot in _marks.values(): - var screen_pos = world_to_screen(dot.position) - dot.mark.position = screen_pos + var scr_pos: Vector2 = world_to_screen(dot.position) + scr_pos.x = posmod(int(scr_pos.x), int(dx)) + dot.mark.position = scr_pos dot.mark.visible = is_mark_visible(dot) - dot.mark.visible = c.distance_to(screen_pos) < (r - dot.gap_size) + dot.mark.visible = c.distance_to(scr_pos) < (r - dot.gap_size) visible_marks_count += int(dot.mark.visible) + # Рисование границ var p1: Vector2 = $canvas.position var p2: Vector2 = $canvas.size / Vector2(1, 20) if is_out_border1 and _dragging: @@ -376,22 +380,33 @@ func _process(delta) -> void: update_scale_label() -func _response(result, code, _headers: Array, body: PackedByteArray, req, tile: Tile) -> void: - var unit_instance = network.get_unit_instance('уарэп-карта') - _req_count -= 1 - remove_child(req) - req.queue_free() +func process_online(result): + # ERROR: res://scenes/tilemap/tilemap.gd:396 - Invalid access to property or key 'online' on a base object of type 'Nil'. + var unit_instance: = network.get_unit_instance('уарэп-карта') + if not unit_instance: return if result != HTTPRequest.RESULT_SUCCESS: if unit_instance.online: unit_instance.online = false unit_instance.emit_signal('line_changed', unit_instance) - _queue[tile.i] = tile - return + return false + unit_instance.rx_tick = Time.get_ticks_msec() if not unit_instance.online: unit_instance.online = true unit_instance.emit_signal('line_changed', unit_instance) + return true + + +func _response(result, code, _headers: Array, body: PackedByteArray, req, tile: Tile) -> void: + _req_count -= 1 + remove_child(req) + req.queue_free() + + if process_online(result): + _queue[tile.i] = tile + else: + return if code == 404: push_error('на сервере нет \"%s\"' % tile.url) @@ -401,11 +416,6 @@ func _response(result, code, _headers: Array, body: PackedByteArray, req, tile: push_error('не удалось получить изображение (неверный формат?) из \"%s\"' % tile.url) return - unit_instance.rx_tick = Time.get_ticks_msec() - if not unit_instance.online: - unit_instance.online = true - unit_instance.emit_signal('line_changed', unit_instance) - tile.texture = ImageTexture.create_from_image(image) _cache[tile.i] = tile @@ -707,7 +717,7 @@ func set_coordinates(lon: float, lat: float, course: float) -> void: add_mark_from_lon_lat(ship_id, lon, lat, ship_instance, 0.0) else: _marks[ship_id].position = lonlat_to_world(lon, lat) - ship_instance.rotation_degrees = course + ship_instance.rotation_degrees = fmod(course, 360.0) queue_redraw() diff --git a/scenes/работа/работа.gd b/scenes/работа/работа.gd index 469e459..804c031 100644 --- a/scenes/работа/работа.gd +++ b/scenes/работа/работа.gd @@ -177,7 +177,7 @@ func _ready(): signaller.connect('map_user_panning', Callable(self, 'on_user_panning')) signaller.connect('update_coordinates_map', Callable(self, 'on_update_coordinates_label')) signaller.connect('update_scale_map', Callable(self, 'on_update_scale_label')) - signaller.connect('sector_klaster', Callable(self, 'sector_klaster')) + signaller.connect('sector_klaster', Callable(self, 'sector_klaster')) signaller.connect('clear_klaster', Callable(self, 'clear_all_klaster')) var unit_nav = network.get_unit_instance('навигация') unit_nav.connect('data_received', on_navi_data_received) diff --git a/scenes/работа/работа.tscn b/scenes/работа/работа.tscn index 8313ec3..8f77b23 100644 --- a/scenes/работа/работа.tscn +++ b/scenes/работа/работа.tscn @@ -379,8 +379,8 @@ texture_normal = ExtResource("14_ggrwd") [connection signal="drag_continue" from="." to="." method="_on_drag_continue"] [connection signal="toggled" from="btn_view" to="." method="on_button_view_toggled"] [connection signal="toggled" from="chk_auto" to="." method="on_value_changed"] -[connection signal="toggled" from="btn_activate" to="." method="on_btn_activate"] [connection signal="toggled" from="btn_activate" to="." method="on_btn_activate_toggled"] +[connection signal="toggled" from="btn_activate" to="." method="on_btn_activate"] [connection signal="toggled" from="btn_center" to="." method="on_btn_center_toggled"] [connection signal="button_down" from="zoom_plus" to="tilemap" method="_on_zoom_plus_button_down"] [connection signal="button_up" from="zoom_plus" to="tilemap" method="_on_zoom_plus_button_up"] diff --git a/scenes/эмс2/эмс2.tscn b/scenes/эмс2/эмс2.tscn index 55ccd98..b88856c 100644 --- a/scenes/эмс2/эмс2.tscn +++ b/scenes/эмс2/эмс2.tscn @@ -77,6 +77,7 @@ scale = Vector2(1.77945, 1.77945) texture = ExtResource("5_yqn2y") [node name="СостояниеРэс2" type="Sprite2D" parent="Op-63"] +visible = false position = Vector2(281.865, 35.2331) scale = Vector2(3.20301, 3.20301) texture = ExtResource("6_m57px") diff --git a/scripts/interfer.gd b/scripts/interfer.gd index 2b4e62b..01c7f52 100644 --- a/scripts/interfer.gd +++ b/scripts/interfer.gd @@ -199,7 +199,7 @@ func _ready() -> void: unit_caps.connect('data_received', Callable(self, 'on_data_capsrpb_received').bind(ecms, seczaps)) unit_5p28.connect('get_interfers', Callable(self, 'on_get_interfers').bind(unit_5p28, ecms)) signaller.connect('interfer_create', Callable(self, 'on_interfer_create').bind(unit_caps, ecms)) - signaller.connect('interfer_rcv', Callable(self, 'on_interfer_rcv').bind(unit_5p28, ecms)) + signaller.connect('interfer_rcv', Callable(self, 'on_interfer_rcv').bind(unit_5p28, unit_caps, ecms)) signaller.connect('interfer_new', Callable(self, 'on_interfer_new').bind(unit_caps)) signaller.connect('interfer_off_all', Callable(self, 'on_interfer_off_all').bind(unit_caps, ecms)) signaller.connect('th_aoa_update', Callable(self, 'on_th_aoa_update').bind(ecms, unit_caps)) @@ -351,8 +351,8 @@ func map_msvk_to_ecms(unit_instance: unit.Unit, ecms: Dictionary): ## Извлекает массив пространственно-частотных фильтров -func map_mpchf_to_seczaps(unit_instance: unit.Unit, seczaps: Dictionary): - var json_dic: = unit_instance.json_dic as Dictionary +func map_mpchf_to_seczaps(unit_instance: unit.Unit, _seczaps: Dictionary): + var json_dic = unit_instance.json_dic var mpchf = json_dic.get('mpchf', []) if mpchf is not Array: return for item in mpchf: @@ -397,7 +397,7 @@ func on_interfer_create(interfer_name, sel_threats, fs_arr, power, u, ecms) -> v interfer_create(u, interfer_name, ecms, param, kni, id, fs, SOURCE_INTERFER[1], power) -func on_interfer_rcv(interfer_params: Array, unit0, ecms) -> void: +func on_interfer_rcv(interfer_params: Array, unit0, unit_caps, ecms) -> void: var err: bool = false var mode = interfer_params[0] var id = interfer_params[1] @@ -425,7 +425,7 @@ func on_interfer_rcv(interfer_params: Array, unit0, ecms) -> void: if interfer_name == '': err = true if not err: - interfer_create(unit0, interfer_name, ecms, param, aoa, id, cu, SOURCE_INTERFER[2], POW_DEFAULT) + interfer_create(unit_caps, interfer_name, ecms, param, aoa, id, cu, SOURCE_INTERFER[2], POW_DEFAULT) unit0.on_interfer_accept(err) diff --git a/scripts/navigation.gd b/scripts/navigation.gd index 2e8ed4a..245c9b8 100644 --- a/scripts/navigation.gd +++ b/scripts/navigation.gd @@ -4,10 +4,12 @@ class_name navigation extends Node const ONLINE_TIMEOUT: = 5000 ## Время ожидания пакета, миллисекунды const pow_2_30: = pow(2.0, 30.0) +const FRACT_MAX: int = 3 ## Источник данных навигации class NaviSource extends unit.Unit: var cmd_tick_rx: int = 0 + var fract: int = 0 var data: = {} ## Принятые данные var source_addr: = [] ## Адрес отправителя const akng_mode = {0:'тестовый', 1:'основной', 2:'резервный', 3:'аварийный'} @@ -43,5 +45,8 @@ class NaviSource extends unit.Unit: if flags & (1 << 3): data['speed'] = rx_data.decode_float(20) # Скорость, м/с data['err'] = rx_data.decode_u16(24) # - emit_signal('data_received', data) + if fract == 0: + emit_signal('data_received', data) + fract += 1 + fract %= FRACT_MAX return true diff --git a/scripts/network.gd b/scripts/network.gd index dea8706..dd0d31b 100644 --- a/scripts/network.gd +++ b/scripts/network.gd @@ -1,4 +1,4 @@ -#@tool +@tool class_name Network extends Node const YAU07_PROTO: = {'yau07tx': yau07.YaU07} @@ -22,18 +22,20 @@ class SocketSerial extends SerialPort: 'O': SerialPort.PARITY_ODD } static var tick: int var unit_instance: unit.Unit + var failed: = {} + + func _init(): + connect('got_error', on_serial_got_error) + + func on_serial_got_error(where: String, what: String): + if where not in failed: + push_error([where, what, unit_instance]) + failed[where] = what func on_serial_data(data: PackedByteArray): + failed.clear() unit_instance.parse(data, tick) - func on_settings_changed(): - try_close() - var rc = try_open() - if rc != Error.OK: - log.message(log.ERROR, 'невозможно открыть %s для \"%s\"' % [self, unit_instance.name]) - else: - log.message(log.INFO, '%s для \"%s\"' % [self, unit_instance.name]) - func format_buffer(data: PackedByteArray): var buffer: PackedByteArray buffer.resize(64) @@ -50,16 +52,16 @@ class SocketSerial extends SerialPort: buffer.resize(i) return buffer - func send_to(data: PackedByteArray): + func send_to(_data: PackedByteArray): if not is_open(): - try_open() + call_deferred('try_open') return # var buffer = format_buffer(data) # Не проверено, но должно работать # Эта последовательность для запроса состояния, получена от разработчиков СПТ-25 const tx_tula: = [0x7e, 0x01, 0x04, 0xbb, 0x50, 0x7e] var sz = write_raw(tx_tula) if sz != tx_tula.size(): - try_open() + call_deferred('try_close') func _to_string() -> String: return 'последовательный порт \"%s\" @ %d (%s)' % [self.port, self.baudrate, 'открыт' if is_open() else 'закрыт'] @@ -144,6 +146,15 @@ var send_sockets: Dictionary[StringName, SocketUDP] ## Таблица <имя var addr_port_to_unit_name: Dictionary[StringName, StringName] ## Преобразование адрес:порт в имя устройства +func on_settings_changed(serial: SocketSerial): + serial.try_close() + var rc = serial.try_open() + if rc != Error.OK: + log.message(log.ERROR, 'невозможно открыть %s для \"%s\"' % [serial.port, serial.unit_instance.name]) + else: + log.message(log.INFO, 'открыт %s для \"%s\"' % [serial.port, serial.unit_instance.name]) + + ## [param unit_name] - Уникальное имя устройства[br] func create_socket_udp(unit_name: StringName) -> SocketUDP: var st = settings.UnitProfiles[unit_name][1] @@ -202,13 +213,10 @@ func create_serial(unit_instance: unit.Unit) -> SocketSerial: serial.bytesize = st[4] serial.stopbits = st[5] serial.unit_instance = unit_instance + ProjectSettings.connect('settings_changed', func(): on_settings_changed(serial)) return serial -func on_serial_got_error(where: String, what: String, serial: SocketSerial, unit_instance: unit.Unit): - push_error([where, what, serial]) - - ## [param unit_name] - Уникальное имя устройства[br] func create_modbus(unit_name: StringName) -> sch_3.Sch3: var unit_modbus: = sch_3.Sch3.new(unit_name) @@ -286,8 +294,6 @@ func _ready() -> void: if proto in SERIAL_PROTO: var unit_instance = SERIAL_PROTO[proto].new(unit_name) var serial: = create_serial(unit_instance) - serial.connect('got_error', on_serial_got_error.bind(serial, unit_instance)) - ProjectSettings.connect('settings_changed', serial.on_settings_changed) units_serial[unit_name] = unit_instance units[unit_name] = unit_instance serials[unit_name] = serial @@ -391,6 +397,7 @@ func get_tcp_data(sock: SocketTCP, peer: StreamPeer, len_rx: int): func _process(_delta: float) -> void: + if Engine.is_editor_hint(): return tick = Time.get_ticks_msec() RenderingServer.global_shader_parameter_set('tick_curent', tick) for unit_name: StringName in units_udptx: @@ -424,5 +431,4 @@ func _process(_delta: float) -> void: ## [param unit_name] - Уникальное имя устройства[br] func get_unit_instance(unit_name: StringName) -> unit.Unit: - tools.allways(unit_name in units, 'нет такого устройства: \"%s\"' % unit_name) - return units[unit_name] + return units.get(unit_name, null) diff --git a/scripts/sch3.gd b/scripts/sch3.gd index baa615a..a7d3155 100644 --- a/scripts/sch3.gd +++ b/scripts/sch3.gd @@ -107,7 +107,7 @@ class Sch3 extends unit.Unit: var unit_prof = ProjectSettings.get_setting('application/config/%s' % unit_sch3.name) if unit_prof: unit_sch3.port = unit_prof[0] - unit_sch3.params = unit_prof[1] + unit_sch3.params = unit_prof.slice(1, -1) step_fsm = Sch3Fsm.CONNECT diff --git a/scripts/tools.gd b/scripts/tools.gd index de9232c..f7b5caa 100644 --- a/scripts/tools.gd +++ b/scripts/tools.gd @@ -34,7 +34,6 @@ func is_overlap(x1, x2, y1, y2) -> bool: return max(x1, y1) <= min(x2, y2) func allways(val: bool, msg: String = '<не указано>'): if val: return push_error('%s\n' % msg) - get_tree().quit(Error.FAILED) ## Преобразует путь в виде целой строки в массив отдельных элементов пути.[br] diff --git a/scripts/trassa.gd b/scripts/trassa.gd index e837737..bd94b61 100644 --- a/scripts/trassa.gd +++ b/scripts/trassa.gd @@ -84,7 +84,6 @@ class Trassa extends unit.Unit: sector_draw(json_dic) emit_signal('data_received', self) else: - var msg = json_conv.get_error_message() emit_signal('parse_failed', self) else: emit_signal('parse_failed', self) @@ -110,7 +109,6 @@ class Trassa extends unit.Unit: var hfb = int(data["hfb"]) var dap = int(data["dap"]) var daa = int(data["daa"]) - var key = str(lfb) + "_" + str(hfb) for i in range(set_klaster.size()): var mapping = set_klaster[i] if lfb == mapping[0] and hfb == mapping[1]: @@ -203,6 +201,7 @@ class Trassa extends unit.Unit: return NOINFO + # Отправка пакета от uarep-ctl func process(now_tick: int) -> int: if online and ((now_tick - rx_tick) > ONLINE_TIMEOUT): online = false @@ -225,15 +224,15 @@ class Trassa extends unit.Unit: # Контрольная сумма func _calc_crc(data: Array) -> int: var acc: int = 0 - for i in range(data.size() - 1): + for i in range(data.size() - 1): # кроме CRC if i in [0, 1]: continue acc = (acc + (data[i] & 0xFFFFFFFF)) & 0xFFFFFFFF return acc - func on_interfer_resized(ecms_dic: Dictionary) -> void: - ecms = ecms_dic + # Обновление всех активных помех + func on_interfer_resized(ecms_dic: Dictionary) -> void: ecms = ecms_dic func interfer_uarep() -> void: diff --git a/shaders/tools.gdshaderinc b/shaders/tools.gdshaderinc index 73ba730..c65ee63 100644 --- a/shaders/tools.gdshaderinc +++ b/shaders/tools.gdshaderinc @@ -3,10 +3,9 @@ const float DS = 0.004; /* Относитель float random_timed(vec2 uv) { - return fract(sin(TIME * dot(uv.xy, vec2(12.9898, 78.233))) * 43758.5453123); + return fract(sin(dot(uv + TIME, vec2(12.9898, 78.233))) * 43758.5453); } - float smooth_px(float r, float R, float ds) { return 1.0 - smoothstep(R - ds, R + ds, r);