summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs
blob: 0898f095cde8d1ed3a5799e1c00a66477b2d584d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#nullable disable

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Mono.Cecil;
using StardewModdingAPI.Toolkit.Utilities;

namespace StardewModdingAPI.Framework.ModLoading
{
    /// <summary>Metadata for mapping assemblies to the current <see cref="Platform"/>.</summary>
    internal class PlatformAssemblyMap : IDisposable
    {
        /*********
        ** Accessors
        *********/
        /****
        ** Data
        ****/
        /// <summary>The target game platform.</summary>
        public readonly Platform TargetPlatform;

        /// <summary>The short assembly names to remove as assembly reference, and replace with the <see cref="Targets"/>. These should be short names (like "Stardew Valley").</summary>
        public readonly string[] RemoveNames;

        /****
        ** Metadata
        ****/
        /// <summary>The assemblies to target. Equivalent types should be rewritten to use these assemblies.</summary>
        public readonly Assembly[] Targets;

        /// <summary>An assembly => reference cache.</summary>
        public readonly IDictionary<Assembly, AssemblyNameReference> TargetReferences;

        /// <summary>An assembly => module cache.</summary>
        public readonly IDictionary<Assembly, ModuleDefinition> TargetModules;


        /*********
        ** Public methods
        *********/
        /// <summary>Construct an instance.</summary>
        /// <param name="targetPlatform">The target game platform.</param>
        /// <param name="removeAssemblyNames">The assembly short names to remove (like <c>Stardew Valley</c>).</param>
        /// <param name="targetAssemblies">The assemblies to target.</param>
        public PlatformAssemblyMap(Platform targetPlatform, string[] removeAssemblyNames, Assembly[] targetAssemblies)
        {
            // save data
            this.TargetPlatform = targetPlatform;
            this.RemoveNames = removeAssemblyNames;

            // cache assembly metadata
            this.Targets = targetAssemblies;
            this.TargetReferences = this.Targets.ToDictionary(assembly => assembly, assembly => AssemblyNameReference.Parse(assembly.FullName));
            this.TargetModules = this.Targets.ToDictionary(assembly => assembly, assembly => ModuleDefinition.ReadModule(assembly.Modules.Single().FullyQualifiedName, new ReaderParameters { InMemory = true }));
        }

        /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
        public void Dispose()
        {
            foreach (ModuleDefinition module in this.TargetModules.Values)
                module.Dispose();
        }
    }
}