Created plugin Custom Runner, but is not specifically needed for what it was originally created for. Still checking it in, since it might be useful later.
151 lines
4.2 KiB
GDScript
151 lines
4.2 KiB
GDScript
@tool
|
|
extends EditorPlugin
|
|
|
|
var _runner_btn: RunnerButton
|
|
var _play_icon: Texture2D
|
|
var _stop_icon: Texture2D
|
|
|
|
func _enter_tree() -> void:
|
|
ProjectSettings.set("application/run/custom_runner", "")
|
|
ProjectSettings.add_property_info({
|
|
"name": "application/run/custom_runner",
|
|
"type": TYPE_STRING,
|
|
"hint": PROPERTY_HINT_GLOBAL_FILE,
|
|
"hint_string": ""
|
|
})
|
|
_runner_btn = RunnerButton.new()
|
|
add_control_to_container(EditorPlugin.CONTAINER_TOOLBAR, _runner_btn)
|
|
|
|
var cnt := _runner_btn.get_parent()
|
|
cnt.move_child(_runner_btn, cnt.get_child_count() - 3)
|
|
|
|
|
|
func _exit_tree() -> void:
|
|
remove_control_from_container(EditorPlugin.CONTAINER_TOOLBAR, _runner_btn)
|
|
_runner_btn.queue_free()
|
|
_runner_btn = null
|
|
|
|
|
|
class RunnerButton:
|
|
extends Button
|
|
|
|
var _play: Texture2D
|
|
var _stop: Texture2D
|
|
var _running_pid: int = -1
|
|
var _io: FileAccess = null
|
|
var _err: FileAccess = null
|
|
|
|
func _init() -> void:
|
|
_play = EditorInterface.get_editor_theme().get_icon(&"Play", &"EditorIcons")
|
|
_stop = EditorInterface.get_editor_theme().get_icon(&"Stop", &"EditorIcons")
|
|
shortcut = Shortcut.new()
|
|
var key := InputEventKey.new()
|
|
key.keycode = KEY_F5
|
|
key.shift_pressed = true
|
|
shortcut.events = [key]
|
|
modulate = Color.GREEN
|
|
var esb := StyleBoxEmpty.new()
|
|
add_theme_stylebox_override(&"normal", esb)
|
|
|
|
func _ready() -> void:
|
|
icon = _play
|
|
|
|
func _process(_d: float) -> void:
|
|
if _running_pid == -1: return
|
|
if not OS.is_process_running(_running_pid):
|
|
_running_pid = -1
|
|
icon = _play
|
|
modulate = Color.GREEN
|
|
|
|
func _pressed() -> void:
|
|
if _running_pid != -1:
|
|
OS.kill(_running_pid)
|
|
_running_pid = -1
|
|
icon = _play
|
|
modulate = Color.GREEN
|
|
return
|
|
|
|
var runner := ProjectSettings.get_setting("application/run/custom_runner", "")
|
|
if runner == "":
|
|
EditorInterface.play_main_scene()
|
|
return
|
|
|
|
if not FileAccess.file_exists(runner):
|
|
EditorInterface.get_editor_toaster().push_toast("Custom runner does not exist!",
|
|
EditorToaster.SEVERITY_ERROR,
|
|
"Provide the full path to the custom runner!")
|
|
return
|
|
|
|
var godot = OS.get_executable_path()
|
|
var project = ProjectSettings.globalize_path("res://").rstrip("/")
|
|
var host: String = EditorInterface.get_editor_settings().get_setting("network/debug/remote_host")
|
|
var port: int = EditorInterface.get_editor_settings().get_setting("network/debug/remote_port")
|
|
var pid: int = OS.get_process_id()
|
|
var main_scene: String = ProjectSettings.get_setting("application/run/main_scene")
|
|
var run_arguments := [
|
|
godot,
|
|
"--path", project,
|
|
"-d"
|
|
#"--remote-debug", "tcp://%s:%s" % [host, port],
|
|
#"--editor-pid", "%s" % pid,
|
|
#"--position", "320,-24",
|
|
#"--scene", main_scene
|
|
]
|
|
# --remote-debug tcp://127.0.0.1:6007 --editor-pid 3480813 --position 320,-24 --scene uid://2t2hslaaewee
|
|
print("Executing project with the following Command Line: %s %s" % [runner, run_arguments])
|
|
|
|
|
|
#_running_pid = OS.create_process(runner, run_arguments)
|
|
var res := OS.execute_with_pipe(runner, run_arguments, false)
|
|
|
|
if res.is_empty():
|
|
EditorInterface.get_editor_toaster().push_toast("Failed to Run custom runner.",EditorToaster.SEVERITY_ERROR)
|
|
|
|
_running_pid = res.pid
|
|
_io = res.stdio
|
|
_err = res.stderr
|
|
|
|
icon = _stop
|
|
modulate = Color.RED
|
|
_monitor_input_output()
|
|
|
|
func _monitor_input_output() -> void:
|
|
var output: PackedByteArray = []
|
|
var err: PackedByteArray = []
|
|
|
|
while OS.is_process_running(_running_pid):
|
|
await get_tree().process_frame
|
|
|
|
var res := _read_io(_io, output)
|
|
if res != "":
|
|
print_rich(res)
|
|
|
|
res = _read_io(_err, err)
|
|
if res != "":
|
|
print_rich(res)
|
|
|
|
await get_tree().process_frame
|
|
var str := _read_io(_io, output)
|
|
if str != "":
|
|
print(str)
|
|
|
|
str = _read_io(_err, err)
|
|
if str != "":
|
|
print(str)
|
|
_io.close()
|
|
_err.close()
|
|
_io = null
|
|
_err = null
|
|
|
|
func _read_io(io: FileAccess, buffer: PackedByteArray) -> String:
|
|
if io.get_position() < io.get_length():
|
|
buffer.append_array(io.get_buffer(io.get_length() - io.get_position()))
|
|
var nl = buffer.rfind(10)
|
|
if nl == -1:
|
|
return ""
|
|
|
|
var part := buffer.slice(0,nl)
|
|
var leftover := buffer.slice(nl+1)
|
|
buffer.clear()
|
|
buffer.append_array(leftover)
|
|
return part.get_string_from_utf8()
|