97 lines
3.5 KiB
GDScript
97 lines
3.5 KiB
GDScript
extends Panel
|
||
|
||
@onready var output_status = $output
|
||
# Константы состояний фреймов
|
||
const DEVICE: String = 'ПРД-К'
|
||
const FRAME_OFF := 0
|
||
const FRAME_CONST := 1
|
||
const FRAME_IMPULSE := 2
|
||
|
||
var _input_impulse: int = 0
|
||
var _input_const: int = 0
|
||
var _output_impulse: int = 0
|
||
var _output_const: int = 0
|
||
|
||
#region Сигналы для уведомления об изменениях
|
||
signal input_bits_updated(input_impulse: int, input_const: int)
|
||
signal output_bits_updated(output_impulse: int, output_const: int)
|
||
signal bits_changed(input_impulse: int, input_const: int, output_impulse: int, output_const: int)
|
||
#endregion
|
||
|
||
func _ready():
|
||
_setup_connections()
|
||
|
||
|
||
func _setup_connections():
|
||
var _all_input_nodes = get_tree().get_nodes_in_group('input')
|
||
var _all_outputs_nodes= get_tree().get_nodes_in_group('output')
|
||
var _filtered_inputs = _all_input_nodes.filter(
|
||
func(node): return node.get_meta('device') == DEVICE)
|
||
var _filtered_outputs = _all_outputs_nodes.filter(
|
||
func(node): return node.get_meta('device') == DEVICE)
|
||
|
||
for node in _filtered_inputs:
|
||
if node.has_signal('update_frame'):
|
||
node.update_frame.connect(on_update_frame_input)
|
||
|
||
for node in _filtered_outputs:
|
||
if node.has_signal('update_frame'):
|
||
node.update_frame.connect(on_update_frame_output)
|
||
|
||
|
||
func on_update_frame_input(bit: int, frame: int)-> void:
|
||
var mask = 1 << bit
|
||
var old_impulse = _input_impulse
|
||
var old_const = _input_const
|
||
_input_impulse = _input_impulse & ~mask | (mask if frame == FRAME_IMPULSE else 0)
|
||
_input_const = _input_const & ~mask | (mask if frame == FRAME_CONST else 0)
|
||
# Отправляем сигналы только если значения изменились
|
||
if _input_impulse != old_impulse || _input_const != old_const:
|
||
input_bits_updated.emit(get_input_impulse(), get_input_const())
|
||
bits_changed.emit(get_input_impulse(), get_input_const(), get_output_impulse(), get_output_const())
|
||
|
||
|
||
func on_update_frame_output(bit: int, frame: int)-> void:
|
||
var mask = 1 << bit
|
||
var old_impulse = _output_impulse
|
||
var old_const = _output_const
|
||
_output_impulse = _output_impulse & ~mask | (mask if frame == FRAME_IMPULSE else 0)
|
||
_output_const = _output_const & ~mask | (mask if frame == FRAME_CONST else 0)
|
||
# Отправляем сигналы только если значения изменились
|
||
if _output_impulse != old_impulse || _output_const != old_const:
|
||
output_bits_updated.emit(get_output_impulse(), get_output_const())
|
||
bits_changed.emit(get_input_impulse(), get_input_const(), get_output_impulse(), get_output_const())
|
||
|
||
|
||
func _invert_bits(value: int) -> int:
|
||
'''Инвертирует все биты (0 становится 0xFFFF, 0xFFFF становится 0)'''
|
||
return value ^ 0xFFFF
|
||
|
||
|
||
#region Геттеры для безопасного доступа к данным
|
||
func get_input_impulse() -> int:
|
||
return _input_impulse
|
||
|
||
|
||
func get_input_const() -> int:
|
||
return _input_const
|
||
|
||
|
||
func get_output_impulse() -> int:
|
||
return _output_impulse
|
||
|
||
|
||
func get_output_const() -> int:
|
||
return _output_const
|
||
#endregion
|
||
|
||
#region Функция для получения всех данных сразу
|
||
func get_all_bits() -> Dictionary:
|
||
return {
|
||
'input_impulse': _input_impulse,
|
||
'input_const': _input_const,
|
||
'output_impulse': _output_impulse,
|
||
'output_const': _output_const
|
||
}
|
||
#endregion
|