Added Glitch Room Source code to Gitty
This commit is contained in:
commit
1ac9eb5644
505 files changed
+28504
No files matched your search
@@ -0,0 +1,677 @@
|
||||
@tool
|
||||
class_name SimulationTimeline
|
||||
extends VBoxContainer
|
||||
|
||||
signal pause_requested
|
||||
signal resume_requested
|
||||
signal step_requested(
|
||||
seconds: float
|
||||
)
|
||||
signal reset_requested
|
||||
|
||||
signal sequence_selected(
|
||||
index: int
|
||||
)
|
||||
|
||||
signal run_sequence_requested
|
||||
signal stop_sequence_requested
|
||||
signal replay_sequence_requested
|
||||
|
||||
var sequence_select: OptionButton
|
||||
var run_button: Button
|
||||
var stop_button: Button
|
||||
var replay_button: Button
|
||||
|
||||
var tree: Tree
|
||||
var clear_button: Button
|
||||
var count_label: Label
|
||||
|
||||
var _first_trace_time: float = -1.0
|
||||
var _entry_count: int = 0
|
||||
|
||||
var pause_button: Button
|
||||
var step_button: Button
|
||||
var reset_button: Button
|
||||
|
||||
var _paused: bool = false
|
||||
|
||||
func _ready() -> void:
|
||||
|
||||
if tree != null:
|
||||
return
|
||||
|
||||
_build_ui()
|
||||
|
||||
|
||||
func _build_ui() -> void:
|
||||
|
||||
var toolbar := HBoxContainer.new()
|
||||
|
||||
add_child(
|
||||
toolbar
|
||||
)
|
||||
|
||||
|
||||
var title := Label.new()
|
||||
|
||||
title.text = "Simulation Timeline"
|
||||
|
||||
title.size_flags_horizontal = (
|
||||
Control.SIZE_EXPAND_FILL
|
||||
)
|
||||
|
||||
toolbar.add_child(
|
||||
title
|
||||
)
|
||||
|
||||
|
||||
count_label = Label.new()
|
||||
|
||||
count_label.text = "0 events"
|
||||
|
||||
toolbar.add_child(
|
||||
count_label
|
||||
)
|
||||
|
||||
sequence_select = OptionButton.new()
|
||||
|
||||
sequence_select.custom_minimum_size.x = 180.0
|
||||
|
||||
sequence_select.item_selected.connect(
|
||||
func(index: int):
|
||||
sequence_selected.emit(
|
||||
index
|
||||
)
|
||||
)
|
||||
|
||||
toolbar.add_child(
|
||||
sequence_select
|
||||
)
|
||||
|
||||
|
||||
run_button = Button.new()
|
||||
|
||||
run_button.text = "Run"
|
||||
|
||||
run_button.pressed.connect(
|
||||
func():
|
||||
run_sequence_requested.emit()
|
||||
)
|
||||
|
||||
toolbar.add_child(
|
||||
run_button
|
||||
)
|
||||
|
||||
|
||||
stop_button = Button.new()
|
||||
|
||||
stop_button.text = "Stop"
|
||||
|
||||
stop_button.disabled = true
|
||||
|
||||
stop_button.pressed.connect(
|
||||
func():
|
||||
stop_sequence_requested.emit()
|
||||
)
|
||||
|
||||
toolbar.add_child(
|
||||
stop_button
|
||||
)
|
||||
|
||||
|
||||
replay_button = Button.new()
|
||||
|
||||
replay_button.text = "Replay"
|
||||
|
||||
replay_button.pressed.connect(
|
||||
func():
|
||||
replay_sequence_requested.emit()
|
||||
)
|
||||
|
||||
toolbar.add_child(
|
||||
replay_button
|
||||
)
|
||||
|
||||
pause_button = Button.new()
|
||||
|
||||
pause_button.text = "Pause"
|
||||
|
||||
pause_button.pressed.connect(
|
||||
_on_pause_button_pressed
|
||||
)
|
||||
|
||||
toolbar.add_child(
|
||||
pause_button
|
||||
)
|
||||
|
||||
|
||||
step_button = Button.new()
|
||||
|
||||
step_button.text = "Step 0.1s"
|
||||
|
||||
step_button.pressed.connect(
|
||||
func():
|
||||
step_requested.emit(
|
||||
0.1
|
||||
)
|
||||
)
|
||||
|
||||
toolbar.add_child(
|
||||
step_button
|
||||
)
|
||||
|
||||
|
||||
reset_button = Button.new()
|
||||
|
||||
reset_button.text = "Reset"
|
||||
|
||||
reset_button.pressed.connect(
|
||||
func():
|
||||
reset_requested.emit()
|
||||
)
|
||||
|
||||
toolbar.add_child(
|
||||
reset_button
|
||||
)
|
||||
|
||||
clear_button = Button.new()
|
||||
|
||||
clear_button.text = "Clear"
|
||||
|
||||
clear_button.pressed.connect(
|
||||
clear
|
||||
)
|
||||
|
||||
toolbar.add_child(
|
||||
clear_button
|
||||
)
|
||||
|
||||
|
||||
tree = Tree.new()
|
||||
|
||||
tree.size_flags_horizontal = (
|
||||
Control.SIZE_EXPAND_FILL
|
||||
)
|
||||
|
||||
tree.size_flags_vertical = (
|
||||
Control.SIZE_EXPAND_FILL
|
||||
)
|
||||
|
||||
tree.custom_minimum_size.y = 180.0
|
||||
|
||||
tree.columns = 4
|
||||
|
||||
tree.set_column_title(
|
||||
0,
|
||||
"Time"
|
||||
)
|
||||
|
||||
tree.set_column_title(
|
||||
1,
|
||||
"Type"
|
||||
)
|
||||
|
||||
tree.set_column_title(
|
||||
2,
|
||||
"Source / Target"
|
||||
)
|
||||
|
||||
tree.set_column_title(
|
||||
3,
|
||||
"Detail"
|
||||
)
|
||||
|
||||
tree.column_titles_visible = true
|
||||
|
||||
tree.set_column_expand(
|
||||
0,
|
||||
false
|
||||
)
|
||||
|
||||
tree.set_column_custom_minimum_width(
|
||||
0,
|
||||
80
|
||||
)
|
||||
|
||||
tree.set_column_expand(
|
||||
1,
|
||||
false
|
||||
)
|
||||
|
||||
tree.set_column_custom_minimum_width(
|
||||
1,
|
||||
90
|
||||
)
|
||||
|
||||
tree.set_column_expand(
|
||||
2,
|
||||
true
|
||||
)
|
||||
|
||||
tree.set_column_expand(
|
||||
3,
|
||||
true
|
||||
)
|
||||
|
||||
add_child(
|
||||
tree
|
||||
)
|
||||
|
||||
tree.create_item()
|
||||
set_paused(
|
||||
false
|
||||
)
|
||||
|
||||
func clear() -> void:
|
||||
|
||||
_first_trace_time = -1.0
|
||||
_entry_count = 0
|
||||
|
||||
if count_label != null:
|
||||
count_label.text = "0 events"
|
||||
|
||||
if tree == null:
|
||||
return
|
||||
|
||||
tree.clear()
|
||||
|
||||
tree.create_item()
|
||||
|
||||
|
||||
func add_trace_entry(
|
||||
entry: Dictionary
|
||||
) -> void:
|
||||
|
||||
if tree == null:
|
||||
_build_ui()
|
||||
|
||||
var absolute_time := float(
|
||||
entry.get(
|
||||
"time",
|
||||
0.0
|
||||
)
|
||||
)
|
||||
|
||||
if _first_trace_time < 0.0:
|
||||
_first_trace_time = absolute_time
|
||||
|
||||
var relative_time := (
|
||||
absolute_time
|
||||
- _first_trace_time
|
||||
)
|
||||
|
||||
var root := tree.get_root()
|
||||
|
||||
if root == null:
|
||||
root = tree.create_item()
|
||||
|
||||
var item := tree.create_item(
|
||||
root
|
||||
)
|
||||
|
||||
item.set_text(
|
||||
0,
|
||||
"%.3f" % relative_time
|
||||
)
|
||||
|
||||
var entry_type := StringName(
|
||||
entry.get(
|
||||
"type",
|
||||
&"unknown"
|
||||
)
|
||||
)
|
||||
|
||||
item.set_text(
|
||||
1,
|
||||
String(entry_type).to_upper()
|
||||
)
|
||||
|
||||
item.set_text(
|
||||
2,
|
||||
_get_subject_text(
|
||||
entry
|
||||
)
|
||||
)
|
||||
|
||||
item.set_text(
|
||||
3,
|
||||
_get_detail_text(
|
||||
entry
|
||||
)
|
||||
)
|
||||
|
||||
_entry_count += 1
|
||||
|
||||
if count_label != null:
|
||||
|
||||
count_label.text = (
|
||||
"%d events"
|
||||
% _entry_count
|
||||
)
|
||||
|
||||
tree.scroll_to_item(
|
||||
item
|
||||
)
|
||||
|
||||
|
||||
func _get_subject_text(
|
||||
entry: Dictionary
|
||||
) -> String:
|
||||
|
||||
var entry_type := StringName(
|
||||
entry.get(
|
||||
"type",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
match entry_type:
|
||||
|
||||
&"event":
|
||||
return String(
|
||||
entry.get(
|
||||
"source_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
&"rule":
|
||||
return String(
|
||||
entry.get(
|
||||
"rule_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
&"action":
|
||||
return String(
|
||||
entry.get(
|
||||
"target_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
&"gpio":
|
||||
return String(
|
||||
entry.get(
|
||||
"cabinet_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
&"device":
|
||||
return String(
|
||||
entry.get(
|
||||
"device_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
&"input":
|
||||
return String(
|
||||
entry.get(
|
||||
"source_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
&"sequence":
|
||||
return String(
|
||||
entry.get(
|
||||
"display_name",
|
||||
entry.get(
|
||||
"sequence_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
)
|
||||
_:
|
||||
return ""
|
||||
|
||||
|
||||
func _get_detail_text(
|
||||
entry: Dictionary
|
||||
) -> String:
|
||||
|
||||
var entry_type := StringName(
|
||||
entry.get(
|
||||
"type",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
match entry_type:
|
||||
|
||||
&"event":
|
||||
|
||||
return String(
|
||||
entry.get(
|
||||
"event_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
&"rule":
|
||||
|
||||
var target_id := String(
|
||||
entry.get(
|
||||
"target_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
var action_id := String(
|
||||
entry.get(
|
||||
"action_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
var delay := float(
|
||||
entry.get(
|
||||
"delay_seconds",
|
||||
0.0
|
||||
)
|
||||
)
|
||||
|
||||
if delay > 0.0:
|
||||
|
||||
return (
|
||||
"→ %s.%s after %.3fs"
|
||||
% [
|
||||
target_id,
|
||||
action_id,
|
||||
delay
|
||||
]
|
||||
)
|
||||
|
||||
return (
|
||||
"→ %s.%s"
|
||||
% [
|
||||
target_id,
|
||||
action_id
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
&"action":
|
||||
|
||||
return String(
|
||||
entry.get(
|
||||
"action_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
&"gpio":
|
||||
|
||||
var pin := int(
|
||||
entry.get(
|
||||
"gpio_pin",
|
||||
-1
|
||||
)
|
||||
)
|
||||
|
||||
var electrical_state := bool(
|
||||
entry.get(
|
||||
"electrical_state",
|
||||
false
|
||||
)
|
||||
)
|
||||
|
||||
var action_id := String(
|
||||
entry.get(
|
||||
"action_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
var level := "LOW"
|
||||
|
||||
if electrical_state:
|
||||
level = "HIGH"
|
||||
|
||||
return (
|
||||
"GPIO %d %s (%s)"
|
||||
% [
|
||||
pin,
|
||||
level,
|
||||
action_id
|
||||
]
|
||||
)
|
||||
|
||||
&"device":
|
||||
|
||||
var active := bool(
|
||||
entry.get(
|
||||
"active",
|
||||
false
|
||||
)
|
||||
)
|
||||
|
||||
if active:
|
||||
return "ACTIVE"
|
||||
|
||||
return "INACTIVE"
|
||||
|
||||
&"input":
|
||||
|
||||
var event_id := String(
|
||||
entry.get(
|
||||
"event_id",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
var note := String(
|
||||
entry.get(
|
||||
"note",
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
if not note.is_empty():
|
||||
|
||||
return (
|
||||
"%s — %s"
|
||||
% [
|
||||
event_id,
|
||||
note
|
||||
]
|
||||
)
|
||||
|
||||
return event_id
|
||||
|
||||
|
||||
&"sequence":
|
||||
|
||||
var state := String(
|
||||
entry.get(
|
||||
"state",
|
||||
&""
|
||||
)
|
||||
)
|
||||
|
||||
return state.to_upper()
|
||||
_:
|
||||
return str(
|
||||
entry
|
||||
)
|
||||
|
||||
func _on_pause_button_pressed() -> void:
|
||||
|
||||
if _paused:
|
||||
|
||||
resume_requested.emit()
|
||||
|
||||
else:
|
||||
|
||||
pause_requested.emit()
|
||||
|
||||
func set_paused(
|
||||
value: bool
|
||||
) -> void:
|
||||
|
||||
_paused = value
|
||||
|
||||
if pause_button != null:
|
||||
|
||||
if _paused:
|
||||
pause_button.text = "Resume"
|
||||
else:
|
||||
pause_button.text = "Pause"
|
||||
|
||||
if step_button != null:
|
||||
step_button.disabled = not _paused
|
||||
|
||||
func set_sequences(
|
||||
sequences: Array[TestSequence]
|
||||
) -> void:
|
||||
|
||||
if sequence_select == null:
|
||||
return
|
||||
|
||||
sequence_select.clear()
|
||||
|
||||
for sequence in sequences:
|
||||
|
||||
if sequence == null:
|
||||
continue
|
||||
|
||||
var label := (
|
||||
sequence.display_name
|
||||
)
|
||||
|
||||
if label.is_empty():
|
||||
label = String(
|
||||
sequence.sequence_id
|
||||
)
|
||||
|
||||
sequence_select.add_item(
|
||||
label
|
||||
)
|
||||
|
||||
if sequence_select.item_count > 0:
|
||||
|
||||
sequence_select.select(
|
||||
0
|
||||
)
|
||||
|
||||
|
||||
func set_sequence_running(
|
||||
running: bool
|
||||
) -> void:
|
||||
|
||||
if run_button != null:
|
||||
run_button.disabled = running
|
||||
|
||||
if stop_button != null:
|
||||
stop_button.disabled = not running
|
||||
|
||||
if replay_button != null:
|
||||
replay_button.disabled = running
|
||||
|
||||
if sequence_select != null:
|
||||
sequence_select.disabled = running
|
||||
Reference in new issue
Block a user