Files
PRD_TU_MP550/threads.txt
2024-12-18 20:47:40 +03:00

193 lines
6.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'BackgroundThread.gd'
extends Node
var semaphore: Semaphore
var mutex: Mutex
var thread: Thread
var exit_thread: bool = false
var nodeWhoRequestedJob: Node
var delta: float = 0.0
var address: String = ""
var port: int = 0
var soc_brodcast: PacketPeerUDP
var soc_unicast: PacketPeerUDP
var unit: Object
func _enter_tree():
semaphore = Semaphore.new()
mutex = Mutex.new()
exit_thread = false
thread = Thread.new()
thread.start(_thread_function)
func _thread_function():
while true:
semaphore.wait() # Wait until posted.
mutex.lock()
var should_exit = exit_thread # Protect with Mutex.
mutex.unlock()
if should_exit:
break
mutex.lock()
var local_delta = delta
var local_address = address
var local_port = port
var local_soc_brodcast = soc_brodcast
var local_soc_unicast = soc_unicast
var local_unit = unit
mutex.unlock()
# Выполнение задач
local_unit.poll_receive(local_soc_brodcast)
local_unit.poll_receive(local_soc_unicast)
local_unit.state_machine()
match local_unit.process(local_delta):
Error.OK:
nodeWhoRequestedJob.call_deferred('data_sent', local_address, local_port, local_unit.tx_data.slice(0, local_unit.tx_len))
Error.FAILED:
nodeWhoRequestedJob.call_deferred('data_send_failed')
func tellTheThreadToDoSomething(requester, delta, address, port, soc_brodcast, soc_unicast, unit):
mutex.lock()
nodeWhoRequestedJob = requester
self.delta = delta
self.address = address
self.port = port
self.soc_brodcast = soc_brodcast
self.soc_unicast = soc_unicast
self.unit = unit
mutex.unlock()
semaphore.post()
func _exit_tree():
# Set exit condition to true.
mutex.lock()
exit_thread = true # Protect with Mutex.
mutex.unlock()
# Post to semaphore to wake up the thread.
semaphore.post()
# Wait until it exits.
thread.wait_to_finish()
'Network.gd'
extends Node
var unit = Yau07.YaU07.new('ЯУ07')
var soc_unicast: PacketPeerUDP
var soc_brodcast: PacketPeerUDP
var address: String = Constants.ADDRESSES[0][1]
var port: int = Constants.ADDRESSES[0][2]
var timeout: float = Yau07.ONLINE_TIMEOUT
var last_update_time: float = 0.0
var broadcast_packet: PackedByteArray
var state = Constants.STATE.WAIT
var send_array: Array = []
signal yau_status_line(_status) ## Вызывается когда меняется состояние связи с ячейкой
signal yau_receive(_data_from_yau) ##
signal yau_read_isa(_unit_isa_ports)
## Класс для отправки данных в сокет
class Socket extends PacketPeerUDP:
func send_to(addr: String, port: int, data: PackedByteArray):
self.set_dest_address(addr, port)
self.put_packet(data)
func poll_receive(sock: PacketPeerUDP) -> bool: ## Приёмник
if timeout - last_update_time > 0:
while sock.get_available_packet_count() > 0:
broadcast_packet = sock.get_packet()
var addr_receive = sock.get_packet_ip()
var port_receive = sock.get_packet_port()
if (address == addr_receive) and (port == port_receive):
last_update_time = 0.0
unit.parse(broadcast_packet)
var data_from_yau_07 = unit.status
emit_signal('yau_receive', data_from_yau_07)
else:
if sock.get_available_packet_count():
last_update_time = 0.0
return false
func _ready() -> void:
# Привязка для принятия широковещательного канала
soc_brodcast = Socket.new()
var rc = soc_brodcast.bind(Constants.BROADCAST_PORT, '*')
if rc != OK:
print('Ошибка: Неудачная привязка широковещательного адреса')
soc_unicast = Socket.new()
rc = soc_unicast.bind(Constants.UNICAST_PORT, Constants.UNICAST_ADDRESS)
if rc != OK:
print('Ошибка: неудачная привязка адреса: ', address)
unit.connect('line_changed', Callable(self, 'on_line_changed'))
unit.connect('command_fail', Callable(self, 'on_command_fail'))
# Создание и запуск фонового потока
var background_thread_node = BackgroundThread.new()
add_child(background_thread_node)
background_thread_node.name = "BackgroundThreadNode"
func _process(delta: float) -> void:
last_update_time += delta
background_thread_node.tellTheThreadToDoSomething(self, delta, address, port, soc_brodcast, soc_unicast, unit)
func state_machine():
var fl_done = (unit.cmd_state == unit.CmdState.DONE)
## Режим ожидания
if state == Constants.STATE.WAIT and fl_done:
if send_array.size():
state = Constants.STATE.READ_ISA if send_array[0][0] == 'rd' else Constants.STATE.WRITE_ISA
## Режим чтения из ИСА
elif state == Constants.STATE.READ_ISA and fl_done:
var ports_read = send_array.pop_front()
unit.send_isa(unit.CmdCode.READ_ISA, ports_read[1])
state = Constants.STATE.DONE
## Режим записи в ИСА
elif state == Constants.STATE.WRITE_ISA and fl_done:
var ports_write = send_array.pop_front()
var key = ports_write[1].keys()
unit.send_isa(unit.CmdCode.WRITE_ISA, [key[0], ports_write[1][key[0]]])
state = Constants.STATE.WAIT
elif state == Constants.STATE.DONE and fl_done:
emit_signal('yau_read_isa', unit.isa_ports)
state = Constants.STATE.WAIT
func on_line_changed(_unit) -> void:
emit_signal('yau_status_line', unit.online)
## Если отсутствует подключение к ячейке ЯУ-07
func on_command_fail(_unit) -> void:
print_debug('Command send fail')
func data_sent(address, port, data):
soc_unicast.send_to(address, port, data)
func data_send_failed():
print('Ошибка отправки данных')