mirror of
https://github.com/Ale32bit/Capy64.git
synced 2025-12-14 10:05:44 +00:00
197 lines
4.3 KiB
C#
197 lines
4.3 KiB
C#
using Capy64.API;
|
|
using Capy64.Eventing.Events;
|
|
using Capy64.Runtime.Libraries;
|
|
using KeraLua;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Capy64.Runtime;
|
|
|
|
internal class RuntimeManager : IPlugin
|
|
{
|
|
private LuaState luaState;
|
|
private InputEmitter emitter;
|
|
private int step = 0;
|
|
|
|
private static bool close = false;
|
|
private static bool inPanic = false;
|
|
|
|
private static IGame _game;
|
|
public RuntimeManager(IGame game)
|
|
{
|
|
_game = game;
|
|
|
|
_game.EventEmitter.OnInit += OnInit;
|
|
_game.EventEmitter.OnTick += OnTick;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Start Capy64 state.
|
|
/// First BIOS, then OS
|
|
/// </summary>
|
|
private void Start()
|
|
{
|
|
emitter?.Unregister();
|
|
|
|
luaState?.Dispose();
|
|
luaState = null;
|
|
close = false;
|
|
|
|
switch (step++)
|
|
{
|
|
case 0:
|
|
InitBIOS();
|
|
break;
|
|
case 1:
|
|
InitOS();
|
|
break;
|
|
default:
|
|
step = 0;
|
|
Start();
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void Resume()
|
|
{
|
|
if (inPanic) return;
|
|
try
|
|
{
|
|
if (close || !luaState.ProcessQueue())
|
|
{
|
|
Start();
|
|
}
|
|
}
|
|
catch (LuaException e)
|
|
{
|
|
Console.Error.WriteLine(e);
|
|
inPanic = true;
|
|
close = true;
|
|
PanicScreen.Render(e.Message);
|
|
}
|
|
}
|
|
|
|
public static void ResetPanic()
|
|
{
|
|
inPanic = false;
|
|
}
|
|
|
|
private void InitBIOS()
|
|
{
|
|
luaState = new LuaState();
|
|
_game.LuaRuntime = luaState;
|
|
|
|
emitter = new(_game.EventEmitter, luaState);
|
|
|
|
luaState.QueueEvent("init", LK =>
|
|
{
|
|
LK.PushInteger(step);
|
|
return 1;
|
|
});
|
|
|
|
emitter.Register();
|
|
|
|
luaState.Thread.PushCFunction(L_OpenDataFolder);
|
|
luaState.Thread.SetGlobal("openDataFolder");
|
|
|
|
luaState.Thread.PushCFunction(L_InstallOS);
|
|
luaState.Thread.SetGlobal("installOS");
|
|
|
|
luaState.Thread.PushCFunction(L_Exit);
|
|
luaState.Thread.SetGlobal("exit");
|
|
|
|
var status = luaState.Thread.LoadFile("Assets/bios.lua");
|
|
if (status != LuaStatus.OK)
|
|
{
|
|
throw new LuaException(luaState.Thread.ToString(-1));
|
|
}
|
|
}
|
|
|
|
private void InitOS()
|
|
{
|
|
luaState = new LuaState();
|
|
_game.LuaRuntime = luaState;
|
|
|
|
emitter = new(_game.EventEmitter, luaState);
|
|
|
|
luaState.QueueEvent("init", LK =>
|
|
{
|
|
LK.PushInteger(step);
|
|
return 1;
|
|
});
|
|
|
|
emitter.Register();
|
|
|
|
var initContent = File.ReadAllText(Path.Combine(FileSystem.DataPath, "init.lua"));
|
|
var status = luaState.Thread.LoadString(initContent, "=init.lua");
|
|
if (status != LuaStatus.OK)
|
|
{
|
|
throw new LuaException(luaState.Thread.ToString(-1));
|
|
}
|
|
}
|
|
|
|
public static void Reboot()
|
|
{
|
|
close = true;
|
|
}
|
|
|
|
public static void Shutdown()
|
|
{
|
|
close = true;
|
|
_game.Exit();
|
|
}
|
|
|
|
public static void InstallOS(bool force = false)
|
|
{
|
|
var installedFilePath = Path.Combine(Capy64.AppDataPath, ".installed");
|
|
if (!File.Exists(installedFilePath) || force)
|
|
{
|
|
FileSystem.CopyDirectory("Assets/Lua", FileSystem.DataPath, true, true);
|
|
File.Create(installedFilePath).Dispose();
|
|
}
|
|
}
|
|
|
|
private static int L_OpenDataFolder(IntPtr state)
|
|
{
|
|
var path = FileSystem.DataPath;
|
|
switch (Environment.OSVersion.Platform)
|
|
{
|
|
case PlatformID.Win32NT:
|
|
Process.Start("explorer.exe", path);
|
|
break;
|
|
case PlatformID.Unix:
|
|
Process.Start("xdg-open", path);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private static int L_InstallOS(IntPtr state)
|
|
{
|
|
InstallOS(true);
|
|
return 0;
|
|
}
|
|
|
|
private static int L_Exit(IntPtr state)
|
|
{
|
|
close = true;
|
|
return 0;
|
|
}
|
|
|
|
private void OnInit(object sender, EventArgs e)
|
|
{
|
|
Start();
|
|
}
|
|
|
|
private void OnTick(object sender, TickEvent e)
|
|
{
|
|
Resume();
|
|
}
|
|
}
|