ClientScript loading logic

This commit is contained in:
sardelka9515
2022-10-09 23:35:30 +08:00
parent 617dbc9812
commit fe53e01a4a
8 changed files with 104 additions and 203 deletions

View File

@ -8,6 +8,7 @@ using System.Windows.Forms;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Concurrent;
using static System.Net.WebRequestMethods;
namespace RageCoop.Client.Scripting
{
@ -36,6 +37,8 @@ namespace RageCoop.Client.Scripting
// Bridge to current ScriptDomain
primary.Tick += Tick;
primary.KeyEvent += KeyEvent;
CurrentDomain.Start();
SetupScripts();
AppDomain.CurrentDomain.SetData("Primary", false);
Console.WriteLine("Loaded scondary domain: " + AppDomain.CurrentDomain.Id + " " + Util.IsPrimaryDomain);
}
@ -45,10 +48,31 @@ namespace RageCoop.Client.Scripting
}
public void SetupScripts()
{
foreach(var s in ScriptDomain.CurrentDomain.RunningScripts)
foreach (var s in GetClientScripts())
{
try
{
var script = (ClientScript)s;
var res = Main.API.GetResource(Path.GetFileName(Directory.GetParent(script.Filename).FullName));
if (res == null) { Main.API.Logger.Warning("Failed to locate resource for script: " + script.Filename); continue; }
script.CurrentResource = res;
script.CurrentFile = res.Files.Values.Where(x => x.Name.ToLower() == script.Filename.Substring(res.BaseDirectory.Length + 1).Replace('\\', '/')).FirstOrDefault();
res.Scripts.Add(script);
script.OnStart();
}
catch (Exception ex)
{
Main.API.Logger.Error($"Failed to start {s.GetType().FullName}", ex);
}
}
}
public object[] GetClientScripts()
{
return ScriptDomain.CurrentDomain.RunningScripts.Where(x =>
x.ScriptInstance.GetType().IsAssignableFrom(typeof(ClientScript)) &&
!x.ScriptInstance.GetType().IsAbstract).Select(x => x.ScriptInstance).ToArray();
}
public static ResourceDomain Load(string dir = @"RageCoop\Scripts\Debug")
{
lock (_loadedDomains)
@ -62,7 +86,7 @@ namespace RageCoop.Client.Scripting
{
throw new Exception("Already loaded");
}
ScriptDomain domain = null;
ScriptDomain sDomain = null;
try
{
dir = Path.GetFullPath(dir);
@ -81,11 +105,10 @@ namespace RageCoop.Client.Scripting
.Select(x => Assembly.Load(x.FullName).Location)
.Where(x => !string.IsNullOrEmpty(x)));
domain = ScriptDomain.Load(Directory.GetParent(typeof(ScriptDomain).Assembly.Location).FullName, dir);
domain.AppDomain.SetData("Console", ScriptDomain.CurrentDomain.AppDomain.GetData("Console"));
domain.AppDomain.SetData("RageCoop.Client.API", API.GetInstance());
_loadedDomains.TryAdd(dir, (ResourceDomain)domain.AppDomain.CreateInstanceFromAndUnwrap(typeof(ResourceDomain).Assembly.Location, typeof(ResourceDomain).FullName, false, BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { ScriptDomain.CurrentDomain, api.ToArray() }, null, null));
domain.Start();
sDomain = ScriptDomain.Load(Directory.GetParent(typeof(ScriptDomain).Assembly.Location).FullName, dir);
sDomain.AppDomain.SetData("Console", ScriptDomain.CurrentDomain.AppDomain.GetData("Console"));
sDomain.AppDomain.SetData("RageCoop.Client.API", API.GetInstance());
_loadedDomains.TryAdd(dir, (ResourceDomain)sDomain.AppDomain.CreateInstanceFromAndUnwrap(typeof(ResourceDomain).Assembly.Location, typeof(ResourceDomain).FullName, false, BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { ScriptDomain.CurrentDomain, api.ToArray() }, null, null));
});
// Wait till next tick
@ -96,9 +119,9 @@ namespace RageCoop.Client.Scripting
{
GTA.UI.Notification.Show(ex.ToString());
Main.Logger.Error(ex);
if (domain != null)
if (sDomain != null)
{
ScriptDomain.Unload(domain);
ScriptDomain.Unload(sDomain);
}
throw;
}
@ -109,13 +132,19 @@ namespace RageCoop.Client.Scripting
{
lock (_loadedDomains)
{
Exception ex=null;
Main.QueueToMainThread(() =>
{
domain.Dispose();
ScriptDomain.Unload(domain.CurrentDomain);
_loadedDomains.TryRemove(domain.BaseDirectory, out _);
try
{
domain.Dispose();
ScriptDomain.Unload(domain.CurrentDomain);
_loadedDomains.TryRemove(domain.BaseDirectory, out _);
}
catch(Exception e) { ex = e; }
});
GTA.Script.Yield();
if(ex != null) { throw ex; }
}
}
public static void Unload(string dir)
@ -145,6 +174,17 @@ namespace RageCoop.Client.Scripting
public void Dispose()
{
foreach(var s in GetClientScripts())
{
try
{
((ClientScript)s).OnStop();
}
catch(Exception ex)
{
Main.API.Logger.Error($"Failed to stop {s.GetType().FullName}",ex);
}
}
PrimaryDomain.Tick -= Tick;
PrimaryDomain.KeyEvent -= KeyEvent;
}