Skip to content

Commit 6c6b17c

Browse files
committed
Add load and unload triggers
1 parent 5c38319 commit 6c6b17c

5 files changed

Lines changed: 120 additions & 37 deletions

File tree

scripts/Attributes.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System;
2+
3+
namespace UnityNativeTool
4+
{
5+
/// <summary>
6+
/// Member native functions in types with this attributes will be mocked. This attribute is redundant if "Mock all native functions" option is true.
7+
/// </summary>
8+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
9+
public class MockNativeDeclarationsAttribute : Attribute
10+
{
11+
12+
}
13+
14+
/// <summary>
15+
/// Native functions with this attribute will be mocked. This attribute is redundant if "Mock all native functions" option is true.
16+
/// </summary>
17+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
18+
public class MockNativeDeclarationAttribute : Attribute
19+
{
20+
21+
}
22+
23+
/// <summary>
24+
/// Applied to native function, prevents it from being mocked.
25+
/// Applied to class, prevents all member native functions from being mocked.
26+
/// </summary>
27+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
28+
public class DisableMockingAttribute : Attribute
29+
{
30+
31+
}
32+
33+
/// <summary>
34+
/// Methods with this attribute are called directly after a native DLL has been loaded.
35+
/// Such method must be <see langword="static"/> and either have no parameters or one parameter of type <see cref="NativeDll"/>
36+
/// which indicates the state of the dll being loaded. Please treat this parameter as readonly.
37+
/// </summary>
38+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
39+
public class NativeDllLoadedTriggerAttribute : Attribute
40+
{
41+
42+
}
43+
44+
/// <summary>
45+
/// Methods with this attribute are called directly before a native DLL is going to be unloaded.
46+
/// Such method must be <see langword="static"/> and either have no parameters or one parameter of type <see cref="NativeDll"/>
47+
/// which indicates the state of the dll being unloaded. Please treat this parameter as readonly.
48+
/// </summary>
49+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
50+
public class NativeDllBeforeUnloadTriggerAttribute : Attribute
51+
{
52+
53+
}
54+
55+
/// <summary>
56+
/// Methods with this attribute are called directly after a native DLL has been unloaded.
57+
/// Such method must be <see langword="static"/> and either have no parameters or one parameter of type <see cref="NativeDll"/>
58+
/// which indicates the state of the dll being unloaded. Please treat this parameter as readonly.
59+
/// </summary>
60+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
61+
public class NativeDllAfterUnloadTriggerAttribute : Attribute
62+
{
63+
64+
}
65+
}

scripts/DllManipulator.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ public partial class DllManipulator
3030
private static List<NativeFunction> _mockedNativeFunctions = new List<NativeFunction>();
3131
private static int _createdDelegateTypes = 0;
3232
private static int _lastNativeCallIndex = 0; //Use with synchronization
33+
private static List<MethodInfo> _customLoadedTriggers = null;
34+
private static List<MethodInfo> _customBeforeUnloadTriggers = null;
35+
private static List<MethodInfo> _customAfterUnloadTriggers = null;
3336

3437
/// <summary>
3538
/// Initialization.
@@ -78,6 +81,18 @@ internal static void Initialize(int unityMainThreadId, string assetsPath)
7881
if (Options.mockAllNativeFunctions || method.IsDefined(typeof(MockNativeDeclarationAttribute)) || method.DeclaringType.IsDefined(typeof(MockNativeDeclarationsAttribute)))
7982
MockNativeFunction(method);
8083
}
84+
else if(method.IsDefined(typeof(NativeDllLoadedTriggerAttribute)))
85+
{
86+
RegisterTriggerMethod(method, ref _customLoadedTriggers);
87+
}
88+
else if (method.IsDefined(typeof(NativeDllBeforeUnloadTriggerAttribute)))
89+
{
90+
RegisterTriggerMethod(method, ref _customBeforeUnloadTriggers);
91+
}
92+
else if (method.IsDefined(typeof(NativeDllAfterUnloadTriggerAttribute)))
93+
{
94+
RegisterTriggerMethod(method, ref _customAfterUnloadTriggers);
95+
}
8196
}
8297
}
8398
}
@@ -86,6 +101,21 @@ internal static void Initialize(int unityMainThreadId, string assetsPath)
86101
LoadAll();
87102
}
88103

