Compare commits

...

3 Commits

Author SHA1 Message Date
kira-a-k
9daae7b6b9 zalupa1 2025-11-08 13:37:26 +03:00
kira-a-k
f002e9125e zalupa 2025-11-08 13:31:48 +03:00
sasha80
3bff1cd90f Доработка. Статическая проверка 2025-11-04 15:33:24 +03:00
6 changed files with 168 additions and 4 deletions

View File

@@ -36,3 +36,4 @@
- После клонирования запустить скрипт `git-hooks-config.sh`
- В среде **Windows** запуск скрипта `git-hooks-config.sh` производить из оболочки `git bash`
- Нужно обновить `settings.json`
- поиск циклических зависимостей

164
check-graph.py Normal file
View 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("----------------------------------")

View File

@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -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 = 4.71239
scale = Vector2(0.496934, 0.496934)
texture = ExtResource("1_v0nwa")

View File

@@ -717,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 = fmod(270.0 + course, 360.0)
ship_instance.rotation_degrees = fmod(course, 360.0)
queue_redraw()