Created Plugin Custom Runner

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.
This commit is contained in:
Mario Steele 2026-03-02 02:00:30 -06:00
parent 3804940b22
commit e02daac0ff
3 changed files with 159 additions and 0 deletions

View file

@ -0,0 +1,7 @@
[plugin]
name="Custom Runner"
description="A plugin that runs the Godot Engine with a specific tool, such as obs-gamecapture, to capture the game window."
author="Mario Steele"
version="0.1"
script="plugin.gd"

View file

@ -0,0 +1,151 @@
@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()

View file

@ -0,0 +1 @@
uid://bsdgmd1nimt6n