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.Cil;
|
||||
|
||||
@ -8,56 +7,10 @@ public static class SyncObjectInitializer
|
||||
{
|
||||
public static void GenerateSyncObjectInitializer(ILProcessor worker, FieldDefinition fd)
|
||||
{
|
||||
// call syncobject constructor
|
||||
GenerateSyncObjectInstanceInitializer(worker, fd);
|
||||
|
||||
// register syncobject in network behaviour
|
||||
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)
|
||||
{
|
||||
try
|
||||
|
@ -154,7 +154,10 @@ public int ComponentIndex
|
||||
// We collect all of them and we synchronize them with OnSerialize/OnDeserialize
|
||||
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
|
||||
|
@ -43,8 +43,7 @@ public void SyncListInheritance()
|
||||
[Test]
|
||||
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",
|
||||
"WeaverSyncListTests.SyncListMissingParamlessCtor.SyncListMissingParamlessCtor/SyncListString2 WeaverSyncListTests.SyncListMissingParamlessCtor.SyncListMissingParamlessCtor::Foo");
|
||||
IsSuccess();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
Loading…
Reference in New Issue
Block a user