104+
private static void RegisterTriggerMethod(MethodInfo method, ref List<MethodInfo> triggersList)
105+
{
106+
var parameters = method.GetParameters();
107+
if (parameters.Length == 0 || parameters.Length == 1 && parameters[0].ParameterType == typeof(NativeDll))
108+
{
109+
if (triggersList == null)
110+
triggersList = new List<MethodInfo>(2);
111+
triggersList.Add(method);
112+
}
113+
else
114+
{
115+
Debug.LogError($"Trigger method must either take no parameters or one parameter of type {nameof(NativeDll)}. Violation on method {method.Name} in {method.DeclaringType.FullName}");
116+
}
117+
}
118+
89119
/// <summary>
90120
/// Loads all DLLs and functions for mocked methods
91121
/// </summary>
@@ -124,12 +154,14 @@ public static void UnloadAll()
124154
if (dll.handle != IntPtr.Zero)
125155
{
126156
LowLevelPluginManager.OnBeforeDllUnload(dll);
157+
InvokeCustomTriggers(_customBeforeUnloadTriggers, dll);
127158

128159
bool success = SysUnloadDll(dll.handle);
129160
if (!success)
130161
Debug.LogWarning($"Error while unloading DLL \"{dll.name}\" at path \"{dll.path}\"");
131162

132163
dll.ResetAsUnloaded();
164+
InvokeCustomTriggers(_customAfterUnloadTriggers, dll);
133165
}
134166
}
135167
}
@@ -449,6 +481,7 @@ internal static void LoadTargetFunction(NativeFunction nativeFunction, bool igno
449481
else
450482
{
451483
dll.loadingError = false;
484+
InvokeCustomTriggers(_customLoadedTriggers, dll);
452485
LowLevelPluginManager.OnDllLoaded(dll);
453486
}
454487
}
@@ -476,6 +509,20 @@ internal static void LoadTargetFunction(NativeFunction nativeFunction, bool igno
476509
}
477510
}
478511

512+
private static void InvokeCustomTriggers(List<MethodInfo> triggers, NativeDll dll)
513+
{
514+
if (triggers == null)
515+
return;
516+
517+
foreach(var triggerMethod in triggers)
518+
{
519+
if (triggerMethod.GetParameters().Length == 1)
520+
triggerMethod.Invoke(null, new object[] { dll });
521+
else
522+
triggerMethod.Invoke(null, Array.Empty<object>());
523+
}
524+
}
525+
479526
/// <summary>
480527
/// Logs native function's call to file. If that file exists, it is overwritten. One file is maintained for each thread.
481528
/// Note: This method is being called by dynamically generated code. Be careful when changing its signature.

scripts/MockAttributes.cs

Lines changed: 0 additions & 32 deletions
This file was deleted.

scripts/NativeDll.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
using System;
22
using System.Collections.Generic;
33

4-
namespace UnityNativeTool.Internal
4+
namespace UnityNativeTool
55
{
6-
internal class NativeDll
6+
public class NativeDll
77
{
88
public readonly string name;
99
public string path;
@@ -30,7 +30,10 @@ public void ResetAsUnloaded()
3030
}
3131
}
3232
}
33+
}
3334

35+
namespace UnityNativeTool.Internal
36+
{
3437
public class NativeDllInfo
3538
{
3639
public string name;

scripts/NativeFunction.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using System;
22

3-
namespace UnityNativeTool.Internal
3+
namespace UnityNativeTool
44
{
5-
internal struct NativeFunctionIdentity
5+
public struct NativeFunctionIdentity
66
{
77
public string symbol;
88
public string containingDllName;
@@ -30,7 +30,7 @@ public override int GetHashCode()
3030
}
3131
}
3232

33-
internal class NativeFunction
33+
public class NativeFunction
3434
{
3535
public readonly NativeFunctionIdentity identity;
3636
public NativeDll containingDll;

0 commit comments

Comments
 (0)