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;
|
||||
}
|
||||
|
||||
// SyncTarget enum is cleaner than 'bool onlyToOwner and allows for more options if needed
|
||||
public enum SyncTarget {Observers, Owner};
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class SyncVarAttribute : Attribute
|
||||
{
|
||||
public string hook;
|
||||
public SyncTarget target = SyncTarget.Observers; // for 'only sync to owner' support
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
|
@ -27,6 +27,10 @@ public class NetworkBehaviour : MonoBehaviour
|
||||
public short playerControllerId { get { return myView.playerControllerId; } }
|
||||
protected ulong syncVarDirtyBits { get { return m_SyncVarDirtyBits; } }
|
||||
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; } }
|
||||
|
||||
|
@ -36,6 +36,8 @@ class NetworkBehaviourProcessor
|
||||
const string k_RpcPrefix = "InvokeRpc";
|
||||
const string k_TargetRpcPrefix = "InvokeTargetRpc";
|
||||
|
||||
public enum SyncTarget { Observers, Owner };
|
||||
|
||||
public NetworkBehaviourProcessor(TypeDefinition td)
|
||||
{
|
||||
Weaver.DLog(td, "NetworkBehaviourProcessor");
|
||||
@ -1902,6 +1904,26 @@ static MethodDefinition ProcessSyncVarGet(FieldDefinition fd, string originalNam
|
||||
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)
|
||||
{
|
||||
//Create the set method
|
||||
@ -2010,7 +2032,6 @@ void ProcessSyncVar(FieldDefinition fd, long dirtyBit)
|
||||
{
|
||||
GetMethod = get, SetMethod = set
|
||||
};
|
||||
|
||||
//add the methods and property to the type.
|
||||
m_td.Methods.Add(get);
|
||||
m_td.Methods.Add(set);
|
||||
@ -2075,6 +2096,52 @@ FieldDefinition ProcessSyncList(FieldDefinition fd, long dirtyBit)
|
||||
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()
|
||||
{
|
||||
int numSyncVars = 0;
|
||||
@ -2083,6 +2150,9 @@ void ProcessSyncVars()
|
||||
// start assigning syncvars at the place the base class stopped, if any
|
||||
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();
|
||||
List<FieldDefinition> listFields = new List<FieldDefinition>();
|
||||
|
||||
@ -2150,9 +2220,17 @@ void ProcessSyncVars()
|
||||
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))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -2219,6 +2297,8 @@ void ProcessSyncVars()
|
||||
m_td.Methods.Add(func);
|
||||
}
|
||||
|
||||
GenerateOwnerMaskProperty(ownerMask);
|
||||
|
||||
Weaver.SetNumSyncVars(m_td.FullName, numSyncVars);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user