feature: Weaver adds 'bool Weaved()' to each NetworkBehaviour, which can be checked at runtime #3523

This commit is contained in:
mischa 2023-06-23 19:01:43 +08:00
parent 1d7af1b750
commit d5664ab202
2 changed files with 18 additions and 4 deletions

View File

@ -1351,5 +1351,10 @@ public virtual void OnStartAuthority() {}
/// <summary>Stop event, only called for objects the client has authority over.</summary> /// <summary>Stop event, only called for objects the client has authority over.</summary>
public virtual void OnStopAuthority() {} public virtual void OnStopAuthority() {}
// Weaver injects this into inheriting classes to return true.
// allows runtime & tests to check if a type was weaved.
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool Weaved() => false;
} }
} }

View File

@ -205,20 +205,29 @@ public static bool WriteArguments(ILProcessor worker, Writers writers, Logger Lo
} }
#region mark / check type as processed #region mark / check type as processed
public const string ProcessedFunctionName = "MirrorProcessed"; public const string ProcessedFunctionName = "Weaved";
// by adding an empty MirrorProcessed() function // check if the type has a "Weaved" function already
public static bool WasProcessed(TypeDefinition td) public static bool WasProcessed(TypeDefinition td)
{ {
return td.GetMethod(ProcessedFunctionName) != null; return td.GetMethod(ProcessedFunctionName) != null;
} }
// add the Weaved() function which returns true.
// can be called at runtime and from tests to check if weaving succeeded.
public void MarkAsProcessed(TypeDefinition td) public void MarkAsProcessed(TypeDefinition td)
{ {
if (!WasProcessed(td)) if (!WasProcessed(td))
{ {
MethodDefinition versionMethod = new MethodDefinition(ProcessedFunctionName, MethodAttributes.Private, weaverTypes.Import(typeof(void))); // add a function:
// public override bool MirrorProcessed() { return true; }
// ReuseSlot means 'override'.
MethodDefinition versionMethod = new MethodDefinition(
ProcessedFunctionName,
MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot,
weaverTypes.Import(typeof(bool)));
ILProcessor worker = versionMethod.Body.GetILProcessor(); ILProcessor worker = versionMethod.Body.GetILProcessor();
worker.Emit(OpCodes.Ldc_I4_1);
worker.Emit(OpCodes.Ret); worker.Emit(OpCodes.Ret);
td.Methods.Add(versionMethod); td.Methods.Add(versionMethod);
} }
@ -531,7 +540,7 @@ void GenerateSerialization(ref bool WeavingFailed)
{ {
writeFunc = writers.GetWriteFunc(syncVar.FieldType, ref WeavingFailed); writeFunc = writers.GetWriteFunc(syncVar.FieldType, ref WeavingFailed);
} }
if (writeFunc != null) if (writeFunc != null)
{ {
worker.Emit(OpCodes.Call, writeFunc); worker.Emit(OpCodes.Call, writeFunc);