mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-30 14:39:42 +08:00
2b6bd5a532
* [audio] added sdl audio backend and in-tree atrac9 decoder * [input] replaced per-platform pad readers with sdl gamepad input * [video] added sdl window and host display plumbing * [gui] added host display options and per-game render settings * [bink] synced host movie playback to the guest audio clock * [cpu] hooked windows write faults into guest image tracking * [perf] added guest and render profiling, reserved host cpu lanes * [kernel] fixed stale pthread mutex handle alias * [host] wired the sdl session, save-data paths and project references * [audio] hoisted ajm trace stackalloc out of its loop * [video] Add guest image sync setting * [build] Strip native symbols * reuse
79 lines
2.3 KiB
C#
79 lines
2.3 KiB
C#
// Copyright (C) 2026 SharpEmu Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
namespace SharpEmu.HLE;
|
|
|
|
/// <summary>
|
|
/// Runs work on the real process main thread. macOS requires its windowing
|
|
/// event loop on that thread, so the CLI moves emulation onto
|
|
/// a worker thread, parks the main thread in <see cref="Pump"/>, and the
|
|
/// video presenter posts its window loop here. On other platforms
|
|
/// <see cref="IsAvailable"/> stays false and nothing changes.
|
|
/// </summary>
|
|
public static class HostMainThread
|
|
{
|
|
private static readonly BlockingCollection<Action> _work = new();
|
|
private static Action? _shutdownRequestHandler;
|
|
|
|
public static bool IsAvailable { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Registers a callback invoked by <see cref="Shutdown"/> so a
|
|
/// long-running posted work item (the presenter's window loop) can be
|
|
/// asked to return to the pump.
|
|
/// </summary>
|
|
public static void SetShutdownRequestHandler(Action handler) =>
|
|
_shutdownRequestHandler = handler;
|
|
|
|
/// <summary>Marks the pump as present. Call before guest code can run.</summary>
|
|
public static void Enable() => IsAvailable = true;
|
|
|
|
public static void Post(Action work)
|
|
{
|
|
try
|
|
{
|
|
_work.Add(work);
|
|
}
|
|
catch (InvalidOperationException)
|
|
{
|
|
// Shutdown already requested; the process is exiting.
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Services posted work on the calling (main) thread until
|
|
/// <see cref="Shutdown"/> is called and the queue drains.
|
|
/// </summary>
|
|
public static void Pump()
|
|
{
|
|
foreach (var work in _work.GetConsumingEnumerable())
|
|
{
|
|
try
|
|
{
|
|
work();
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Console.Error.WriteLine($"[LOADER][ERROR] Main-thread work failed: {exception}");
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void Shutdown()
|
|
{
|
|
IsAvailable = false;
|
|
try
|
|
{
|
|
_shutdownRequestHandler?.Invoke();
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Console.Error.WriteLine($"[LOADER][WARN] Main-thread shutdown handler failed: {exception.Message}");
|
|
}
|
|
|
|
_work.CompleteAdding();
|
|
}
|
|
}
|