mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
* Users must initialize syncobjects (#391) Previously we initialized syncobjects, so this is valid: ```cs public class Pepe : NetworkBehavior { public SyncList<int> mylist; } ``` With this change, users must initialize their own fields: ```cs public class Pepe : NetworkBehavior { public SyncList<int> mylist = new SyncList<int>(); } ``` BREAKING CHANGE: You must initialize all your SyncLists * Add null check * This is no longer a weaver error * Update Assets/Mirror/Runtime/NetworkBehaviour.cs Co-authored-by: James Frowen <jamesfrowendev@gmail.com> * Remove unnecesary using Co-authored-by: James Frowen <jamesfrowendev@gmail.com>
This commit is contained in:
parent
08585c7379
commit
1d05dfc952
@ -1,4 +1,3 @@
|
|||||||
using System.Linq;
|
|
||||||
using Mono.CecilX;
|
using Mono.CecilX;
|
||||||
using Mono.CecilX.Cil;
|
using Mono.CecilX.Cil;
|
||||||
|
|
||||||
@ -8,56 +7,10 @@ public static class SyncObjectInitializer
|
|||||||
{
|
{
|
||||||
public static void GenerateSyncObjectInitializer(ILProcessor worker, FieldDefinition fd)
|
public static void GenerateSyncObjectInitializer(ILProcessor worker, FieldDefinition fd)
|
||||||
{
|
{
|
||||||
// call syncobject constructor
|
|
||||||
GenerateSyncObjectInstanceInitializer(worker, fd);
|
|
||||||
|
|
||||||
// register syncobject in network behaviour
|
// register syncobject in network behaviour
|
||||||
GenerateSyncObjectRegistration(worker, fd);
|
GenerateSyncObjectRegistration(worker, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// generates 'syncListInt = new SyncListInt()' if user didn't do that yet
|
|
||||||
static void GenerateSyncObjectInstanceInitializer(ILProcessor worker, FieldDefinition fd)
|
|
||||||
{
|
|
||||||
// check the ctor's instructions for an Stfld op-code for this specific sync list field.
|
|
||||||
foreach (Instruction ins in worker.Body.Instructions)
|
|
||||||
{
|
|
||||||
if (ins.OpCode.Code == Code.Stfld)
|
|
||||||
{
|
|
||||||
FieldDefinition field = (FieldDefinition)ins.Operand;
|
|
||||||
if (field.DeclaringType == fd.DeclaringType && field.Name == fd.Name)
|
|
||||||
{
|
|
||||||
// Already initialized by the user in the field definition, e.g:
|
|
||||||
// public SyncListInt Foo = new SyncListInt();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not initialized by the user in the field definition, e.g:
|
|
||||||
// public SyncListInt Foo;
|
|
||||||
|
|
||||||
TypeDefinition fieldType = fd.FieldType.Resolve();
|
|
||||||
// find ctor with no parameters
|
|
||||||
MethodDefinition ctor = fieldType.Methods.FirstOrDefault(x => x.Name == ".ctor" && !x.HasParameters);
|
|
||||||
if (ctor == null)
|
|
||||||
{
|
|
||||||
Weaver.Error($"Can not initialize field {fd.Name} because no default constructor was found. Manually initialize the field (call the constructor) or add constructor without Parameter", fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MethodReference objectConstructor = Weaver.CurrentAssembly.MainModule.ImportReference(ctor);
|
|
||||||
|
|
||||||
// if is SyncList<int> instead of SyncListInt then we need to make the ctor generic
|
|
||||||
if (fd.FieldType.IsGenericInstance)
|
|
||||||
{
|
|
||||||
GenericInstanceType genericInstance = (GenericInstanceType)fd.FieldType;
|
|
||||||
objectConstructor = objectConstructor.MakeHostInstanceGeneric(genericInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.Append(worker.Create(OpCodes.Ldarg_0));
|
|
||||||
worker.Append(worker.Create(OpCodes.Newobj, objectConstructor));
|
|
||||||
worker.Append(worker.Create(OpCodes.Stfld, fd));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ImplementsSyncObject(TypeReference typeRef)
|
public static bool ImplementsSyncObject(TypeReference typeRef)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -154,7 +154,10 @@ public int ComponentIndex
|
|||||||
// We collect all of them and we synchronize them with OnSerialize/OnDeserialize
|
// We collect all of them and we synchronize them with OnSerialize/OnDeserialize
|
||||||
protected void InitSyncObject(SyncObject syncObject)
|
protected void InitSyncObject(SyncObject syncObject)
|
||||||
{
|
{
|
||||||
syncObjects.Add(syncObject);
|
if (syncObject == null)
|
||||||
|
Debug.LogError("Uninitialized SyncObject. Manually call the constructor on your SyncList, SyncSet or SyncDictionary", this);
|
||||||
|
else
|
||||||
|
syncObjects.Add(syncObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Commands
|
#region Commands
|
||||||
|
@ -43,8 +43,7 @@ public void SyncListInheritance()
|
|||||||
[Test]
|
[Test]
|
||||||
public void SyncListMissingParamlessCtor()
|
public void SyncListMissingParamlessCtor()
|
||||||
{
|
{
|
||||||
HasError("Can not initialize field Foo because no default constructor was found. Manually initialize the field (call the constructor) or add constructor without Parameter",
|
IsSuccess();
|
||||||
"WeaverSyncListTests.SyncListMissingParamlessCtor.SyncListMissingParamlessCtor/SyncListString2 WeaverSyncListTests.SyncListMissingParamlessCtor.SyncListMissingParamlessCtor::Foo");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
Loading…
Reference in New Issue
Block a user