mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 11:00:32 +00:00
Generate syncOwnerMask in every network behavior
This commit is contained in:
parent
6c80b054ac
commit
e7403a8983
@ -11,10 +11,14 @@ public class NetworkSettingsAttribute : Attribute
|
|||||||
public float sendInterval = 0.1f;
|
public float sendInterval = 0.1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SyncTarget enum is cleaner than 'bool onlyToOwner and allows for more options if needed
|
||||||
|
public enum SyncTarget {Observers, Owner};
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Field)]
|
[AttributeUsage(AttributeTargets.Field)]
|
||||||
public class SyncVarAttribute : Attribute
|
public class SyncVarAttribute : Attribute
|
||||||
{
|
{
|
||||||
public string hook;
|
public string hook;
|
||||||
|
public SyncTarget target = SyncTarget.Observers; // for 'only sync to owner' support
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method)]
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
@ -27,6 +27,10 @@ public class NetworkBehaviour : MonoBehaviour
|
|||||||
public short playerControllerId { get { return myView.playerControllerId; } }
|
public short playerControllerId { get { return myView.playerControllerId; } }
|
||||||
protected ulong syncVarDirtyBits { get { return m_SyncVarDirtyBits; } }
|
protected ulong syncVarDirtyBits { get { return m_SyncVarDirtyBits; } }
|
||||||
protected bool syncVarHookGuard { get { return m_SyncVarGuard; } set { m_SyncVarGuard = value; }}
|
protected bool syncVarHookGuard { get { return m_SyncVarGuard; } set { m_SyncVarGuard = value; }}
|
||||||
|
// determine which variables are SyncToOwner
|
||||||
|
// to get dirty owners, we do syncVarDirtyBits & syncVarOwnerMask
|
||||||
|
// by default it is 0 because none of the variables are synctowoner
|
||||||
|
protected virtual ulong syncVarOwnerMask { get { return 0; } }
|
||||||
|
|
||||||
internal NetworkIdentity netIdentity { get { return myView; } }
|
internal NetworkIdentity netIdentity { get { return myView; } }
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ class NetworkBehaviourProcessor
|
|||||||
const string k_RpcPrefix = "InvokeRpc";
|
const string k_RpcPrefix = "InvokeRpc";
|
||||||
const string k_TargetRpcPrefix = "InvokeTargetRpc";
|
const string k_TargetRpcPrefix = "InvokeTargetRpc";
|
||||||
|
|
||||||
|
public enum SyncTarget { Observers, Owner };
|
||||||
|
|
||||||
public NetworkBehaviourProcessor(TypeDefinition td)
|
public NetworkBehaviourProcessor(TypeDefinition td)
|
||||||
{
|
{
|
||||||
Weaver.DLog(td, "NetworkBehaviourProcessor");
|
Weaver.DLog(td, "NetworkBehaviourProcessor");
|
||||||
@ -1902,6 +1904,26 @@ static MethodDefinition ProcessSyncVarGet(FieldDefinition fd, string originalNam
|
|||||||
return get;
|
return get;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SyncTarget GetSyncVarSyncTarget(FieldDefinition fd)
|
||||||
|
{
|
||||||
|
foreach (CustomAttribute attr in fd.CustomAttributes)
|
||||||
|
{
|
||||||
|
if (attr.AttributeType.FullName == Weaver.SyncVarType.FullName)
|
||||||
|
{
|
||||||
|
foreach (var field in attr.Fields)
|
||||||
|
{
|
||||||
|
if (field.Name == "target") // SyncVar.target == SyncTarget.XYZ
|
||||||
|
{
|
||||||
|
// SyncTarget enum: 0 == Observers, 1 == Owner
|
||||||
|
return (SyncTarget)field.Argument.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SyncTarget.Observers;
|
||||||
|
}
|
||||||
|
|
||||||
MethodDefinition ProcessSyncVarSet(FieldDefinition fd, string originalName, long dirtyBit, FieldDefinition netFieldId)
|
MethodDefinition ProcessSyncVarSet(FieldDefinition fd, string originalName, long dirtyBit, FieldDefinition netFieldId)
|
||||||
{
|
{
|
||||||
//Create the set method
|
//Create the set method
|
||||||
@ -2010,7 +2032,6 @@ void ProcessSyncVar(FieldDefinition fd, long dirtyBit)
|
|||||||
{
|
{
|
||||||
GetMethod = get, SetMethod = set
|
GetMethod = get, SetMethod = set
|
||||||
};
|
};
|
||||||
|
|
||||||
//add the methods and property to the type.
|
//add the methods and property to the type.
|
||||||
m_td.Methods.Add(get);
|
m_td.Methods.Add(get);
|
||||||
m_td.Methods.Add(set);
|
m_td.Methods.Add(set);
|
||||||
@ -2075,6 +2096,52 @@ FieldDefinition ProcessSyncList(FieldDefinition fd, long dirtyBit)
|
|||||||
Weaver.int32Type);
|
Weaver.int32Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenerateOwnerMaskProperty(long ownerMask)
|
||||||
|
{
|
||||||
|
// no new variables are owners,
|
||||||
|
// no need to override syncVarOwnerMask
|
||||||
|
if (ownerMask == 0L)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Create the get method
|
||||||
|
MethodDefinition get = new MethodDefinition(
|
||||||
|
"get_syncVarOwnerMask", MethodAttributes.Family |
|
||||||
|
MethodAttributes.SpecialName |
|
||||||
|
MethodAttributes.HideBySig |
|
||||||
|
MethodAttributes.Virtual,
|
||||||
|
Weaver.uint64Type);
|
||||||
|
|
||||||
|
ILProcessor getWorker = get.Body.GetILProcessor();
|
||||||
|
|
||||||
|
// generate: return (0xabc | base.syncVarOwnerMask);
|
||||||
|
getWorker.Append(getWorker.Create(OpCodes.Ldc_I8, ownerMask)); // 8 byte integer aka long
|
||||||
|
|
||||||
|
if (m_td.BaseType.FullName != Weaver.NetworkBehaviourType.FullName)
|
||||||
|
{
|
||||||
|
MethodReference baseSerialize = Weaver.ResolveMethod(m_td.BaseType, "get_syncVarOwnerMask");
|
||||||
|
if (baseSerialize != null)
|
||||||
|
{
|
||||||
|
getWorker.Append(getWorker.Create(OpCodes.Ldarg_0)); // base
|
||||||
|
getWorker.Append(getWorker.Create(OpCodes.Call, baseSerialize));
|
||||||
|
getWorker.Append(getWorker.Create(OpCodes.Or));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getWorker.Append(getWorker.Create(OpCodes.Ret));
|
||||||
|
|
||||||
|
get.SemanticsAttributes = MethodSemanticsAttributes.Getter;
|
||||||
|
|
||||||
|
|
||||||
|
PropertyDefinition propertyDefinition = new PropertyDefinition("syncVarOwnerMask", PropertyAttributes.None, Weaver.uint64Type)
|
||||||
|
{
|
||||||
|
GetMethod = get
|
||||||
|
};
|
||||||
|
//add the methods and property to the type.
|
||||||
|
m_td.Methods.Add(get);
|
||||||
|
m_td.Properties.Add(propertyDefinition);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void ProcessSyncVars()
|
void ProcessSyncVars()
|
||||||
{
|
{
|
||||||
int numSyncVars = 0;
|
int numSyncVars = 0;
|
||||||
@ -2083,6 +2150,9 @@ void ProcessSyncVars()
|
|||||||
// start assigning syncvars at the place the base class stopped, if any
|
// start assigning syncvars at the place the base class stopped, if any
|
||||||
int dirtyBitCounter = Weaver.GetSyncVarStart(m_td.BaseType.FullName);
|
int dirtyBitCounter = Weaver.GetSyncVarStart(m_td.BaseType.FullName);
|
||||||
|
|
||||||
|
// mask that determines which of these bits are sync to owner
|
||||||
|
long ownerMask = 0;
|
||||||
|
|
||||||
m_SyncVarNetIds.Clear();
|
m_SyncVarNetIds.Clear();
|
||||||
List<FieldDefinition> listFields = new List<FieldDefinition>();
|
List<FieldDefinition> listFields = new List<FieldDefinition>();
|
||||||
|
|
||||||
@ -2150,9 +2220,17 @@ void ProcessSyncVars()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// at this point this is either a list or a syncvar and has
|
||||||
|
// the [SyncVar] attribute. Check if it is SyncToOwner
|
||||||
|
// and adjust the mask
|
||||||
|
if (GetSyncVarSyncTarget(fd) == SyncTarget.Owner)
|
||||||
|
{
|
||||||
|
ownerMask |= 1L << dirtyBitCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (Helpers.InheritsFromSyncList(fd.FieldType))
|
if (Helpers.InheritsFromSyncList(fd.FieldType))
|
||||||
{
|
{
|
||||||
Log.Warning(string.Format("Script class [{0}] has [SyncVar] attribute on SyncList field {1}, SyncLists should not be marked with SyncVar.", m_td.FullName, fd.Name));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2219,6 +2297,8 @@ void ProcessSyncVars()
|
|||||||
m_td.Methods.Add(func);
|
m_td.Methods.Add(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GenerateOwnerMaskProperty(ownerMask);
|
||||||
|
|
||||||
Weaver.SetNumSyncVars(m_td.FullName, numSyncVars);
|
Weaver.SetNumSyncVars(m_td.FullName, numSyncVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user