Browse Source

Fixed load ordering

pull/46/head
Anairkoen Schno 5 years ago
parent
commit
d4112d9581
2 changed files with 60 additions and 12 deletions
  1. +60
    -12
      IPA.Loader/Loader/PluginLoader.cs
  2. BIN
      Refs/UnityEngine.CoreModule.dll

+ 60
- 12
IPA.Loader/Loader/PluginLoader.cs View File

@ -73,6 +73,8 @@ namespace IPA.Loader
private PluginManifest manifest; private PluginManifest manifest;
internal HashSet<PluginMetadata> Dependencies { get; } = new HashSet<PluginMetadata>();
internal PluginManifest Manifest internal PluginManifest Manifest
{ {
get => manifest; get => manifest;
@ -281,30 +283,76 @@ namespace IPA.Loader
internal static void ComputeLoadOrder() internal static void ComputeLoadOrder()
{ {
PluginsMetadata.Sort((a, b) =>
{
if (a.Id == b.Id) return 0;
if (a.Id != null)
#if DEBUG
Logger.loader.Debug(string.Join(", ", PluginsMetadata.Select(p => p.ToString())));
#endif
bool InsertInto(HashSet<PluginMetadata> root, PluginMetadata meta, bool isRoot = false)
{ // this is slow, and hella recursive
bool inserted = false;
foreach (var sr in root)
{ {
if (b.Manifest.Dependencies.ContainsKey(a.Id) || b.Manifest.LoadAfter.Contains(a.Id)) return -1;
if (b.Manifest.LoadBefore.Contains(a.Id)) return 1;
inserted = inserted || InsertInto(sr.Dependencies, meta);
if (meta.Id != null)
if (sr.Manifest.Dependencies.ContainsKey(meta.Id) || sr.Manifest.LoadAfter.Contains(meta.Id))
inserted = inserted || sr.Dependencies.Add(meta);
if (sr.Id != null)
if (meta.Manifest.LoadBefore.Contains(sr.Id))
inserted = inserted || sr.Dependencies.Add(meta);
} }
if (b.Id != null)
if (isRoot)
{ {
if (a.Manifest.Dependencies.ContainsKey(b.Id) || a.Manifest.LoadAfter.Contains(b.Id)) return 1;
if (a.Manifest.LoadBefore.Contains(b.Id)) return -1;
foreach (var sr in root)
{
InsertInto(meta.Dependencies, sr);
if (sr.Id != null)
if (meta.Manifest.Dependencies.ContainsKey(sr.Id) || meta.Manifest.LoadAfter.Contains(sr.Id))
meta.Dependencies.Add(sr);
if (meta.Id != null)
if (sr.Manifest.LoadBefore.Contains(meta.Id))
meta.Dependencies.Add(sr);
}
root.Add(meta);
} }
return 0;
});
return inserted;
}
var pluginTree = new HashSet<PluginMetadata>();
foreach (var meta in PluginsMetadata)
InsertInto(pluginTree, meta, true);
void DeTree(List<PluginMetadata> into, HashSet<PluginMetadata> tree)
{
foreach (var st in tree)
if (!into.Contains(st))
{
DeTree(into, st.Dependencies);
into.Add(st);
}
}
var deTreed = new List<PluginMetadata>();
DeTree(deTreed, pluginTree);
#if DEBUG
Logger.loader.Debug(string.Join(", ", deTreed.Select(p => p.ToString())));
#endif
var metadata = new List<PluginMetadata>(); var metadata = new List<PluginMetadata>();
var pluginsToLoad = new Dictionary<string, Version>(); var pluginsToLoad = new Dictionary<string, Version>();
foreach (var meta in PluginsMetadata)
foreach (var meta in deTreed)
{ {
bool load = true; bool load = true;
foreach (var dep in meta.Manifest.Dependencies) foreach (var dep in meta.Manifest.Dependencies)
{ {
#if DEBUG
Logger.loader.Debug($"Looking for dependency {dep.Key} with version range {dep.Value.Intersect(new SemVer.Range("*.*.*"))}");
#endif
if (pluginsToLoad.ContainsKey(dep.Key) && dep.Value.IsSatisfied(pluginsToLoad[dep.Key])) if (pluginsToLoad.ContainsKey(dep.Key) && dep.Value.IsSatisfied(pluginsToLoad[dep.Key]))
continue; continue;


BIN
Refs/UnityEngine.CoreModule.dll View File


Loading…
Cancel
Save