mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
refactor: split mpv plugin into modular script directory
This commit is contained in:
449
plugin/subminer/process.lua
Normal file
449
plugin/subminer/process.lua
Normal file
@@ -0,0 +1,449 @@
|
||||
local M = {}
|
||||
|
||||
function M.create(ctx)
|
||||
local mp = ctx.mp
|
||||
local opts = ctx.opts
|
||||
local state = ctx.state
|
||||
local binary = ctx.binary
|
||||
local environment = ctx.environment
|
||||
local options_helper = ctx.options_helper
|
||||
local subminer_log = ctx.log.subminer_log
|
||||
local show_osd = ctx.log.show_osd
|
||||
local normalize_log_level = ctx.log.normalize_log_level
|
||||
|
||||
local function resolve_backend(override_backend)
|
||||
local selected = override_backend
|
||||
if selected == nil or selected == "" then
|
||||
selected = opts.backend
|
||||
end
|
||||
if selected == "auto" then
|
||||
return environment.detect_backend()
|
||||
end
|
||||
return selected
|
||||
end
|
||||
|
||||
local function build_command_args(action, overrides)
|
||||
overrides = overrides or {}
|
||||
local args = { state.binary_path }
|
||||
|
||||
table.insert(args, "--" .. action)
|
||||
local log_level = normalize_log_level(overrides.log_level or opts.log_level)
|
||||
if log_level ~= "info" then
|
||||
table.insert(args, "--log-level")
|
||||
table.insert(args, log_level)
|
||||
end
|
||||
|
||||
local needs_start_context = action == "start"
|
||||
if needs_start_context then
|
||||
local backend = resolve_backend(overrides.backend)
|
||||
if backend and backend ~= "" then
|
||||
table.insert(args, "--backend")
|
||||
table.insert(args, backend)
|
||||
end
|
||||
|
||||
local socket_path = overrides.socket_path or opts.socket_path
|
||||
table.insert(args, "--socket")
|
||||
table.insert(args, socket_path)
|
||||
end
|
||||
|
||||
return args
|
||||
end
|
||||
|
||||
local function run_control_command(action)
|
||||
local args = build_command_args(action)
|
||||
subminer_log("debug", "process", "Control command: " .. table.concat(args, " "))
|
||||
local result = mp.command_native({
|
||||
name = "subprocess",
|
||||
args = args,
|
||||
playback_only = false,
|
||||
capture_stdout = true,
|
||||
capture_stderr = true,
|
||||
})
|
||||
return result and result.status == 0
|
||||
end
|
||||
|
||||
local function parse_start_script_message_overrides(...)
|
||||
local overrides = {}
|
||||
for i = 1, select("#", ...) do
|
||||
local token = select(i, ...)
|
||||
if type(token) == "string" and token ~= "" then
|
||||
local key, value = token:match("^([%w_%-]+)=(.+)$")
|
||||
if key and value then
|
||||
local normalized_key = key:lower()
|
||||
if normalized_key == "backend" then
|
||||
local backend = value:lower()
|
||||
if backend == "auto" or backend == "hyprland" or backend == "sway" or backend == "x11" or backend == "macos" then
|
||||
overrides.backend = backend
|
||||
end
|
||||
elseif normalized_key == "socket" or normalized_key == "socket_path" then
|
||||
overrides.socket_path = value
|
||||
elseif normalized_key == "texthooker" or normalized_key == "texthooker_enabled" then
|
||||
local parsed = options_helper.coerce_bool(value, nil)
|
||||
if parsed ~= nil then
|
||||
overrides.texthooker_enabled = parsed
|
||||
end
|
||||
elseif normalized_key == "log-level" or normalized_key == "log_level" then
|
||||
overrides.log_level = normalize_log_level(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return overrides
|
||||
end
|
||||
|
||||
local function resolve_visible_overlay_startup()
|
||||
local visible = options_helper.coerce_bool(opts.auto_start_visible_overlay, false)
|
||||
if options_helper.coerce_bool(opts.auto_start_overlay, false) then
|
||||
visible = true
|
||||
end
|
||||
return visible
|
||||
end
|
||||
|
||||
local function resolve_invisible_overlay_startup()
|
||||
local raw = opts.auto_start_invisible_overlay
|
||||
if type(raw) == "boolean" then
|
||||
return raw
|
||||
end
|
||||
|
||||
local mode = type(raw) == "string" and raw:lower() or "platform-default"
|
||||
if mode == "visible" or mode == "show" or mode == "yes" or mode == "true" or mode == "on" then
|
||||
return true
|
||||
end
|
||||
if mode == "hidden" or mode == "hide" or mode == "no" or mode == "false" or mode == "off" then
|
||||
return false
|
||||
end
|
||||
|
||||
return not environment.is_linux()
|
||||
end
|
||||
|
||||
local function apply_startup_overlay_preferences()
|
||||
local should_show_visible = resolve_visible_overlay_startup()
|
||||
local should_show_invisible = resolve_invisible_overlay_startup()
|
||||
|
||||
local visible_action = should_show_visible and "show-visible-overlay" or "hide-visible-overlay"
|
||||
if not run_control_command(visible_action) then
|
||||
subminer_log("warn", "process", "Failed to apply visible startup action: " .. visible_action)
|
||||
end
|
||||
|
||||
local invisible_action = should_show_invisible and "show-invisible-overlay" or "hide-invisible-overlay"
|
||||
if not run_control_command(invisible_action) then
|
||||
subminer_log("warn", "process", "Failed to apply invisible startup action: " .. invisible_action)
|
||||
end
|
||||
|
||||
state.invisible_overlay_visible = should_show_invisible
|
||||
end
|
||||
|
||||
local function build_texthooker_args()
|
||||
local args = { state.binary_path, "--texthooker", "--port", tostring(opts.texthooker_port) }
|
||||
local log_level = normalize_log_level(opts.log_level)
|
||||
if log_level ~= "info" then
|
||||
table.insert(args, "--log-level")
|
||||
table.insert(args, log_level)
|
||||
end
|
||||
return args
|
||||
end
|
||||
|
||||
local function ensure_texthooker_running(callback)
|
||||
if not opts.texthooker_enabled then
|
||||
callback()
|
||||
return
|
||||
end
|
||||
if state.texthooker_running then
|
||||
callback()
|
||||
return
|
||||
end
|
||||
|
||||
local args = build_texthooker_args()
|
||||
subminer_log("info", "texthooker", "Starting texthooker process: " .. table.concat(args, " "))
|
||||
state.texthooker_running = true
|
||||
|
||||
mp.command_native_async({
|
||||
name = "subprocess",
|
||||
args = args,
|
||||
playback_only = false,
|
||||
capture_stdout = true,
|
||||
capture_stderr = true,
|
||||
}, function(success, result, error)
|
||||
if not success or (result and result.status ~= 0) then
|
||||
state.texthooker_running = false
|
||||
subminer_log("warn", "texthooker", "Texthooker process exited unexpectedly: " .. (error or (result and result.stderr) or "unknown error"))
|
||||
end
|
||||
end)
|
||||
|
||||
mp.add_timeout(0.35, callback)
|
||||
end
|
||||
|
||||
local function start_overlay(overrides)
|
||||
if not binary.ensure_binary_available() then
|
||||
subminer_log("error", "binary", "SubMiner binary not found")
|
||||
show_osd("Error: binary not found")
|
||||
return
|
||||
end
|
||||
if state.overlay_running then
|
||||
subminer_log("info", "process", "Overlay already running")
|
||||
show_osd("Already running")
|
||||
return
|
||||
end
|
||||
|
||||
overrides = overrides or {}
|
||||
local texthooker_enabled = overrides.texthooker_enabled
|
||||
if texthooker_enabled == nil then
|
||||
texthooker_enabled = opts.texthooker_enabled
|
||||
end
|
||||
|
||||
local function launch_overlay()
|
||||
local args = build_command_args("start", overrides)
|
||||
subminer_log("info", "process", "Starting overlay: " .. table.concat(args, " "))
|
||||
show_osd("Starting...")
|
||||
state.overlay_running = true
|
||||
|
||||
mp.command_native_async({
|
||||
name = "subprocess",
|
||||
args = args,
|
||||
playback_only = false,
|
||||
capture_stdout = true,
|
||||
capture_stderr = true,
|
||||
}, function(success, result, error)
|
||||
if not success or (result and result.status ~= 0) then
|
||||
state.overlay_running = false
|
||||
subminer_log("error", "process", "Overlay start failed: " .. (error or (result and result.stderr) or "unknown error"))
|
||||
show_osd("Overlay start failed")
|
||||
end
|
||||
end)
|
||||
|
||||
mp.add_timeout(0.6, function()
|
||||
apply_startup_overlay_preferences()
|
||||
end)
|
||||
end
|
||||
|
||||
if texthooker_enabled then
|
||||
ensure_texthooker_running(launch_overlay)
|
||||
else
|
||||
launch_overlay()
|
||||
end
|
||||
end
|
||||
|
||||
local function start_overlay_from_script_message(...)
|
||||
local overrides = parse_start_script_message_overrides(...)
|
||||
start_overlay(overrides)
|
||||
end
|
||||
|
||||
local function stop_overlay()
|
||||
if not binary.ensure_binary_available() then
|
||||
subminer_log("error", "binary", "SubMiner binary not found")
|
||||
show_osd("Error: binary not found")
|
||||
return
|
||||
end
|
||||
|
||||
local args = build_command_args("stop")
|
||||
subminer_log("info", "process", "Stopping overlay: " .. table.concat(args, " "))
|
||||
local result = mp.command_native({
|
||||
name = "subprocess",
|
||||
args = args,
|
||||
playback_only = false,
|
||||
capture_stdout = true,
|
||||
capture_stderr = true,
|
||||
})
|
||||
|
||||
state.overlay_running = false
|
||||
state.texthooker_running = false
|
||||
if result.status == 0 then
|
||||
subminer_log("info", "process", "Overlay stopped")
|
||||
else
|
||||
subminer_log("warn", "process", "Stop command returned non-zero status: " .. tostring(result.status))
|
||||
end
|
||||
show_osd("Stopped")
|
||||
end
|
||||
|
||||
local function toggle_overlay()
|
||||
if not binary.ensure_binary_available() then
|
||||
subminer_log("error", "binary", "SubMiner binary not found")
|
||||
show_osd("Error: binary not found")
|
||||
return
|
||||
end
|
||||
local args = build_command_args("toggle")
|
||||
subminer_log("info", "process", "Toggling overlay: " .. table.concat(args, " "))
|
||||
local result = mp.command_native({
|
||||
name = "subprocess",
|
||||
args = args,
|
||||
playback_only = false,
|
||||
capture_stdout = true,
|
||||
capture_stderr = true,
|
||||
})
|
||||
if result and result.status ~= 0 then
|
||||
subminer_log("warn", "process", "Toggle command failed")
|
||||
show_osd("Toggle failed")
|
||||
end
|
||||
end
|
||||
|
||||
local function toggle_invisible_overlay()
|
||||
if not binary.ensure_binary_available() then
|
||||
subminer_log("error", "binary", "SubMiner binary not found")
|
||||
show_osd("Error: binary not found")
|
||||
return
|
||||
end
|
||||
local args = build_command_args("toggle-invisible-overlay")
|
||||
subminer_log("info", "process", "Toggling invisible overlay: " .. table.concat(args, " "))
|
||||
local result = mp.command_native({
|
||||
name = "subprocess",
|
||||
args = args,
|
||||
playback_only = false,
|
||||
capture_stdout = true,
|
||||
capture_stderr = true,
|
||||
})
|
||||
if result and result.status ~= 0 then
|
||||
subminer_log("warn", "process", "Invisible toggle command failed")
|
||||
show_osd("Invisible toggle failed")
|
||||
return
|
||||
end
|
||||
state.invisible_overlay_visible = not state.invisible_overlay_visible
|
||||
show_osd("Invisible overlay: " .. (state.invisible_overlay_visible and "visible" or "hidden"))
|
||||
end
|
||||
|
||||
local function show_invisible_overlay()
|
||||
if not binary.ensure_binary_available() then
|
||||
subminer_log("error", "binary", "SubMiner binary not found")
|
||||
show_osd("Error: binary not found")
|
||||
return
|
||||
end
|
||||
local args = build_command_args("show-invisible-overlay")
|
||||
subminer_log("info", "process", "Showing invisible overlay: " .. table.concat(args, " "))
|
||||
local result = mp.command_native({
|
||||
name = "subprocess",
|
||||
args = args,
|
||||
playback_only = false,
|
||||
capture_stdout = true,
|
||||
capture_stderr = true,
|
||||
})
|
||||
if result and result.status ~= 0 then
|
||||
subminer_log("warn", "process", "Show invisible command failed")
|
||||
show_osd("Show invisible failed")
|
||||
return
|
||||
end
|
||||
state.invisible_overlay_visible = true
|
||||
show_osd("Invisible overlay: visible")
|
||||
end
|
||||
|
||||
local function hide_invisible_overlay()
|
||||
if not binary.ensure_binary_available() then
|
||||
subminer_log("error", "binary", "SubMiner binary not found")
|
||||
show_osd("Error: binary not found")
|
||||
return
|
||||
end
|
||||
local args = build_command_args("hide-invisible-overlay")
|
||||
subminer_log("info", "process", "Hiding invisible overlay: " .. table.concat(args, " "))
|
||||
local result = mp.command_native({
|
||||
name = "subprocess",
|
||||
args = args,
|
||||
playback_only = false,
|
||||
capture_stdout = true,
|
||||
capture_stderr = true,
|
||||
})
|
||||
if result and result.status ~= 0 then
|
||||
subminer_log("warn", "process", "Hide invisible command failed")
|
||||
show_osd("Hide invisible failed")
|
||||
return
|
||||
end
|
||||
state.invisible_overlay_visible = false
|
||||
show_osd("Invisible overlay: hidden")
|
||||
end
|
||||
|
||||
local function open_options()
|
||||
if not state.binary_available then
|
||||
subminer_log("error", "binary", "SubMiner binary not found")
|
||||
show_osd("Error: binary not found")
|
||||
return
|
||||
end
|
||||
local args = build_command_args("settings")
|
||||
subminer_log("info", "process", "Opening options: " .. table.concat(args, " "))
|
||||
local result = mp.command_native({
|
||||
name = "subprocess",
|
||||
args = args,
|
||||
playback_only = false,
|
||||
capture_stdout = true,
|
||||
capture_stderr = true,
|
||||
})
|
||||
if result.status == 0 then
|
||||
subminer_log("info", "process", "Options window opened")
|
||||
show_osd("Options opened")
|
||||
else
|
||||
subminer_log("warn", "process", "Failed to open options")
|
||||
show_osd("Failed to open options")
|
||||
end
|
||||
end
|
||||
|
||||
local function restart_overlay()
|
||||
if not binary.ensure_binary_available() then
|
||||
subminer_log("error", "binary", "SubMiner binary not found")
|
||||
show_osd("Error: binary not found")
|
||||
return
|
||||
end
|
||||
|
||||
subminer_log("info", "process", "Restarting overlay...")
|
||||
show_osd("Restarting...")
|
||||
|
||||
local stop_args = build_command_args("stop")
|
||||
mp.command_native({
|
||||
name = "subprocess",
|
||||
args = stop_args,
|
||||
playback_only = false,
|
||||
capture_stdout = true,
|
||||
capture_stderr = true,
|
||||
})
|
||||
|
||||
state.overlay_running = false
|
||||
state.texthooker_running = false
|
||||
|
||||
ensure_texthooker_running(function()
|
||||
local start_args = build_command_args("start")
|
||||
subminer_log("info", "process", "Starting overlay: " .. table.concat(start_args, " "))
|
||||
|
||||
state.overlay_running = true
|
||||
mp.command_native_async({
|
||||
name = "subprocess",
|
||||
args = start_args,
|
||||
playback_only = false,
|
||||
capture_stdout = true,
|
||||
capture_stderr = true,
|
||||
}, function(success, result, error)
|
||||
if not success or (result and result.status ~= 0) then
|
||||
state.overlay_running = false
|
||||
subminer_log("error", "process", "Overlay start failed: " .. (error or (result and result.stderr) or "unknown error"))
|
||||
show_osd("Restart failed")
|
||||
else
|
||||
show_osd("Restarted successfully")
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
local function check_status()
|
||||
if not state.binary_available then
|
||||
show_osd("Status: binary not found")
|
||||
return
|
||||
end
|
||||
local status = state.overlay_running and "running" or "stopped"
|
||||
show_osd("Status: overlay is " .. status)
|
||||
subminer_log("info", "process", "Status check: overlay is " .. status)
|
||||
end
|
||||
|
||||
return {
|
||||
build_command_args = build_command_args,
|
||||
run_control_command = run_control_command,
|
||||
parse_start_script_message_overrides = parse_start_script_message_overrides,
|
||||
apply_startup_overlay_preferences = apply_startup_overlay_preferences,
|
||||
ensure_texthooker_running = ensure_texthooker_running,
|
||||
start_overlay = start_overlay,
|
||||
start_overlay_from_script_message = start_overlay_from_script_message,
|
||||
stop_overlay = stop_overlay,
|
||||
toggle_overlay = toggle_overlay,
|
||||
toggle_invisible_overlay = toggle_invisible_overlay,
|
||||
show_invisible_overlay = show_invisible_overlay,
|
||||
hide_invisible_overlay = hide_invisible_overlay,
|
||||
open_options = open_options,
|
||||
restart_overlay = restart_overlay,
|
||||
check_status = check_status,
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user