186 lines
5.1 KiB
GDScript3
Raw Permalink Normal View History

2026-04-13 11:34:00 -05:00
class_name EditorTubePeerControl extends Control
## @experimental: This class is used as part of the TubeClientDebugPanel scene and is part of a scene. Should not be used as itself.
const STATE_COLOR_DEFAULT := Color.WHITE
const STATE_TEXT_DEFAULT := "Unknown"
@export var client: TubeClient
@export var peer_item: EditorTubePeerItemControl:
set(x):
show()
if peer_item != x:
latency_label.text = "Unknown..."
if null != peer_item:
peer_item.updated.disconnect(update)
if null != x:
x.updated.connect(update)
if null != x:
if not waiting_for_pong:
send_ping(x.peer)
if is_instance_valid(messages_container):
if peer_item != x or not messages_container.is_displaying_from(self):
messages_container.display_messages(
x.message_item_controls,
self
)
if is_instance_valid(id_label):
id_label.text = EditorTubePeerItemControl.get_peer_string(x.peer.id)
id_label.modulate = EditorTubePeerItemControl.get_peer_color(x.peer.id)
if is_instance_valid(channels_containers):
for child in channels_containers.get_children():
channels_containers.remove_child(child)
for channel_item_control in x.channel_item_controls:
channels_containers.add_child(
channel_item_control
)
peer_item = x
update()
@export var messages_container: EditorTubeMessagesContainer
var last_ping_time: float
var waiting_for_pong := false
@onready var ping_timer: Timer = %PingTimer
@onready var id_label: Label = %IdLabel
@onready var connection_state_indicator: Control = %ConnectionStateIndicator
@onready var connection_state_label: Label = %ConnectionStateLabel
@onready var gathering_state_indicator: Control = %GatheringStateIndicator
@onready var gathering_state_label: Label = %GatheringStateLabel
@onready var signaling_state_indicator: Control = %SignalingStateIndicator
@onready var signaling_state_label: Label = %SignalingStateLabel
@onready var channels_containers: Container = %ChannelsContainer
@onready var connection_time_label: Label = %ConnectingTimeLabel
@onready var up_time_label: Label = %UpTimeLabel
@onready var latency_label: Label = %LatencyLabel
@onready var fake_disconnection_timer: Timer = %FakeDisconnectionTimer
@onready var fake_disconnection_button: Button = %FakeDisconnectionButton
@onready var fake_disconnection_spin_box: SpinBox = %FakeDisconnectionSpinBox
func _ready() -> void:
hide()
func update():
if is_instance_valid(connection_state_indicator):
connection_state_indicator.modulate = STATE_COLOR_DEFAULT if not peer_item else peer_item.get_connection_state_color()
if is_instance_valid(connection_state_label):
connection_state_label.text = STATE_TEXT_DEFAULT if not peer_item else peer_item.get_connection_state_text()
if is_instance_valid(gathering_state_indicator):
gathering_state_indicator.modulate = STATE_COLOR_DEFAULT if not peer_item else peer_item.get_gathering_state_color()
if is_instance_valid(gathering_state_label):
gathering_state_label.text = STATE_TEXT_DEFAULT if not peer_item else peer_item.get_gathering_state_text()
if is_instance_valid(signaling_state_indicator):
signaling_state_indicator.modulate = STATE_COLOR_DEFAULT if not peer_item else peer_item.get_signaling_state_color()
if is_instance_valid(signaling_state_label):
signaling_state_label.text = STATE_TEXT_DEFAULT if not peer_item else peer_item.get_signaling_state_text()
if null == peer_item:
return
if is_instance_valid(fake_disconnection_button):
fake_disconnection_button.disabled = not peer_item.peer.is_peer_connected()
if is_instance_valid(messages_container):
if messages_container.is_displaying_from(self):
messages_container.display_messages(
peer_item.message_item_controls,
self
)
func add_channel_item_control(channel_item_control: EditorTubeChannelItemControl):
channels_containers.add_child(channel_item_control)
func send_ping(peer: TubePeer):
if not peer.is_peer_connected():
return
last_ping_time = Time.get_ticks_msec()
ping_timer.start(5.0)
waiting_for_pong = true
receive_ping.rpc_id(peer.id)
@rpc("any_peer", "call_remote", "reliable")
func receive_ping():
var sender_id := multiplayer.get_remote_sender_id()
send_pong(sender_id)
func send_pong(to: int):
receive_pong.rpc_id(to)
@rpc("any_peer", "call_remote", "reliable")
func receive_pong():
waiting_for_pong = false
ping_timer.start(1.0)
var ping := Time.get_ticks_msec() - last_ping_time
latency_label.text = str(ping).pad_decimals(0)
func _on_ping_timer_timeout() -> void:
if not is_visible_in_tree():
return
if not peer_item:
return
send_ping(peer_item.peer)
func _process(_delta: float) -> void:
if null == peer_item:
return
connection_time_label.text = str(
peer_item.peer.connecting_time
).pad_decimals(3)
up_time_label.text = str(
peer_item.peer.up_time
).pad_decimals(3)
func _on_fake_disconnection_button_pressed() -> void:
if not fake_disconnection_timer.is_stopped():
fake_disconnection_timer.stop()
fake_disconnection_timer.timeout.emit()
var peer := peer_item.peer
peer._disconnected()
fake_disconnection_timer.start(
fake_disconnection_spin_box.value
)
await fake_disconnection_timer.timeout
peer._connected()