public override void Serialize(NetworkWriter writer) { if (action == 0) { throw new Exception("action is 0"); } var info = SyncListInfo.GetSyncListInfo(netObj.GetType(), memberIndex); writer.WriteByte(action); writer.WriteNetworkInstanceId(netObj.InstanceId); writer.WriteByte(memberIndex); switch (action) { case Action_Add: case Action_Insert: case Action_Set: object list = info.field.GetValue(netObj); if (action == Action_Insert || action == Action_Set) { writer.WriteByte(itemIndex); } object item = info.ItemProperty.GetGetMethod().Invoke(list, new object[] { (int)itemIndex }); info.SerializeItemMethod.Invoke(list, new object[] { writer, item }); break; case Action_RemoveAt: writer.WriteByte(itemIndex); break; } }
public static SyncListInfo[] GetSyncListInfos(Type type) { if (cachedInfos == null) { cachedInfos = new Dictionary <Type, SyncListInfo[]>(); } SyncListInfo[] infos; if (!cachedInfos.TryGetValue(type, out infos)) { List <SyncListInfo> list = null; foreach (var field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { Type listType = field.FieldType.GetGenericTypeDefinition(typeof(SyncList <>)); if (listType == null) { continue; } SyncListInfo info = new SyncListInfo(); info.field = field; info.ItemProperty = listType.GetProperty("Item"); info.CountProperty = listType.GetProperty("Count"); info.InitMethod = listType.GetMethod("Init", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); info.InsertMethod = listType.GetMethod("Insert"); info.RemoveAtMethod = listType.GetMethod("RemoveAt"); info.ClearMethod = listType.GetMethod("Clear"); info.DeserializeItemMethod = listType.GetMethod("DeserializeItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); info.SerializeItemMethod = listType.GetMethod("SerializeItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (list == null) { list = new List <SyncListInfo>(); } info.memberIndex = (byte)list.Count(); list.Add(info); } if (list != null) { if (list.Count > 32) { throw new Exception("max 32 sync var"); } infos = new SyncListInfo[list.Count]; foreach (var info in list) { infos[info.memberIndex] = info; } } else { infos = null; } cachedInfos[type] = infos; } return(infos); }
public override void Deserialize(NetworkReader reader) { action = reader.ReadByte(); NetworkInstanceId instanceId; instanceId = reader.ReadNetworkInstanceId(); netObj = null; netObj = conn.GetObject(instanceId); if (netObj == null) { return; } memberIndex = reader.ReadByte(); var info = SyncListInfo.GetSyncListInfo(netObj.GetType(), memberIndex); object list = info.field.GetValue(netObj); switch (action) { case Action_Add: case Action_Insert: case Action_Set: { if (action == Action_Add) { itemIndex = (byte)(int)info.CountProperty.GetGetMethod().Invoke(list, null); } else { itemIndex = reader.ReadByte(); } object item; item = info.DeserializeItemMethod.Invoke(list, new object[] { reader }); info.InsertMethod.Invoke(list, new object[] { (int)itemIndex, item }); } break; case Action_RemoveAt: case Action_Remove: if (action == Action_Remove) { itemIndex = (byte)(int)info.CountProperty.GetGetMethod().Invoke(list, null); } else { itemIndex = reader.ReadByte(); } info.RemoveAtMethod.Invoke(list, new object[] { itemIndex }); break; case Action_Clear: info.ClearMethod.Invoke(list, null); break; } }