/// <inheritdoc /> public virtual void SendRPC(NetDataWriter stream, string rpcName) { RPCMethodInfo rpcMethodInfo = null; int rpcMethodIndex = TinyNetStateSyncer.GetRPCMethodInfoFromType(GetType(), rpcName, ref rpcMethodInfo); SendRPC(stream, rpcMethodInfo.target, rpcMethodInfo.caller, rpcMethodIndex); }
protected virtual void CreateDirtyFlag() { int numberOfSyncVars = TinyNetStateSyncer.GetNumberOfSyncedProperties(GetType()); if (numberOfSyncVars == 0) { _dirtyFlag = null; } else if (numberOfSyncVars <= 8) { _dirtyFlag = new BitArray(8); } else if (numberOfSyncVars <= 16) { _dirtyFlag = new BitArray(16); } else if (numberOfSyncVars <= 32) { _dirtyFlag = new BitArray(32); } else if (numberOfSyncVars <= 64) { _dirtyFlag = new BitArray(64); } else { if (TinyNetLogLevel.logError) { TinyLogger.LogError("TinyNetBehaviour::OnNetworkCreate amount of TinyNetSyncVar is bigger than 64."); } return; } }
/// <summary> /// Registers the RPC delegate. /// </summary> /// <param name="rpcDel">The RPC delegate.</param> /// <param name="methodName">Name of the method.</param> protected void RegisterRPCDelegate(RPCDelegate rpcDel, string methodName) { if (rpcHandlers == null) { rpcHandlers = new RPCDelegate[TinyNetStateSyncer.GetNumberOfRPCMethods(GetType())]; } int index = TinyNetStateSyncer.GetRPCMethodIndexFromType(GetType(), methodName); rpcHandlers[index] = new RPCDelegate(rpcDel); }
/*public bool IsTimeToUpdate() { * if (_bIsDirty && Time.time - _lastSendTime > GetNetworkSendInterval()) { * UpdateDirtyFlag(); * return true; * } * * return false; * }*/ /// <summary> /// <inheritdoc /> /// Remember that this is called first and before variables are synced. /// </summary> public virtual void OnNetworkCreate() { TinyNetStateSyncer.OutPropertyNamesFromType(GetType(), out propertiesName); TinyNetStateSyncer.OutPropertyTypesFromType(GetType(), out propertiesTypes); CreateAccessors(); if (isServer) { UpdateDirtyFlag(); } }
/// <summary> /// Updates the dirty flag. /// <para>This will only set dirty values to true, it will not revert them to false.</para> /// </summary> private void UpdateDirtyFlag() { TinyNetStateSyncer.UpdateDirtyFlagOf(this, _dirtyFlag); IsDirty = false; for (int i = 0; i < _dirtyFlag.Length; i++) { if (_dirtyFlag[i]) { IsDirty = true; } } _lastSendTime = Time.time; }
/// <inheritdoc /> public virtual void TinyDeserialize(NetDataReader reader, bool firstStateUpdate) { if (firstStateUpdate) { NetworkID = reader.GetInt(); } if (!firstStateUpdate) { int dFlag = reader.GetInt(); TinyNetStateSyncer.IntToDirtyFlag(dFlag, _dirtyFlag); } Type type; int maxSyncVar = propertiesName.Length; for (int i = 0; i < maxSyncVar; i++) { if (!firstStateUpdate && _dirtyFlag[i] == false) { continue; } type = propertiesTypes[i]; if (type == typeof(byte)) { byteAccessor[propertiesName[i]].Set(this, reader.GetByte()); } else if (type == typeof(sbyte)) { sbyteAccessor[propertiesName[i]].Set(this, reader.GetSByte()); } else if (type == typeof(short)) { shortAccessor[propertiesName[i]].Set(this, reader.GetShort()); } else if (type == typeof(ushort)) { ushortAccessor[propertiesName[i]].Set(this, reader.GetUShort()); } else if (type == typeof(int)) { intAccessor[propertiesName[i]].Set(this, reader.GetInt()); } else if (type == typeof(uint)) { uintAccessor[propertiesName[i]].Set(this, reader.GetUInt()); } else if (type == typeof(long)) { longAccessor[propertiesName[i]].Set(this, reader.GetLong()); } else if (type == typeof(ulong)) { ulongAccessor[propertiesName[i]].Set(this, reader.GetULong()); } else if (type == typeof(float)) { floatAccessor[propertiesName[i]].Set(this, reader.GetFloat()); } else if (type == typeof(double)) { doubleAccessor[propertiesName[i]].Set(this, reader.GetDouble()); } else if (type == typeof(bool)) { boolAccessor[propertiesName[i]].Set(this, reader.GetBool()); } else if (type == typeof(string)) { stringAccessor[propertiesName[i]].Set(this, reader.GetString()); } } }
/// <inheritdoc /> public virtual void TinySerialize(NetDataWriter writer, bool firstStateUpdate) { if (firstStateUpdate) { writer.Put(NetworkID); } if (!firstStateUpdate) { writer.Put(TinyNetStateSyncer.DirtyFlagToInt(_dirtyFlag)); } Type type; int maxSyncVar = propertiesName.Length; for (int i = 0; i < maxSyncVar; i++) { if (!firstStateUpdate && _dirtyFlag[i] == false) { continue; } type = propertiesTypes[i]; if (type == typeof(byte)) { writer.Put(byteAccessor[propertiesName[i]].Get(this)); } else if (type == typeof(sbyte)) { writer.Put(sbyteAccessor[propertiesName[i]].Get(this)); } else if (type == typeof(short)) { writer.Put(shortAccessor[propertiesName[i]].Get(this)); } else if (type == typeof(ushort)) { writer.Put(ushortAccessor[propertiesName[i]].Get(this)); } else if (type == typeof(int)) { writer.Put(intAccessor[propertiesName[i]].Get(this)); } else if (type == typeof(uint)) { writer.Put(uintAccessor[propertiesName[i]].Get(this)); } else if (type == typeof(long)) { writer.Put(longAccessor[propertiesName[i]].Get(this)); } else if (type == typeof(ulong)) { writer.Put(ulongAccessor[propertiesName[i]].Get(this)); } else if (type == typeof(float)) { writer.Put(floatAccessor[propertiesName[i]].Get(this)); } else if (type == typeof(double)) { writer.Put(doubleAccessor[propertiesName[i]].Get(this)); } else if (type == typeof(bool)) { writer.Put(boolAccessor[propertiesName[i]].Get(this)); } else if (type == typeof(string)) { writer.Put(stringAccessor[propertiesName[i]].Get(this)); } } }
/// <summary> /// Updates the dirty flag. /// </summary> private void UpdateDirtyFlag() { TinyNetStateSyncer.UpdateDirtyFlagOf(this, _dirtyFlag); _lastSendTime = Time.time; }
/// <summary> /// Does the reflection process. /// </summary> public static void GetAllSyncVarProps() { List<Type> types = GetAllClassesAndChildsOf<TinyNetBehaviour>(); foreach (Type type in types) { PropertyInfo[] props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(prop => Attribute.IsDefined(prop, typeof(TinyNetSyncVar))) .ToArray(); //.OrderBy(info => info.Name).ToArray(); Array.Sort(props, delegate(PropertyInfo x, PropertyInfo y) { return String.Compare(x.Name, y.Name, StringComparison.InvariantCulture); }); if (props.Length < 32) { TinyNetStateSyncer.InitializePropertyInfoListOfType(props.Length, type); for (int i = 0; i < props.Length; i++) { if (TinyNetSyncVar.allowedTypes.Contains(props[i].PropertyType)) { if (TinyNetLogLevel.logDev) { TinyLogger.Log(props[i].Name); } //MethodInfo getMethod = props[i].GetGetMethod(true); //MethodInfo setMethod = props[i].GetSetMethod(true); TinyNetStateSyncer.AddPropertyToType(props[i], type); } else { if (TinyNetLogLevel.logError) { TinyLogger.LogError("TinyNetSyncVar used in incompatible property type: " + props[i].Name); } } } } else { if (TinyNetLogLevel.logError) { TinyLogger.LogError("ERROR: " + type + " have more than 32 syncvar"); } } // Time for the RPC methods MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(method => Attribute.IsDefined(method, typeof(TinyNetRPC))) .ToArray(); //.OrderBy(info => info.Name).ToArray(); Array.Sort(methods, delegate (MethodInfo x, MethodInfo y) { return String.Compare(x.Name, y.Name, StringComparison.InvariantCulture); }); TinyNetStateSyncer.InitializeRPCMethodsOfType(methods.Length, type); ParameterInfo[] pars; bool bValid = true; TinyNetRPC rpcAttribute; for (int i = 0; i < methods.Length; i++) { pars = methods[i].GetParameters(); rpcAttribute = (TinyNetRPC)methods[i].GetCustomAttributes(typeof(TinyNetRPC), true)[0]; bValid = true; for (int x = 0; x < pars.Length; x++) { if (!TinyNetSyncVar.allowedTypes.Contains(pars[x].ParameterType)) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("TinyNetRPC used with incompatible parameter: " + pars[x].Name); } bValid = false; } } if (bValid) { if (TinyNetLogLevel.logDev) { TinyLogger.Log(methods[i].Name); } TinyNetStateSyncer.AddRPCMethodNameToType(methods[i].Name, rpcAttribute.Targets, rpcAttribute.Callers, type); } } } }