feat(mod): 完成外部 DLL 事务热替换

This commit is contained in:
2026-08-16 23:52:53 +08:00
parent ad256f109b
commit de5ab449cd
23 changed files with 416 additions and 18 deletions
@@ -11,10 +11,9 @@ namespace ShrinkModFramework
private static ShrinkModRuntimeDriver _instance;
private readonly ConcurrentQueue<Action> _mainThreadActions = new();
private readonly ShrinkModReloadDebouncer _externalReloadDebouncer = new();
private FileSystemWatcher _watcher;
private ShrinkModFrameworkSettings _settings;
private bool _pendingExternalReload;
private float _reloadAtRealtime;
public static void EnsureCreated(ShrinkModFrameworkSettings settings)
{
@@ -25,7 +24,8 @@ namespace ShrinkModFramework
}
var go = new GameObject("ShrinkModRuntimeDriver");
DontDestroyOnLoad(go);
if (Application.isPlaying)
DontDestroyOnLoad(go);
_instance = go.AddComponent<ShrinkModRuntimeDriver>();
_instance.ApplySettings(settings);
}
@@ -41,6 +41,12 @@ namespace ShrinkModFramework
_instance._mainThreadActions.Enqueue(action);
}
internal static ShrinkModRuntimeDriver InstanceForTesting => _instance;
internal bool HasWatcherForTesting => _watcher != null;
internal void PumpForTesting() => Update();
private void Update()
{
while (_mainThreadActions.TryDequeue(out var action))
@@ -55,11 +61,9 @@ namespace ShrinkModFramework
}
}
if (!_pendingExternalReload || Time.realtimeSinceStartup < _reloadAtRealtime)
if (!_externalReloadDebouncer.TryConsume(Time.realtimeSinceStartup))
return;
_pendingExternalReload = false;
try
{
ShrinkModLoader.LoadNewExternalMods(_settings);
@@ -117,6 +121,7 @@ namespace ShrinkModFramework
};
_watcher.Created += OnExternalModsChanged;
_watcher.Changed += OnExternalModsChanged;
_watcher.Deleted += OnExternalModsChanged;
_watcher.Renamed += OnExternalModsRenamed;
_watcher.EnableRaisingEvents = true;
}
@@ -135,6 +140,7 @@ namespace ShrinkModFramework
private void OnExternalModsRenamed(object sender, RenamedEventArgs args)
{
ScheduleExternalReload(args.OldFullPath);
ScheduleExternalReload(args.FullPath);
}
@@ -145,9 +151,8 @@ namespace ShrinkModFramework
_mainThreadActions.Enqueue(() =>
{
_pendingExternalReload = true;
var delay = _settings ? Mathf.Max(0.05f, _settings.externalModsReloadDelaySeconds) : 0.5f;
_reloadAtRealtime = Time.realtimeSinceStartup + delay;
_externalReloadDebouncer.Schedule(Time.realtimeSinceStartup, delay);
});
}
@@ -159,6 +164,7 @@ namespace ShrinkModFramework
_watcher.EnableRaisingEvents = false;
_watcher.Created -= OnExternalModsChanged;
_watcher.Changed -= OnExternalModsChanged;
_watcher.Deleted -= OnExternalModsChanged;
_watcher.Renamed -= OnExternalModsRenamed;
_watcher.Dispose();
_watcher = null;