Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions addons/beehave/debug/debugger.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
@tool
class_name BeehaveEditorDebugger
extends EditorDebuggerPlugin

const DebuggerTab := preload("debugger_tab.gd")
var debugger_tab := DebuggerTab.new()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where do we free this node? I remember that anything allocated with .new() needs be called .free() manually.

var floating_window: Window
var session: EditorDebuggerSession


func _has_capture(prefix: String) -> bool:
return prefix == "beehave"


func _capture(message: String, data: Array, session_id: int) -> bool:
if message == "beehave:register_tree":
debugger_tab.register_tree(data[0])
return true
if message == "beehave:unregister_tree":
debugger_tab.unregister_tree(data[0])
return true
if message == "beehave:process_tick":
debugger_tab.graph.process_tick(data[0], data[1])
return true
if message == "beehave:process_begin":
debugger_tab.graph.process_begin(data[0])
return true
if message == "beehave:process_end":
debugger_tab.graph.process_end(data[0])
return true
return false


func _setup_session(session_id: int) -> void:
session = get_session(session_id)
session.started.connect(debugger_tab.start)
session.stopped.connect(debugger_tab.stop)

debugger_tab.name = "🐝 Beehave"
debugger_tab.make_floating.connect(_on_make_floating)
session.add_session_tab(debugger_tab)


static func can_send_message() -> bool:
return not Engine.is_editor_hint() and OS.has_feature("editor")


static func register_tree(beehave_tree: Dictionary) -> void:
if can_send_message():
EngineDebugger.send_message("beehave:register_tree", [beehave_tree])


static func unregister_tree(instance_id: int) -> void:
if can_send_message():
EngineDebugger.send_message("beehave:unregister_tree", [instance_id])


static func process_tick(instance_id: int, status: int) -> void:
if can_send_message():
EngineDebugger.send_message("beehave:process_tick", [instance_id, status])


static func process_begin(instance_id: int) -> void:
if can_send_message():
EngineDebugger.send_message("beehave:process_begin", [instance_id])


static func process_end(instance_id: int) -> void:
if can_send_message():
EngineDebugger.send_message("beehave:process_end", [instance_id])


func _on_make_floating() -> void:
var plugin := BeehaveUtils.get_plugin()
if not plugin:
return
if floating_window:
_on_window_close_requested()
return

var border_size := Vector2(4, 4) * BeehaveUtils.get_editor_scale()
var editor_interface: EditorInterface = plugin.get_editor_interface()
var editor_main_screen = editor_interface.get_editor_main_screen()
debugger_tab.get_parent().remove_child(debugger_tab)

floating_window = Window.new()

var panel := Panel.new()
panel.add_theme_stylebox_override("panel", editor_interface.get_base_control().get_theme_stylebox("PanelForeground", "EditorStyles"))
panel.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
floating_window.add_child(panel)

var margin := MarginContainer.new()
margin.add_child(debugger_tab)
margin.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
margin.add_theme_constant_override("margin_right", border_size.x)
margin.add_theme_constant_override("margin_left", border_size.x)
margin.add_theme_constant_override("margin_top", border_size.y)
margin.add_theme_constant_override("margin_bottom", border_size.y)
panel.add_child(margin)

floating_window.title = "🐝 Beehave"
floating_window.wrap_controls = true
floating_window.min_size = Vector2i(600, 350)
floating_window.size = debugger_tab.size
floating_window.position = editor_main_screen.global_position
floating_window.transient = true
floating_window.close_requested.connect(_on_window_close_requested)
editor_interface.get_base_control().add_child(floating_window)


func _on_window_close_requested() -> void:
debugger_tab.get_parent().remove_child(debugger_tab)
session.add_session_tab(debugger_tab)
floating_window.queue_free()
floating_window = null
95 changes: 95 additions & 0 deletions addons/beehave/debug/debugger_tab.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
@tool
extends PanelContainer

signal make_floating()

const BeehaveGraphEdit := preload("graph_edit.gd")
const TREE_ICON := preload("../icons/tree.svg")

var container: HSplitContainer
var item_list: ItemList
var graph: BeehaveGraphEdit
var message: Label

var active_trees: Dictionary


func _ready() -> void:
container = HSplitContainer.new()
add_child(container)

item_list = ItemList.new()
item_list.custom_minimum_size = Vector2(200, 0)
item_list.item_selected.connect(_on_item_selected)
container.add_child(item_list)

graph = BeehaveGraphEdit.new()
container.add_child(graph)

message = Label.new()
message.text = "Run Project for debugging"
message.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
message.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
message.set_anchors_preset(Control.PRESET_CENTER)
add_child(message)

var button := Button.new()
button.flat = true
button.icon = get_theme_icon(&"ExternalLink", &"EditorIcons")
button.pressed.connect(func(): make_floating.emit())
button.tooltip_text = "Make floating"
graph.get_zoom_hbox().add_child(button)

var toggle_button := Button.new()
toggle_button.flat = true
toggle_button.icon = get_theme_icon(&"Back", &"EditorIcons")
toggle_button.pressed.connect(_on_toggle_button_pressed.bind(toggle_button))
toggle_button.tooltip_text = "Toggle Panel"
graph.get_zoom_hbox().add_child(toggle_button)
graph.get_zoom_hbox().move_child(toggle_button, 0)

stop()


func start() -> void:
container.visible = true
message.visible = false


func stop() -> void:
container.visible = false
message.visible = true

active_trees.clear()
item_list.clear()
graph.beehave_tree = {}


func register_tree(data: Dictionary) -> void:
var idx := item_list.add_item(data.name, TREE_ICON)
item_list.set_item_tooltip(idx, data.path)
item_list.set_item_metadata(idx, data.id)
active_trees[data.id] = data


func unregister_tree(instance_id: int) -> void:
var id := str(instance_id)
for i in item_list.item_count:
if item_list.get_item_metadata(i) == id:
item_list.remove_item(i)
break

active_trees.erase(id)

if graph.beehave_tree.get("id", "") == id:
graph.beehave_tree = {}


func _on_toggle_button_pressed(toggle_button: Button) -> void:
item_list.visible = !item_list.visible
toggle_button.icon = get_theme_icon(&"Back" if item_list.visible else &"Forward", &"EditorIcons")


func _on_item_selected(idx: int) -> void:
var id: StringName = item_list.get_item_metadata(idx)
graph.beehave_tree = active_trees.get(id, {})
33 changes: 33 additions & 0 deletions addons/beehave/debug/frames.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@tool
extends RefCounted

const SUCCESS_COLOR := Color("#009944c8")
const NORMAL_COLOR := Color("#15181e")
const FAILURE_COLOR := Color("#cf000f80")
const RUNNING_COLOR := Color("#ffcc00c8")

var empty: StyleBoxEmpty
var normal: StyleBoxFlat
var success: StyleBoxFlat
var failure: StyleBoxFlat
var running: StyleBoxFlat


func _init() -> void:
var plugin := BeehaveUtils.get_plugin()
if not plugin:
return

var editor_scale := BeehaveUtils.get_editor_scale()

empty = StyleBoxEmpty.new()

normal = plugin.get_editor_interface().get_base_control().get_theme_stylebox(&"frame", &"GraphNode").duplicate()

success = plugin.get_editor_interface().get_base_control().get_theme_stylebox(&"selected_frame", &"GraphNode").duplicate()
failure = success.duplicate()
running = success.duplicate()

success.border_color = SUCCESS_COLOR
failure.border_color = FAILURE_COLOR
running.border_color = RUNNING_COLOR
Loading