Compare commits
7 Commits
17f76d2171
...
9720726d91
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9720726d91 | ||
|
|
06e909ad9c | ||
|
|
16ca216bdd | ||
|
|
91b79266df | ||
|
|
379504994c | ||
|
|
1fc284939c | ||
|
|
10fca2d34c |
@@ -36,3 +36,4 @@
|
||||
- После клонирования запустить скрипт `git-hooks-config.sh`
|
||||
- В среде **Windows** запуск скрипта `git-hooks-config.sh` производить из оболочки `git bash`
|
||||
- Нужно обновить `settings.json`
|
||||
- поиск циклических зависимостей
|
||||
|
||||
164
check-graph.py
Normal file
164
check-graph.py
Normal file
@@ -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("----------------------------------")
|
||||
2
generate-sertificate.sh
Normal file
2
generate-sertificate.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
#openssl req -x509 -newkey rsa:4096 -keyout key.pem -nodes -out cert.pem -sha256 -days 365 -subj "/C=RU/ST=NTC/L=TNIIS/O=Company Name/OU=Org/CN=www.example.com"
|
||||
openssl req -new -x509 -keyout "html/server.pem" -out "html/server.pem" -days 365 -nodes
|
||||
17
https-server.py
Normal file
17
https-server.py
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python3
|
||||
from http import server # Python 3
|
||||
import ssl
|
||||
import os
|
||||
|
||||
|
||||
class MyHTTPRequestHandler(server.SimpleHTTPRequestHandler):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
html_dir = os.path.join(os.path.dirname(__file__), 'html')
|
||||
os.chdir(html_dir)
|
||||
srv = server.HTTPServer(('', 8000), MyHTTPRequestHandler)
|
||||
sdc = ssl.create_default_context()
|
||||
srv.serve_forever()
|
||||
@@ -6,6 +6,10 @@ var selected: bool
|
||||
func set_track_visible(value: bool): $track.visible = value
|
||||
|
||||
|
||||
## Задаёт цвет точки
|
||||
func set_bip_color(val: Color): $bip.set_instance_shader_parameter('color', val)
|
||||
|
||||
|
||||
## Присваивает заданное значение видимости индикатору выполнения.
|
||||
func set_ecm_visible(value: bool): $ecm_done.visible = value
|
||||
|
||||
|
||||
@@ -47,11 +47,10 @@ theme_override_styles/tab_focus = SubResource("StyleBoxEmpty_41d34")
|
||||
theme_override_styles/tab_disabled = SubResource("StyleBoxEmpty_cw2ss")
|
||||
theme_override_styles/tabbar_background = SubResource("StyleBoxEmpty_nmdfd")
|
||||
theme_override_styles/panel = SubResource("StyleBoxEmpty_vap7n")
|
||||
current_tab = 3
|
||||
current_tab = 0
|
||||
script = ExtResource("1_fg0vd")
|
||||
|
||||
[node name="Работа" parent="tab_switch" instance=ExtResource("2_u7p16")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
metadata/_tab_index = 0
|
||||
|
||||
@@ -66,6 +65,7 @@ layout_mode = 2
|
||||
metadata/_tab_index = 2
|
||||
|
||||
[node name="ЭМС" parent="tab_switch" instance=ExtResource("5_u71bh")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
metadata/_tab_index = 3
|
||||
|
||||
@@ -95,15 +95,13 @@ script = ExtResource("8_tidwt")
|
||||
metadata/_edit_lock_ = true
|
||||
|
||||
[node name="remote_control" type="Label" parent="."]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
offset_left = 1358.0
|
||||
offset_right = 1501.0
|
||||
offset_left = 1244.0
|
||||
offset_right = 1401.0
|
||||
offset_bottom = 27.0
|
||||
tooltip_text = "Комплекс находится под внешним управлением"
|
||||
mouse_filter = 0
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_o1r22")
|
||||
text = "Внешнее управление"
|
||||
horizontal_alignment = 1
|
||||
|
||||
@@ -179,6 +179,7 @@ func _ready():
|
||||
signaller.connect('update_scale_map', Callable(self, 'on_update_scale_label'))
|
||||
signaller.connect('sector_klaster', Callable(self, 'sector_klaster'))
|
||||
signaller.connect('clear_klaster', Callable(self, 'clear_all_klaster'))
|
||||
signaller.connect('th_aoa_update', Callable(self, 'on_th_aoa_update'))
|
||||
var unit_nav = network.get_unit_instance('навигация')
|
||||
unit_nav.connect('data_received', on_navi_data_received)
|
||||
on_btn_center_toggled(true)
|
||||
@@ -252,9 +253,10 @@ func map_threat_to_bip(th: threats.Threat, bip: Control) -> bool:
|
||||
|
||||
|
||||
## Обработчик сигнала обновления цели.
|
||||
func on_threat_update(th):
|
||||
func on_threat_update(th: threats.Threat):
|
||||
var bip = get_node('%d' % th.id)
|
||||
bip.update(th.tick_rx)
|
||||
bip.set_bip_color(Color.CORAL if th.proto else Color.WHITE)
|
||||
bip.visible = map_threat_to_bip(th, bip)
|
||||
|
||||
|
||||
@@ -595,6 +597,7 @@ func on_btn_close(btn):
|
||||
fs_closed.merge(fs_selected)
|
||||
signaller.emit_signal('update_fs_closed', fs_closed)
|
||||
|
||||
|
||||
func on_btn_work(btn):
|
||||
await get_tree().create_timer(0.2).timeout
|
||||
btn.pressed = false
|
||||
@@ -604,6 +607,13 @@ func on_btn_work(btn):
|
||||
fs_closed[fs_index] = null
|
||||
signaller.emit_signal('update_fs_closed', fs_closed)
|
||||
|
||||
|
||||
func _on_btn_all_work_pressed() -> void:
|
||||
fs_closed.clear()
|
||||
signaller.emit_signal('update_fs_closed', fs_closed)
|
||||
|
||||
|
||||
func on_th_aoa_update(ths):
|
||||
$count_all_pad/count_all.text = '%02d' % ths.size()
|
||||
var c: int = ths.values().filter(func(th: threats.Threat): return th.proto != '').size()
|
||||
$count_danger_pad/count_danger.text = '%02d' % c
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[gd_scene load_steps=34 format=3 uid="uid://musb21x2u0xs"]
|
||||
[gd_scene load_steps=35 format=3 uid="uid://musb21x2u0xs"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://hkcvl2waf63s" path="res://scenes/эмс2/вид сверху.png" id="1_b7vcf"]
|
||||
[ext_resource type="Script" uid="uid://bvlqgv7aapebl" path="res://scenes/эмс2/эмс_тг.gd" id="1_l3ueu"]
|
||||
[ext_resource type="Texture2D" uid="uid://0w6q4vfst0ry" path="res://scenes/эмс2/OP-63.png" id="3_8gk36"]
|
||||
[ext_resource type="Texture2D" uid="uid://coxhivvc6uibs" path="res://scenes/эмс2/Состояние РЭС 40.png" id="4_b3mus"]
|
||||
[ext_resource type="Texture2D" uid="uid://073el51yholj" path="res://scenes/эмс2/454.png" id="4_nqi0i"]
|
||||
@@ -39,6 +40,7 @@ load_path = "res://.godot/imported/Окно частот0.png-6b01791c971bddb013
|
||||
load_path = "res://.godot/imported/Скруглённый квадрат серый.png-4655829309cca3b1dec2c9ae01376d54.ctex"
|
||||
|
||||
[node name="Panel" type="Panel"]
|
||||
script = ExtResource("1_l3ueu")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
modulate = Color(1, 0.596078, 0.4, 1)
|
||||
@@ -106,6 +108,15 @@ position = Vector2(275.641, 38.4615)
|
||||
scale = Vector2(3.20513, 3.20513)
|
||||
texture = ExtResource("6_m57px")
|
||||
|
||||
[node name="lbl_trassa" type="Label" parent="454"]
|
||||
layout_mode = 0
|
||||
offset_left = -42.0
|
||||
offset_top = -135.0
|
||||
offset_right = 221.0
|
||||
offset_bottom = -36.0
|
||||
theme_override_font_sizes/font_size = 100
|
||||
text = "Трасса"
|
||||
|
||||
[node name="Го" type="TextureRect" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 488.0
|
||||
|
||||
37
scenes/эмс2/эмс_тг.gd
Normal file
37
scenes/эмс2/эмс_тг.gd
Normal file
@@ -0,0 +1,37 @@
|
||||
extends Panel
|
||||
|
||||
func _ready() -> void:
|
||||
var unit_trassa = network.get_unit_instance('уарэп-трасса')
|
||||
unit_trassa.connect('line_changed', Callable(self, 'on_trassa_line_changed'))
|
||||
signaller.connect('sector_klaster', Callable(self, 'on_sector_klaster').bind(unit_trassa))
|
||||
|
||||
|
||||
func on_trassa_line_changed(unit_trassa):
|
||||
if unit_trassa.online:
|
||||
$"454/СостояниеРэс3".self_modulate = Color.WEB_GREEN
|
||||
$"СкруглённыйПрямоугольникБелый/Label3".text = 'Трасса'
|
||||
$"СкруглённыйПрямоугольникБелый/Label4".text = 'Трасса'
|
||||
$"СкруглённыйПрямоугольникБелый/Label5".text = 'Активный'
|
||||
$"СкруглённыйПрямоугольникБелый/Label6".text = str(unit_trassa.daa)
|
||||
$"СкруглённыйПрямоугольникБелый/Label7".text = str(unit_trassa.dap)
|
||||
$"СкруглённыйПрямоугольникБелый/Label8".text = '1'
|
||||
$"СкруглённыйПрямоугольникБелый/Label9".text = str(unit_trassa.lfb)
|
||||
$"СкруглённыйПрямоугольникБелый/Label10".text = str(unit_trassa.lfb)
|
||||
else:
|
||||
$"454/СостояниеРэс3".self_modulate = Color.WHITE
|
||||
$"СкруглённыйПрямоугольникБелый/Label3".text = '-'
|
||||
$"СкруглённыйПрямоугольникБелый/Label4".text = '-'
|
||||
$"СкруглённыйПрямоугольникБелый/Label5".text = '-'
|
||||
$"СкруглённыйПрямоугольникБелый/Label6".text = '-'
|
||||
$"СкруглённыйПрямоугольникБелый/Label7".text = '-'
|
||||
$"СкруглённыйПрямоугольникБелый/Label8".text = '-'
|
||||
$"СкруглённыйПрямоугольникБелый/Label9".text = '-'
|
||||
$"СкруглённыйПрямоугольникБелый/Label10".text = '-'
|
||||
|
||||
|
||||
func on_sector_klaster(data, unit_trassa):
|
||||
$"СкруглённыйПрямоугольникБелый/Label6".text = str(unit_trassa.dap)
|
||||
$"СкруглённыйПрямоугольникБелый/Label7".text = str(unit_trassa.daa)
|
||||
$"СкруглённыйПрямоугольникБелый/Label8".text = '1'
|
||||
$"СкруглённыйПрямоугольникБелый/Label9".text = str(unit_trassa.lfb)
|
||||
$"СкруглённыйПрямоугольникБелый/Label10".text = str(unit_trassa.hfb)
|
||||
1
scenes/эмс2/эмс_тг.gd.uid
Normal file
1
scenes/эмс2/эмс_тг.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bvlqgv7aapebl
|
||||
@@ -10,7 +10,7 @@ var UnitProfiles: Dictionary[StringName, Array] = { \
|
||||
'уарэп-яу07-частный': ['yau07rx', ['10.1.1.2', 50002, false, true], 'IP-адрес для приёма частных сообщений от ЯУ-07'],
|
||||
'уарэп-яу07-общий': ['yau07rx', ['*', 50000, true, true], 'IP-адрес для приёма широковещательных сообщений от ЯУ-07'],
|
||||
'уарэп-капсрпб': ['capsrpb', ['127.0.0.1', '127.0.0.1', 42023, 42022, false, true], 'IP-адрес для обмена сообщениями со службой \"МП550\" (СТЦ)'],
|
||||
'уарэп-трасса': ['trassa', ['127.0.0.1', '127.0.0.1', 50200, 10004, false, true], 'IP-адрес для обмена сообщениями с \"Трассой\"'],
|
||||
'уарэп-трасса': ['trassa', ['192.168.11.34', '192.168.11.105', 50200, 10004, false, true], 'IP-адрес для обмена сообщениями с \"Трассой\"'],
|
||||
'уарэп-эмс': ['yau07tx', ['10.1.1.52', 50052, false, false], 'IP-адрес прибора УФ'],
|
||||
'уарэп-яу07-2в': ['yau07tx', ['10.1.1.22', 50022, false, false], 'IP-адрес прибора ПРД-В2'],
|
||||
'уарэп-яу07-2н': ['yau07tx', ['10.1.1.21', 50021, false, false], 'IP-адрес прибора ПРД-Н2'],
|
||||
|
||||
@@ -30,6 +30,8 @@ signal режим_журнал()
|
||||
## Вызывается при переходе в режим [b]ЭМС[/b].
|
||||
signal режим_эмс()
|
||||
|
||||
## Вызывается при переходе в режим [b]ЭМС ТГ[/b].
|
||||
signal режим_эмс2()
|
||||
|
||||
## Вызывается при переходе в режим [b]Настройка[/b].
|
||||
signal режим_настройки()
|
||||
|
||||
@@ -29,9 +29,9 @@ const MOD_TYPES: Array = [
|
||||
const CU_STATE: Dictionary = {
|
||||
0: 2, # Подготовка к выполнению
|
||||
1: 1, # Выполняется
|
||||
2: 9, # Ошибка в команде
|
||||
2: 3, # Ошибка в команде
|
||||
3: 7, # Занят выполнением другого ЦУ
|
||||
4: 9, # Неисправность
|
||||
4: 2, # Неисправность
|
||||
}
|
||||
|
||||
class TCP5P28 extends unit.Unit:
|
||||
@@ -135,7 +135,7 @@ class TCP5P28 extends unit.Unit:
|
||||
continue
|
||||
var cu = ecms[id]
|
||||
cu_data.encode_u16(0, cu.ispp)
|
||||
var state: int = CU_STATE[cu.svk] if CU_STATE.has(cu.svk) else 9
|
||||
var state: int = CU_STATE[cu.svk] if CU_STATE.has(cu.svk) else 8
|
||||
cu_data.encode_u8(2, state) # Состояние выполнения команды
|
||||
cu_data.encode_u8(3, 0xFF) # Эффективность работы помехи
|
||||
data.append_array(cu_data)
|
||||
|
||||
@@ -35,6 +35,10 @@ class Trassa extends unit.Unit:
|
||||
[2000, 6000, 500, 100],
|
||||
[3500, 6000, 524, 50],
|
||||
[390, 6000, 374, 50*7]]
|
||||
var lfb = 0
|
||||
var hfb = 0
|
||||
var dap = 0
|
||||
var daa = 0
|
||||
|
||||
# Инициализация
|
||||
func _init(nm: StringName, buttons: Array = []) -> void:
|
||||
@@ -105,10 +109,10 @@ class Trassa extends unit.Unit:
|
||||
if txe == true or rxe == true:
|
||||
sector_data["draw"] = true
|
||||
if data.has("lfb") and data.has("hfb") and data.has("dap") and data.has("daa"):
|
||||
var lfb = int(data["lfb"])
|
||||
var hfb = int(data["hfb"])
|
||||
var dap = int(data["dap"])
|
||||
var daa = int(data["daa"])
|
||||
lfb = int(data["lfb"])
|
||||
hfb = int(data["hfb"])
|
||||
dap = int(data["dap"])
|
||||
daa = int(data["daa"])
|
||||
for i in range(set_klaster.size()):
|
||||
var mapping = set_klaster[i]
|
||||
if lfb == mapping[0] and hfb == mapping[1]:
|
||||
|
||||
12
uarep-ctl.linux.x86_64
Normal file
12
uarep-ctl.linux.x86_64
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
DATE_TIME=$(date "+%F %H-%M-%S")
|
||||
LOG_PATH="/home/${USER}/$(basename "$0")-${DATE_TIME}.log" # Путь к файлу журнала.
|
||||
|
||||
# { Вывод этого скрипта в файл журнала и консоль одновременно
|
||||
# shellcheck disable=SC2015,SC2086
|
||||
test $1 = x$'\x00' && shift || { set -o pipefail ; ( exec 2>&1 ; $0 $'\x00' "$@" ) | tee "${LOG_PATH}" ; exit $? ; }
|
||||
# }
|
||||
|
||||
/opt/uarep-ctl/bin/uarep-ctl.linux.x86_64 -f -t --screen 1
|
||||
Reference in New Issue
Block a user