Merge branch 'tmp'
@@ -33,7 +33,7 @@ Log.fatal(text)
|
||||
const CUSTOM = Log.MAX << 1 # Bitwise left shift the MAX value for a custom level.
|
||||
|
||||
func _ready() -> void:
|
||||
Log.add_level(CUSTOM, "Level Name")
|
||||
Log.add_level(CUSTOM, "Level Name")
|
||||
```
|
||||
|
||||
## Calling the custom level:
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
# Copyright (c) 2020-2023 Mansur Isaev and contributors - MIT License
|
||||
# See `LICENSE.md` included in the source distribution for details.
|
||||
|
||||
## Logger class.
|
||||
class_name Logger
|
||||
extends Node
|
||||
## Класс журнал событий.
|
||||
class_name Logger extends Node
|
||||
|
||||
## Emitted when the logger create a message.
|
||||
## Выдается, когда журнал событий создаёт сообщение.
|
||||
signal logged(message: Dictionary)
|
||||
|
||||
|
||||
enum {
|
||||
INFO = 1, ## Info level.
|
||||
DEBUG = 1<<1, ## Warning level.
|
||||
WARNING = 1<<2, ## Debug level.
|
||||
ERROR = 1<<3, ## Error level.
|
||||
FATAL = 1<<4, ## Fatal level.
|
||||
MAX = FATAL, ## Bitwise left shift for custom levels.
|
||||
INFO = 1, ## Информационный уровень.
|
||||
DEBUG = 1<<1, ## Уровень предупреждения.
|
||||
WARNING = 1<<2, ## Уровень отладки.
|
||||
ERROR = 1<<3, ## Уровень ошибок.
|
||||
FATAL = 1<<4, ## Критический уровень.
|
||||
MAX = FATAL, ## Побитовый сдвиг влево для пользовательских уровней.
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +40,7 @@ var _names = {
|
||||
var _msg_array: Array
|
||||
var _filters: Array
|
||||
|
||||
# Can be overridden to define custom default values.
|
||||
## Преопределение пользовательских значений по умолчанию.
|
||||
func _enter_tree() -> void:
|
||||
set_log_enabled(ProjectSettings.get_setting("plugins/logger/log_enabled", true))
|
||||
set_default_output_enabled(ProjectSettings.get_setting("plugins/logger/default_output", false))
|
||||
@@ -58,11 +57,11 @@ func _enter_tree() -> void:
|
||||
func _exit_tree() -> void:
|
||||
_close_file()
|
||||
|
||||
## Return [param true] if logger has level.
|
||||
## Возвращает [param true], если у журнала события есть уровень.
|
||||
func has_level(level: int) -> bool:
|
||||
return _names.has(level)
|
||||
|
||||
## Set the level enabled.
|
||||
## Установить включенный уровень.
|
||||
func set_level(level: int, enabled: bool) -> void:
|
||||
assert(has_level(level), "Invalid level.")
|
||||
if not has_level(level):
|
||||
@@ -73,8 +72,8 @@ func set_level(level: int, enabled: bool) -> void:
|
||||
else:
|
||||
_level &= ~level
|
||||
|
||||
## Add a custom log level. The level value must be unique and be greater than [member MAX].
|
||||
## To call the custom level use [method message] method.
|
||||
## Добавить пользовательский уровень журнала. Значение уровня должно быть уникальным и превышать [member MAX].
|
||||
## Для вызова пользовательского уровня используйте метод - [method message].
|
||||
func add_level(level: int, nm: String) -> void:
|
||||
assert(not has_level(level), "Has level.")
|
||||
assert(level > MAX and not level % 2, "Invalid level.")
|
||||
@@ -84,27 +83,27 @@ func add_level(level: int, nm: String) -> void:
|
||||
_names[level] = nm
|
||||
set_level(level, true)
|
||||
|
||||
## Return the level name.
|
||||
## Возвращает имя уровня.
|
||||
func get_level_name(level: int) -> String:
|
||||
return _names[level]
|
||||
|
||||
## Set Log enabled. Disable ALL messages.
|
||||
## Установить включенный журнал. Отключить ВСЕ сообщения.
|
||||
func set_log_enabled(enabled: bool) -> void:
|
||||
_log_enabled = enabled
|
||||
|
||||
## Return [param true] if Log enabled.
|
||||
## Возвращает [param true], если журнал включен.
|
||||
func is_log_enabled() -> bool:
|
||||
return _log_enabled
|
||||
|
||||
## Set default output enabled.
|
||||
## Установка выхода по умолчанию включена.
|
||||
func set_default_output_enabled(enabled: bool) -> void:
|
||||
_default_output_enabled = enabled
|
||||
|
||||
## Returns [param true] if default output is enabled.
|
||||
## Возвращает [param true], если вывод по умолчанию включен.
|
||||
func is_default_output_enabled() -> bool:
|
||||
return _default_output_enabled
|
||||
|
||||
## Set file write enabled.
|
||||
## Установить разрешение на запись файла.
|
||||
func set_file_write_enabled(enabled: bool) -> void:
|
||||
if _file_write_enabled == enabled:
|
||||
return
|
||||
@@ -116,11 +115,11 @@ func set_file_write_enabled(enabled: bool) -> void:
|
||||
else:
|
||||
_close_file()
|
||||
|
||||
## Returns [param true] if write to a file is enabled.
|
||||
## Возвращает [param true], если запись в файл разрешена.
|
||||
func is_file_write_enabled() -> bool:
|
||||
return _file_write_enabled
|
||||
|
||||
## Set the path to the log file.
|
||||
## Задать путь к файлу журнала.
|
||||
func set_file_path(path: String) -> void:
|
||||
assert(path.is_absolute_path(), "Invalid path.")
|
||||
if not path.is_absolute_path() or _file_path == path:
|
||||
@@ -131,32 +130,32 @@ func set_file_path(path: String) -> void:
|
||||
if is_file_write_enabled():
|
||||
_open_file()
|
||||
|
||||
## Return path to log file.
|
||||
## Возвращает путь к файлу журнала.
|
||||
func get_file_path() -> String:
|
||||
return _file_path
|
||||
|
||||
## Create an info message.
|
||||
## Создать информационное сообщение.
|
||||
func info(text: String) -> void:
|
||||
message(INFO, text)
|
||||
|
||||
## Create a debug message. Debug build only.
|
||||
## Создать отладочное сообщение. Только для отладочной сборки.
|
||||
func debug(text: String) -> void:
|
||||
if OS.is_debug_build():
|
||||
message(DEBUG, text)
|
||||
|
||||
## Create a warning message.
|
||||
## Создать предупреждающее сообщение.
|
||||
func warning(text: String) -> void:
|
||||
message(WARNING, text)
|
||||
|
||||
## Create an error message.
|
||||
## Создать сообщение об ошибке.
|
||||
func error(text: String) -> void:
|
||||
message(ERROR, text)
|
||||
|
||||
## Create a fatal error message.
|
||||
## Создать сообщение о критической ошибке.
|
||||
func fatal(text: String) -> void:
|
||||
message(FATAL, text)
|
||||
|
||||
## Format string for log file.
|
||||
## Форматировать строку для файла.
|
||||
func format_file(msg: Dictionary) -> String:
|
||||
return _format_file.format(
|
||||
{
|
||||
@@ -171,7 +170,7 @@ func format_file(msg: Dictionary) -> String:
|
||||
}
|
||||
)
|
||||
|
||||
## Format string for editor output.
|
||||
## Форматировать строку для вывода редактора.
|
||||
func format_stdout(msg: Dictionary) -> String:
|
||||
return _format_default_output.format(
|
||||
{
|
||||
@@ -186,7 +185,7 @@ func format_stdout(msg: Dictionary) -> String:
|
||||
}
|
||||
)
|
||||
|
||||
## Create a message with a custom level.
|
||||
## Создать сообщение с пользовательским уровнем.
|
||||
func message(level: int, text: String) -> void:
|
||||
assert(has_level(level), "Has not level.")
|
||||
assert(text, "Invalid message text.")
|
||||
@@ -207,7 +206,7 @@ func message(level: int, text: String) -> void:
|
||||
_file.call_deferred('flush')
|
||||
|
||||
if _default_output_enabled:
|
||||
print(format_stdout(msg))
|
||||
print_debug(format_stdout(msg))
|
||||
|
||||
|
||||
func _open_file() -> void:
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
# See `LICENSE.md` included in the source distribution for details.
|
||||
|
||||
@tool
|
||||
## LoggerOutput class.
|
||||
class_name LoggerOutput
|
||||
extends RichTextLabel
|
||||
## Класс вывода журнала событий.
|
||||
class_name LoggerOutput extends RichTextLabel
|
||||
|
||||
## Emited when handle [signal Logger.logged] signal.
|
||||
## Выдаётся при ошибке сигнала - [signal Logger.logged].
|
||||
signal handled()
|
||||
|
||||
|
||||
@@ -33,11 +32,11 @@ func _exit_tree() -> void:
|
||||
if is_instance_valid(_logger) and _logger.logged.is_connected(handle_message):
|
||||
_logger.logged.disconnect(handle_message)
|
||||
|
||||
## Return the level color or [member Color.WHITE].
|
||||
## Вернуть цвет уровня или [member Color.WHITE].
|
||||
func get_color(level: int) -> Color:
|
||||
return colors.get(level, Color.WHITE)
|
||||
|
||||
## Set the logger.
|
||||
## Установить журнал событий.
|
||||
func set_logger(logger: Logger) -> void:
|
||||
assert(is_instance_valid(logger), "Invalid Logger.")
|
||||
if not is_instance_valid(logger) or is_same(_logger, logger):
|
||||
@@ -51,11 +50,11 @@ func set_logger(logger: Logger) -> void:
|
||||
|
||||
_logger = logger
|
||||
|
||||
## Return the logger.
|
||||
## Вернуть журнал событий.
|
||||
func get_logger() -> Logger:
|
||||
return _logger
|
||||
|
||||
## Return formatted string from message.
|
||||
## Вернуть строку после форматирования из сообщения.
|
||||
func format(message: Dictionary) -> String:
|
||||
return format_text.format(
|
||||
{
|
||||
@@ -70,7 +69,7 @@ func format(message: Dictionary) -> String:
|
||||
}
|
||||
)
|
||||
|
||||
## Handle the message.
|
||||
## Обработать сообщение.
|
||||
func handle_message(message: Dictionary) -> void:
|
||||
push_color(get_color(message["level"]))
|
||||
append_text(format(message) + "\n")
|
||||
|
||||
24
build.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Описание
|
||||
#
|
||||
# Этот скрипт создаёт исполняемый файл (загружаемый модуль) из файла проекта Godot
|
||||
#
|
||||
|
||||
# Имя выходного исполняемого файла (загружаемый модуль)
|
||||
TARGET_BIN="uarep-ctl.linux.x86_64"
|
||||
|
||||
# Целевой путь папки в которой будет расположен исполняемый файл (загружаемый модуль)
|
||||
TARGET_PATH="./bin"
|
||||
|
||||
# Путь к исполняемому файлу редактора Godot
|
||||
EDITOR="/opt/godot/Godot_v4.2.2-stable_linux.x86_64"
|
||||
|
||||
# Если используется своя сборка движка, то соответствующий файл
|
||||
# (исполняемый модуль движка, шаблон экспорта) нужно заменить
|
||||
# в этой папке: "~/.local/share/godot/export_templates/4.2.2.stable/"
|
||||
|
||||
# Путь к файлу проекта Godot
|
||||
PROJECT_PATH="$(pwd)"
|
||||
|
||||
${EDITOR} --path "${PROJECT_PATH}" --export-release "Linux-X11" "${TARGET_PATH}/${TARGET_BIN}"
|
||||
@@ -11,6 +11,7 @@ cache/0/16/0/underline_thickness = 0.0
|
||||
cache/0/16/0/scale = 1.0
|
||||
cache/0/16/0/kerning_overrides/16/0 = Vector2(0, 0)
|
||||
cache/0/16/0/kerning_overrides/14/0 = Vector2(0, 0)
|
||||
cache/0/16/0/kerning_overrides/50/0 = Vector2(0, 0)
|
||||
cache/0/14/0/ascent = 0.0
|
||||
cache/0/14/0/descent = 0.0
|
||||
cache/0/14/0/underline_position = 0.0
|
||||
@@ -18,3 +19,12 @@ cache/0/14/0/underline_thickness = 0.0
|
||||
cache/0/14/0/scale = 1.0
|
||||
cache/0/14/0/kerning_overrides/16/0 = Vector2(0, 0)
|
||||
cache/0/14/0/kerning_overrides/14/0 = Vector2(0, 0)
|
||||
cache/0/14/0/kerning_overrides/50/0 = Vector2(0, 0)
|
||||
cache/0/50/0/ascent = 0.0
|
||||
cache/0/50/0/descent = 0.0
|
||||
cache/0/50/0/underline_position = 0.0
|
||||
cache/0/50/0/underline_thickness = 0.0
|
||||
cache/0/50/0/scale = 1.0
|
||||
cache/0/50/0/kerning_overrides/16/0 = Vector2(0, 0)
|
||||
cache/0/50/0/kerning_overrides/14/0 = Vector2(0, 0)
|
||||
cache/0/50/0/kerning_overrides/50/0 = Vector2(0, 0)
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 25 KiB |
BIN
data/Окно.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
34
data/Окно.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://co5xj5uhjfk84"
|
||||
path="res://.godot/imported/Окно.png-ff4b5eac96df23ad4cd8e06dc32f5bb8.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://data/Окно.png"
|
||||
dest_files=["res://.godot/imported/Окно.png-ff4b5eac96df23ad4cd8e06dc32f5bb8.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
data/П16.png
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 15 KiB |
BIN
data/ПРД.png
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 13 KiB |
BIN
data/СПТ.png
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 7.7 KiB |
BIN
data/УФ.png
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 11 KiB |
BIN
data/Щ3.png
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 8.9 KiB |
@@ -24,9 +24,7 @@ config/map_tile_size=256
|
||||
config/map_minimum_zoom=5
|
||||
config/map_maximum_zoom=19
|
||||
config/map_server_addr="https://b.tile.openstreetmap.org"
|
||||
config/map_image_size_rto=Vector2i(512, 512)
|
||||
config/map_image_size_rls=Vector2i(1024, 1024)
|
||||
interfer/center_offset=Vector2(0, 25)
|
||||
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)
|
||||
interfer/select_color=Vector3(1, 1, 1)
|
||||
@@ -89,12 +87,55 @@ window/vsync/vsync_mode=false
|
||||
|
||||
[editor]
|
||||
|
||||
movie_writer/mjpeg_quality=0.5
|
||||
movie_writer/fps=24
|
||||
version_control/autoload_on_startup=true
|
||||
|
||||
[editor_plugins]
|
||||
|
||||
enabled=PackedStringArray()
|
||||
|
||||
[file_customization]
|
||||
|
||||
folder_colors={
|
||||
"res://addons/": "blue",
|
||||
"res://data/": "yellow",
|
||||
"res://modbus/": "blue",
|
||||
"res://scenes/": "teal",
|
||||
"res://scenes/bip/": "blue",
|
||||
"res://scenes/button-flat/": "blue",
|
||||
"res://scenes/button-scale/": "blue",
|
||||
"res://scenes/cell/": "blue",
|
||||
"res://scenes/count-all/": "blue",
|
||||
"res://scenes/count-danger/": "blue",
|
||||
"res://scenes/diagram/": "blue",
|
||||
"res://scenes/frame-ecm-list/": "blue",
|
||||
"res://scenes/frame-ecm-params/": "blue",
|
||||
"res://scenes/frame-params/": "blue",
|
||||
"res://scenes/frame-threats/": "blue",
|
||||
"res://scenes/frame/": "blue",
|
||||
"res://scenes/grid-buttons-ecm/": "blue",
|
||||
"res://scenes/grid-side-panel/": "blue",
|
||||
"res://scenes/pribor-afsp/": "purple",
|
||||
"res://scenes/pribor-prd-k/": "purple",
|
||||
"res://scenes/pribor-prd-n/": "purple",
|
||||
"res://scenes/pribor-prd-v/": "purple",
|
||||
"res://scenes/pribor-rtr/": "purple",
|
||||
"res://scenes/pribor-uf/": "purple",
|
||||
"res://scenes/pribor-uyep/": "purple",
|
||||
"res://scenes/tabs-switch/": "blue",
|
||||
"res://scenes/tilemap/": "blue",
|
||||
"res://scenes/журнал/": "green",
|
||||
"res://scenes/контроль/": "green",
|
||||
"res://scenes/настройки/": "green",
|
||||
"res://scenes/работа/": "green",
|
||||
"res://scenes/эмс/": "green",
|
||||
"res://scenes/эмс2/": "green",
|
||||
"res://scripts/": "pink",
|
||||
"res://shaders/": "pink",
|
||||
"res://table/": "blue"
|
||||
}
|
||||
|
||||
[global]
|
||||
|
||||
map_server_addr=false
|
||||
@@ -111,6 +152,29 @@ theme/default_font_subpixel_positioning=3
|
||||
theme/lcd_subpixel_layout=0
|
||||
common/drop_mouse_on_gui_input_disabled=true
|
||||
|
||||
[input]
|
||||
|
||||
up={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
down={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
left={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
right={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[input_devices]
|
||||
|
||||
buffering/agile_event_flushing=true
|
||||
@@ -129,7 +193,6 @@ common/enable_object_picking=false
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.web="mobile"
|
||||
gl_compatibility/item_buffer_size=8192
|
||||
shader_compiler/shader_cache/strip_debug=true
|
||||
textures/default_filters/anisotropic_filtering_level=0
|
||||
anti_aliasing/screen_space_roughness_limiter/enabled=false
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
extends Control
|
||||
class_name bip_ extends Control
|
||||
|
||||
var selected: bool
|
||||
|
||||
# Функция присваивает заданое значение видимости селектору
|
||||
## Функция присваивает заданое значение видимости селектору.
|
||||
func set_sel_visible(value: bool):
|
||||
selected = value
|
||||
$selector.visible = value
|
||||
|
||||
|
||||
# Функция присваивает заданое значение видимости селектору
|
||||
## Функция присваивает заданое значение видимости селектору.
|
||||
func set_track_visible(value: bool): $track.visible = value
|
||||
# Функция присваивает заданое значение видимости индикатору выполнения
|
||||
## Функция присваивает заданое значение видимости индикатору выполнения.
|
||||
func set_ecm_visible(value: bool): $ecm_done.visible = value
|
||||
|
||||
|
||||
@@ -23,3 +23,7 @@ func _on_bip_gui_input(event):
|
||||
if selected:
|
||||
signaller.emit_signal('rto_threat_unsel', name.to_int())
|
||||
|
||||
|
||||
func update():
|
||||
$bip.material.set('shader_parameter/tick_update', float(Time.get_ticks_msec()/1000))
|
||||
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_2dulj"]
|
||||
shader = ExtResource("2_rt0la")
|
||||
shader_parameter/color = Color(0.972549, 0.12549, 0.411765, 1)
|
||||
shader_parameter/color_up = Color(1, 1, 1, 1)
|
||||
shader_parameter/tick_update = 0
|
||||
shader_parameter/tick_update = 0.0
|
||||
|
||||
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_w5pye"]
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ resource_local_to_scene = true
|
||||
shader = ExtResource("2_5ngiq")
|
||||
shader_parameter/rotation = 0.0
|
||||
shader_parameter/color = Vector4(1, 1, 1, 0.1)
|
||||
shader_parameter/width = 1.0
|
||||
shader_parameter/width = 3.0
|
||||
shader_parameter/speed = 0.0
|
||||
shader_parameter/disabled = false
|
||||
shader_parameter/scale = Vector2(1, 1)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extends Sprite2D
|
||||
class_name Diagram extends Sprite2D
|
||||
|
||||
var fs_default_colors: Array # Цвета по умолчанию для блоков ФС
|
||||
var fs_default_colors: Array ## Цвета по умолчанию для блоков ФС.
|
||||
|
||||
func _ready() -> void:
|
||||
signaller.connect('map_mode_changed', Callable(self, 'set_view_mode'))
|
||||
@@ -23,14 +23,14 @@ func get_strob_width() -> float: return $строб.material.get('shader_par
|
||||
func get_strob_band() -> float: return $строб.material.get('shader_parameter/band') * 125.0
|
||||
func get_strob_radius() -> float: return $строб.material.get('shader_parameter/radius') * 125.0
|
||||
|
||||
func get_radius_outter() -> float: return material.get('shader_parameter/radius_outter')
|
||||
func get_radius_inner_0() -> float: return material.get('shader_parameter/radius_inner_0')
|
||||
func get_radius_inner_1() -> float: return material.get('shader_parameter/radius_inner_1')
|
||||
func get_radius_outter() -> float: return material.get('shader_parameter/radius_outter')
|
||||
func get_radius_inner_0() -> float: return material.get('shader_parameter/radius_inner_0')
|
||||
func get_radius_inner_1() -> float: return material.get('shader_parameter/radius_inner_1')
|
||||
|
||||
func set_view_mode(val: int): material.set('shader_parameter/mode', val);
|
||||
func set_band_colors(val: Array): material.set('shader_parameter/ant_band_c', val)
|
||||
|
||||
## Закрашивание по умолчанию блоков ФС цветами из настроек
|
||||
## Закрашивание по умолчанию блоков ФС цветами из настроек.
|
||||
func set_def_colors():
|
||||
var color0: Vector3 = ProjectSettings.get_setting('application/interfer/default_color0', Vector3(0.38, 0.47, 0.51))
|
||||
var color1: Vector3 = ProjectSettings.get_setting('application/interfer/default_color1', Vector3(0.39, 0.44, 0.50))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
extends NinePatchRect
|
||||
class_name frm_ecm_list extends NinePatchRect
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
## Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
$grd_forced/btn_cancel.button_connect('pressed', Callable(self, 'on_btn_cancel_pressed').bind($grd_forced/btn_cancel))
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
tooltip_text = "Включает принудительную помеху"
|
||||
strips_rotation = 15.0
|
||||
text = "СРН"
|
||||
metadata/rfi_name = "ozp1"
|
||||
|
||||
@@ -63,6 +64,7 @@ editor_description = "Кнопка для принудительного вкл
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
strips_rotation = 15.0
|
||||
text = "СПРС"
|
||||
metadata/rfi_name = "ozp1"
|
||||
|
||||
@@ -71,6 +73,7 @@ layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
tooltip_text = "Кнопка для принудительного включения группы секторов в режим КУПД"
|
||||
strips_rotation = 15.0
|
||||
text = "КУПД"
|
||||
metadata/rfi_name = "ozp1"
|
||||
|
||||
@@ -78,5 +81,6 @@ metadata/rfi_name = "ozp1"
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
strips_rotation = 15.0
|
||||
text = "Отключить все"
|
||||
metadata/rfi_name = "<off>"
|
||||
|
||||
@@ -84,7 +84,6 @@ func _ready():
|
||||
interfer.connect('interfer_update', Callable(self, 'on_interfer_update').bind(table_index))
|
||||
$table.connect('row_pressed', Callable(self, 'on_row_pressed'))
|
||||
call_deferred('init_table')
|
||||
#$btn_cancel.button_connect('pressed', Callable(self, 'on_btn_cancel_pressed').bind($btn_cancel))
|
||||
|
||||
|
||||
func init_table():
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
extends ScrollContainer
|
||||
class_name scroll_ecm_params extends ScrollContainer
|
||||
|
||||
## Отображает список параметров помехи в таблице.
|
||||
|
||||
@@ -33,7 +33,7 @@ func init_table():
|
||||
$table.set_meta('id', 0)
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
## Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
signaller.connect('interfer_selected', Callable(self, 'on_interfer_selected'))
|
||||
signaller.connect('rto_threat_unsel', Callable(self, 'on_rto_threat_unsel'))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extends ScrollContainer
|
||||
class_name scroll_params extends ScrollContainer
|
||||
|
||||
## Отображение параметров цели
|
||||
## Отображение параметров цели.
|
||||
|
||||
const CellLineEdit = preload('res://table/ячейка-2.tscn') ## Ячейка таблицы.
|
||||
const TableHeader = preload('res://table/header.tscn') ## Ячейка заголовок таблицы.
|
||||
@@ -23,7 +23,7 @@ const TABLE_PARAMS = {
|
||||
'rkrp': [5, 'Рекомендуемая помеха'] }
|
||||
|
||||
|
||||
## Обрабатывает сигнал [signal threats.threat_selected]
|
||||
## Обрабатывает сигнал [signal threats.threat_selected].
|
||||
func on_threat_selected(th):
|
||||
$table.set_meta('id', th.id)
|
||||
on_threat_update(th)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
extends ScrollContainer
|
||||
class_name scroll_threats extends ScrollContainer
|
||||
|
||||
## Отображает список целей в таблице.
|
||||
|
||||
@@ -46,7 +46,7 @@ func _ready() -> void:
|
||||
call_deferred('init_table')
|
||||
|
||||
|
||||
## Перестраивает индекс таблицы. Вызывать при удалении строки
|
||||
## Перестраивает индекс таблицы. Вызывать при удалении строки.
|
||||
func rehash(table_index: Dictionary):
|
||||
var rows_count = $table.get_rows_count()
|
||||
for i_row in rows_count:
|
||||
@@ -54,21 +54,21 @@ func rehash(table_index: Dictionary):
|
||||
table_index[int(item.text)] = i_row
|
||||
|
||||
|
||||
## Обрабатывает сигнал [b]threat_update[/b]
|
||||
## Обрабатывает сигнал [b]threat_update[/b].
|
||||
func on_threat_update(th, table_index: Dictionary):
|
||||
var row = map_th_to_row(th)
|
||||
var i_row = table_index[th.id]
|
||||
$table.set_row_text(i_row, row)
|
||||
|
||||
|
||||
## Обрабатывает сигнал [b]threat_lost[/b]
|
||||
## Обрабатывает сигнал [b]threat_lost[/b].
|
||||
func on_threat_lost(th, table_index: Dictionary):
|
||||
$table.remove_row(table_index[th.id])
|
||||
table_index.clear()
|
||||
rehash(table_index)
|
||||
|
||||
|
||||
## Обрабатывает сигнал [b]threat_new[/b]
|
||||
## Обрабатывает сигнал [b]threat_new[/b].
|
||||
func on_threat_new(th, table_index):
|
||||
var i_row = $table.get_rows_count()
|
||||
$table.add_row(TABLE_ROW)
|
||||
@@ -79,7 +79,7 @@ func on_threat_new(th, table_index):
|
||||
table_index[th.id] = i_row
|
||||
|
||||
|
||||
## Преобразует цель в строку таблицы
|
||||
## Преобразует цель в строку таблицы.
|
||||
func map_th_to_row(th) -> Array:
|
||||
var row: = Array()
|
||||
row.resize(TABLE_COLUMN_PARAM.size())
|
||||
@@ -90,7 +90,7 @@ func map_th_to_row(th) -> Array:
|
||||
return row
|
||||
|
||||
|
||||
## Выделяет выбранную цель в таблице
|
||||
## Выделяет выбранную цель в таблице.
|
||||
func on_rto_threat_sel(th_id, tbl):
|
||||
for i in tbl.get_rows_count():
|
||||
var node = tbl.get_node2(0, i)
|
||||
@@ -99,6 +99,6 @@ func on_rto_threat_sel(th_id, tbl):
|
||||
break
|
||||
|
||||
|
||||
## Снимает выделение цели
|
||||
## Снимает выделение цели.
|
||||
func on_rto_threat_unsel(_th_id): $table.clear_rows_selected()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
extends "res://scenes/контроль/прибор.gd"
|
||||
class_name pribor_rtr extends "res://scenes/контроль/прибор.gd"
|
||||
|
||||
|
||||
static var json_parser: JSON = JSON.new()
|
||||
@@ -101,7 +101,7 @@ func map_value_to_item(data, item, value_name: StringName):
|
||||
|
||||
## 1. Поле [b]'ErCode'[/b] содержит [b]0[/b] - если нет ошибки, и другое значение - если есть ошибка.[br]
|
||||
## 2. Для каждого проверяемого параметра устройства есть своё поле [b]'ErCode'[/b].[br]
|
||||
## 3. Индикатор исправности у устройства один.[br]
|
||||
## 3. Есть только один индикатор исправности при отображении состояния устройства.[br]
|
||||
## 4. [i]Нет результата порверки[/i] - поле [param state] принимает значение [b]0[/b], [i]всё
|
||||
## исправно[/i] - [b]1[/b], [i]хотябы один[/i] параметр с ошибкой - [b]2[/b].[br]
|
||||
func map_error_codes_to_item(data, item, value_name: StringName):
|
||||
@@ -123,11 +123,11 @@ func map_error_codes_to_item(data, item, value_name: StringName):
|
||||
item.set(value_name, test_res)
|
||||
|
||||
|
||||
## Вызывается при клике мыши на элементе контроля
|
||||
## [param block_a] - Кликнутый элемент контроля
|
||||
## Вызывается при клике мыши на элементе контроля.
|
||||
## [param block_a] - Кликнутый элемент контроля.
|
||||
func _on_item_pressed(block_a: Control):
|
||||
var metas = block_a.get_meta_list()
|
||||
print_debug(block_a)
|
||||
for n in metas:
|
||||
var v = block_a.get_meta(n)
|
||||
print('%s:%s' % [n, v])
|
||||
print_debug('%s:%s' % [n, v])
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=10 format=3 uid="uid://3slb0i3pvowc"]
|
||||
[gd_scene load_steps=11 format=3 uid="uid://3slb0i3pvowc"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/tabs-switch/tab-switch.gd" id="1_fg0vd"]
|
||||
[ext_resource type="PackedScene" uid="uid://b276iygic5itk" path="res://scenes/работа/работа.tscn" id="2_u7p16"]
|
||||
@@ -6,6 +6,7 @@
|
||||
[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://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="FontFile" uid="uid://clrxfflc1wrhj" path="res://data/main-font.tres" id="7_i7l8n"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_fe3e1"]
|
||||
@@ -39,6 +40,10 @@ layout_mode = 2
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ЭМС2" parent="tab_switch" instance=ExtResource("6_rsg03")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Настройки" parent="tab_switch" instance=ExtResource("6_i8iv3")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
@@ -1,173 +1,665 @@
|
||||
extends Sprite2D
|
||||
@tool
|
||||
extends CanvasGroup
|
||||
class_name MercatorTileMap
|
||||
|
||||
## Возможные состояния конечного автомата заданий
|
||||
enum TASK_STATE {
|
||||
DONE, ## Выполнено
|
||||
WAIT, ## Ожидание плитки
|
||||
RUN, ## Запуск выполнения
|
||||
CHECK, ## Проверка пустого места
|
||||
ERROR ## Ошибка
|
||||
}
|
||||
## Отображение карт WEB Mercator
|
||||
|
||||
#http://10.1.1.220/osm_tiles/0/0/0.png
|
||||
#https://tile.openstreetmap.org/{z}/{x}/{y}.png
|
||||
@export var base_url: String = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png':
|
||||
set(v):
|
||||
if base_url != v:
|
||||
base_url = v
|
||||
_clean_all()
|
||||
queue_redraw()
|
||||
|
||||
@export var zoom_step: float = 0.025
|
||||
@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_color_no_alpha() var back_color: = Color.BLACK
|
||||
@export var animation_time: float = 1.0
|
||||
|
||||
|
||||
## Координаты для проверок [lng, lat]
|
||||
const TEST_DATA: = {
|
||||
'Калиниград': [ 20.51095, 54.70649 ],
|
||||
'Москва': [ 37.6156, 55.7522 ],
|
||||
'Нью-Йорк': [ -74.006, 40.7143 ],
|
||||
'Сидней': [ 151.20732, -33.8678500 ],
|
||||
'Таганрог': [ 38.8969, 47.2362 ],
|
||||
'Хельсинки': [ 24.9354, 60.1695 ],
|
||||
'Азорские о-ва': [ 28.3996582, 38.5397568 ],
|
||||
'Мехико': [ -99.12766, 19.42847 ],
|
||||
'Белое море': [ 68.136606, 42.045546 ],
|
||||
'море Беллинсгаузена': [ -72.406587, -74.857997 ],
|
||||
'Фиджи': [ 178.065032, -17.713371 ],
|
||||
'Ноль': [ 0.0, 0.0 ],
|
||||
'Точка1': [ 170.0, 0.0 ],
|
||||
'Точка2': [-170.0, 0.0 ],
|
||||
'Море' : [ 19.4, 54.91 ] }
|
||||
@export var size: Vector2i = Vector2i(400, 400):
|
||||
set(v):
|
||||
$canvas.size = v
|
||||
_on_resize()
|
||||
queue_redraw()
|
||||
get:
|
||||
return $canvas.size
|
||||
|
||||
|
||||
const MAP_MODES: = {
|
||||
0: 'application/config/map_image_size_rto',
|
||||
1: 'application/config/map_image_size_rls' }
|
||||
@export var ax: float = 0.0:
|
||||
set(v):
|
||||
_xyz.x = v
|
||||
queue_redraw()
|
||||
get:
|
||||
return _xyz.x
|
||||
|
||||
|
||||
const MAP_RELATIVE_RADIUSES: = {
|
||||
0: 0.39,
|
||||
1: 0.466
|
||||
}
|
||||
@export var ay: float = 0.0:
|
||||
set(v):
|
||||
_xyz.y = v
|
||||
queue_redraw()
|
||||
get:
|
||||
return _xyz.y
|
||||
|
||||
|
||||
var map_image: Image ## Изображение с картой
|
||||
var map_tile_state: TASK_STATE ## Текущее состояние конечного автомата плитки
|
||||
var map_bcs: Vector3 ## Яркость, контраст насыщенность
|
||||
var map_server_addr: String ## Адрес сервера изображений карт в проекции Меркатора
|
||||
var map_tile_format: String ##
|
||||
var map_tile_stack: Array ## Стек для хранения плиток карты
|
||||
var map_request: HTTPRequest ## Обработчик запросов http
|
||||
var map_zoom: int ## Уровень детализации карты
|
||||
var map_tile: Rect2i ## Область одной плитки: [x-координата области, y-координата области, x-индекс плитки, y-индекс плитки]
|
||||
var map_mode: int ## Режим карты: 0 - приоритет РТО, 1 - приоритет РЛС
|
||||
var prev_tiles_dic: Dictionary ##
|
||||
var lnglat: Array ## Текущие координаты
|
||||
var root_rect: Rect2i
|
||||
@export var az: float = 0.0:
|
||||
set(v):
|
||||
_xyz.z = v
|
||||
queue_redraw()
|
||||
get:
|
||||
return _xyz.z
|
||||
|
||||
|
||||
var _xyz: Vector3 = Vector3(0, 0, min_zoom_level)
|
||||
var _cache: Dictionary = {}
|
||||
var _queue: Dictionary = {}
|
||||
var _dragging: bool = false
|
||||
var _drag_pos: Vector2 = Vector2.ZERO
|
||||
var _last_cache_check: float = 0
|
||||
var _rollover: bool = false
|
||||
var _marks: Dictionary = {}
|
||||
var _req_count: = 0
|
||||
var image: = Image.new()
|
||||
var image_load_proc: Callable
|
||||
var now: = 0
|
||||
var spr_mask: = Sprite2D.new()
|
||||
var visible_marks_count: = 0
|
||||
var mouse_wheel_count: = 0
|
||||
var map_server_available: = false
|
||||
|
||||
|
||||
## Вызывается после того, как загрузка плиток завершена
|
||||
signal load_completed()
|
||||
|
||||
## Вызывается при запуске загрузки плиток
|
||||
signal load_started()
|
||||
|
||||
## Вызывается при получении ответа от сервера карт
|
||||
signal map_server_online()
|
||||
|
||||
## Вызывается при отсутствии ответа от сервера карт
|
||||
signal map_server_offline()
|
||||
|
||||
const image_load_proc_names = {
|
||||
'png': 'load_png_from_buffer',
|
||||
'jpg': 'load_jpg_from_buffer',
|
||||
'tga': 'load_tga_from_buffer',
|
||||
'webp': 'load_webp_from_buffer' }
|
||||
|
||||
|
||||
@export_enum('png', 'jpg', 'jpeg', 'tga', 'webp') var image_type: String = 'png':
|
||||
set(v): image_load_proc = Callable(image, image_load_proc_names[v])
|
||||
|
||||
|
||||
func _ready():
|
||||
lnglat = TEST_DATA['Таганрог']
|
||||
map_tile_state = TASK_STATE.DONE
|
||||
map_request = HTTPRequest.new()
|
||||
add_child(map_request)
|
||||
map_request.request_completed.connect(self._map_request_completed)
|
||||
map_bcs = ProjectSettings.get_setting('application/config/map_bcs', Vector3(1.0, 1.0, 1.0))
|
||||
map_server_addr = ProjectSettings.get_setting('application/config/map_server_addr')
|
||||
map_tile_format = ProjectSettings.get_setting('application/config/map_tile_format', '%s/%d/%d/%d.png')
|
||||
var map_image_size = ProjectSettings.get_setting(MAP_MODES[0], Vector2i(512, 512))
|
||||
var map_tile_size = ProjectSettings.get_setting('application/config/map_tile_size', 256)
|
||||
map_image = Image.create(map_image_size.x, map_image_size.y, true, Image.FORMAT_RGB8)
|
||||
map_tile = Rect2i(0, 0, map_tile_size, map_tile_size)
|
||||
signaller.connect('zoom_changed', Callable(self, '_on_zoom_changed'))
|
||||
signaller.connect('map_mode_changed', Callable(self, '_on_map_mode_changed'))
|
||||
log.info('Адрес сервера поставщика карт: \"%s\"' % map_server_addr)
|
||||
log.info('Модуль географической карты готов')
|
||||
$canvas.connect('mouse_entered', func(): _rollover = true)
|
||||
$canvas.connect('mouse_exited', func(): _rollover = false)
|
||||
_on_resize()
|
||||
image_type = 'png'
|
||||
spr_mask.name = StringName('spr_mask')
|
||||
spr_mask.material = CanvasItemMaterial.new()
|
||||
spr_mask.material.blend_mode = CanvasItemMaterial.BLEND_MODE_SUB
|
||||
spr_mask.add_to_group('gui_items')
|
||||
$canvas.add_child(spr_mask)
|
||||
|
||||
|
||||
func _on_map_mode_changed(mode: int) -> void:
|
||||
var map_image_size = ProjectSettings.get_setting(MAP_MODES[mode])
|
||||
material.set('shader_parameter/radius', MAP_RELATIVE_RADIUSES[mode])
|
||||
map_image.fill(Color(0, 0, 0, 0))
|
||||
map_image.resize(map_image_size.x, map_image_size.y)
|
||||
map_tile_state = TASK_STATE.DONE
|
||||
map_mode = mode
|
||||
var tile: = mercator.create_tile(lnglat[0], lnglat[1], map_zoom)
|
||||
map_tile_stack.clear()
|
||||
map_tile_stack.append(tile)
|
||||
prev_tiles_dic.clear()
|
||||
func _on_resize() -> void:
|
||||
var img_mask: = Image.create($canvas.size.x, $canvas.size.y, false, Image.FORMAT_RGBA8)
|
||||
var c = $canvas.size / 2.0
|
||||
var r = min($canvas.size.x, $canvas.size.y) / 2.0
|
||||
var color = Color.WHITE
|
||||
var sz = img_mask.get_size()
|
||||
for x in sz.x:
|
||||
for y in sz.y:
|
||||
var dist = c.distance_to(Vector2(x, y))
|
||||
color.a = smoothstep(r - 2.0, r + 2.0, dist)
|
||||
img_mask.set_pixel(x, y, color)
|
||||
spr_mask.texture = ImageTexture.create_from_image(img_mask)
|
||||
spr_mask.position = $canvas.position + $canvas.size / 2.0
|
||||
|
||||
|
||||
func mark_image_center(image: Image, color: Color = Color.RED):
|
||||
var c = image.get_size() / 2
|
||||
map_image.set_pixel(c.x - 1, c.y - 1, color)
|
||||
map_image.set_pixel(c.x - 1, c.y, color)
|
||||
map_image.set_pixel(c.x, c.y - 1, color)
|
||||
map_image.set_pixel(c.x, c.y, color)
|
||||
## Создаёт новую отметку из координат экрана
|
||||
func add_mark_from_screen_pos(id: int, x: float, y: float, mark: Node):
|
||||
if _marks.has(id):
|
||||
return false
|
||||
var wrld_pos = screen_to_world(_xyz, x, y)
|
||||
var p = world_to_tile(wrld_pos.x, wrld_pos.y, _xyz.z)
|
||||
var tile_index = xyz_to_idx(p.x, p.y, _xyz.z)
|
||||
var dot = { 'position': wrld_pos, 'tile_index': tile_index, 'mark': mark }
|
||||
_marks[id] = dot
|
||||
add_child(mark)
|
||||
fix_mark_position(dot)
|
||||
return true
|
||||
|
||||
|
||||
func _on_zoom_changed(zoom: int):
|
||||
if map_tile_stack.size() != 0:
|
||||
func get_marks_count(): return _marks.size()
|
||||
|
||||
|
||||
func delete_mark(id: int):
|
||||
if not _marks.has(id):
|
||||
return false
|
||||
_marks[id].mark.queue_free()
|
||||
_marks.erase(id)
|
||||
queue_redraw()
|
||||
|
||||
|
||||
## Создаёт новую отметку из долготы и широты
|
||||
func add_mark_from_lon_lat(id: int, lon: float, lat: float, mark: Node, gap_size: float = 32):
|
||||
if _marks.has(id):
|
||||
return false
|
||||
var wrld_pos = lonlat_to_world(lon, lat)
|
||||
var scr_pos = world_to_screen(wrld_pos.x, wrld_pos.y)
|
||||
mark.set_global_position(scr_pos)
|
||||
_marks[id] = {'position': wrld_pos, 'mark': mark, 'gap_size': gap_size }
|
||||
add_child(mark)
|
||||
queue_redraw()
|
||||
return true
|
||||
|
||||
|
||||
## Возвращает новую позицию для точки, если она выходит из поля видимости
|
||||
func fix_mark_position(dot):
|
||||
if is_mark_visible(dot):
|
||||
return
|
||||
map_zoom = zoom
|
||||
var tile: = mercator.create_tile(lnglat[0], lnglat[1], zoom)
|
||||
map_tile_stack.clear()
|
||||
map_tile_stack.append(tile)
|
||||
prev_tiles_dic.clear()
|
||||
var v = 2 * tile_width * pow(2, _xyz.z)
|
||||
if dot.position.x < _xyz.x - $canvas.size.x / v:
|
||||
dot.position.x = _xyz.x - $canvas.size.x / v
|
||||
elif dot.position.x > _xyz.x + $canvas.size.x / v:
|
||||
dot.position.x = _xyz.x + $canvas.size.x / v
|
||||
|
||||
|
||||
func img_tile_to_map_image(image: Image, dst_pos: Vector2i):
|
||||
image.adjust_bcs(map_bcs.x, map_bcs.y, map_bcs.z)
|
||||
map_image.blit_rect(image, map_tile, dst_pos)
|
||||
func is_mark_visible(dot):
|
||||
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 _process(_delta: float):
|
||||
if (map_tile_state == TASK_STATE.DONE) and map_tile_stack.size():
|
||||
var tile: mercator.Tile = map_tile_stack[-1]
|
||||
var tile_addr: = map_tile_format % [map_server_addr, tile.z, tile.x , tile.y]
|
||||
var rc = map_request.request(tile_addr)
|
||||
if rc == OK:
|
||||
map_tile_state = TASK_STATE.WAIT
|
||||
func _input(e):
|
||||
var lmp = get_local_mouse_position()
|
||||
if not _rollover:
|
||||
return
|
||||
if e is InputEventMouseButton:
|
||||
if e.pressed:
|
||||
if e.button_index == MOUSE_BUTTON_WHEEL_DOWN:
|
||||
mouse_wheel_count -= 1
|
||||
queue_redraw()
|
||||
elif e.button_index == MOUSE_BUTTON_WHEEL_UP:
|
||||
mouse_wheel_count += 1
|
||||
queue_redraw()
|
||||
|
||||
if e.button_index == MOUSE_BUTTON_LEFT:
|
||||
_dragging = e.pressed
|
||||
_drag_pos = screen_to_world(_xyz, lmp.x, lmp.y)
|
||||
|
||||
|
||||
elif e is InputEventMouseMotion:
|
||||
if _dragging:
|
||||
var wp = screen_to_world(_xyz, lmp.x, lmp.y)
|
||||
var diff = _drag_pos - wp
|
||||
_xyz.x += diff.x
|
||||
_xyz.y += diff.y
|
||||
queue_redraw()
|
||||
|
||||
|
||||
## Возвращает true, если видна область за краем карты
|
||||
func is_border_visible():
|
||||
var z = min(max_zoom_level, _xyz.z)
|
||||
return screen_to_tile(0, 0, z).y != 0
|
||||
|
||||
|
||||
func multiply_zoom(multiplier: float, pivot: Vector2):
|
||||
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)
|
||||
_xyz.x -= p2.x - p1.x
|
||||
_xyz.y -= p2.y - p1.y
|
||||
|
||||
|
||||
func set_zoom(zoom: float, pivot=null):
|
||||
if pivot == null:
|
||||
pivot = $canvas.size / 2.0
|
||||
|
||||
var p1: = screen_to_world(_xyz, pivot.x, pivot.y)
|
||||
_xyz.z = clampf(zoom, max_zoom_level, min_zoom_level)
|
||||
var p2: = screen_to_world(_xyz, pivot.x, pivot.y)
|
||||
_xyz.x -= p2.x - p1.x
|
||||
_xyz.y -= p2.y - p1.y
|
||||
|
||||
|
||||
func _draw():
|
||||
|
||||
var lmp = get_local_mouse_position()
|
||||
if mouse_wheel_count > 0:
|
||||
multiply_zoom(1.0 + zoom_step, lmp)
|
||||
mouse_wheel_count -= 1
|
||||
elif mouse_wheel_count < 0:
|
||||
multiply_zoom(1.0 - zoom_step, lmp)
|
||||
mouse_wheel_count += 1
|
||||
|
||||
var z = min(max_zoom_level, _xyz.z)
|
||||
var t1 = screen_to_tile(0, 0, z)
|
||||
var t2 = screen_to_tile($canvas.size.x, $canvas.size.y, z)
|
||||
for tx in range(t1.x, t2.x + 1):
|
||||
for ty in range(t1.y, t2.y + 1):
|
||||
_draw_tile(tx, ty, z)
|
||||
|
||||
var n = pow(2, z)
|
||||
var dx = n * tile_width
|
||||
var c = $canvas.size / 2.0
|
||||
var r = min($canvas.size.x, $canvas.size.y) / 2.0
|
||||
visible_marks_count = 0
|
||||
for dot in _marks.values():
|
||||
var pos = world_to_screen(dot.position.x, dot.position.y)
|
||||
if pos.x >= 0:
|
||||
pos.x = fmod(pos.x, dx)
|
||||
else:
|
||||
log.error('%s: Невозможно сформировать запрос HTTP' % self)
|
||||
map_tile_state = TASK_STATE.ERROR
|
||||
elif map_tile_state == TASK_STATE.CHECK:
|
||||
var root_tile: = mercator.Tile.new(root_rect.size.x, root_rect.size.y, map_zoom)
|
||||
var neighbors_tiles = mercator.get_perimetr_tiles(root_tile, (map_image.get_size().x / map_tile.size.x) / 2)
|
||||
var neighbors_tiles_dic = {}
|
||||
for tile in neighbors_tiles:
|
||||
neighbors_tiles_dic[[tile.x, tile.y]] = false
|
||||
if neighbors_tiles_dic != prev_tiles_dic:
|
||||
for tile in neighbors_tiles:
|
||||
tile.is_root = false
|
||||
map_tile_stack.push_front(tile)
|
||||
prev_tiles_dic[[tile.x, tile.y]] = false
|
||||
else:
|
||||
if map_tile_stack.size() == 0:
|
||||
signaller.emit_signal('zoom_complete', map_zoom)
|
||||
map_tile_state = TASK_STATE.DONE
|
||||
pos.x = -pos.x - 1
|
||||
pos.x = int(dx - 1) - fmod(pos.x, dx)
|
||||
dot.mark.position = pos
|
||||
dot.mark.visible = c.distance_to(pos) < (r - dot.gap_size)
|
||||
visible_marks_count += int(dot.mark.visible)
|
||||
|
||||
|
||||
func _map_request_completed(result, response_code, headers, data):
|
||||
func _clean_all():
|
||||
_queue.clear()
|
||||
_cache.clear()
|
||||
_marks.clear()
|
||||
_req_count = 0
|
||||
for c in get_children().filter(func (item): return not item.is_in_group('gui_items')):
|
||||
remove_child(c)
|
||||
c.queue_free()
|
||||
|
||||
|
||||
# get the tile from queue with the newest timestamp
|
||||
func get_next_in_queue():
|
||||
var tile = null
|
||||
for idx in _queue:
|
||||
var t = _queue.get(idx)
|
||||
if not tile or t.t > tile.t:
|
||||
tile = t
|
||||
return tile
|
||||
|
||||
|
||||
# delete oldest tiles from cache
|
||||
func _clean_cache():
|
||||
var overflow = _cache.size() - max_cached_tiles
|
||||
if overflow <= 0:
|
||||
return
|
||||
|
||||
var vals = _cache.values()
|
||||
vals.sort_custom(func(t1, t2): return t1.t < t2.t)
|
||||
for i in overflow:
|
||||
_cache.erase(vals[i].i)
|
||||
|
||||
|
||||
func _process(delta):
|
||||
now += delta
|
||||
|
||||
# if cache is overflowing - clean it
|
||||
if not _last_cache_check or now - _last_cache_check > 5:
|
||||
_last_cache_check = now
|
||||
_clean_cache()
|
||||
|
||||
while not _queue.is_empty() and (_req_count < max_concurrent_requests):
|
||||
|
||||
var tile = get_next_in_queue()
|
||||
if not tile:
|
||||
break
|
||||
|
||||
var req = HTTPRequest.new()
|
||||
_req_count += 1
|
||||
req.set_meta('tile', tile)
|
||||
add_child(req)
|
||||
req.name = NodePath(str(tile.i))
|
||||
|
||||
_queue.erase(tile.i)
|
||||
req.request_completed.connect(_response.bind(req, tile))
|
||||
|
||||
if req.request(tile.url) != OK:
|
||||
tile.t = now
|
||||
remove_child(req)
|
||||
req.queue_free()
|
||||
_req_count -= 1
|
||||
push_error('ошибка: запрос плитки \"%s\" не отправлен' % tile.url)
|
||||
if _queue.is_empty():
|
||||
emit_signal('load_completed')
|
||||
|
||||
|
||||
# result, response_code, headers, body
|
||||
func _response(result, code, _headers: Array, body: PackedByteArray, req, tile: Tile):
|
||||
|
||||
_req_count -= 1
|
||||
remove_child(req)
|
||||
req.queue_free()
|
||||
|
||||
if result != HTTPRequest.RESULT_SUCCESS:
|
||||
log.error('%s: Запрос не обработан. result: \"%s\", response_code: \"%s\", headers: \"%s\"' % [self, result, response_code, headers])
|
||||
map_tile_state = TASK_STATE.ERROR
|
||||
if map_server_available:
|
||||
map_server_available = false
|
||||
emit_signal('map_server_offline')
|
||||
_queue[tile.i] = tile
|
||||
return
|
||||
|
||||
var img_tile = Image.new()
|
||||
var error = img_tile.load_png_from_buffer(data)
|
||||
if error != OK:
|
||||
log.error('%s: Полученые данные невозможно использовать для формироания изображения. result: \"%s\", response_code: \"%s\", headers: \"%s\"' % [self, result, response_code, headers])
|
||||
map_tile_state = TASK_STATE.ERROR
|
||||
if not map_server_available:
|
||||
map_server_available = true
|
||||
emit_signal('map_server_online')
|
||||
|
||||
if code == 404:
|
||||
push_error('ошибка: на сервере нет \"%s\"' % tile.url)
|
||||
return
|
||||
|
||||
var tile = map_tile_stack.pop_back()
|
||||
map_tile_state = TASK_STATE.CHECK
|
||||
if Error.OK != image_load_proc.call(body):
|
||||
push_error('ошибка: не удалось получить изображение (неверный формат?) из \"%s\"' % tile.url)
|
||||
return
|
||||
|
||||
if tile.is_root:
|
||||
# Отображение корневой плитки
|
||||
map_image.fill(Color(0, 0, 0, 0))
|
||||
var bounds: = mercator.bounds(tile)
|
||||
var lng_c = (bounds.east + bounds.west) / 2.0
|
||||
var lat_c = (bounds.north + bounds.south) / 2.0
|
||||
var sx: float = float(map_tile.size.x) / (bounds.east - bounds.west) * (lng_c - tile.lng) + map_tile.size.x / 2.0 # Cмещение в пискселях центра плитки от заданной точки по горизонтали.
|
||||
var sy: float = float(map_tile.size.y) / (bounds.north - bounds.south) * (lat_c - tile.lat) - map_tile.size.y / 2.0 # Cмещение в пискселях центра плитки от заданной точки по вертикали.
|
||||
var dst_pos: Vector2i = Vector2i(int(sx), int(-sy)) + map_tile.size * map_mode
|
||||
img_tile_to_map_image(img_tile, dst_pos)
|
||||
root_rect = Rect2i(dst_pos.x, dst_pos.y, tile.x, tile.y)
|
||||
# create texture from image and add it to the cache
|
||||
tile.texture = ImageTexture.create_from_image(image)
|
||||
_cache[tile.i] = tile
|
||||
|
||||
# redraw the map
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _draw_subtile(tx: int, ty: int, tz: int, origx: int, origy: int, origz: float) -> bool:
|
||||
var subtile = get_tile(tx, ty, tz)
|
||||
if not subtile:
|
||||
return false
|
||||
|
||||
var p1 = tile_to_screen(origx, origy, origz)
|
||||
var p2 = tile_to_screen(origx + 1, origy + 1, origz)
|
||||
var x1 = tile_to_screen(tx, ty, tz)
|
||||
var x2 = tile_to_screen(tx + 1, ty + 1, tz)
|
||||
|
||||
var xdiff = x2.x - x1.x
|
||||
var xrat1 = (p1.x - x1.x) / xdiff
|
||||
var xrat2 = (p2.x - x1.x) / xdiff
|
||||
var xwidth = xrat2 - xrat1
|
||||
|
||||
var ydiff = x2.y - x1.y
|
||||
var yrat1 = (p1.y - x1.y) / ydiff
|
||||
var yrat2 = (p2.y - x1.y) / ydiff
|
||||
var yheight = yrat2 - yrat1
|
||||
|
||||
var rect = Rect2(xrat1 * tile_width, yrat1 * tile_height, xwidth * tile_width, yheight * tile_height)
|
||||
if subtile.texture:
|
||||
draw_texture_rect_region(subtile.texture, Rect2(p1, p2 - p1), rect)
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func _draw_tile(tx: int, ty: int, z: float):
|
||||
var tz = floor(z)
|
||||
var p1 = tile_to_screen(tx, ty, z)
|
||||
var p2 = tile_to_screen(tx + 1, ty + 1, z)
|
||||
var tile = get_tile(tx, ty, tz)
|
||||
if tile:
|
||||
if tile.texture:
|
||||
draw_texture_rect(tile.texture, Rect2(p1, p2 - p1), false, Color.WHITE, false)
|
||||
else:
|
||||
var zzz = tz
|
||||
var txx = tx
|
||||
var tyy = ty
|
||||
while zzz > 1:
|
||||
zzz -= 1
|
||||
txx = floor(txx / 2.0)
|
||||
tyy = floor(tyy / 2.0)
|
||||
if _draw_subtile(txx, tyy, zzz, tx, ty,z):
|
||||
break
|
||||
|
||||
|
||||
## convert lon/lat to world coords
|
||||
func lonlat_to_world(lon: float, lat: float) -> Vector2:
|
||||
var x = lon / 180.0
|
||||
var latsin = sin(deg_to_rad(lat) * sign(lat))
|
||||
var y = (sign(lat) * (log((1.0 + latsin) / (1.0 - latsin)) / 2.0)) / PI
|
||||
return Vector2(x, y)
|
||||
|
||||
|
||||
## convert lon/lat to screen coords
|
||||
func lonlat_to_screen(lon: float, lat: float) -> Vector2:
|
||||
var w = lonlat_to_world(lon, lat)
|
||||
return world_to_screen(w.x, w.y)
|
||||
|
||||
|
||||
## convert lon/lat to tile coords
|
||||
func lonlat_to_tile(lon: float, lat: float, z: float) -> Vector2:
|
||||
var w = lonlat_to_world(lon,lat)
|
||||
return world_to_tile(w.x, w.y, z)
|
||||
|
||||
|
||||
## convert world coords to lon/lat
|
||||
func world_to_lonlat(wx: float, wy: float) -> Vector2:
|
||||
var lon = wx * 180.0
|
||||
var lat = rad_to_deg(atan(sinh(wy * PI)))
|
||||
return Vector2(lon, lat)
|
||||
|
||||
|
||||
## convert screen coords to lon/lat
|
||||
func screen_to_lonlat(sx: float, sy: float) -> Vector2:
|
||||
var w = screen_to_world(_xyz, sx, sy)
|
||||
return world_to_lonlat(w.x, w.y)
|
||||
|
||||
|
||||
## convert tile coords to lon/lat
|
||||
func tile_to_lonlat(tx: float, ty: float, tz: float) -> Vector2:
|
||||
var w = tile_to_world(tx, ty, tz)
|
||||
return world_to_lonlat(w.x, w.y)
|
||||
|
||||
|
||||
## convert screen coords to world coords
|
||||
func screen_to_world(xyz: Vector3, sx: float, sy: float) -> Vector2:
|
||||
var n = pow(2.0, xyz.z)
|
||||
var span_w = n * tile_width
|
||||
var span_h = n * tile_height
|
||||
var px = sx - $canvas.size.x / 2 + span_w / 2
|
||||
var py = sy - $canvas.size.y / 2 + span_h / 2
|
||||
var xr = px / span_w
|
||||
var yr = py / span_h
|
||||
var x = (xr * 2.0 - 1.0) + xyz.x
|
||||
var y = ((-yr * 2.0) + 1.0) + xyz.y
|
||||
return Vector2(x, y)
|
||||
|
||||
|
||||
## convert screen coords to tile coords
|
||||
func screen_to_tile(sx: float, sy: float, z: float) -> Vector2:
|
||||
var world = screen_to_world(_xyz, sx, sy)
|
||||
return world_to_tile(world.x, world.y, z)
|
||||
|
||||
|
||||
## convert tile coords to screen coords
|
||||
func tile_to_screen(tx: float, ty: float, tz: float) -> Vector2:
|
||||
var w = tile_to_world(tx, ty, tz)
|
||||
return world_to_screen(w.x, w.y)
|
||||
|
||||
|
||||
## convert tile coords to world coords
|
||||
func tile_to_world(tx: float, ty: float, tz: float) -> Vector2:
|
||||
var n = pow(2.0, floor(tz))
|
||||
var x = (tx / n) * 2.0 - 1.0
|
||||
var y = -((ty / n) * 2.0 - 1.0)
|
||||
return Vector2(x, y)
|
||||
|
||||
|
||||
## convert world coords to tile coords
|
||||
func world_to_tile(wx: float, wy: float, z: float) -> Vector2:
|
||||
var n: = pow(2.0, floor(z))
|
||||
var tx: = ((wx + 1.0) / 2.0) * n
|
||||
var ty: = ((-wy + 1.0) / 2.0) * n
|
||||
tx = floor(tx)
|
||||
ty = floor(ty)
|
||||
return Vector2(tx, ty)
|
||||
|
||||
|
||||
## convert world coords to screen coords
|
||||
func world_to_screen(wx: float, wy: float) -> Vector2:
|
||||
var n: = pow(2.0, _xyz.z)
|
||||
var w: = n * tile_width
|
||||
var h: = n * tile_height
|
||||
var xr: = ((wx - _xyz.x) + 1.0) / 2.0
|
||||
var yr: = (-(wy - _xyz.y) + 1.0) / 2.0
|
||||
var x = w * xr - w / 2.0 + $canvas.size.x / 2.0
|
||||
var y = h * yr - h / 2.0 + $canvas.size.y / 2.0
|
||||
return Vector2(x, y)
|
||||
|
||||
|
||||
## get the tile index from xyz tile coords
|
||||
func xyz_to_idx(x: float, y: float, z: float) -> int:
|
||||
var i: = (pow(4.0, z) - 1.0) / 3.0
|
||||
var n: = pow(2.0, z)
|
||||
return int(i + (y * n + x))
|
||||
|
||||
|
||||
func get_tile(x: int, y: int, z: int, create: bool = true) -> Tile:
|
||||
|
||||
var n = pow(2, z)
|
||||
if x >= 0:
|
||||
x %= int(n)
|
||||
else:
|
||||
# Отображение соседних плиток
|
||||
var delta: = Vector2i(tile.x - root_rect.size.x, tile.y - root_rect.size.y)
|
||||
var dst_pos: Vector2i = root_rect.position + delta * map_tile.size
|
||||
img_tile_to_map_image(img_tile, dst_pos)
|
||||
mark_image_center(map_image)
|
||||
texture = ImageTexture.create_from_image(map_image)
|
||||
x = -x - 1
|
||||
x = int(n - 1) - (x % int(n))
|
||||
|
||||
# out of bounds
|
||||
if z < 0 or y < 0 or y >= n:
|
||||
return null
|
||||
|
||||
# get tile index
|
||||
var idx = xyz_to_idx(x, y, z)
|
||||
var tile = null
|
||||
|
||||
# retrieve from current requests...
|
||||
var req = get_node_or_null(NodePath(str(idx)))
|
||||
if req:
|
||||
tile = req.get_meta('tile')
|
||||
tile.t = now
|
||||
return tile
|
||||
|
||||
# retrieve from cache
|
||||
tile = _cache.get(idx)
|
||||
if tile:
|
||||
tile.t = now
|
||||
return tile
|
||||
|
||||
# retrieve from queue
|
||||
tile = _queue.get(idx)
|
||||
if tile:
|
||||
tile.t = now
|
||||
return tile
|
||||
|
||||
# create a new tile - add it to queue
|
||||
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 queue_size == 0 and _queue.size():
|
||||
emit_signal('load_started')
|
||||
|
||||
return tile
|
||||
|
||||
|
||||
func lonlat_to_dms(lon: float, lat: float) -> String:
|
||||
var pf = 'N' if lat >= 0 else 'S'
|
||||
lat = abs(lat)
|
||||
var deg = floor(lat)
|
||||
var minute = (lat - deg) * 60
|
||||
var second = (minute - floor(minute)) * 60
|
||||
var text = ('%02d' % deg) + ('%02d' % floor(minute)) + ('%02d' % floor(second)) + pf + ' '
|
||||
|
||||
pf = 'E' if lon >= 0 else 'W'
|
||||
lon = abs(lon)
|
||||
deg = floor(lon)
|
||||
minute = (lon - deg) * 60
|
||||
second = (minute - floor(minute)) * 60
|
||||
text += ('%02d' % deg) + ('%02d' % floor(minute)) + ('%02d' % floor(second)) + pf
|
||||
|
||||
return text
|
||||
|
||||
|
||||
class Tile:
|
||||
var i: int = 0
|
||||
var x: int = 0
|
||||
var y: int = 0
|
||||
var z: int = 0
|
||||
var t: int = 0
|
||||
var url: String = ''
|
||||
var texture: Texture2D = null
|
||||
|
||||
func _init(i0: int, x0: int, y0: int, z0: int):
|
||||
self.i = i0
|
||||
self.x = x0
|
||||
self.y = y0
|
||||
self.z = z0
|
||||
|
||||
|
||||
func haversine_m(lat1, lon1, lat2, lon2):
|
||||
# Радиус Земли в метрах
|
||||
var R: = 6372795.0
|
||||
# Преобразование градусов в радианы
|
||||
var rlat1: = deg_to_rad(lat1)
|
||||
var rlon1: = deg_to_rad(lon1)
|
||||
var rlat2: = deg_to_rad(lat2)
|
||||
var rlon2: = deg_to_rad(lon2)
|
||||
var cl1: = cos(rlat1)
|
||||
var cl2: = cos(rlat2)
|
||||
var sl1: = sin(rlat1)
|
||||
var sl2: = sin(rlat2)
|
||||
var delta: = rlon2 - rlon1
|
||||
var cdelta: = cos(delta)
|
||||
var sdelta: = sin(delta)
|
||||
# вычисления длины большого круга
|
||||
var y: = sqrt(pow(cl2 * sdelta, 2) + pow(cl1 * sl2 - sl1 * cl2 * cdelta, 2))
|
||||
var x: = sl1 * sl2 + cl1 * cl2 * cdelta
|
||||
var ad: = atan2(y, x)
|
||||
var dist: = ad * R
|
||||
return dist
|
||||
|
||||
|
||||
func remove_closest_dot(screen_pos):
|
||||
var closest_dot = find_at_screen_position(screen_pos)
|
||||
if not closest_dot:
|
||||
return
|
||||
remove_child(closest_dot.mark)
|
||||
closest_dot.mark.queue_free()
|
||||
_marks.erase(closest_dot)
|
||||
|
||||
|
||||
func find_at_screen_position(screen_pos: Vector2):
|
||||
var closest_dot = null
|
||||
var closest_distance = INF
|
||||
for mark in _marks.values():
|
||||
var dot_screen_pos = world_to_screen(mark.position.x, mark.position.y)
|
||||
var distance = dot_screen_pos.distance_to(screen_pos)
|
||||
if distance < closest_distance:
|
||||
closest_distance = distance
|
||||
closest_dot = mark
|
||||
return closest_dot
|
||||
|
||||
|
||||
func clear() -> void:
|
||||
_clean_all()
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func set_coordinates(lon: float, lat: float):
|
||||
var anim: Animation = $canvas/player.get_animation('goto')
|
||||
var wrld_pos = lonlat_to_world(lon, lat)
|
||||
|
||||
anim.track_insert_key(0, 0, _xyz.x)
|
||||
anim.track_insert_key(1, 0, _xyz.y)
|
||||
|
||||
anim.track_insert_key(0, animation_time, wrld_pos.x)
|
||||
anim.track_insert_key(1, animation_time, wrld_pos.y)
|
||||
|
||||
anim.length = animation_time
|
||||
$canvas/player.play('goto')
|
||||
|
||||
|
||||
func blend_mask(val: bool) -> void:
|
||||
spr_mask.visible = val
|
||||
queue_redraw()
|
||||
|
||||
@@ -1,14 +1,27 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://bbq6nklh36yij"]
|
||||
[gd_scene load_steps=3 format=3 uid="uid://ceknxxfu1loo5"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/tilemap/tilemap.gd" id="1_mkfgj"]
|
||||
[ext_resource type="Shader" path="res://shaders/tilemap.gdshader" id="1_tsdui"]
|
||||
[ext_resource type="Script" path="res://scenes/tilemap/tilemap.gd" id="1_l64tp"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_pmqvj"]
|
||||
resource_local_to_scene = true
|
||||
shader = ExtResource("1_tsdui")
|
||||
shader_parameter/radius = 0.39
|
||||
[sub_resource type="CanvasTexture" id="CanvasTexture_58cl1"]
|
||||
|
||||
[node name="tilemap" type="Sprite2D"]
|
||||
material = SubResource("ShaderMaterial_pmqvj")
|
||||
position = Vector2(560, 560)
|
||||
script = ExtResource("1_mkfgj")
|
||||
[node name="tilemap" type="CanvasGroup" groups=["gui_items"]]
|
||||
script = ExtResource("1_l64tp")
|
||||
max_zoom_level = 21
|
||||
az = 2.0
|
||||
|
||||
[node name="canvas" type="TextureRect" parent="." groups=["gui_items"]]
|
||||
clip_contents = true
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 400.0
|
||||
offset_bottom = 400.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = SubResource("CanvasTexture_58cl1")
|
||||
|
||||
[node name="player" type="AnimationPlayer" parent="canvas" groups=["gui_items"]]
|
||||
|
||||
[connection signal="resized" from="canvas" to="." method="_on_resize"]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
extends Panel
|
||||
class_name setting extends Panel
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
## Вызывается, когда узел впервые попадает в дерево сцены.
|
||||
func _ready() -> void:
|
||||
$lbl_commit.text = 'Текущая версия ПО УАРЭП: \"%s\"' % commit.VCS_HEAD
|
||||
if not OS.get_cmdline_args().has('++ограниченный'):
|
||||
|
||||
@@ -244,9 +244,9 @@ text = "Управление элементами в режиме с огран
|
||||
|
||||
[node name="Label2" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 16.0
|
||||
offset_left = 20.0
|
||||
offset_top = 20.0
|
||||
offset_right = 476.0
|
||||
offset_right = 445.0
|
||||
offset_bottom = 50.0
|
||||
text = "Текущий режим доступа: полный"
|
||||
vertical_alignment = 1
|
||||
@@ -295,13 +295,13 @@ text = "Кнопка «Подавление».
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
disabled = true
|
||||
|
||||
[node name="lbl_commit" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 480.0
|
||||
offset_left = 500.0
|
||||
offset_top = 20.0
|
||||
offset_right = 1040.0
|
||||
offset_right = 1060.0
|
||||
offset_bottom = 50.0
|
||||
text = "Текущая версия ПО УАРЭП:"
|
||||
vertical_alignment = 1
|
||||
|
||||
@@ -1,43 +1,44 @@
|
||||
@tool
|
||||
|
||||
extends Panel
|
||||
class_name work extends Panel
|
||||
|
||||
## Основной скрипт для режима "Работа"
|
||||
## Основной скрипт для режима "Работа".
|
||||
|
||||
@export var Bip: PackedScene ## Индикатор излучения цели
|
||||
@export var col_grey: Color ## Второй цвет для фона
|
||||
@export var col_red: Color ## Первый цвет для фона
|
||||
@export var drag_scale_band: float ## Масштаб изменения параметра от движения мыши для строба по радиальному размеру
|
||||
@export var drag_scale_width: float ## Масштаб изменения параметра от движения мыши для строба по угловому размеру
|
||||
@export var Bip: PackedScene ## Индикатор излучения цели.
|
||||
@export var col_grey: Color ## Второй цвет для фона.
|
||||
@export var col_red: Color ## Первый цвет для фона.
|
||||
@export var drag_scale_band: float ## Масштаб изменения параметра от движения мыши для строба по радиальному размеру.
|
||||
@export var drag_scale_width: float ## Масштаб изменения параметра от движения мыши для строба по угловому размеру.
|
||||
@export var freq_high: float ## Верхняя рабочая частота, МГЦ.
|
||||
@export var freq_low: float ## Нижняя рабочая частота, МГЦ.
|
||||
@export var radius_center: Vector2 ## Координаты центра диаграммы пеленг-частота
|
||||
@export var radius_internal: float ## Внутренний радиус диаграммы пеленг-частота
|
||||
@export var radius_outter: float ## Внешний радиус диаграммы пеленг-частота
|
||||
@export var strob_max_band: float ## Максимальная ширина строба по углу
|
||||
@export var strob_max_width: float ## Максимальная ширина строба по углу
|
||||
@export var strob_min_band: float ## Минимальная ширина строба по частоте
|
||||
@export var strob_min_width: float ## Минимальная ширина строба по углу
|
||||
@export var window_0_id: int ## Идетификатор окна. Присваивается godot от 0 до количества созданных окон
|
||||
@export var radius_center: Vector2 ## Координаты центра диаграммы пеленг-частота.
|
||||
@export var radius_internal: float ## Внутренний радиус диаграммы пеленг-частота.
|
||||
@export var radius_outter: float ## Внешний радиус диаграммы пеленг-частота.
|
||||
@export var strob_max_band: float ## Максимальная ширина строба по углу.
|
||||
@export var strob_max_width: float ## Максимальная ширина строба по углу.
|
||||
@export var strob_min_band: float ## Минимальная ширина строба по частоте.
|
||||
@export var strob_min_width: float ## Минимальная ширина строба по углу.
|
||||
@export var window_0_id: int ## Идетификатор окна. Присваивается godot от 0 до количества созданных окон.
|
||||
|
||||
|
||||
var drag_button: MouseButton ## Кнопка мыши нажатая при перетаскивании
|
||||
var drag_fsm: DragFSM = DragFSM.IDLE ## Текущее состояние перетаскивания
|
||||
var btn_select: BtnSel = BtnSel.THREAT ## Текущее состояние кнопки выбора цели
|
||||
var drag_pos_begin: Vector2 ## Точка начала перетаскивания
|
||||
var max_zoom: int ## Максимальный уровень детализации
|
||||
var min_zoom: int ## Минимальный уровень детализации
|
||||
var shift_pressed: bool ## Кнопка SHIFT нажата
|
||||
var strob_band_begin: float ## Ширина строба в момент начала перетаскивания
|
||||
var strob_dir_begin: float ## Направление антенны в момент начала перетаскивания
|
||||
var strob_width_begin: float ## Ширина строба по углу в момент начала перетаскивания
|
||||
var drag_button: MouseButton ## Кнопка мыши нажатая при перетаскивании.
|
||||
var drag_fsm: DragFSM = DragFSM.IDLE ## Текущее состояние перетаскивания.
|
||||
var btn_select: BtnSel = BtnSel.THREAT ## Текущее состояние кнопки выбора цели.
|
||||
var drag_pos_begin: Vector2 ## Точка начала перетаскивания.
|
||||
var max_zoom: int ## Максимальный уровень детализации.
|
||||
var min_zoom: int ## Минимальный уровень детализации.
|
||||
var shift_pressed: bool ## Кнопка SHIFT нажата.
|
||||
var strob_band_begin: float ## Ширина строба в момент начала перетаскивания.
|
||||
var strob_dir_begin: float ## Направление антенны в момент начала перетаскивания.
|
||||
var strob_width_begin: float ## Ширина строба по углу в момент начала перетаскивания.
|
||||
|
||||
|
||||
signal drag_begin ## Вызывается в момент начала перетаскивания
|
||||
signal drag_continue ## Вызывается во время продолжения перетаскивания
|
||||
signal drag_end ## Вызывается в момент завершения перетаскивания
|
||||
signal drag_begin ## Вызывается в момент начала перетаскивания.
|
||||
signal drag_continue ## Вызывается во время продолжения перетаскивания.
|
||||
signal drag_end ## Вызывается в момент завершения перетаскивания.
|
||||
|
||||
## Границы секторов блоков ФС по частоте в режиме РТО
|
||||
|
||||
## Границы секторов блоков ФС по частоте в режиме РТО.
|
||||
const fs_band_rto: Dictionary = {
|
||||
0: [200.0, 250.0],
|
||||
1: [250.0, 300.0],
|
||||
@@ -47,7 +48,7 @@ const fs_band_rto: Dictionary = {
|
||||
5: [450.0, 500.0],
|
||||
6: [500.0, 550.0] }
|
||||
|
||||
## Границы секторов блоков ФС по частоте в режиме РЛС
|
||||
## Границы секторов блоков ФС по частоте в режиме РЛС.
|
||||
const fs_band_rls: Dictionary = {
|
||||
0: [480.0, 490.0],
|
||||
1: [490.0, 500.0],
|
||||
@@ -57,7 +58,7 @@ const fs_band_rls: Dictionary = {
|
||||
5: [530.0, 540.0],
|
||||
6: [540.0, 550.0] }
|
||||
|
||||
## Границы секторов блоков ФС по пеленгу
|
||||
## Границы секторов блоков ФС по пеленгу.
|
||||
const fs_sectors: Dictionary = {
|
||||
0: [0.0, 90.0],
|
||||
3: [90.0, 180.0],
|
||||
@@ -73,42 +74,52 @@ const fs_freq: Dictionary = {
|
||||
5: [4400.0, 5200.0],
|
||||
6: [5200.0, 6000.0] }
|
||||
|
||||
var fs_band = fs_band_rto # Текущий режим блоков ФС по частоте
|
||||
var fs_selected: Dictionary # Словарь выбранных секторов
|
||||
var fs_active: Dictionary # Словарь секторов назначенных на подавление
|
||||
|
||||
## Состояние перетаскивания
|
||||
## Размеры карты для разных режимов РТО и РЛС соответственно
|
||||
const map_sizes = [
|
||||
Rect2i(360, 360, 400, 400),
|
||||
Rect2i(82, 82, 955, 955)]
|
||||
var fs_band = fs_band_rto ## Текущий режим блоков ФС по частоте
|
||||
var fs_selected: Dictionary ## Словарь выбранных секторов
|
||||
var fs_active: Dictionary ## Словарь секторов назначенных на подавление
|
||||
|
||||
## Состояние перетаскивания.
|
||||
enum DragFSM {
|
||||
DRAG, ## В процессе
|
||||
IDLE, ## Не активно, ожидание
|
||||
OFF ## Выключено
|
||||
DRAG, ## В процессе.
|
||||
IDLE, ## Не активно, ожидание.
|
||||
OFF ## Выключено.
|
||||
}
|
||||
|
||||
## Состояние перетаскивания
|
||||
## Состояние перетаскивания.
|
||||
enum BtnSel {
|
||||
SECTOR, ## В процессе
|
||||
THREAT, ## Не активно, ожидание
|
||||
FS ## Выключено
|
||||
SECTOR, ## В процессе.
|
||||
THREAT, ## Не активно, ожидание.
|
||||
FS ## Выключено.
|
||||
}
|
||||
|
||||
## Обработчик сигнала изменения списка целей
|
||||
|
||||
## Обработчик сигнала изменения списка целей.
|
||||
func on_threats_resized(threats: Dictionary): $count_all_pad/count_all.text = '%02d' % threats.size()
|
||||
|
||||
|
||||
## Обработчик выбора цели
|
||||
## Обработчик выбора цели.
|
||||
func on_threat_selected(th, ecm_btns): on_rto_threat_sel(th.id, ecm_btns)
|
||||
|
||||
|
||||
## Обработчик нажатия на кнопку вид
|
||||
## Встроенный обратный вызов.
|
||||
func on_enter_tree() -> void: call_deferred('on_button_strobe_pressed')
|
||||
|
||||
|
||||
## Обработчик нажатия на кнопку вид.
|
||||
func on_button_view_toggled(toggled: bool):
|
||||
signaller.emit_signal('map_mode_changed', int(toggled))
|
||||
if toggled:
|
||||
fs_band = fs_band_rls
|
||||
else:
|
||||
fs_band = fs_band_rto
|
||||
fs_band = fs_band_rls if toggled else fs_band_rto
|
||||
var s = map_sizes[int(toggled)]
|
||||
$tilemap.size = s.size
|
||||
$tilemap.position = s.position
|
||||
|
||||
|
||||
##
|
||||
## Встроенный обратный вызов.
|
||||
func _enter_tree() -> void:
|
||||
var timer1 = Timer.new()
|
||||
timer1.name = 'timer1'
|
||||
@@ -118,18 +129,18 @@ func _enter_tree() -> void:
|
||||
timer1.start(1.0)
|
||||
|
||||
|
||||
## Встроенный обратный вызов.
|
||||
func _exit_tree() -> void:
|
||||
var timer1 = get_node('timer1')
|
||||
remove_child(timer1)
|
||||
timer1.queue_free()
|
||||
|
||||
|
||||
## Производит инициализацию
|
||||
## Производит инициализацию.
|
||||
func _ready():
|
||||
min_zoom = ProjectSettings.get_setting('application/config/map_minimum_zoom', 5)
|
||||
max_zoom = ProjectSettings.get_setting('application/config/map_maximum_zoom', 19)
|
||||
drag_fsm = DragFSM.OFF
|
||||
$btn_zoom.set_meta('zoom', min_zoom - 1)
|
||||
var btns_select: Array = $btns_select.get_children()
|
||||
btns_select.any(func(btn): btn.button_connect('pressed', Callable(self, 'on_button_select').bind(btn, btns_select)))
|
||||
$btn_view.button_connect('toggled', Callable(self, 'on_button_view_toggled'))
|
||||
@@ -139,7 +150,6 @@ func _ready():
|
||||
threats.connect('threat_lost', Callable(self, 'on_threat_lost'))
|
||||
threats.connect('threats_resized', Callable(self, 'on_threats_resized'))
|
||||
threats.connect('threat_update', Callable(self, 'on_threat_update'))
|
||||
signaller.connect('zoom_complete', Callable(self, '_on_zoom_complete'))
|
||||
signaller.connect('rto_threat_sel', Callable(self, 'on_rto_threat_sel').bind(nodes))
|
||||
signaller.connect('bip_pressed', Callable(self, 'on_bip_pressed').bind(nodes))
|
||||
signaller.connect('rto_threat_unsel', Callable(self, 'on_rto_threat_unsel').bind(nodes))
|
||||
@@ -151,13 +161,15 @@ func _ready():
|
||||
interfer.connect('interfer_update', Callable(self, 'on_interfer_new'))
|
||||
|
||||
|
||||
func on_enter_tree() -> void:
|
||||
call_deferred('_on_btn_scale_pressed')
|
||||
call_deferred('on_button_strobe_pressed')
|
||||
$tilemap.position = $canvas.get_strob_center()
|
||||
func get_all_nodes(root):
|
||||
var nodes = []
|
||||
nodes.append(root)
|
||||
for child in root.get_children():
|
||||
nodes.append_array(get_all_nodes(child))
|
||||
return nodes
|
||||
|
||||
|
||||
## Производит отображение цели на диаграмму
|
||||
## Производит отображение цели на диаграмму.
|
||||
func map_threat_to_bip(th: threats.Threat, bip: Control):
|
||||
bip.position = tools.pos_calc(
|
||||
th.freq,
|
||||
@@ -169,13 +181,14 @@ func map_threat_to_bip(th: threats.Threat, bip: Control):
|
||||
freq_high) - bip.size / 2
|
||||
|
||||
|
||||
## Обработчик сигнала обновления цели
|
||||
## Обработчик сигнала обновления цели.
|
||||
func on_threat_update(th):
|
||||
var bip = get_node('%d' % th.id)
|
||||
bip.update()
|
||||
map_threat_to_bip(th, bip)
|
||||
|
||||
|
||||
## Обработчик выбора помехи для цели
|
||||
## Обработчик выбора помехи для цели.
|
||||
func on_interfer_new(ecm):
|
||||
if interfer.thrs.has(ecm.ispp):
|
||||
if interfer.thrs.has(ecm.ispp):
|
||||
@@ -192,7 +205,7 @@ func on_interfer_new(ecm):
|
||||
set_fs_color(ecm)
|
||||
|
||||
|
||||
## Обработчик выключения всех помех
|
||||
## Обработчик выключения всех помех.
|
||||
func on_interfer_off_all():
|
||||
var bips: Array = get_children().filter(func(item): return item.name.is_valid_int())
|
||||
for bip in bips:
|
||||
@@ -202,7 +215,7 @@ func on_interfer_off_all():
|
||||
update_fs_colors()
|
||||
|
||||
|
||||
## Обработчик сигнала обнаружения цели
|
||||
## Обработчик сигнала обнаружения цели.
|
||||
func on_threat_new(th) -> void:
|
||||
var bip = Bip.instantiate()
|
||||
bip.name = '%d' % th.id
|
||||
@@ -210,20 +223,20 @@ func on_threat_new(th) -> void:
|
||||
add_child(bip)
|
||||
|
||||
|
||||
## Обработчик сигнала потери цели
|
||||
## Обработчик сигнала потери цели.
|
||||
func on_threat_lost(th) -> void:
|
||||
var bip = get_node('%d' % th.id)
|
||||
remove_child(bip)
|
||||
bip.free()
|
||||
|
||||
|
||||
## обработчик нажатия на цель на экране
|
||||
## обработчик нажатия на цель на экране.
|
||||
func on_bip_pressed(th_id, _ecm_btns):
|
||||
if btn_select == BtnSel.THREAT:
|
||||
signaller.emit_signal('rto_threat_sel', th_id)
|
||||
|
||||
|
||||
## Обработчик выбора РТО цели
|
||||
## Обработчик выбора РТО цели.
|
||||
func on_rto_threat_sel(th_id, ecm_btns):
|
||||
var bips: Array = get_children().filter(func(item): return item.name.is_valid_int())
|
||||
for item in bips:
|
||||
@@ -236,7 +249,7 @@ func on_rto_threat_sel(th_id, ecm_btns):
|
||||
set_btns_disabled(false, btn)
|
||||
|
||||
|
||||
## Обработчик снятия выбора РТО цели
|
||||
## Обработчик снятия выбора РТО цели.
|
||||
func on_rto_threat_unsel(th_id, _ecm_btns):
|
||||
var bips: Array = get_children().filter(func(item): return item.name.is_valid_int())
|
||||
for item in bips:
|
||||
@@ -246,13 +259,13 @@ func on_rto_threat_unsel(th_id, _ecm_btns):
|
||||
set_ecm_btns_state(true)
|
||||
|
||||
|
||||
## Обработчик нажатия кнопки "Строб". Управляет отображением строба
|
||||
## Обработчик нажатия кнопки "Строб". Управляет отображением строба.
|
||||
func on_button_strobe_pressed() -> void:
|
||||
drag_fsm = DragFSM.IDLE if $btns_select/btn_strob.is_pressed() else DragFSM.OFF
|
||||
$canvas.set_strob_visible(drag_fsm == DragFSM.IDLE)
|
||||
|
||||
|
||||
## Поведение радиокнопок в группе. Управляет состоянием кнопок выбора целей
|
||||
## Поведение радиокнопок в группе. Управляет состоянием кнопок выбора целей.
|
||||
func on_button_select(btn_this, btn_others) -> void:
|
||||
for btn_other in btn_others: btn_other.set_pressed(btn_this == btn_other)
|
||||
btn_select = btn_this.get_meta('state')
|
||||
@@ -262,7 +275,7 @@ func on_button_select(btn_this, btn_others) -> void:
|
||||
set_ecm_btns_state(true)
|
||||
|
||||
|
||||
## Поведение радиокнопок в группе. Управляет состоянием кнопок в радиогруппе
|
||||
## Поведение радиокнопок в группе. Управляет состоянием кнопок в радиогруппе.
|
||||
func on_button_pressed(btn_this, btn_others) -> void:
|
||||
var fs_arr: Array = []
|
||||
for btn_other in btn_others: btn_other.set_pressed(btn_this == btn_other)
|
||||
@@ -271,7 +284,7 @@ func on_button_pressed(btn_this, btn_others) -> void:
|
||||
signaller.emit_signal('interfer_init', btn_this, fs_arr)
|
||||
|
||||
|
||||
## Управляет состоянием кнопок в радиогруппе при выборе помехи
|
||||
## Управляет состоянием кнопок в радиогруппе при выборе помехи.
|
||||
func on_interfer_selected(ecm, btns) -> void:
|
||||
var ecm_name: String
|
||||
if ecm != null:
|
||||
@@ -287,21 +300,21 @@ func on_interfer_selected(ecm, btns) -> void:
|
||||
btn.set_pressed(false)
|
||||
|
||||
|
||||
## Возвращает ширину строба по направлению
|
||||
## Возвращает ширину строба по направлению.
|
||||
func get_strob_width(pos: Vector2, prev: float) -> float:
|
||||
var strob_dir_width: float = prev + (drag_pos_begin.y - pos.y) * drag_scale_width
|
||||
strob_dir_width = tools.clip_value(strob_dir_width, strob_min_width, strob_max_width)
|
||||
return strob_dir_width
|
||||
|
||||
|
||||
## Возвращает ширину строба по частоте
|
||||
## Возвращает ширину строба по частоте.
|
||||
func get_strob_band(pos: Vector2, prev: float) -> float:
|
||||
var strob_dir_band: float = prev - (drag_pos_begin.y - pos.y) * drag_scale_band
|
||||
strob_dir_band = tools.clip_value(strob_dir_band, strob_min_band, strob_max_band)
|
||||
return strob_dir_band
|
||||
|
||||
|
||||
## Устанавливает центр строба по частоте и направлению
|
||||
## Устанавливает центр строба по частоте и направлению.
|
||||
func set_strob(pos: Vector2) -> void:
|
||||
var radp: Vector2 = tools.map_dec_to_rad(radius_center, pos)
|
||||
if radp.y < $canvas.get_radius_outter():
|
||||
@@ -309,7 +322,7 @@ func set_strob(pos: Vector2) -> void:
|
||||
$canvas.set_strob_radius(radp.y)
|
||||
|
||||
|
||||
## Обработка движения мыши для управления стробом. Вызывается во время движения мыши
|
||||
## Обработка движения мыши для управления стробом. Вызывается во время движения мыши.
|
||||
func _on_drag_continue(event) -> void:
|
||||
if drag_button == MOUSE_BUTTON_RIGHT:
|
||||
if shift_pressed:
|
||||
@@ -322,7 +335,7 @@ func _on_drag_continue(event) -> void:
|
||||
set_strob(event.position)
|
||||
|
||||
|
||||
## Обработка движения мыши для управления стробом. Вызывается при нажатии мыши
|
||||
## Обработка движения мыши для управления стробом. Вызывается при нажатии мыши.
|
||||
func _on_drag_begin(event) -> void:
|
||||
drag_pos_begin = event.position
|
||||
if drag_button == MOUSE_BUTTON_LEFT:
|
||||
@@ -332,7 +345,7 @@ func _on_drag_begin(event) -> void:
|
||||
strob_band_begin = $canvas.get_strob_band()
|
||||
|
||||
|
||||
## Обработчик событий ввода. Вызывается godot
|
||||
## Обработчик событий ввода. Вызывается godot.
|
||||
func _input(event) -> void:
|
||||
if not is_visible_in_tree(): return
|
||||
if event is InputEventMouseMotion:
|
||||
@@ -355,21 +368,7 @@ func _input(event) -> void:
|
||||
shift_pressed = event.pressed
|
||||
|
||||
|
||||
## Вызывается по нажатию кнопки "Детализация"
|
||||
func _on_btn_scale_pressed() -> void:
|
||||
var zoom = $btn_zoom.get_meta('zoom')
|
||||
zoom = zoom + 1 if zoom < max_zoom else min_zoom
|
||||
signaller.emit_signal('zoom_changed', zoom)
|
||||
|
||||
|
||||
## Вызывается по завершению изменения детализации карты
|
||||
func _on_zoom_complete(zoom: int) -> void:
|
||||
var prefix = $btn_zoom.get_meta('prefix')
|
||||
$btn_zoom/lbl.text = '%s %d' % [prefix, zoom]
|
||||
$btn_zoom.set_meta('zoom', zoom)
|
||||
|
||||
|
||||
# Обработчик нажатия по сектору формирователя сигналов
|
||||
## Обработчик нажатия по сектору формирователя сигналов.
|
||||
func sel_fs_sector(event):
|
||||
if (event.button_index == MOUSE_BUTTON_LEFT) or (event.button_index == MOUSE_BUTTON_RIGHT):
|
||||
var center: Vector2 = $tilemap.position
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=14 format=3 uid="uid://b276iygic5itk"]
|
||||
[gd_scene load_steps=12 format=3 uid="uid://b276iygic5itk"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/работа/работа.gd" id="1_niok4"]
|
||||
[ext_resource type="PackedScene" uid="uid://nl1vklubr5kr" path="res://scenes/bip/bip.tscn" id="2_br3s6"]
|
||||
@@ -7,16 +7,11 @@
|
||||
[ext_resource type="PackedScene" uid="uid://dymo732qc2doa" path="res://scenes/count-all/count-all-pad.tscn" id="6_e3re7"]
|
||||
[ext_resource type="PackedScene" uid="uid://bwti82byphl68" path="res://scenes/count-danger/count_danger_pad.tscn" id="7_2arls"]
|
||||
[ext_resource type="PackedScene" uid="uid://da7w3vkhadfwe" path="res://scenes/button-flat/button-flat.tscn" id="8_k0iv2"]
|
||||
[ext_resource type="PackedScene" uid="uid://0uqi1ghf7sma" path="res://scenes/button-scale/btn-scale.tscn" id="9_oey3x"]
|
||||
[ext_resource type="PackedScene" uid="uid://bbq6nklh36yij" path="res://scenes/tilemap/tilemap.tscn" id="10_gtwyg"]
|
||||
[ext_resource type="PackedScene" uid="uid://ceknxxfu1loo5" path="res://scenes/tilemap/tilemap.tscn" id="10_gtwyg"]
|
||||
[ext_resource type="PackedScene" uid="uid://b5kjdyxuwsot5" path="res://scenes/diagram/diagram.tscn" id="11_b6su4"]
|
||||
[ext_resource type="Shader" path="res://shaders/tilemap.gdshader" id="11_ekapd"]
|
||||
[ext_resource type="Script" path="res://scenes/работа/sld-mode.gd" id="12_gqdkl"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_4p7y1"]
|
||||
resource_local_to_scene = true
|
||||
shader = ExtResource("11_ekapd")
|
||||
shader_parameter/radius = 0.39
|
||||
[sub_resource type="ImageTexture" id="ImageTexture_cnmvt"]
|
||||
|
||||
[node name="Работа" type="Panel"]
|
||||
script = ExtResource("1_niok4")
|
||||
@@ -39,7 +34,8 @@ metadata/_edit_vertical_guides_ = []
|
||||
[node name="canvas" parent="." instance=ExtResource("11_b6su4")]
|
||||
|
||||
[node name="tilemap" parent="." instance=ExtResource("10_gtwyg")]
|
||||
material = SubResource("ShaderMaterial_4p7y1")
|
||||
self_modulate = Color(1, 1, 1, 0.415686)
|
||||
position = Vector2(360, 360)
|
||||
|
||||
[node name="grd_side" parent="." instance=ExtResource("3_s2j0e")]
|
||||
layout_mode = 0
|
||||
@@ -47,7 +43,6 @@ offset_left = 1114.0
|
||||
offset_top = 7.0
|
||||
offset_right = 1594.0
|
||||
offset_bottom = 1170.0
|
||||
metadata/_edit_lock_ = true
|
||||
|
||||
[node name="grd_btns" parent="." instance=ExtResource("5_2jnbs")]
|
||||
layout_mode = 0
|
||||
@@ -106,27 +101,48 @@ offset_right = 111.0
|
||||
offset_bottom = 953.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
strips_rotation = 25.0
|
||||
text = "Вид"
|
||||
toggle_mode = true
|
||||
|
||||
[node name="btn_activate" parent="." instance=ExtResource("8_k0iv2")]
|
||||
layout_mode = 2
|
||||
offset_left = 954.0
|
||||
offset_left = 906.0
|
||||
offset_top = 1060.0
|
||||
offset_right = 1106.0
|
||||
offset_bottom = 1112.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
strips_rotation = 15.0
|
||||
text = "Подавление"
|
||||
toggle_mode = true
|
||||
|
||||
[node name="btn_zoom" parent="." instance=ExtResource("9_oey3x")]
|
||||
[node name="bt_navig_u" type="TextureButton" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 12.0
|
||||
offset_top = 986.0
|
||||
offset_right = 112.0
|
||||
offset_bottom = 1006.0
|
||||
metadata/zoom = 4
|
||||
offset_left = 530.0
|
||||
offset_top = 428.0
|
||||
offset_right = 570.0
|
||||
offset_bottom = 468.0
|
||||
|
||||
[node name="bt_navig_l" type="TextureButton" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 410.0
|
||||
offset_top = 532.0
|
||||
offset_right = 460.0
|
||||
offset_bottom = 581.0
|
||||
texture_normal = SubResource("ImageTexture_cnmvt")
|
||||
|
||||
[node name="bt_navig_r" type="TextureButton" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 651.0
|
||||
offset_top = 540.0
|
||||
offset_right = 691.0
|
||||
offset_bottom = 580.0
|
||||
|
||||
[node name="bt_navig_d" type="TextureButton" parent="."]
|
||||
layout_mode = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
|
||||
[node name="btns_select" type="GridContainer" parent="."]
|
||||
layout_mode = 0
|
||||
@@ -140,6 +156,7 @@ layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
tooltip_text = "Кнопка для выбора сектора при помощи клика мышкой"
|
||||
strips_rotation = 25.0
|
||||
text = "Строб"
|
||||
toggle_mode = true
|
||||
metadata/state = 0
|
||||
@@ -149,6 +166,7 @@ layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
tooltip_text = "Кнопка для выбора сектора при помощи клика мышкой"
|
||||
strips_rotation = 25.0
|
||||
text = "Цель"
|
||||
toggle_mode = true
|
||||
metadata/state = 1
|
||||
@@ -158,6 +176,7 @@ layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
tooltip_text = "Кнопка для выбора сектора при помощи клика мышкой"
|
||||
strips_rotation = 25.0
|
||||
text = "Сектор"
|
||||
toggle_mode = true
|
||||
metadata/state = 2
|
||||
@@ -236,5 +255,4 @@ vertical_alignment = 1
|
||||
|
||||
[connection signal="drag_begin" from="." to="." method="_on_drag_begin"]
|
||||
[connection signal="drag_continue" from="." to="." method="_on_drag_continue"]
|
||||
[connection signal="pressed" from="btn_zoom" to="." method="_on_btn_scale_pressed"]
|
||||
[connection signal="value_changed" from="vslider" to="vslider" method="_on_value_changed"]
|
||||
|
||||
@@ -4,28 +4,28 @@ extends PanelContainer
|
||||
|
||||
|
||||
@export var texture_state0: Texture2D = preload('res://data/кнопка-эмс-1.png'):
|
||||
set(val): $state.set_texture(val)
|
||||
set(val): $state.set_texture(val)
|
||||
|
||||
|
||||
@export var texture_state1: Texture2D = preload('res://data/кнопка-эмс-0.png'):
|
||||
set(val): $state.set_texture(val)
|
||||
set(val): $state.set_texture(val)
|
||||
|
||||
|
||||
@export var text: String = '':
|
||||
set(val): $button.set_text(val)
|
||||
get: return $button.get_text()
|
||||
set(val): $button.set_text(val)
|
||||
get: return $button.get_text()
|
||||
|
||||
|
||||
@export var pressed: bool = false:
|
||||
set(val): $button.set_pressed(val)
|
||||
get: return $button.is_pressed()
|
||||
set(val): $button.set_pressed(val)
|
||||
get: return $button.is_pressed()
|
||||
|
||||
|
||||
@export var toggle_mode: bool = false:
|
||||
set(val):
|
||||
if is_inside_tree():
|
||||
$button.set_toggle_mode(val)
|
||||
get: return $button.is_toggle_mode()
|
||||
set(val):
|
||||
if is_inside_tree():
|
||||
$button.set_toggle_mode(val)
|
||||
get: return $button.is_toggle_mode()
|
||||
|
||||
|
||||
func set_text (val: String): $button.set_text(val)
|
||||
@@ -33,8 +33,8 @@ func set_pressed (val: bool): $button.set_pressed(val)
|
||||
|
||||
|
||||
func set_toggle_mode (val: bool):
|
||||
if is_inside_tree():
|
||||
$button.set_toggle_mode(val)
|
||||
if is_inside_tree():
|
||||
$button.set_toggle_mode(val)
|
||||
|
||||
|
||||
func get_text(): return $button.get_text()
|
||||
@@ -43,13 +43,13 @@ func is_toggle_mode(): return $button.is_toggle_mode()
|
||||
|
||||
|
||||
func _on_button_toggled(val: bool):
|
||||
if val: $state.set_texture(texture_state1)
|
||||
else: $state.set_texture(texture_state0)
|
||||
if val: $state.set_texture(texture_state1)
|
||||
else: $state.set_texture(texture_state0)
|
||||
|
||||
|
||||
func button_connect(button_signal: String, proc: Callable):
|
||||
$button.connect(button_signal, proc)
|
||||
$button.connect(button_signal, proc)
|
||||
|
||||
|
||||
func _on_button_mouse_entered():
|
||||
emit_signal("mouse_entered")
|
||||
emit_signal("mouse_entered")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extends Panel
|
||||
class_name ems extends Panel
|
||||
|
||||
# Предзагрузка ячеек таблиц
|
||||
## Предзагрузка ячеек таблиц.
|
||||
const TableHeader = preload('res://table/header.tscn')
|
||||
const CellYemsButton = preload('res://scenes/эмс/кнопка-эмс.tscn')
|
||||
const CellLineEdit = preload('res://table/ячейка-2.tscn')
|
||||
@@ -10,7 +10,7 @@ const CellLEEmpty = preload('res://scenes/эмс/line-edit-empty.tscn')
|
||||
const CellFront = preload('res://scenes/cell/cell-front.tscn')
|
||||
const CellFrontRear = preload('res://scenes/cell/cell-front-rear.tscn')
|
||||
|
||||
# Режимы работы выходов
|
||||
## Режимы работы выходов.
|
||||
const OUT_MODE: Array = ['Работа', 'Контроль', '1', '0'] #
|
||||
const COLUMN_OPTS_BTN: Array = [5]
|
||||
const TABLE_ENTRY_COLUMNS: Array = [2,3]
|
||||
@@ -18,16 +18,16 @@ const OUT_SET_ROW: Array = [CellLineEdit, CellLEEmpty, CellLEEmpty, CellLEEmpty,
|
||||
const IN_SET_ROW: Array = [CellLineEdit, CellLEEmpty, CellLEEmpty, CellLEEmpty, CellLEEmpty]
|
||||
|
||||
|
||||
var g_boards: Dictionary # Словарь плат ЭМС
|
||||
var posx: int = 125 # Позиция элементов по x
|
||||
var posy: int = 70 # Позиция элементов по y
|
||||
var g_boards: Dictionary ## Словарь плат ЭМС.
|
||||
var posx: int = 125 ## Позиция элементов по x.
|
||||
var posy: int = 70 ## Позиция элементов по y.
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
call_deferred('init_boards')
|
||||
|
||||
|
||||
## Инициализация основных элементов экрана ЭМС
|
||||
## Инициализация основных элементов экрана ЭМС.
|
||||
func init_boards():
|
||||
# Выставление позиций элементов ЭМС на экране
|
||||
$scrollin.set_position(Vector2(posx,posy))
|
||||
@@ -68,8 +68,8 @@ func on_btn_disconnect():
|
||||
on_disconnect($scrl_out_set/tbl_out_set, selected_rows_out, 'выход')
|
||||
|
||||
|
||||
## Разрывает связь входа и выхода, [param tbl] - таблица, [param selected_rows] - выбранные строки
|
||||
## [param type_dev] - тип, 'вход' или 'выход'
|
||||
## Разрывает связь входа и выхода, [param tbl] - таблица, [param selected_rows] - выбранные строки.
|
||||
## [param type_dev] - тип, 'вход' или 'выход'.
|
||||
func on_disconnect(tbl, selected_rows, type_dev: String):
|
||||
var dev = tbl.get_node_user_data(0, 0)
|
||||
var user_data: Array = tbl.get_node_user_data(0, selected_rows[0])
|
||||
@@ -85,26 +85,26 @@ func on_disconnect(tbl, selected_rows, type_dev: String):
|
||||
set_out_dev(dev)
|
||||
|
||||
|
||||
## Обработчик нажатия кнопки "Прочитать"
|
||||
## Обработчик нажатия кнопки "Прочитать".
|
||||
func on_btn_flash_read(btn):
|
||||
await get_tree().create_timer(0.1).timeout
|
||||
btn.pressed = false
|
||||
|
||||
|
||||
## Обработчик нажатия кнопки "Записать"
|
||||
## Обработчик нажатия кнопки "Записать".
|
||||
func on_btn_flash_write(btn):
|
||||
await get_tree().create_timer(0.1).timeout
|
||||
btn.pressed = false
|
||||
|
||||
|
||||
## Инициализация таблицы с файлами настроек ЭМС
|
||||
## Инициализация таблицы с файлами настроек ЭМС.
|
||||
func init_tbl_files():
|
||||
$scrl_files/tbl_files.set_header([TableHeader, TableHeader, TableHeader])
|
||||
$scrl_files/tbl_files.set_header_text(['Имя файла', 'Дата изменения', 'Размер'])
|
||||
$scrl_files/tbl_files.set_columns_min_size([200, 120, 70])
|
||||
|
||||
|
||||
## Инициализация таблиц входов
|
||||
## Инициализация таблиц входов.
|
||||
func init_tbl_in():
|
||||
# Инициализация основной таблицы входов, в ней отображается информация о параметрах и состоянии
|
||||
var header_type: Array = [TableHeader, TableHeader, CellFront, CellFrontRear, TableHeader]
|
||||
@@ -142,12 +142,12 @@ func init_tbl_in():
|
||||
$scrl_in_set/tbl_in_set.connect('selected_changed', Callable(self, 'on_selected_changed_si'))
|
||||
|
||||
|
||||
## Обработчик редактирования Entry в таблице параметров входов/выходов
|
||||
## Обработчик редактирования Entry в таблице параметров входов/выходов.
|
||||
func on_edit_entry(text : String, entry):
|
||||
print_debug(text, entry)
|
||||
|
||||
|
||||
## Обработчик выбора строки в таблице входов
|
||||
## Обработчик выбора строки в таблице входов.
|
||||
func on_selected_changed_in(i_row: int):
|
||||
var selecter_rows: Array = []
|
||||
$scrollin/tbl_in.get_selected_rows(selecter_rows)
|
||||
@@ -156,19 +156,19 @@ func on_selected_changed_in(i_row: int):
|
||||
set_in_dev(dev)
|
||||
|
||||
|
||||
## Обработчик нажатия на таблицу входов
|
||||
## Обработчик нажатия на таблицу входов.
|
||||
func on_row_pressed_in(i_row: int):
|
||||
on_row_pressed(i_row, $scrollin/tbl_in)
|
||||
on_selected_changed_in(i_row)
|
||||
|
||||
|
||||
## Выбор входного устройства, для отображения в таблице соединений входа и изменения параметров
|
||||
## Выбор входного устройства, для отображения в таблице соединений входа и изменения параметров.
|
||||
func set_in_dev(dev):
|
||||
var row_type: Array = [CellLineEdit, CellLineEdit, CellLineEdit, CellLineEdit, CellState]
|
||||
set_dev($scrl_in_set/tbl_in_set, dev, row_type, IN_SET_ROW, 'Список соединённых выходов :', [250, 100, 70, 70, 70])
|
||||
|
||||
|
||||
## Обработчик выбора строки в таблице соединений входа и изменения параметров
|
||||
## Обработчик выбора строки в таблице соединений входа и изменения параметров.
|
||||
func on_selected_changed_si(i_row: int):
|
||||
if i_row < 2:
|
||||
return
|
||||
@@ -181,7 +181,7 @@ func on_selected_changed_si(i_row: int):
|
||||
on_row_pressed_out(i)
|
||||
|
||||
|
||||
## Обработчик нажатия на таблицу соединений входа и изменения параметров
|
||||
## Обработчик нажатия на таблицу соединений входа и изменения параметров.
|
||||
func on_row_pressed_si(i_row: int):
|
||||
if i_row < 2:
|
||||
return
|
||||
@@ -189,7 +189,7 @@ func on_row_pressed_si(i_row: int):
|
||||
on_selected_changed_si(i_row)
|
||||
|
||||
|
||||
## Инициализация таблиц выходов
|
||||
## Инициализация таблиц выходов.
|
||||
func init_tbl_out():
|
||||
# Инициализация основной таблицы выходов, в ней отображается информация о параметрах и состоянии
|
||||
var header_text = ['Выходы', 'Соединитель', 'мкс', 'мкс', 'Состояние', 'Режим']
|
||||
@@ -225,7 +225,7 @@ func init_tbl_out():
|
||||
$scrl_out_set/tbl_out_set.connect('selected_changed', Callable(self, 'on_selected_changed_so'))
|
||||
|
||||
|
||||
## Обработчик выбора строки в таблице соединений выхода и изменения параметров
|
||||
## Обработчик выбора строки в таблице соединений выхода и изменения параметров.
|
||||
func on_selected_changed_so(i_row: int):
|
||||
if i_row < 2:
|
||||
return
|
||||
@@ -238,7 +238,7 @@ func on_selected_changed_so(i_row: int):
|
||||
on_row_pressed_in(i)
|
||||
|
||||
|
||||
## Обработчик нажатия на таблицу соединений выхода и изменения параметров
|
||||
## Обработчик нажатия на таблицу соединений выхода и изменения параметров.
|
||||
func on_row_pressed_so(i_row: int):
|
||||
if i_row < 2:
|
||||
return
|
||||
@@ -246,7 +246,7 @@ func on_row_pressed_so(i_row: int):
|
||||
on_selected_changed_so(i_row)
|
||||
|
||||
|
||||
## Обработчик выбора строки в таблице выходов
|
||||
## Обработчик выбора строки в таблице выходов.
|
||||
func on_selected_changed_out(i_row: int):
|
||||
var selecter_rows: Array = []
|
||||
$scrollout/tbl_out.get_selected_rows(selecter_rows)
|
||||
@@ -255,13 +255,13 @@ func on_selected_changed_out(i_row: int):
|
||||
set_out_dev(dev)
|
||||
|
||||
|
||||
## Обработчик выбора строки в таблице выходов
|
||||
## Обработчик выбора строки в таблице выходов.
|
||||
func on_row_pressed_out(i_row: int):
|
||||
on_row_pressed(i_row, $scrollout/tbl_out)
|
||||
on_selected_changed_out(i_row)
|
||||
|
||||
|
||||
## Выбор выходного устройства, для отображения в таблице соединений выхода и изменения параметров
|
||||
## Выбор выходного устройства, для отображения в таблице соединений выхода и изменения параметров.
|
||||
func set_out_dev(dev):
|
||||
var row_type: Array = [CellLineEdit, CellLineEdit, CellLineEdit, CellLineEdit, CellState, CellOptBtn]
|
||||
set_dev($scrl_out_set/tbl_out_set, dev, row_type, OUT_SET_ROW, 'Список соединённых входов :', [250, 100, 70, 70, 70, 100])
|
||||
@@ -273,9 +273,12 @@ func set_out_dev(dev):
|
||||
mode.select(mode_index)
|
||||
|
||||
|
||||
## Выбор входного или выходного устройства [param tbl] - таблица, [param dev] - устройство,
|
||||
## [param row_type] - массив с типами колонок, [param row_type_conn] - массив с пустыми LineEdit
|
||||
## [param lbl_text] - текст отображаемый во 2 строке: пример: ('Список соединённых входов :')
|
||||
## Выбор входного или выходного устройства.[br]
|
||||
## [param tbl] - таблица,[br]
|
||||
## [param dev] - устройство,[br]
|
||||
## [param row_type] - массив с типами колонок,[br]
|
||||
## [param row_type_conn] - массив с пустыми LineEdit,[br]
|
||||
## [param lbl_text] - текст отображаемый во 2 строке: пример: ('Список соединённых входов :').[br]
|
||||
func set_dev(tbl, dev, row_type, row_type_conn, lbl_text, row_size):
|
||||
tbl.clear_rows()
|
||||
tbl.add_row(row_type)
|
||||
@@ -311,7 +314,7 @@ func set_dev(tbl, dev, row_type, row_type_conn, lbl_text, row_size):
|
||||
tbl.connect_columns(self, 'text_submitted', 'on_edit_entry', TABLE_ENTRY_COLUMNS, [])
|
||||
|
||||
|
||||
## Обработчик нажатия кнопки connect
|
||||
## Обработчик нажатия кнопки connect.
|
||||
func on_btn_connect():
|
||||
var in_row_index: Array = []
|
||||
var out_row_index: Array = []
|
||||
@@ -326,9 +329,12 @@ func on_btn_connect():
|
||||
add_connection_dev($scrl_in_set/tbl_in_set, out_dev, in_dev, IN_SET_ROW, out_user_data)
|
||||
|
||||
|
||||
## образовывает связь между выбранным входом и выходом [param tbl] - таблица, [param dev1] - устройство1,
|
||||
## [param dev2] - устройство 2, [param set_row] - массив с пустыми LineEdit
|
||||
## [param user_data] - пользовательские данные устройства1
|
||||
## Образовывает связь между выбранным входом и выходом.[br]
|
||||
## [param tbl] - таблица,[br]
|
||||
## [param dev1] - устройство1,[br]
|
||||
## [param dev2] - устройство 2,[br]
|
||||
## [param set_row] - массив с пустыми LineEdit,[br]
|
||||
## [param user_data] - пользовательские данные устройства1.[br]
|
||||
func add_connection_dev(tbl, dev1, dev2, set_row, user_data):
|
||||
if not dev1.connector in dev2.connect_devs:
|
||||
tbl.add_row(set_row)
|
||||
@@ -340,15 +346,17 @@ func add_connection_dev(tbl, dev1, dev2, set_row, user_data):
|
||||
dev2.connect_devs[dev1.connector] = user_data
|
||||
|
||||
|
||||
## Отключает возможность редактирования LineEdit в таблице [param tbl] - таблица,
|
||||
## [param num_col] - номер колонки, [param i_row] - номер столбца
|
||||
## Отключает возможность редактирования LineEdit в таблице.[br]
|
||||
## [param tbl] - таблица,[br]
|
||||
## [param num_col] - номер колонки,[br]
|
||||
## [param i_row] - номер столбца.[br]
|
||||
func disable_edit(tbl, num_col: int, i_row: int):
|
||||
for col in range(num_col):
|
||||
var node: LineEdit = tbl.get_node2(col, i_row)
|
||||
node.editable = false
|
||||
|
||||
|
||||
## Обработчик выбора строки с таблице
|
||||
## Обработчик выбора строки с таблице.
|
||||
func on_row_pressed(i_row: int, tbl):
|
||||
tbl.clear_rows_selected()
|
||||
var is_row_selected = tbl.is_row_selected(i_row)
|
||||
|
||||
@@ -29,6 +29,7 @@ offset_left = 1446.0
|
||||
offset_top = 55.0
|
||||
offset_right = 1583.0
|
||||
offset_bottom = 85.0
|
||||
strips_rotation = 10.0
|
||||
text = "Прочитать"
|
||||
|
||||
[node name="btn_flash_write" parent="." instance=ExtResource("2_eju8r")]
|
||||
@@ -37,6 +38,7 @@ offset_left = 1446.0
|
||||
offset_top = 99.0
|
||||
offset_right = 1583.0
|
||||
offset_bottom = 129.0
|
||||
strips_rotation = 10.0
|
||||
text = "Записать"
|
||||
|
||||
[node name="btn_new" type="Button" parent="."]
|
||||
|
||||
345
scenes/эмс2/эмс2.tscn
Normal file
@@ -0,0 +1,345 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://musb21x2u0xs"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://co5xj5uhjfk84" path="res://data/Окно.png" id="1_k6k6b"]
|
||||
|
||||
[node name="ЭМС2" type="Panel"]
|
||||
|
||||
[node name="TextureRect2" type="TextureRect" parent="."]
|
||||
layout_mode = 0
|
||||
offset_top = 8.0
|
||||
offset_right = 1597.0
|
||||
offset_bottom = 712.0
|
||||
texture = ExtResource("1_k6k6b")
|
||||
|
||||
[node name="Label2" type="Label" parent="TextureRect2"]
|
||||
layout_mode = 0
|
||||
offset_left = 795.0
|
||||
offset_top = 8.0
|
||||
offset_right = 868.0
|
||||
offset_bottom = 27.0
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
text = "Излучение"
|
||||
|
||||
[node name="Label3" type="Label" parent="TextureRect2"]
|
||||
layout_mode = 0
|
||||
offset_left = 813.0
|
||||
offset_top = 293.0
|
||||
offset_right = 864.0
|
||||
offset_bottom = 312.0
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
text = "Приём"
|
||||
|
||||
[node name="RichTextLabel" type="RichTextLabel" parent="TextureRect2"]
|
||||
layout_mode = 0
|
||||
offset_left = 11.0
|
||||
offset_top = 36.0
|
||||
offset_right = 126.0
|
||||
offset_bottom = 286.0
|
||||
|
||||
[node name="RichTextLabel2" type="RichTextLabel" parent="TextureRect2"]
|
||||
layout_mode = 0
|
||||
offset_left = 12.0
|
||||
offset_top = 318.0
|
||||
offset_right = 127.0
|
||||
offset_bottom = 568.0
|
||||
|
||||
[node name="GridContainer2" type="GridContainer" parent="."]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
self_modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
layout_mode = 0
|
||||
offset_left = -8.0
|
||||
offset_top = 840.0
|
||||
offset_right = 1592.0
|
||||
offset_bottom = 1208.0
|
||||
|
||||
[node name="Label11" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 1224.0
|
||||
offset_top = 752.0
|
||||
offset_right = 3304.0
|
||||
offset_bottom = 1872.0
|
||||
scale = Vector2(0.05, 0.05)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 350
|
||||
text = "Запрет
|
||||
приёма"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Label11"]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label14" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 1336.0
|
||||
offset_top = 752.0
|
||||
offset_right = 3736.0
|
||||
offset_bottom = 1872.0
|
||||
scale = Vector2(0.05, 0.05)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 350
|
||||
text = "Исполнено"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Label14"]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label12" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 1464.0
|
||||
offset_top = 752.0
|
||||
offset_right = 3704.0
|
||||
offset_bottom = 1872.0
|
||||
scale = Vector2(0.05, 0.05)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 350
|
||||
text = "Запрет
|
||||
приёма"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Label12"]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label15" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 1096.0
|
||||
offset_top = 752.0
|
||||
offset_right = 3496.0
|
||||
offset_bottom = 1872.0
|
||||
scale = Vector2(0.05, 0.05)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 350
|
||||
text = "Исполнено"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Label15"]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label13" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 976.0
|
||||
offset_top = 752.0
|
||||
offset_right = 3216.0
|
||||
offset_bottom = 1872.0
|
||||
scale = Vector2(0.05, 0.05)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 350
|
||||
text = "Верхняя
|
||||
Частота"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Label13"]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label16" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 856.0
|
||||
offset_top = 752.0
|
||||
offset_right = 3096.0
|
||||
offset_bottom = 1872.0
|
||||
scale = Vector2(0.05, 0.05)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 350
|
||||
text = "Нижняя
|
||||
частота"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Label16"]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -0.000976563
|
||||
offset_right = -0.000976563
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label17" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 728.0
|
||||
offset_top = 752.0
|
||||
offset_right = 3128.0
|
||||
offset_bottom = 1872.0
|
||||
scale = Vector2(0.05, 0.05)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 350
|
||||
text = "Кластер"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Label17"]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label18" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 600.0
|
||||
offset_top = 752.0
|
||||
offset_right = 3000.0
|
||||
offset_bottom = 1872.0
|
||||
scale = Vector2(0.05, 0.05)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 350
|
||||
text = "Угол места"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Label18"]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label19" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 472.0
|
||||
offset_top = 752.0
|
||||
offset_right = 2872.0
|
||||
offset_bottom = 1872.0
|
||||
scale = Vector2(0.05, 0.05)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 350
|
||||
text = "Азимут"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Label19"]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 0.000610352
|
||||
offset_top = 6.10352e-05
|
||||
offset_right = 0.000488281
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label20" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 344.0
|
||||
offset_top = 752.0
|
||||
offset_right = 2744.0
|
||||
offset_bottom = 1872.0
|
||||
scale = Vector2(0.05, 0.05)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 350
|
||||
text = "Режим"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Label20"]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 0.000610352
|
||||
offset_top = 6.10352e-05
|
||||
offset_right = 0.000488281
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label21" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 216.0
|
||||
offset_top = 752.0
|
||||
offset_right = 2616.0
|
||||
offset_bottom = 1872.0
|
||||
scale = Vector2(0.05, 0.05)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 350
|
||||
text = "Изделие"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Label21"]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = 6.10352e-05
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label22" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 88.0
|
||||
offset_top = 752.0
|
||||
offset_right = 2488.0
|
||||
offset_bottom = 1872.0
|
||||
scale = Vector2(0.05, 0.05)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 350
|
||||
text = "Комплекс
|
||||
"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Label22"]
|
||||
modulate = Color(0.8, 0.533333, 0.27451, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = 6.10352e-05
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
@@ -1,26 +1,26 @@
|
||||
extends Node
|
||||
class_name STC extends Node
|
||||
|
||||
## Реализация "Протокол информационного сопряжения
|
||||
## СПО АСУ изделия «МП‑550» с СПО «Управления КАПС РПБ»"
|
||||
## Реализация "Протокол информационного сопряжения.
|
||||
## СПО АСУ изделия «МП‑550» с СПО «Управления КАПС РПБ».
|
||||
|
||||
|
||||
const ONLINE_TIMEOUT = 3000 ## Время ожидания пакета от КАПС РПБ, мс
|
||||
const BUFFER_SIZE = 2048 ## Размер приёмного буфера для датаграмм
|
||||
const ONLINE_TIMEOUT = 3000 ## Время ожидания пакета от КАПС РПБ, мс.
|
||||
const BUFFER_SIZE = 2048 ## Размер приёмного буфера для датаграмм.
|
||||
|
||||
|
||||
class CapsRpb:
|
||||
signal line_changed(unit: CapsRpb) ## Сигнал состояние связи изменилось
|
||||
signal data_received(unit: CapsRpb) ## Сигнал данные приняты
|
||||
signal command_fail(unit: CapsRpb) ## Сигнал при не выполнении команды
|
||||
signal parse_error(unit: CapsRpb, msg: String) ## Сигнал ошибки разбора сообщения
|
||||
signal line_changed(unit: CapsRpb) ## Сигнал состояние связи изменилось.
|
||||
signal data_received(unit: CapsRpb) ## Сигнал данные приняты.
|
||||
signal command_fail(unit: CapsRpb) ## Сигнал при не выполнении команды.
|
||||
signal parse_error(unit: CapsRpb, msg: String) ## Сигнал ошибки разбора сообщения.
|
||||
|
||||
static var json_conv: = JSON.new()
|
||||
var online: = false ## Состояние связи с источником сообщений
|
||||
var name: String ## Имя экземпляра
|
||||
var json_dic: Dictionary ## Аппарат для разбора сообщений
|
||||
var tick: = 0 ## Тик время последнего обновления, мс
|
||||
var tx_data: = PackedByteArray() ## Пакет для отправки
|
||||
var tx_stack: Array ## Массив пакетов для отправки
|
||||
var online: = false ## Состояние связи с источником сообщений.
|
||||
var name: String ## Имя экземпляра.
|
||||
var json_dic: Dictionary ## Аппарат для разбора сообщений.
|
||||
var tick: = 0 ## Тик время последнего обновления, мс.
|
||||
var tx_data: = PackedByteArray() ## Пакет для отправки.
|
||||
var tx_stack: Array ## Массив пакетов для отправки.
|
||||
|
||||
func _to_string() -> String: return String('капсрпб: "%s" %s ' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
func _init(nm): self.name = nm
|
||||
|
||||
@@ -9,30 +9,30 @@ var FILES_ROWS_ALIGNMENT = [ HORIZONTAL_ALIGNMENT_LEFT, HORIZONTAL_ALIGNM
|
||||
|
||||
|
||||
func fill_files_table(tbl: table, folder: String, rows_types: Array):
|
||||
var dir: = DirAccess.open(folder)
|
||||
if dir == null:
|
||||
return
|
||||
var files: = []
|
||||
var exclude_names: = ['.', '..']
|
||||
dir.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
|
||||
while true:
|
||||
var file: = dir.get_next()
|
||||
if file == '':
|
||||
break
|
||||
if file in exclude_names:
|
||||
continue
|
||||
var file_name = folder + '/' + file
|
||||
var fd = FileAccess.open(file_name, FileAccess.READ)
|
||||
if not fd:
|
||||
continue
|
||||
var glob_path = ProjectSettings.globalize_path(file_name)
|
||||
var sz = fd.get_length()
|
||||
var ut = fd.get_modified_time(file_name)
|
||||
fd.close()
|
||||
var mt = Time.get_datetime_dict_from_unix_time(ut)
|
||||
var file_row = [file, '%d' % sz, '%d-%02d-%02d %02d:%02d' % [mt.year, mt.month, mt.day, mt.hour, mt.minute]]
|
||||
tbl.add_row(rows_types)
|
||||
var i_row = tbl.get_rows_count() - 1
|
||||
tbl.set_row_text(i_row, file_row)
|
||||
tbl.set_node_meta(0, i_row, 'file_path', glob_path)
|
||||
dir.list_dir_end()
|
||||
var dir: = DirAccess.open(folder)
|
||||
if dir == null:
|
||||
return
|
||||
var files: = []
|
||||
var exclude_names: = ['.', '..']
|
||||
dir.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
|
||||
while true:
|
||||
var file: = dir.get_next()
|
||||
if file == '':
|
||||
break
|
||||
if file in exclude_names:
|
||||
continue
|
||||
var file_name = folder + '/' + file
|
||||
var fd = FileAccess.open(file_name, FileAccess.READ)
|
||||
if not fd:
|
||||
continue
|
||||
var glob_path = ProjectSettings.globalize_path(file_name)
|
||||
var sz = fd.get_length()
|
||||
var ut = fd.get_modified_time(file_name)
|
||||
fd.close()
|
||||
var mt = Time.get_datetime_dict_from_unix_time(ut)
|
||||
var file_row = [file, '%d' % sz, '%d-%02d-%02d %02d:%02d' % [mt.year, mt.month, mt.day, mt.hour, mt.minute]]
|
||||
tbl.add_row(rows_types)
|
||||
var i_row = tbl.get_rows_count() - 1
|
||||
tbl.set_row_text(i_row, file_row)
|
||||
tbl.set_node_meta(0, i_row, 'file_path', glob_path)
|
||||
dir.list_dir_end()
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
extends Node
|
||||
class_name HotKeys extends Node
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
signaller.connect('full_screen', Callable(self, 'toggle_full_screen').bind(0))
|
||||
signaller.connect('full_screen', Callable(self, 'toggle_full_screen').bind(0))
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventKey:
|
||||
if event.pressed and event.physical_keycode == KEY_F11:
|
||||
signaller.emit_signal('full_screen')
|
||||
if event is InputEventKey:
|
||||
if event.pressed and event.physical_keycode == KEY_F11:
|
||||
signaller.emit_signal('full_screen')
|
||||
|
||||
|
||||
## Переключает режим окна программы полный - обычный экран
|
||||
## Переключает режим окна программы полный - обычный экран.
|
||||
func toggle_full_screen(id: int) -> void:
|
||||
var mode = DisplayServer.window_get_mode(id)
|
||||
mode = DisplayServer.WINDOW_MODE_WINDOWED \
|
||||
if mode == DisplayServer.WINDOW_MODE_FULLSCREEN \
|
||||
else DisplayServer.WINDOW_MODE_FULLSCREEN
|
||||
DisplayServer.window_set_mode(mode, id)
|
||||
var mode = DisplayServer.window_get_mode(id)
|
||||
mode = DisplayServer.WINDOW_MODE_WINDOWED \
|
||||
if mode == DisplayServer.WINDOW_MODE_FULLSCREEN \
|
||||
else DisplayServer.WINDOW_MODE_FULLSCREEN
|
||||
DisplayServer.window_set_mode(mode, id)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
extends Node
|
||||
class_name Iterfer extends Node
|
||||
|
||||
## Представление помехи
|
||||
## Представление помехи.
|
||||
|
||||
## Режимы помехи
|
||||
## Режимы помехи.
|
||||
const ITERFER_MODE = {
|
||||
'off': ['Откл', ['freq', 'width'], 0],
|
||||
'auto': ['АВТО', ['freq', 'width'], 1000],
|
||||
@@ -27,16 +27,16 @@ const WIDTH_MAX = 120
|
||||
const WIDTH_MIN = 0
|
||||
|
||||
const SOURCE_INTERFER = ['th','fs','cu']
|
||||
const ID_INTERFERS_LEN = 63 ## Размер пула номеров целей
|
||||
const ID_INTERFERS_LEN = 63 ## Размер пула номеров целей.
|
||||
const INTERFER_OFF = 'off'
|
||||
const STATE_TSMT = 5 ## Значение svk для цели, когда ответ ещё не получен
|
||||
var msg_ss: int = 0 ## счётчик сообщений
|
||||
var id_array: Array ## Массив id воздействий
|
||||
var thrs: Dictionary ## Словарь воздействия для целей, ключ - id воздействия
|
||||
var fs: Dictionary ## Словарь воздействий для секторов, ключ - id воздействия
|
||||
var cu: Dictionary ## Словарь воздействий для 5П-28, ключ - id воздействия
|
||||
const STATE_TSMT = 5 ## Значение svk для цели, когда ответ ещё не получен.
|
||||
var msg_ss: int = 0 ## Счётчик сообщений.
|
||||
var id_array: Array ## Массив id воздействий.
|
||||
var thrs: Dictionary ## Словарь воздействия для целей, ключ - id воздействия.
|
||||
var fs: Dictionary ## Словарь воздействий для секторов, ключ - id воздействия.
|
||||
var cu: Dictionary ## Словарь воздействий для 5П-28, ключ - id воздействия.
|
||||
|
||||
## Сеанс помехи
|
||||
## Сеанс помехи.
|
||||
class Interfer:
|
||||
var ss: int = 0 ## Счётчик сообщений.
|
||||
var ispp: int = 0 ## Индекс сеанса.
|
||||
@@ -48,7 +48,7 @@ class Interfer:
|
||||
var get_params: Array[String] ## Запрос массива параметров (список запрошенных параметров).
|
||||
var retss: int ## Значение счётчика сообщения в котором был произведён запрос массива параметров.
|
||||
var tick_tx: int ## Тик время обновления цели, мс.
|
||||
var source_interfer: String = '' ## Тип объекта по которой поставлена помеха
|
||||
var source_interfer: String = '' ## Тип объекта по которой поставлена помеха.
|
||||
|
||||
func _to_string() -> String:
|
||||
return 'номер: %d название: %s частота: %0.1f МГц пеленг: %0.1f гр.' % [ispp, ITERFER_MODE[krp][0], params['freq'], kni]
|
||||
@@ -94,7 +94,7 @@ signal interfer_resized(ecms: Dictionary) ## Вызывается пр
|
||||
|
||||
|
||||
func _ready():
|
||||
var ecms: Dictionary = {} ## Словарь помех
|
||||
var ecms: Dictionary = {} ## Словарь помех.
|
||||
for i in range(ID_INTERFERS_LEN): # Заполняет массив ID целей
|
||||
id_array.append(i + 1)
|
||||
var unit_key = repsettings.get_unit_key('уарэп-капсрпб-отп')
|
||||
@@ -114,7 +114,7 @@ func _ready():
|
||||
signaller.connect('interfer_off_all', Callable(self, 'on_interfer_off_all').bind(unit, ecms))
|
||||
|
||||
|
||||
# Проверяет состояние отправки пакета и если не доставлен, повторяет отправку
|
||||
## Проверяет состояние отправки пакета и если не доставлен, повторяет отправку.
|
||||
func on_timer_check_state(unit, ecms, resend_timeout):
|
||||
var tick = Time.get_ticks_msec()
|
||||
for ecm in ecms.values():
|
||||
@@ -124,7 +124,7 @@ func on_timer_check_state(unit, ecms, resend_timeout):
|
||||
ecm.tick_tx = tick
|
||||
|
||||
|
||||
## Производит приём состояния помех. [param unit] -> [param ecms]
|
||||
## Производит приём состояния помех. [param unit] -> [param ecms].
|
||||
func on_data_capsrpb_received(unit: capsrpb.CapsRpb, ecms: Dictionary):
|
||||
if not unit.json_dic.has('ts'): return
|
||||
if not (unit.json_dic['ts'] is float): return
|
||||
@@ -150,7 +150,7 @@ func on_data_capsrpb_received(unit: capsrpb.CapsRpb, ecms: Dictionary):
|
||||
call_deferred('emit_signal', 'interfer_resized', ecms)
|
||||
|
||||
|
||||
## Вызыватся, когда пользователь выбрал помеху и выбраны цели
|
||||
## Вызыватся, когда пользователь выбрал помеху и выбраны цели.
|
||||
func on_interfer_create(btn, sel_threats, fs_arr, _unit, ecms):
|
||||
for item in sel_threats:
|
||||
var param: Dictionary = {}
|
||||
@@ -262,5 +262,5 @@ func push_id(id : int):
|
||||
id_array.sort()
|
||||
|
||||
|
||||
## отправляет словаhь помех в юнит, для запаковки и отправки в 5П28
|
||||
## Отправляет словарь помех в юнит, для запаковки и отправки в 5П28.
|
||||
func on_get_interfers(unit, ecms): unit.pack_interfers(cu, ecms)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
extends Node
|
||||
class_name Mercator extends Node
|
||||
|
||||
## Утилиты для работы с меркаторовскими XYZ-плитками.
|
||||
|
||||
const R2D: = 180.0 / PI
|
||||
const RE: = 6378137.0 ## Радиус Земли экваториальный в метрах
|
||||
const RP: = 6356752.31424518 ## Радиус Земли полярный в метрах
|
||||
const CE: = 2.0 * PI * RE ## Длина окружности Земли в метрах по экватору
|
||||
const CP: = 2.0 * PI * RP ## Длина окружности Земли в метрах через полюсы
|
||||
const RE: = 6378137.0 ## Радиус Земли экваториальный в метрах.
|
||||
const RP: = 6356752.31424518 ## Радиус Земли полярный в метрах.
|
||||
const CE: = 2.0 * PI * RE ## Длина окружности Земли в метрах по экватору.
|
||||
const CP: = 2.0 * PI * RP ## Длина окружности Земли в метрах через полюсы.
|
||||
const EPSILON: = 1e-14
|
||||
const LL_EPSILON: = 1e-11
|
||||
const MAX_ZOOM: = 20
|
||||
@@ -14,15 +14,15 @@ const MAX_NORTH = 85.051129
|
||||
const MAX_SOUTH = -85.051129
|
||||
|
||||
|
||||
## XYZ-плитка веб-меркатора [param x], [param y], [param z] индексы
|
||||
# [b]x[/b] и [b]y[/b] плитки и уровень масштабирования [b]z[/b].
|
||||
## XYZ-плитка веб-меркатора [param x], [param y], [param z] индексы.
|
||||
## [b]x[/b] и [b]y[/b] плитки и уровень масштабирования [b]z[/b].
|
||||
class Tile:
|
||||
var x: int
|
||||
var y: int
|
||||
var z: int
|
||||
var lng: float ## Координаты, которые плитка должна покрывать, долгота, градусы
|
||||
var lat: float ## Широта, градусы
|
||||
var is_root: bool ## Признак, что плитка корневая (покрывает координаты)
|
||||
var lng: float ## Координаты, которые плитка должна покрывать, долгота, градусы.
|
||||
var lat: float ## Широта, градусы.
|
||||
var is_root: bool ## Признак, что плитка корневая (покрывает координаты).
|
||||
|
||||
func as_array(): return [self.x, self.y, self.z]
|
||||
|
||||
@@ -45,9 +45,8 @@ class Tile:
|
||||
func _bound_index(index: int) -> int:
|
||||
var mi: int = 2 ** z
|
||||
if index < 0:
|
||||
index *= -1
|
||||
index %= mi
|
||||
index = mi - index
|
||||
index = -index - 1;
|
||||
index = int(mi - 1) - (index % int(mi))
|
||||
else:
|
||||
index %= mi
|
||||
return index
|
||||
@@ -62,7 +61,7 @@ class LngLat:
|
||||
var lng: float = 0.0 ## Долгота в десятичных градусах восточной долготы.
|
||||
var lat: float = 0.0 ## Широта в десятичных градусах северной широты.
|
||||
|
||||
## Возвращает в виде массива
|
||||
## Возвращает в виде массива.
|
||||
func as_array() -> Array: return [self.lng, self.lat]
|
||||
|
||||
func _to_string() -> String: return '[%f, %f, %f]' % [self.x, self.y, self.z]
|
||||
@@ -79,7 +78,7 @@ class LngLatBbox:
|
||||
var east: float ## Восток
|
||||
var north: float ## Север
|
||||
|
||||
## Возвращает в виде массива
|
||||
## Возвращает в виде массива.
|
||||
func as_array() -> Array: return [self.west, self.south, self.east, self.north]
|
||||
|
||||
func _to_string() -> String: return '[%f, %f, %f, %f]' % [self.west, self.south, self.east, self.north]
|
||||
@@ -114,12 +113,12 @@ func radians(v: float) -> float: return (v * PI) / 180.0
|
||||
func rshift(val: int, n: int) -> int: return (val % 0x100000000) >> n
|
||||
|
||||
|
||||
# Возвращает арксинус гиперболический от значения [param val]
|
||||
## Возвращает арксинус гиперболический от значения [param val].
|
||||
func asinh(val: float): return log(val + sqrt(val * val + 1.0))
|
||||
|
||||
|
||||
# Преобразует [param lon] в градусах восточной долготы, [param lat] в градусах
|
||||
# северной долготы, [param alt] высоты в метрах в фиксированные координаты (x, y, z) Земли.
|
||||
## Преобразует [param lon] в градусах восточной долготы, [param lat] в градусах.
|
||||
## северной долготы, [param alt] высоты в метрах в фиксированные координаты (x, y, z) Земли.
|
||||
func lnglat_to_ecef(lng: float, lat: float, alt: float = 0.0) -> Array:
|
||||
alt += (RE + RP) / 2.0
|
||||
var latrad: float = radians(lat)
|
||||
@@ -148,23 +147,23 @@ func find_up_left(tiles: Array):
|
||||
return null
|
||||
|
||||
|
||||
## Lon./lat. to tile numbers
|
||||
## [param lon]/[param lat]. для номера плитки.
|
||||
func deg2num(lng: float, lat: float, zoom: int):
|
||||
var n: = float(1 << zoom)
|
||||
var xtile: = int((lng + 180.0) / 360.0 * n)
|
||||
var ytile: = int((1.0 - asinh(tan(radians(lat))) / PI) / 2.0 * n)
|
||||
return [xtile, ytile]
|
||||
var n: = float(1 << zoom)
|
||||
var xtile: = int((lng + 180.0) / 360.0 * n)
|
||||
var ytile: = int((1.0 - asinh(tan(radians(lat))) / PI) / 2.0 * n)
|
||||
return [xtile, ytile]
|
||||
|
||||
|
||||
## Tile numbers to lon./lat.
|
||||
## Номера плитки для [param lon]/[param lat].
|
||||
func num2deg(x: int, y: int, zoom: int):
|
||||
var n: = float(1 << zoom)
|
||||
var lng: = float(x) / n * 360.0 - 180.0
|
||||
var lat: = atan(sinh(PI * (1.0 - 2.0 * float(y) / n)))
|
||||
return [lng, degrees(lat)]
|
||||
var n: = float(1 << zoom)
|
||||
var lng: = float(x) / n * 360.0 - 180.0
|
||||
var lat: = atan(sinh(PI * (1.0 - 2.0 * float(y) / n)))
|
||||
return [lng, degrees(lat)]
|
||||
|
||||
|
||||
## Расстояние по горизонтали в метрах, представленное одним пикселем
|
||||
## Расстояние по горизонтали в метрах, представленное одним пикселем.
|
||||
## [param lat] - Широта, градусы.[br]
|
||||
## [param zoom] - Уровень детализации.[br]
|
||||
## [param size] - Размер плитки в пикселях.[br]
|
||||
@@ -172,7 +171,7 @@ func dist_per_pixel(lat: float, zoom: int, size: int = 256) -> float:
|
||||
return (CE / float(size)) * cos(radians(lat)) / float(2 ** zoom)
|
||||
|
||||
|
||||
## Расстояние по горизонтали в метрах, представленное одной плиткой
|
||||
## Расстояние по горизонтали в метрах, представленное одной плиткой.
|
||||
## [param lat] - Широта, градусы.[br]
|
||||
## [param zoom] - Уровень детализации.[br]
|
||||
func dist_per_tile(lat: float, zoom: int) -> float:
|
||||
@@ -226,7 +225,7 @@ func get_degrees_bounds(m: float, lng: float, lat: float) -> Array[float]:
|
||||
return [x_y[0] - m, x_y[1] - m, x_y[0] + m, x_y[1] + m]
|
||||
|
||||
|
||||
## Возвращает границы плиток в градусах
|
||||
## Возвращает границы плиток в градусах.
|
||||
func get_tiles_bounds(tiles: Array[Tile]) -> Array:
|
||||
var mm = []
|
||||
for t in tiles: mm.append(bounds(t).west)
|
||||
@@ -245,7 +244,7 @@ func get_tiles_bounds(tiles: Array[Tile]) -> Array:
|
||||
|
||||
|
||||
## Возвращает левую верхнюю долготу и широту плитки.[br]
|
||||
## [param tile] Плитка.[br]
|
||||
## [param tile] - Плитка.[br]
|
||||
## [codeblock]
|
||||
## >>> ul(Tile(x=0, y=0, z=1))
|
||||
## LngLat(lng=-180.0, lat=85.0511287798066)
|
||||
@@ -322,10 +321,10 @@ func lnglat(x: float, y: float, truncate: bool = false) -> LngLat:
|
||||
return LngLat.new(ll[0], ll[1])
|
||||
|
||||
|
||||
## Соседи плитки. [method neighbors] возвращает до восьми
|
||||
## соседних плиток, при этом плитки будут опущены, если они не являются действительными, например.
|
||||
## Tile(-1, -1, z). [param tile]: Плитка или последовательность int
|
||||
## Может быть либо экземпляр Tile, либо 3 ints, X, Y, Z.
|
||||
## Соседи плитки. [method neighbors] возвращает до восьми.[br]
|
||||
## Cоседних плиток, при этом плитки будут опущены, если они не являются действительными, например:[br]
|
||||
## Tile(-1, -1, z). [param tile]: Плитка или последовательность int.[br]
|
||||
## Может быть либо экземпляр Tile, либо 3 ints, X, Y, Z.[br]
|
||||
## [return] Массив
|
||||
## [codeblock]
|
||||
## >>> neighbors(Tile(486, 332, 10))
|
||||
@@ -343,7 +342,7 @@ func neighbors(tile: Tile) -> Array:
|
||||
return tiles
|
||||
|
||||
|
||||
## Возвращает все плитки в радиусе [param r] вокруг заданной плитки [param tile]
|
||||
## Возвращает все плитки в радиусе [param r] вокруг заданной плитки [param tile].
|
||||
func get_allaround_tiles(tile: Tile, mr: int = 1) -> Array:
|
||||
var xys = {}
|
||||
var mi: int = 2 ** tile.z
|
||||
@@ -361,7 +360,7 @@ func get_allaround_tiles(tile: Tile, mr: int = 1) -> Array:
|
||||
return tiles
|
||||
|
||||
|
||||
## Возвращает все плитки по периметру заданной плитки
|
||||
## Возвращает все плитки по периметру заданной плитки.
|
||||
func get_perimetr_tiles(tile: Tile, mr: int = 1) -> Array:
|
||||
var tiles = []
|
||||
for i in range(-mr, mr + 1):
|
||||
@@ -375,7 +374,7 @@ func get_perimetr_tiles(tile: Tile, mr: int = 1) -> Array:
|
||||
|
||||
## Получение меркаторской граничной рамки веб-плитки.[br]
|
||||
## [param tile] - Плитка.[br]
|
||||
## [i]Эпсилон вычитается из правой границы и прибавляется к нижней[/i]
|
||||
## [i]Эпсилон вычитается из правой границы и прибавляется к нижней.[/i]
|
||||
func xy_bounds(tile: Tile, zoom: int) -> Bbox:
|
||||
var tile_size = CE / pow(2, zoom)
|
||||
var left = tile.x * tile_size - CE / 2
|
||||
@@ -393,7 +392,7 @@ func _xy(lng: float, lat: float, truncate=false) -> Array:
|
||||
return [x, y]
|
||||
|
||||
|
||||
## Получение плитки, содержащей долготу и широту
|
||||
## Получение плитки, содержащей долготу и широту.
|
||||
## [param lng], [param lat] - Пара долготы и широты в десятичных градусах.[br]
|
||||
## [param zoom] - Уровень масштабирования веб-меркатора.[br]
|
||||
## [param truncate] - Нужно ли усекать вводимые данные до границ веб-меркатора.[br]
|
||||
@@ -419,7 +418,7 @@ func create_tile(lng: float, lat: float, zoom: int, truncate: bool=false) -> Til
|
||||
|
||||
|
||||
## Получение четверного ключа плитки.[br]
|
||||
## [param tile] - Плитка
|
||||
## [param tile] - Плитка.
|
||||
func quadkey(tile: Tile, zoom: int) -> String:
|
||||
var rs: = ''
|
||||
for z in range(zoom, 0, -1):
|
||||
@@ -650,7 +649,7 @@ func _get_bbox_zoom(bbox: Array):
|
||||
## [param tile] - Плитка.[br]
|
||||
## [param fid] - Идентификатор объекта.[br]
|
||||
## [param props] - Необязательные дополнительные свойства признака.[br]
|
||||
## [param projected] - Можно создать нестандартный веб-меркатор GeoJSON передав 'mercator'[br]
|
||||
## [param projected] - Можно создать нестандартный веб-меркатор GeoJSON передав 'mercator'.[br]
|
||||
## [param buffer] - Необязательное буферное расстояние для полигона GeoJSON.[br]
|
||||
## [param precision] - Координаты GeoJSON будут усечены до данного количества знаков после запятой.[br]
|
||||
func feature(tile: Tile, fid:String = 'null', props=null, projected='geographic', buffer=null) -> Dictionary:
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
extends Node
|
||||
class_name mod_bus extends Node
|
||||
|
||||
const ONLINE_TIMEOUT = 5.0 ## Время ожидания пакета от ячейки, секунды
|
||||
const ONLINE_TIMEOUT = 5.0 ## Время ожидания пакета от ячейки, секунды.
|
||||
|
||||
class ModbusClient:
|
||||
|
||||
## Состояние автомата выполнения команды
|
||||
## Состояние автомата выполнения команды.
|
||||
enum CmdState {
|
||||
DONE, ## Команда выполнена
|
||||
FAIL, ## Команда не выполнена
|
||||
SEND, ## Буфер готов для отправки
|
||||
WAIT ## Ожидание выполнения
|
||||
DONE, ## Команда выполнена.
|
||||
FAIL, ## Команда не выполнена.
|
||||
SEND, ## Буфер готов для отправки.
|
||||
WAIT ## Ожидание выполнения.
|
||||
}
|
||||
|
||||
var name: String
|
||||
var unit: = 1 ## Адрес устройства Modbus
|
||||
var cmd_state: = CmdState.DONE ## Код текущей команды
|
||||
var tx_data: PackedByteArray ## Данные для отправки
|
||||
var unit: = 1 ## Адрес устройства Modbus.
|
||||
var cmd_state: = CmdState.DONE ## Код текущей команды.
|
||||
var tx_data: PackedByteArray ## Данные для отправки.
|
||||
var online: = false ## Флаг. Если установлен, устройство на связи. Активный уровень - [b]true[/b].
|
||||
var tick_rx: = 0 ## Время приёма крайнего сообщения
|
||||
var tick_tx: = 0 ## Время отправки крайнего сообщения
|
||||
var tick_rx: = 0 ## Время приёма крайнего сообщения.
|
||||
var tick_tx: = 0 ## Время отправки крайнего сообщения.
|
||||
|
||||
static var json_conv: = JSON.new()
|
||||
|
||||
signal command_done() ## Вызывается при успешном выполнении команды
|
||||
signal command_fail() ## Вызывается при возникновении ошибки во время выполнения команды
|
||||
signal line_changed() ## Вызывается при смене состояния связи с ячейкой
|
||||
signal data_received() ## Вызывается при приёме сообщения, до его разбора
|
||||
signal parse_failed(msg: String) ## Вызывается при возникновении ошибки во время разбора пакета. Передаёт сообщение об ошибке
|
||||
signal command_done() ## Вызывается при успешном выполнении команды.
|
||||
signal command_fail() ## Вызывается при возникновении ошибки во время выполнения команды.
|
||||
signal line_changed() ## Вызывается при смене состояния связи с ячейкой.
|
||||
signal data_received() ## Вызывается при приёме сообщения, до его разбора.
|
||||
signal parse_failed(msg: String) ## Вызывается при возникновении ошибки во время разбора пакета. Передаёт сообщение об ошибке.
|
||||
|
||||
signal holding_received(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров хранения
|
||||
signal input_received(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров входов
|
||||
signal info_received(msg: String) ## Вызывается при получении информационного сообщения
|
||||
signal except_received(msg: String) ## Вызывается при получении сообщения об исключительной ситуации
|
||||
signal holding_received(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров хранения.
|
||||
signal input_received(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров входов.
|
||||
signal info_received(msg: String) ## Вызывается при получении информационного сообщения.
|
||||
signal except_received(msg: String) ## Вызывается при получении сообщения об исключительной ситуации.
|
||||
|
||||
func _init(nm: String, u: int = 1):
|
||||
unit = u
|
||||
name = nm
|
||||
|
||||
## Изменяет состояние. Вызывать периодически[br]
|
||||
## [param tick] - Текущщее время в мс[br]
|
||||
## Изменяет состояние. Вызывать периодически.[br]
|
||||
## [param tick] - Текущщее время в мс.[br]
|
||||
func process(tick: int):
|
||||
if online and ((tick - tick_rx) > ONLINE_TIMEOUT):
|
||||
online = false
|
||||
@@ -53,9 +53,9 @@ class ModbusClient:
|
||||
cmd_state = CmdState.WAIT
|
||||
return rc
|
||||
|
||||
## Производит разбор принятых данных. Вызывать при приёме данных на сокете[br]
|
||||
## [param data] - Данные принятые на сокете[br]
|
||||
## [param tick] - Текущщее время в мс[br]
|
||||
## Производит разбор принятых данных. Вызывать при приёме данных на сокете.[br]
|
||||
## [param data] - Данные принятые на сокете.[br]
|
||||
## [param tick] - Текущщее время в мс.[br]
|
||||
func parse(data: PackedByteArray, tick: int) -> bool:
|
||||
tick_rx = tick
|
||||
if not online:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
extends Node
|
||||
class_name rep_network extends Node
|
||||
|
||||
|
||||
const PROTOCOL_TYPES: = {'yau07tx': yau07.YaU07, 'jsontx': capsrpb.CapsRpb, 'udp-json-mbcs': modbus.ModbusClient}
|
||||
@@ -11,17 +11,17 @@ class Socket extends PacketPeerUDP:
|
||||
|
||||
|
||||
class SocketTCP extends TCPServer:
|
||||
const RX_TIMEOUT: int = 1000 # Время сброса счётчика принятия части пакета
|
||||
const RX_TIMEOUT: int = 1000 ## Время сброса счётчика принятия части пакета.
|
||||
var peerstream: = PacketPeerStream.new()
|
||||
var unit_key: Array # Клюс юнита
|
||||
var head_len: int = 8 # Длинна заголовка команды
|
||||
var len_place: int = 4 # Номер начального байта с длинной блока данных
|
||||
var type_len: int = 4 # Количество байт в размере длинны
|
||||
var rx_tick: int # Время приёма последнего пакета
|
||||
var rx_all: bool = true # Флаг, что пакет принят полностью
|
||||
var rx_len: int # Количество принятых байт
|
||||
var rx_data: PackedByteArray # Принятые данные
|
||||
var data_len: int # Размер ожидаемых данных
|
||||
var unit_key: Array ## Клюс юнита.
|
||||
var head_len: int = 8 ## Длинна заголовка команды.
|
||||
var len_place: int = 4 ## Номер начального байта с длинной блока данных.
|
||||
var type_len: int = 4 ## Количество байт в размере длинны.
|
||||
var rx_tick: int ## Время приёма последнего пакета.
|
||||
var rx_all: bool = true ## Флаг, что пакет принят полностью.
|
||||
var rx_len: int ## Количество принятых байт.
|
||||
var rx_data: PackedByteArray ## Принятые данные.
|
||||
var data_len: int ## Размер ожидаемых данных.
|
||||
|
||||
func send_to(data):
|
||||
var peer = peerstream.get_stream_peer()
|
||||
@@ -69,8 +69,8 @@ func _ready() -> void:
|
||||
sock_capsrpb = poll_sockets[2]
|
||||
|
||||
for unit_name in repsettings.UnitProfiles:
|
||||
var setting = repsettings.UnitProfiles[unit_name]
|
||||
var proto = setting[0]
|
||||
var settings = repsettings.UnitProfiles[unit_name]
|
||||
var proto = settings[0]
|
||||
if proto in PROTOCOL_TYPES:
|
||||
var unit = PROTOCOL_TYPES[proto].new(unit_name)
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
extends Node
|
||||
|
||||
## Параметры
|
||||
class_name rep_settings extends Node
|
||||
|
||||
## Параметры.
|
||||
|
||||
@export var UnitProfiles: = { \
|
||||
# Название | Протокол | Адрес | Порт | Широковещательное | Привязывать к адресу | Комментарий
|
||||
@@ -34,7 +33,7 @@ extends Node
|
||||
'уарэп-спт25-2': ['uart', '/dev/tty3', 115200, false, 'Адрес прибора СПТ-25 (G2)'],
|
||||
}
|
||||
|
||||
## Параметры цели
|
||||
## Параметры цели.
|
||||
@export var ThreatParams = {
|
||||
'time_lost': 5000 ## Время после последнего обновления в мс, через которое цель считается потерянной.
|
||||
}
|
||||
@@ -43,7 +42,7 @@ extends Node
|
||||
func _ready() -> void: log.info('Модуль настроек готов')
|
||||
|
||||
|
||||
## Возвращает ключ устройства
|
||||
## Возвращает ключ устройства.
|
||||
func get_unit_key(unit_name: String) -> Array:
|
||||
assert(UnitProfiles.has(unit_name), 'ошибка: нет такого устройства \"%s\"' % unit_name)
|
||||
var item = UnitProfiles[unit_name]
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
class_name Signaller extends Node
|
||||
|
||||
## Обмен сигналами между узлами. Здесь объявлены сигналы, которые используют
|
||||
## Обмен сигналами между узлами. Здесь объявлены сигналы, которые используют.
|
||||
## два и более узла, из разных файлов. Должен быть помещён в автозагрузку.
|
||||
|
||||
func conn(sgnl: Signal, clbl: Callable): connect(sgnl.get_name(), clbl)
|
||||
|
||||
## Вызывается при переходе в режим [b]Работа[/b]
|
||||
## Вызывается при переходе в режим [b]Работа[/b].
|
||||
signal режим_работа()
|
||||
|
||||
|
||||
## Вызывается при переходе в режим [b]Контроль[/b]
|
||||
## Вызывается при переходе в режим [b]Контроль[/b].
|
||||
signal режим_контроль()
|
||||
|
||||
|
||||
## Вызывается при переходе в режим [b]Журнал[/b]
|
||||
## Вызывается при переходе в режим [b]Журнал[/b].
|
||||
signal режим_журнал()
|
||||
|
||||
|
||||
## Вызывается при переходе в режим [b]ЭМС[/b]
|
||||
## Вызывается при переходе в режим [b]ЭМС[/b].
|
||||
signal режим_эмс()
|
||||
|
||||
|
||||
## Вызывается при переходе в режим [b]Настройка[/b]
|
||||
## Вызывается при переходе в режим [b]Настройка[/b].
|
||||
signal режим_настройки()
|
||||
|
||||
|
||||
## Вызывается, когда оператор переводит программу в режим [b]Автомат выбора цели и помехи[/b]
|
||||
## Вызывается, когда оператор переводит программу в режим [b]Автомат выбора цели и помехи[/b].
|
||||
signal full_auto()
|
||||
|
||||
|
||||
## Вызывается, когда оператор переводит программу в режим [b]Автомат выбора цели[/b]
|
||||
## Вызывается, когда оператор переводит программу в режим [b]Автомат выбора цели[/b].
|
||||
signal threat_auto()
|
||||
|
||||
|
||||
## Вызывается, когда оператор переводит программу в режим [b]Автомат выбора помехи[/b]
|
||||
## Вызывается, когда оператор переводит программу в режим [b]Автомат выбора помехи[/b].
|
||||
signal interfer_auto()
|
||||
|
||||
|
||||
## Вызывается, когда оператор переводит программу в режим [b]Ручной[/b]
|
||||
## Вызывается, когда оператор переводит программу в режим [b]Ручной[/b].
|
||||
signal manual_control()
|
||||
|
||||
|
||||
@@ -59,21 +59,21 @@ signal full_screen(id: int)
|
||||
|
||||
|
||||
## Вызывается, когда пользователь выбирает цель.[br]
|
||||
## [param th_id] - Отметка цели на экране
|
||||
## [param th_id] - Отметка цели на экране.
|
||||
signal rto_threat_sel (th_id: int)
|
||||
|
||||
|
||||
## Вызывается, когда пользователь нажимает на значёк цели.[br]
|
||||
## [param th_id] - Отметка цели на экране
|
||||
## [param th_id] - Отметка цели на экране.
|
||||
signal bip_pressed (th_id: int)
|
||||
|
||||
|
||||
## Вызывается, когда пользователь снимает выделение с цели.[br]
|
||||
## [param th_id] - Отметка цели на экране
|
||||
## [param th_id] - Отметка цели на экране.
|
||||
signal rto_threat_unsel (th_id: int)
|
||||
|
||||
|
||||
## Вызывается, когда пользователь снимает выделение со всех целей
|
||||
## Вызывается, когда пользователь снимает выделение со всех целей.
|
||||
signal rto_threat_unsel_all ()
|
||||
|
||||
|
||||
@@ -100,40 +100,30 @@ signal interfer_new (ecm: interfer.Interfer)
|
||||
signal interfer_off (ecm: interfer.Interfer, ecms: Dictionary, thrs: Dictionary)
|
||||
|
||||
|
||||
## Вызывается при нажатии отключить все помехи
|
||||
## Вызывается при нажатии отключить все помехи.
|
||||
signal interfer_off_all ()
|
||||
|
||||
|
||||
## Вызывается при получении внешнего целеуказания
|
||||
## Вызывается при получении внешнего целеуказания.
|
||||
## [param interfer_params] - Параметры полученной помехи от 5П-28.[br]
|
||||
signal interfer_rcv(interfer_params: Array)
|
||||
|
||||
|
||||
## Вызывается, когда отключается действующая помеха.[br]
|
||||
## [param ecm] - Выбранная помеха
|
||||
## [param ecm] - Выбранная помеха.
|
||||
signal interfer_selected (ecm: interfer.Interfer)
|
||||
|
||||
|
||||
## Вызывается, когда отключается выбираем помеху по сектору в таблице.[br]
|
||||
## [param ecm] - Выбранная помеха
|
||||
## [param ecm] - Выбранная помеха.
|
||||
signal fs_selected(ecm: interfer.Interfer)
|
||||
|
||||
|
||||
## Вызывается при запросе изменения уровня детализации карты.[br]
|
||||
## [param zoom] - Вновь установленный уровень детализации
|
||||
signal zoom_changed(zoom: int)
|
||||
|
||||
|
||||
## Вызывается при завершении изменения уровня детализации карты.[br]
|
||||
## [param zoom] - Вновь установленный уровень детализации
|
||||
signal zoom_complete(zoom: int)
|
||||
|
||||
|
||||
## Вызывается при изменении координат карты.[br]
|
||||
## [param lan], [param lat] - Вновь установленные координаты.
|
||||
signal map_coords_changed(lan: float, lat: float)
|
||||
|
||||
|
||||
## Вызывается при изменении размера изображения для отображения карты.[br]
|
||||
## [param mode] - Вновь установленный режим
|
||||
## [param mode] - Вновь установленный режим.
|
||||
signal map_mode_changed(mode: int)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
extends Node
|
||||
class_name tcp5_p28 extends Node
|
||||
|
||||
## Реализация "Протокол информационного сопряжения
|
||||
## СПО АСУ изделия «МП‑550» с СПО 5П-28"
|
||||
## Реализация "Протокол информационного сопряжения.
|
||||
## СПО АСУ изделия «МП‑550» с СПО 5П-28".
|
||||
|
||||
|
||||
const ONLINE_TIMEOUT = 5000 ## Время ожидания пакета от 5П-28, мс
|
||||
const BUFFER_SIZE = 2048 ## Размер приёмного буфера для датаграмм
|
||||
const ONLINE_TIMEOUT = 5000 ## Время ожидания пакета от 5П-28, мс.
|
||||
const BUFFER_SIZE = 2048 ## Размер приёмного буфера для датаграмм.
|
||||
|
||||
## Тип модуляции для запаковки в пакет для 5П-28
|
||||
## Тип модуляции для запаковки в пакет для 5П-28.
|
||||
const MOD_TYPES: Array = ['',
|
||||
'am',
|
||||
'ook',
|
||||
@@ -41,18 +41,18 @@ class TCP5P28:
|
||||
const CMD_TYPE_TH: int = 2
|
||||
const CMD_TYPE_IN: int = 3
|
||||
|
||||
signal line_changed(unit: TCP5P28) ## Сигнал состояние связи изменилось
|
||||
signal data_received(unit: TCP5P28) ## Сигнал данные приняты
|
||||
signal command_fail(unit: TCP5P28) ## Сигнал при не выполнении команды
|
||||
signal parse_error(unit: TCP5P28, msg: String) ## Сигнал ошибки разбора сообщения
|
||||
signal get_threats(unit: TCP5P28) ## Сигнал запрос целей
|
||||
signal get_interfers(unit: TCP5P28) ## Запрос состояния выполнения целеуказания
|
||||
signal line_changed(unit: TCP5P28) ## Сигнал состояние связи изменилось.
|
||||
signal data_received(unit: TCP5P28) ## Сигнал данные приняты.
|
||||
signal command_fail(unit: TCP5P28) ## Сигнал при не выполнении команды.
|
||||
signal parse_error(unit: TCP5P28, msg: String) ## Сигнал ошибки разбора сообщения.
|
||||
signal get_threats(unit: TCP5P28) ## Сигнал запрос целей.
|
||||
signal get_interfers(unit: TCP5P28) ## Запрос состояния выполнения целеуказания.
|
||||
|
||||
var online: = false ## Состояние связи с источником сообщений
|
||||
var name: String ## Имя экземпляра
|
||||
var rx_tick: = 0 ## Тик время последнего приёма, мс
|
||||
var tx_data: = PackedByteArray() ## Пакет для отправки
|
||||
var tx_stack: Array ## Массив пакетов для отправки
|
||||
var online: = false ## Состояние связи с источником сообщений.
|
||||
var name: String ## Имя экземпляра.
|
||||
var rx_tick: = 0 ## Тик время последнего приёма, мс.
|
||||
var tx_data: = PackedByteArray() ## Пакет для отправки.
|
||||
var tx_stack: Array ## Массив пакетов для отправки.
|
||||
|
||||
func _to_string() -> String: return String('капсрпб: "%s" %s ' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
func _init(nm): self.name = nm
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extends Node
|
||||
|
||||
## Работа с целями
|
||||
## Работа с целями.
|
||||
|
||||
|
||||
## Цель
|
||||
@@ -26,7 +26,7 @@ class Threat:
|
||||
var tick_rx: int ## Тик время обновления цели, мс.
|
||||
var tmod: String ## Тип модуляции.
|
||||
var width: float ## Ширина занимаемого диапазона частот, МГц.
|
||||
var selected: bool ## Флаг, что цель выбрана
|
||||
var selected: bool ## Флаг, что цель выбрана.
|
||||
|
||||
func _init(): clear_fflags()
|
||||
func _to_string() -> String: return 'номер: %d пеленг: %0.1f частота: %0.1f МГц' % [id, aoa, freq]
|
||||
@@ -62,7 +62,7 @@ func _ready() -> void:
|
||||
signaller.connect('threat_selected', Callable(self, 'on_threat_selected').bind(threats))
|
||||
signaller.connect('interfer_init', Callable(self, 'on_interfer_init').bind(threats))
|
||||
|
||||
## Периодически удаляет устаревшие цели
|
||||
## Периодически удаляет устаревшие цели.
|
||||
func on_timer_check_lost(time_lost: int, threats: Dictionary):
|
||||
var tick = Time.get_ticks_msec()
|
||||
var sz: = threats.size()
|
||||
@@ -74,7 +74,7 @@ func on_timer_check_lost(time_lost: int, threats: Dictionary):
|
||||
call_deferred('emit_signal', 'threats_resized', threats)
|
||||
|
||||
|
||||
## отправляет словарь целей в юнит, для запаковки и отправки в 5П28
|
||||
## отправляет словарь целей в юнит, для запаковки и отправки в 5П28.
|
||||
func on_get_threats(unit, threats): unit.pack_threats(threats)
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ func on_get_threats(unit, threats): unit.pack_threats(threats)
|
||||
func on_rto_threat_unsel(th_id, threats): threats[th_id].selected = false
|
||||
|
||||
|
||||
## Снимает выделение со всех целей
|
||||
## Снимает выделение со всех целей.
|
||||
func on_rto_threat_unsel_all(threats):
|
||||
for th in threats.values():
|
||||
signaller.emit_signal('rto_threat_unsel', th.id)
|
||||
@@ -92,14 +92,14 @@ func on_rto_threat_unsel_all(threats):
|
||||
func on_rto_threat_sel(th_id, threats): on_threat_selected(threats[th_id], threats)
|
||||
|
||||
|
||||
## Выбирает цель, если выбрать в таблице
|
||||
## Выбирает цель, если выбрать в таблице.
|
||||
func on_threat_selected(th, threats):
|
||||
for threat in threats.values():
|
||||
threat.selected = false
|
||||
th.selected = true
|
||||
|
||||
|
||||
## Формирует список выбранных целей для включения помехи
|
||||
## Формирует список выбранных целей для включения помехи.
|
||||
func on_interfer_init(btn, fs_arr, threats):
|
||||
var sel_threats: Array = []
|
||||
for threat in threats.values():
|
||||
@@ -109,7 +109,7 @@ func on_interfer_init(btn, fs_arr, threats):
|
||||
signaller.emit_signal('interfer_create', btn, sel_threats, fs_arr)
|
||||
|
||||
|
||||
## Производит приём целей
|
||||
## Производит приём целей.
|
||||
func on_data_capsrpb_received(unit: capsrpb.CapsRpb, threats: Dictionary):
|
||||
if not unit.json_dic.has('ts'): return
|
||||
if unit.json_dic['ts'] != 5: return
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
@tool
|
||||
extends Node
|
||||
class_name Tools extends Node
|
||||
|
||||
## Простые часто используемые функции
|
||||
## Простые часто используемые функции.
|
||||
|
||||
|
||||
## Возвращает округлённое значение [param v] с точностью [param a]
|
||||
## Возвращает округлённое значение [param v] с точностью [param a].
|
||||
func round_to(v: float, a: float) -> float: return snappedf(v, -a if v < 0 else a)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ func radians(val: float): return (val * PI) / 180.0
|
||||
func ibytes_to_word(buf: PackedByteArray, i: int) -> int: return buf[i] + (buf[i + 1] * 256)
|
||||
|
||||
|
||||
## Возвращает расстояние от центра координат до точки
|
||||
## Возвращает расстояние от центра координат до точки.
|
||||
func hypot(x: float, y: float) -> float: return sqrt(x * x + y * y)
|
||||
|
||||
|
||||
@@ -70,21 +70,21 @@ func get_string_slice(s_in: String, s_out: Array, i0: int, i1: int):
|
||||
s_out[0] += s_in[i]
|
||||
|
||||
|
||||
## Производит преобразование из декартовой в полярную систему координат
|
||||
## Производит преобразование из декартовой в полярную систему координат.
|
||||
func pos_calc(freq: float, aoa: float, pos0: Vector2, r0: float, r1: float, f0: float, f1: float):
|
||||
var r = ((freq - f0) / (f1 - f0)) * r1 + r0
|
||||
var aoa_rad = radians(aoa) - PI / 2.0
|
||||
return Vector2(cos(aoa_rad), sin(aoa_rad)) * r + pos0
|
||||
|
||||
|
||||
## Отсекает значение до заданного диапазона
|
||||
## Отсекает значение до заданного диапазона.
|
||||
func clip_value(val, val_min, val_max):
|
||||
if val < val_min: val = val_min
|
||||
if val > val_max: val = val_max
|
||||
return val
|
||||
|
||||
|
||||
## Возвращает массив с именами членов [param obj]
|
||||
## Возвращает массив с именами членов [param obj].
|
||||
func get_members_names(obj: Object) -> Array:
|
||||
var pl = obj.get_property_list()
|
||||
var names: = Array()
|
||||
@@ -92,7 +92,7 @@ func get_members_names(obj: Object) -> Array:
|
||||
return names
|
||||
|
||||
|
||||
## Проверяет, что заданный массив [param val] похож на ip-адрес
|
||||
## Проверяет, что заданный массив [param val] похож на ip-адрес.
|
||||
func is_array_ipaddr(val: Array):
|
||||
return (val.size() == 2) \
|
||||
and (val[0] is String) \
|
||||
@@ -111,7 +111,7 @@ func map_dec_to_rad(pos0: Vector2, pos: Vector2) -> Vector2:
|
||||
return Vector2(ang + 360.0 * float(ang < 0.0), hypot(x1, y1))
|
||||
|
||||
|
||||
## Переводит значение val из диапазона a0...a1 в диапазон b0...b1
|
||||
## Переводит значение val из диапазона a0...a1 в диапазон b0...b1.
|
||||
func map_range(val: float, a0: float, a1: float, b0: float, b1: float) -> float:
|
||||
return (((val - a0) * (b1 - b0)) / (a1 - a0)) + b0
|
||||
|
||||
@@ -131,7 +131,7 @@ func is_point_in_polygon(pos: Vector2, p: PackedVector2Array) -> bool:
|
||||
return odd_nodes > 0
|
||||
|
||||
|
||||
## Записывает слово [param val] в элемент байтовго массива [param buf]
|
||||
## Записывает слово [param val] в элемент байтовго массива [param buf].
|
||||
## расположенный по индексу [param index] (младшее слово).[br]
|
||||
## [i]Следует использовать встроенные в[/i] [b]PackedByteArray[/b] [i]методы вместо этой функции.[/i]
|
||||
func set_wordi(buf: PackedByteArray, index: int, val: int) -> void:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extends Node
|
||||
class_name yau_07 extends Node
|
||||
|
||||
## Протокол ячейки ЯУ-07
|
||||
## Протокол ячейки ЯУ-07.
|
||||
|
||||
const ONLINE_TIMEOUT = 5.0 ## Время ожидания пакета от ячейки, секунды
|
||||
const RESEND_TIMEOUT = 0.3 ## Задержка для повторной отправки команды, секунды
|
||||
@@ -8,47 +8,47 @@ const RETRY_COUNT = 5 ## Количество повторных отпр
|
||||
const BUFFER_SIZE = 2048 ## Размер буфера для приёма датаграмм
|
||||
|
||||
|
||||
## Ячейка ЯУ-07
|
||||
## Ячейка ЯУ-07.
|
||||
class YaU07:
|
||||
|
||||
## Коды выполняемых команд
|
||||
## Коды выполняемых команд.
|
||||
enum CmdCode {
|
||||
READ_ISA = 0, ## Код команды "читать порт ISA" ячейки ЯУ-07
|
||||
WRITE_ISA = 1, ## Код команды "записать порт ISA" ячейки ЯУ-07
|
||||
WRITE_BLOCK = 60, ## Код команды "записать блок данных ISA" внешней шины ячейки ЯУ-07
|
||||
READ_BLOCK = 61, ## Код команды "читать блок данных ISA" внешней шины ячейки ЯУ-07
|
||||
READ_ISA = 0, ## Код команды "читать порт ISA" ячейки ЯУ-07.
|
||||
WRITE_ISA = 1, ## Код команды "записать порт ISA" ячейки ЯУ-07.
|
||||
WRITE_BLOCK = 60, ## Код команды "записать блок данных ISA" внешней шины ячейки ЯУ-07.
|
||||
READ_BLOCK = 61, ## Код команды "читать блок данных ISA" внешней шины ячейки ЯУ-07.
|
||||
}
|
||||
|
||||
## Состояние автомата выполнения команды
|
||||
## Состояние автомата выполнения команды.
|
||||
enum CmdState {
|
||||
UNCK, ## Номер команды не ининциирован
|
||||
SEND, ## Буфер готов для отправки
|
||||
WAIT, ## Ожидание выполнения
|
||||
DONE, ## Команда выполнена
|
||||
FAIL ## Команда не выполнена
|
||||
UNCK, ## Номер команды не ининциирован.
|
||||
SEND, ## Буфер готов для отправки.
|
||||
WAIT, ## Ожидание выполнения.
|
||||
DONE, ## Команда выполнена.
|
||||
FAIL ## Команда не выполнена.
|
||||
}
|
||||
|
||||
signal line_changed(unit: YaU07) ## Вызывается когда меняется состояние связи с ячейкой
|
||||
signal command_done(unit: YaU07) ## Вызывается после выполнения команды
|
||||
signal command_fail(unit: YaU07) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена
|
||||
signal line_changed(unit: YaU07) ## Вызывается когда меняется состояние связи с ячейкой.
|
||||
signal command_done(unit: YaU07) ## Вызывается после выполнения команды.
|
||||
signal command_fail(unit: YaU07) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена.
|
||||
signal parse_failed(unit: YaU07)
|
||||
|
||||
var name: = String()
|
||||
var cmd_num_rx: = 0 ## Номер команды принятый
|
||||
var cmd_num_tx: = 0 ## Номер команды переданный
|
||||
var cmd_state = CmdState.UNCK ## Состояние выполнения команды
|
||||
var cmd_result: = 1 ## Результат выполнения команды. Устанавливается в ЯУ-07
|
||||
var cmd_data: = PackedByteArray() ## Данные команды. Устанавливается в ЯУ-07
|
||||
var cmd_retry = 0 ## Счётчик оставшихся попыток выполнить команду
|
||||
var tick = 0.0 ## Текущее тик-время в мс
|
||||
var cmd_tick_tx = 0.0 ## Время последней отправки команды
|
||||
var cmd_tick_rx = 0.0 ## Время последнего приёма команды
|
||||
var status: = PackedByteArray() ## Поле "состояние прибора"
|
||||
var tx_data: = PackedByteArray() ## Буфер отправленный
|
||||
var tx_len = 0 ## Длина последнего отправленного пакета
|
||||
var isa_ports = {} ## Результат выполнения команды "читать порт"
|
||||
var isa_block = {} ## Результат выполнения команды "читать массив из порта"
|
||||
var online = false ## Состояние связи с ячейкой
|
||||
var cmd_num_rx: = 0 ## Номер команды принятый.
|
||||
var cmd_num_tx: = 0 ## Номер команды переданный.
|
||||
var cmd_state = CmdState.UNCK ## Состояние выполнения команды.
|
||||
var cmd_result: = 1 ## Результат выполнения команды. Устанавливается в ЯУ-07.
|
||||
var cmd_data: = PackedByteArray() ## Данные команды. Устанавливается в ЯУ-07.
|
||||
var cmd_retry = 0 ## Счётчик оставшихся попыток выполнить команду.
|
||||
var tick = 0.0 ## Текущее тик-время в мс.
|
||||
var cmd_tick_tx = 0.0 ## Время последней отправки команды.
|
||||
var cmd_tick_rx = 0.0 ## Время последнего приёма команды.
|
||||
var status: = PackedByteArray() ## Поле "состояние прибора".
|
||||
var tx_data: = PackedByteArray() ## Буфер отправленный.
|
||||
var tx_len = 0 ## Длина последнего отправленного пакета.
|
||||
var isa_ports = {} ## Результат выполнения команды "читать порт".
|
||||
var isa_block = {} ## Результат выполнения команды "читать массив из порта".
|
||||
var online = false ## Состояние связи с ячейкой.
|
||||
|
||||
func _to_string() -> String: return String('яу07: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
|
||||
@@ -134,9 +134,9 @@ class YaU07:
|
||||
tx_data.encode_u16(9, int(port[0]))
|
||||
cmd_state = CmdState.SEND
|
||||
return true
|
||||
## Возвращает код команды ЯУ-07
|
||||
## rx_data - Принятые данные
|
||||
## Возвращает - Код команды не найден, 0...255 - код команды
|
||||
## Возвращает код команды ЯУ-07.
|
||||
## rx_data - Принятые данные.
|
||||
## Возвращает - Код команды не найден, 0...255 - код команды.
|
||||
func get_cmd_code(rx_data: PackedByteArray):
|
||||
|
||||
var rx_data_len = rx_data.size()
|
||||
@@ -185,11 +185,11 @@ class YaU07:
|
||||
return true
|
||||
|
||||
|
||||
## Заполняет состояние прибора данными прочитанными из портов ЯУ-07
|
||||
## для команд "читать порты" или "записать порты"[br]
|
||||
## [param rx_data] - Принятые данные[br]
|
||||
## Возвращает [b]true[/b] - Данные обработаны успешно[br]
|
||||
## Возвращает [b]false[/b] - Данные не обработаны из за ошибки[br]
|
||||
## Заполняет состояние прибора данными прочитанными из портов ЯУ-07.
|
||||
## для команд "читать порты" или "записать порты".[br]
|
||||
## [param rx_data] - Принятые данные.[br]
|
||||
## Возвращает [b]true[/b] - Данные обработаны успешно.[br]
|
||||
## Возвращает [b]false[/b] - Данные не обработаны из за ошибки.[br]
|
||||
func parse(rx_data: PackedByteArray) -> bool:
|
||||
|
||||
cmd_tick_rx = tick
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
extends Node
|
||||
class_name yems_boards extends Node
|
||||
|
||||
class EmsBoard:
|
||||
var id_board: String
|
||||
var in_devs: Dictionary ## Словарь с входными устройствами
|
||||
var out_devs: Dictionary ## Словарь с выходными устройствами
|
||||
var base_addr_isa: int ## Базовый адрес ячейки isa
|
||||
var in_tbl: Array
|
||||
var out_tbl: Array
|
||||
var id_board: String
|
||||
var in_devs: Dictionary ## Словарь с входными устройствами.
|
||||
var out_devs: Dictionary ## Словарь с выходными устройствами.
|
||||
var base_addr_isa: int ## Базовый адрес ячейки isa.
|
||||
var in_tbl: Array
|
||||
var out_tbl: Array
|
||||
|
||||
func _init(id, base_addr, in_table, out_table):
|
||||
id_board = id
|
||||
in_tbl = in_table
|
||||
out_tbl = out_table
|
||||
base_addr_isa = base_addr
|
||||
func _init(id, base_addr, in_table, out_table):
|
||||
id_board = id
|
||||
in_tbl = in_table
|
||||
out_tbl = out_table
|
||||
base_addr_isa = base_addr
|
||||
|
||||
@@ -1,144 +1,144 @@
|
||||
extends Node
|
||||
class_name yerms_consts extends Node
|
||||
|
||||
##
|
||||
## Таблица с данными для входов, первое значение - индекс устройства в ячейке КЭМС.
|
||||
const INPUT_ROWS1 = [
|
||||
[12,['283333 МР-231S, Строб ЭМС', 'X52', '0.00', '0.00']],
|
||||
[13,['29НРЛС МР-231-3, УИЗП', 'X54', '0.00', '0.00']],
|
||||
[14,['30НРЛС МР-231-3, Строб ЭМС', 'X55', '0.00', '0.00']],
|
||||
[15,['31ЦИСВС-1010, УИЗП', 'X23', '0.00', '0.00']],
|
||||
[21,['32НРЛС МР-231S, УИЗП', 'X21', '0.00', '0.00']],
|
||||
[22,['33НРЛС МР-231S, Строб ЭМС', 'X22', '0.00', '0.00']],
|
||||
[23,['34НРЛС МР-231-3, УИЗП', 'X24', '0.00', '0.00']],
|
||||
[32,['352222 МР-231S, Строб ЭМС', 'X32', '0.00', '0.00']],
|
||||
[33,['36НРЛС МР-231-3, УИЗП', 'X34', '0.00', '0.00']],
|
||||
[34,['37НРЛС МР-231-3, Строб ЭМС', 'X35', '0.00', '0.00']],
|
||||
[35,['38ЦИСВС-1010, УИЗП', 'X43', '0.00', '0.00']],
|
||||
[38,['394302-01, 4302-04, УИЗП', 'X46', '0.00', '0.00']],
|
||||
[31,['40НРЛС МР-231S, УИЗП', 'X51', '0.00', '0.00']]]
|
||||
[12,['283333 МР-231S, Строб ЭМС', 'X52', '0.00', '0.00']],
|
||||
[13,['29НРЛС МР-231-3, УИЗП', 'X54', '0.00', '0.00']],
|
||||
[14,['30НРЛС МР-231-3, Строб ЭМС', 'X55', '0.00', '0.00']],
|
||||
[15,['31ЦИСВС-1010, УИЗП', 'X23', '0.00', '0.00']],
|
||||
[21,['32НРЛС МР-231S, УИЗП', 'X21', '0.00', '0.00']],
|
||||
[22,['33НРЛС МР-231S, Строб ЭМС', 'X22', '0.00', '0.00']],
|
||||
[23,['34НРЛС МР-231-3, УИЗП', 'X24', '0.00', '0.00']],
|
||||
[32,['352222 МР-231S, Строб ЭМС', 'X32', '0.00', '0.00']],
|
||||
[33,['36НРЛС МР-231-3, УИЗП', 'X34', '0.00', '0.00']],
|
||||
[34,['37НРЛС МР-231-3, Строб ЭМС', 'X35', '0.00', '0.00']],
|
||||
[35,['38ЦИСВС-1010, УИЗП', 'X43', '0.00', '0.00']],
|
||||
[38,['394302-01, 4302-04, УИЗП', 'X46', '0.00', '0.00']],
|
||||
[31,['40НРЛС МР-231S, УИЗП', 'X51', '0.00', '0.00']]]
|
||||
|
||||
## Таблица с данными для выходов, первое значение - индекс устройства в ячейке КЭМС
|
||||
## Таблица с данными для выходов, первое значение - индекс устройства в ячейке КЭМС.
|
||||
const OUTPUT_ROWS1 = [
|
||||
[41,['41НРЛС МР-231S, БИ', 'X61', '0.00', '0.00']],
|
||||
[42,['42НРЛС МР-231S', 'X62', '0.00', '0.00']],
|
||||
[43,['43НРЛС МР-231-3, БИ', 'X64', '0.00', '0.00']],
|
||||
[44,['44НРЛС МР-231-3', 'X65', '0.00', '0.00']],
|
||||
[45,['45ЦИСВС-1010, БИ', 'X63', '0.00', '0.00']],
|
||||
[46,['464302-01, 4302-04, БИ', 'X66', '0.00', '0.00']],
|
||||
[48,['47НРЛС 11111111', 'X69', '0.00', '0.00']],
|
||||
[62,['48НРЛС МР-231S', 'X62', '0.00', '0.00']],
|
||||
[63,['49НРЛС МР-231-3, БИ', 'X64', '0.00', '0.00']],
|
||||
[64,['50НРЛС МР-231-3', 'X65', '0.00', '0.00']],
|
||||
[65,['51ЦИСВС-1010, БИ', 'X63', '0.00', '0.00']],
|
||||
[66,['524302-01, 4302-04, БИ', 'X66', '0.00', '0.00']],
|
||||
[68,['53НРЛС 11111111', 'X69', '0.00', '0.00']]]
|
||||
[41,['41НРЛС МР-231S, БИ', 'X61', '0.00', '0.00']],
|
||||
[42,['42НРЛС МР-231S', 'X62', '0.00', '0.00']],
|
||||
[43,['43НРЛС МР-231-3, БИ', 'X64', '0.00', '0.00']],
|
||||
[44,['44НРЛС МР-231-3', 'X65', '0.00', '0.00']],
|
||||
[45,['45ЦИСВС-1010, БИ', 'X63', '0.00', '0.00']],
|
||||
[46,['464302-01, 4302-04, БИ', 'X66', '0.00', '0.00']],
|
||||
[48,['47НРЛС 11111111', 'X69', '0.00', '0.00']],
|
||||
[62,['48НРЛС МР-231S', 'X62', '0.00', '0.00']],
|
||||
[63,['49НРЛС МР-231-3, БИ', 'X64', '0.00', '0.00']],
|
||||
[64,['50НРЛС МР-231-3', 'X65', '0.00', '0.00']],
|
||||
[65,['51ЦИСВС-1010, БИ', 'X63', '0.00', '0.00']],
|
||||
[66,['524302-01, 4302-04, БИ', 'X66', '0.00', '0.00']],
|
||||
[68,['53НРЛС 11111111', 'X69', '0.00', '0.00']]]
|
||||
|
||||
## Таблица с данными для входов, первое значение - индекс устройства в ячейке КЭМС
|
||||
## Таблица с данными для входов, первое значение - индекс устройства в ячейке КЭМС.
|
||||
const INPUT_ROWS = [
|
||||
[1,['УИЗП №1', 'Х7', '0.00', '0.00']],
|
||||
[2,['УИЗПФ №1', 'Х8', '0.00', '0.00']],
|
||||
[3,['УИЗП №2', 'Х10', '0.00', '0.00']],
|
||||
[4,['УИЗПФ №2', 'Х11', '0.00', '0.00']],
|
||||
[5,['УИЗП №3', 'Х13', '0.00', '0.00']],
|
||||
[6,['УИЗПФ №3', 'Х14', '0.00', '0.00']],
|
||||
[7,['УИЗП №4', 'Х16', '0.00', '0.00']],
|
||||
[8,['УИЗПФ №4', 'Х17', '0.00', '0.00']],
|
||||
[9,['УИЗП №5', 'Х19', '0.00', '0.00']],
|
||||
[10,['УИЗПФ №5', 'Х20', '0.00', '0.00']],
|
||||
[11,['УИЗП №6', 'Х22', '0.00', '0.00']],
|
||||
[12,['УИЗПФ №6','Х23', '0.00', '0.00']],
|
||||
[13,['УИЗП №7','Х25', '0.00', '0.00']],
|
||||
[14,['УИЗПФ №7','Х26', '0.00', '0.00']],
|
||||
[15,['СИ1 Л1','X31 : 2', '0.00', '0.00']],
|
||||
[16,['СИ1 Л6','X31 : 5', '0.00', '0.00']],
|
||||
[17,['СИ1 Л7','X31 : 8', '0.00', '0.00']],
|
||||
[18,['СИ2 Л1','X32 : 2', '0.00', '0.00']],
|
||||
[19,['СИ2 Л6','X32 : 5', '0.00', '0.00']],
|
||||
[20,['СИ2 Л7','X32 : 8', '0.00', '0.00']],
|
||||
[21,['СИ3 Л1','X33 : 2', '0.00', '0.00']],
|
||||
[22,['СИ3 Л6','X33 : 5', '0.00', '0.00']],
|
||||
[23,['СИ3 Л7','X33 : 8', '0.00', '0.00']],
|
||||
[24,['СИ4 Л1','X34 : 2', '0.00', '0.00']],
|
||||
[25,['СИ4 Л6','X34 : 5', '0.00', '0.00']],
|
||||
[26,['СИ4 Л7','X34 : 8', '0.00', '0.00']],
|
||||
[27,['СИ1 Л2','X38 : 2', '0.00', '0.00']],
|
||||
[28,['СИ1 Л3','X38 : 5', '0.00', '0.00']],
|
||||
[29,['СИ2 Л2','X39 : 2', '0.00', '0.00']],
|
||||
[30,['СИ2 Л3','X39 : 5', '0.00', '0.00']],
|
||||
[31,['СИ3 Л2','X40 : 2', '0.00', '0.00']],
|
||||
[32,['СИ3 Л3','X40 : 5', '0.00', '0.00']],
|
||||
[33,['СИ4 Л2','X41 : 2', '0.00', '0.00']],
|
||||
[34,['СИ4 Л3','X41 : 5', '0.00', '0.00']],
|
||||
[35,['СИ1 Л4','X42 : 2', '0.00', '0.00']],
|
||||
[36,['СИ1 Л5','X42 : 5', '0.00', '0.00']],
|
||||
[37,['СИ2 Л4','X43 : 2', '0.00', '0.00']],
|
||||
[38,['СИ2 Л5','X43 : 5', '0.00', '0.00']],
|
||||
[39,['СИ3 Л4','X44 : 2', '0.00', '0.00']],
|
||||
[40,['СИ3 Л5','X44 : 5', '0.00', '0.00']],
|
||||
[41,['СИ4 Л4','X45 : 2', '0.00', '0.00']],
|
||||
[42,['СИ4 Л5','X45 : 5', '0.00', '0.00']],
|
||||
[43,['БИ В Лб','Х49 : 37', '0.00', '0.00']],
|
||||
[44,['БИ В ПрБ','Х49 : 31', '0.00', '0.00']],
|
||||
[45,['БИ Г Лб','Х49 : 15', '0.00', '0.00']],
|
||||
[46,['БИ Г ПрБ','Х49 : 8', '0.00', '0.00']],
|
||||
[47,['БИ Д Лб','Х49 : 6', '0.00', '0.00']],
|
||||
[48,['БИ Д ПрБ','Х49 : 10', '0.00', '0.00']],
|
||||
[49,['БИ Е Лб','Х49 : 25', '0.00', '0.00']],
|
||||
[50,['БИ Е ПрБ','Х49 : 40', '0.00', '0.00']],
|
||||
[51,['СЗИ В Лб','Х49 : 42', '0.00', '0.00']],
|
||||
[52,['СЗИ В ПрБ','Х49 : 32', '0.00', '0.00']],
|
||||
[53,['СЗИ Г Лб','Х49 : 46', '0.00', '0.00']],
|
||||
[54,['СЗИ Г ПрБ','Х49 : 32', '0.00', '0.00']],
|
||||
[55,['СЗИ Д Лб','Х49 : 16', '0.00', '0.00']],
|
||||
[56,['СЗИ Д ПрБ','Х49 : 47', '0.00', '0.00']],
|
||||
[57,['СЗИ Е Лб','Х49 : 1', '0.00', '0.00']],
|
||||
[58,['СЗИ Е ПрБ','Х49 : 50', '0.00', '0.00']]]
|
||||
[1,['УИЗП №1', 'Х7', '0.00', '0.00']],
|
||||
[2,['УИЗПФ №1', 'Х8', '0.00', '0.00']],
|
||||
[3,['УИЗП №2', 'Х10', '0.00', '0.00']],
|
||||
[4,['УИЗПФ №2', 'Х11', '0.00', '0.00']],
|
||||
[5,['УИЗП №3', 'Х13', '0.00', '0.00']],
|
||||
[6,['УИЗПФ №3', 'Х14', '0.00', '0.00']],
|
||||
[7,['УИЗП №4', 'Х16', '0.00', '0.00']],
|
||||
[8,['УИЗПФ №4', 'Х17', '0.00', '0.00']],
|
||||
[9,['УИЗП №5', 'Х19', '0.00', '0.00']],
|
||||
[10,['УИЗПФ №5', 'Х20', '0.00', '0.00']],
|
||||
[11,['УИЗП №6', 'Х22', '0.00', '0.00']],
|
||||
[12,['УИЗПФ №6','Х23', '0.00', '0.00']],
|
||||
[13,['УИЗП №7','Х25', '0.00', '0.00']],
|
||||
[14,['УИЗПФ №7','Х26', '0.00', '0.00']],
|
||||
[15,['СИ1 Л1','X31 : 2', '0.00', '0.00']],
|
||||
[16,['СИ1 Л6','X31 : 5', '0.00', '0.00']],
|
||||
[17,['СИ1 Л7','X31 : 8', '0.00', '0.00']],
|
||||
[18,['СИ2 Л1','X32 : 2', '0.00', '0.00']],
|
||||
[19,['СИ2 Л6','X32 : 5', '0.00', '0.00']],
|
||||
[20,['СИ2 Л7','X32 : 8', '0.00', '0.00']],
|
||||
[21,['СИ3 Л1','X33 : 2', '0.00', '0.00']],
|
||||
[22,['СИ3 Л6','X33 : 5', '0.00', '0.00']],
|
||||
[23,['СИ3 Л7','X33 : 8', '0.00', '0.00']],
|
||||
[24,['СИ4 Л1','X34 : 2', '0.00', '0.00']],
|
||||
[25,['СИ4 Л6','X34 : 5', '0.00', '0.00']],
|
||||
[26,['СИ4 Л7','X34 : 8', '0.00', '0.00']],
|
||||
[27,['СИ1 Л2','X38 : 2', '0.00', '0.00']],
|
||||
[28,['СИ1 Л3','X38 : 5', '0.00', '0.00']],
|
||||
[29,['СИ2 Л2','X39 : 2', '0.00', '0.00']],
|
||||
[30,['СИ2 Л3','X39 : 5', '0.00', '0.00']],
|
||||
[31,['СИ3 Л2','X40 : 2', '0.00', '0.00']],
|
||||
[32,['СИ3 Л3','X40 : 5', '0.00', '0.00']],
|
||||
[33,['СИ4 Л2','X41 : 2', '0.00', '0.00']],
|
||||
[34,['СИ4 Л3','X41 : 5', '0.00', '0.00']],
|
||||
[35,['СИ1 Л4','X42 : 2', '0.00', '0.00']],
|
||||
[36,['СИ1 Л5','X42 : 5', '0.00', '0.00']],
|
||||
[37,['СИ2 Л4','X43 : 2', '0.00', '0.00']],
|
||||
[38,['СИ2 Л5','X43 : 5', '0.00', '0.00']],
|
||||
[39,['СИ3 Л4','X44 : 2', '0.00', '0.00']],
|
||||
[40,['СИ3 Л5','X44 : 5', '0.00', '0.00']],
|
||||
[41,['СИ4 Л4','X45 : 2', '0.00', '0.00']],
|
||||
[42,['СИ4 Л5','X45 : 5', '0.00', '0.00']],
|
||||
[43,['БИ В Лб','Х49 : 37', '0.00', '0.00']],
|
||||
[44,['БИ В ПрБ','Х49 : 31', '0.00', '0.00']],
|
||||
[45,['БИ Г Лб','Х49 : 15', '0.00', '0.00']],
|
||||
[46,['БИ Г ПрБ','Х49 : 8', '0.00', '0.00']],
|
||||
[47,['БИ Д Лб','Х49 : 6', '0.00', '0.00']],
|
||||
[48,['БИ Д ПрБ','Х49 : 10', '0.00', '0.00']],
|
||||
[49,['БИ Е Лб','Х49 : 25', '0.00', '0.00']],
|
||||
[50,['БИ Е ПрБ','Х49 : 40', '0.00', '0.00']],
|
||||
[51,['СЗИ В Лб','Х49 : 42', '0.00', '0.00']],
|
||||
[52,['СЗИ В ПрБ','Х49 : 32', '0.00', '0.00']],
|
||||
[53,['СЗИ Г Лб','Х49 : 46', '0.00', '0.00']],
|
||||
[54,['СЗИ Г ПрБ','Х49 : 32', '0.00', '0.00']],
|
||||
[55,['СЗИ Д Лб','Х49 : 16', '0.00', '0.00']],
|
||||
[56,['СЗИ Д ПрБ','Х49 : 47', '0.00', '0.00']],
|
||||
[57,['СЗИ Е Лб','Х49 : 1', '0.00', '0.00']],
|
||||
[58,['СЗИ Е ПрБ','Х49 : 50', '0.00', '0.00']]]
|
||||
|
||||
## Таблица с данными для выходов, первое значение - индекс устройства в ячейке КЭМС
|
||||
## Таблица с данными для выходов, первое значение - индекс устройства в ячейке КЭМС.
|
||||
const OUTPUT_ROWS = [
|
||||
[11,['Бланк №1','Х6', '0.00', '0.00']],
|
||||
[12,['Бланк №2','Х9', '0.00', '0.00']],
|
||||
[13,['Бланк №3','Х12', '0.00', '0.00']],
|
||||
[14,['Бланк №4','Х15', '0.00', '0.00']],
|
||||
[15,['Бланк №5','Х18', '0.00', '0.00']],
|
||||
[16,['Бланк №6','Х21', '0.00', '0.00']],
|
||||
[17,['Бланк №7','Х24', '0.00', '0.00']],
|
||||
[18,['СЗИ1 Л1','X31 : 11', '0.00', '0.00']],
|
||||
[19,['СЗИ1 Л6','X31 :14', '0.00', '0.00']],
|
||||
[20,['СЗИ1 Л7','X31 : 17', '0.00', '0.00']],
|
||||
[21,['СЗИ2 Л1','X32 : 11', '0.00', '0.00']],
|
||||
[22,['СЗИ2 Л6','X32 : 14', '0.00', '0.00']],
|
||||
[23,['СЗИ2 Л7','X32: 17', '0.00', '0.00']],
|
||||
[24,['СЗИ3 Л1','X33 : 11', '0.00', '0.00']],
|
||||
[25,['СЗИ3 Л6','X33 :14', '0.00', '0.00']],
|
||||
[26,['СЗИ3 Л7','X33: 17', '0.00', '0.00']],
|
||||
[27,['СЗИ4 Л1','X34 : 11', '0.00', '0.00']],
|
||||
[28,['СЗИ4 Л6','X34 :14', '0.00', '0.00']],
|
||||
[29,['СЗИ4 Л7','X34: 17', '0.00', '0.00']],
|
||||
[30,['СЗИ1 Л2','X38 : 11', '0.00', '0.00']],
|
||||
[31,['СЗИ1 Л3','X38 : 14', '0.00', '0.00']],
|
||||
[32,['СЗИ2 Л2','X39 : 11', '0.00', '0.00']],
|
||||
[33,['СЗИ2 Л3','X39 : 14', '0.00', '0.00']],
|
||||
[34,['СЗИ3 Л2','X40 : 11', '0.00', '0.00']],
|
||||
[35,['СЗИ3 Л3','X40 : 14', '0.00', '0.00']],
|
||||
[36,['СЗИ4 Л2','X41 : 11', '0.00', '0.00']],
|
||||
[37,['СЗИ4 Л3','X41 :14', '0.00', '0.00']],
|
||||
[38,['СЗИ1 Л4','X42 : 11', '0.00', '0.00']],
|
||||
[39,['СЗИ1 Л5','X42 :14', '0.00', '0.00']],
|
||||
[40,['СЗИ2 Л4','X43 : 11', '0.00', '0.00']],
|
||||
[41,['СЗИ2 Л5','X43 : 14', '0.00', '0.00']],
|
||||
[42,['СЗИ3 Л4','X44 : 11', '0.00', '0.00']],
|
||||
[43,['СЗИ3 Л5','X44 :14', '0.00', '0.00']],
|
||||
[44,['СЗИ4 Л4','X45 : 11', '0.00', '0.00']],
|
||||
[45,['СЗИ4 Л5','X45 : 14', '0.00', '0.00']],
|
||||
[46,['БИ РТР №1','X47 : 2', '0.00', '0.00']],
|
||||
[47,['БИ РТР №2','X47 : 5', '0.00', '0.00']],
|
||||
[48,['БИ РТР №3','X47 : 8', '0.00', '0.00']],
|
||||
[49,['БИ РТР №4','X47 : 11', '0.00', '0.00']],
|
||||
[50,['СИ В Лб','Х49 : 21', '0.00', '0.00']],
|
||||
[51,['СИ В ПрБ','Х49 : 19', '0.00', '0.00']],
|
||||
[52,['СИ Г Лб','Х49 : 28', '0.00', '0.00']],
|
||||
[53,['СИ Г ПрБ','Х49 : 30', '0.00', '0.00']],
|
||||
[54,['СИ Д Лб','Х49 : 13', '0.00', '0.00']],
|
||||
[55,['СИ Д ПрБ','Х49 : 11', '0.00', '0.00']],
|
||||
[56,['СИ Е Лб','Х49 : 26', '0.00', '0.00']],
|
||||
[57,['СИ Е ПрБ','Х49 : 35', '0.00', '0.00']]]
|
||||
[11,['Бланк №1','Х6', '0.00', '0.00']],
|
||||
[12,['Бланк №2','Х9', '0.00', '0.00']],
|
||||
[13,['Бланк №3','Х12', '0.00', '0.00']],
|
||||
[14,['Бланк №4','Х15', '0.00', '0.00']],
|
||||
[15,['Бланк №5','Х18', '0.00', '0.00']],
|
||||
[16,['Бланк №6','Х21', '0.00', '0.00']],
|
||||
[17,['Бланк №7','Х24', '0.00', '0.00']],
|
||||
[18,['СЗИ1 Л1','X31 : 11', '0.00', '0.00']],
|
||||
[19,['СЗИ1 Л6','X31 :14', '0.00', '0.00']],
|
||||
[20,['СЗИ1 Л7','X31 : 17', '0.00', '0.00']],
|
||||
[21,['СЗИ2 Л1','X32 : 11', '0.00', '0.00']],
|
||||
[22,['СЗИ2 Л6','X32 : 14', '0.00', '0.00']],
|
||||
[23,['СЗИ2 Л7','X32: 17', '0.00', '0.00']],
|
||||
[24,['СЗИ3 Л1','X33 : 11', '0.00', '0.00']],
|
||||
[25,['СЗИ3 Л6','X33 :14', '0.00', '0.00']],
|
||||
[26,['СЗИ3 Л7','X33: 17', '0.00', '0.00']],
|
||||
[27,['СЗИ4 Л1','X34 : 11', '0.00', '0.00']],
|
||||
[28,['СЗИ4 Л6','X34 :14', '0.00', '0.00']],
|
||||
[29,['СЗИ4 Л7','X34: 17', '0.00', '0.00']],
|
||||
[30,['СЗИ1 Л2','X38 : 11', '0.00', '0.00']],
|
||||
[31,['СЗИ1 Л3','X38 : 14', '0.00', '0.00']],
|
||||
[32,['СЗИ2 Л2','X39 : 11', '0.00', '0.00']],
|
||||
[33,['СЗИ2 Л3','X39 : 14', '0.00', '0.00']],
|
||||
[34,['СЗИ3 Л2','X40 : 11', '0.00', '0.00']],
|
||||
[35,['СЗИ3 Л3','X40 : 14', '0.00', '0.00']],
|
||||
[36,['СЗИ4 Л2','X41 : 11', '0.00', '0.00']],
|
||||
[37,['СЗИ4 Л3','X41 :14', '0.00', '0.00']],
|
||||
[38,['СЗИ1 Л4','X42 : 11', '0.00', '0.00']],
|
||||
[39,['СЗИ1 Л5','X42 :14', '0.00', '0.00']],
|
||||
[40,['СЗИ2 Л4','X43 : 11', '0.00', '0.00']],
|
||||
[41,['СЗИ2 Л5','X43 : 14', '0.00', '0.00']],
|
||||
[42,['СЗИ3 Л4','X44 : 11', '0.00', '0.00']],
|
||||
[43,['СЗИ3 Л5','X44 :14', '0.00', '0.00']],
|
||||
[44,['СЗИ4 Л4','X45 : 11', '0.00', '0.00']],
|
||||
[45,['СЗИ4 Л5','X45 : 14', '0.00', '0.00']],
|
||||
[46,['БИ РТР №1','X47 : 2', '0.00', '0.00']],
|
||||
[47,['БИ РТР №2','X47 : 5', '0.00', '0.00']],
|
||||
[48,['БИ РТР №3','X47 : 8', '0.00', '0.00']],
|
||||
[49,['БИ РТР №4','X47 : 11', '0.00', '0.00']],
|
||||
[50,['СИ В Лб','Х49 : 21', '0.00', '0.00']],
|
||||
[51,['СИ В ПрБ','Х49 : 19', '0.00', '0.00']],
|
||||
[52,['СИ Г Лб','Х49 : 28', '0.00', '0.00']],
|
||||
[53,['СИ Г ПрБ','Х49 : 30', '0.00', '0.00']],
|
||||
[54,['СИ Д Лб','Х49 : 13', '0.00', '0.00']],
|
||||
[55,['СИ Д ПрБ','Х49 : 11', '0.00', '0.00']],
|
||||
[56,['СИ Е Лб','Х49 : 26', '0.00', '0.00']],
|
||||
[57,['СИ Е ПрБ','Х49 : 35', '0.00', '0.00']]]
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
extends Node
|
||||
class_name yems_dev extends Node
|
||||
|
||||
|
||||
class InDev:
|
||||
var id: int ## Идентификатор индекс устройства
|
||||
var dev_name: String ## Имя подключаемого комплекса
|
||||
var connector: String ## Номер разъёма в приборе
|
||||
var delay: float ## Задержка фронта импульса
|
||||
var offset: float ## Смещение фронта импульса
|
||||
var state: int ## Состояние входа
|
||||
var freq: int ## Предполагаемая частота на которой работает комплекс
|
||||
var ports_data: Dictionary ## Словарь состояния портов устройства
|
||||
var tbl_row_id: int ## Индекс устройства в таблице выходов
|
||||
var out_dots: Array ## Список выходных устройств в порядке, как в таблице и точки матрицы
|
||||
var connect_devs: Dictionary ## Список присоединённых устройств
|
||||
var board: String ## Плата в которой находится устройство
|
||||
var id: int ## Идентификатор индекс устройства.
|
||||
var dev_name: String ## Имя подключаемого комплекса.
|
||||
var connector: String ## Номер разъёма в приборе.
|
||||
var delay: float ## Задержка фронта импульса.
|
||||
var offset: float ## Смещение фронта импульса.
|
||||
var state: int ## Состояние входа.
|
||||
var freq: int ## Предполагаемая частота на которой работает комплекс.
|
||||
var ports_data: Dictionary ## Словарь состояния портов устройства.
|
||||
var tbl_row_id: int ## Индекс устройства в таблице выходов.
|
||||
var out_dots: Array ## Список выходных устройств в порядке, как в таблице и точки матрицы.
|
||||
var connect_devs: Dictionary ## Список присоединённых устройств.
|
||||
var board: String ## Плата в которой находится устройство.
|
||||
|
||||
func _init(dev_id : int, params : Array, row_id : int):
|
||||
id = dev_id
|
||||
@@ -25,7 +25,7 @@ class InDev:
|
||||
|
||||
|
||||
class OutDev extends InDev:
|
||||
var mode: String ## Режим работы выхода
|
||||
var mode: String ## Режим работы выхода.
|
||||
|
||||
func _init(dev_id : int, params : Array, row_id : int):
|
||||
id = dev_id
|
||||
|
||||
@@ -3,17 +3,24 @@ shader_type canvas_item;
|
||||
#include "res://shaders/tools.gdshaderinc"
|
||||
|
||||
/* Закрашенная окружность */
|
||||
uniform vec4 color: source_color = vec4(1, 1, 1, 1);
|
||||
uniform vec4 color_up: source_color = vec4(1, 1, 1, 1); /* Цвет вспышки при обновлении */
|
||||
uniform uint tick_update = 0; /* Время последнего обновления, мс */
|
||||
const float time_delta = 0.1; /* Время вспышки при обновлении, c */
|
||||
uniform float tick_update = 0.0; /* Время последнего обновления, мс */
|
||||
const float time_delta = 0.5; /* Время вспышки при обновлении, c */
|
||||
const float ds = 0.01; /* Относительное расстояние на котором выполняется сглаживание краёв */
|
||||
const vec2 center = vec2(0.125, 0.125); /* Центр должен быть в (0.5, 0.5), но это не так */
|
||||
const float radius = 0.075 - ds * 2.0; /* Радиус должен быть 0.5, но это не так */
|
||||
|
||||
|
||||
const float alpha_offset = 0.15; /* Изменние скорости альфа канала */
|
||||
|
||||
void fragment()
|
||||
{
|
||||
float time_now = TIME;
|
||||
float alpha = 1.0;
|
||||
if ((time_now - tick_update) < time_delta)
|
||||
{
|
||||
alpha = (time_delta - (time_now - tick_update)) * alpha_offset;
|
||||
}
|
||||
else{
|
||||
alpha = 0.0;
|
||||
}
|
||||
vec4 color = vec4(0.972549, 0.12549, 0.411765, 1.0 - alpha);
|
||||
COLOR = color * smooth_px(length(UV - center), radius, ds);
|
||||
}
|
||||
|
||||