void OnDestroy() { #if !CLUSTER_ENABLE return; #endif if (ClusterHelper.Instance.Server != null) { if (IsObservingDestruction) { FduClusterViewManager.NotifyOneViewDisappear(ViewId, true); } else { FduClusterViewManager.NotifyOneViewDisappear(ViewId, false); } } else { FduClusterViewManager.NotifyOneViewDisappear(ViewId, false); } foreach (FduObserverBase ob in observerList) { if (ob != null) { ob.OnviewDestroy(); } } }
//Only called in matser node 通知一个新的view出现 public static void NotifyOneNewViewAppear(int assetId, FduClusterView view) { ClusterGameObjectCreatePara para = new ClusterGameObjectCreatePara(view.ViewId, assetId, view.transform.position, view.transform.rotation); if (view.transform.parent != null) { para.parentPath = FduSupportClass.getGameObjectPath(view.transform.parent.gameObject); } para.viewInstance = view; var subViews = view.getSubViews(); if (subViews != null) { for (int i = 0; i < subViews.Count; ++i) { if (subViews[i] != null) { if (!subViews[i].gameObject.activeSelf) { subViews[i].ObjectID = FduSyncBaseIDManager.ApplyNextAvaliableId(); FduClusterViewManager.RegistToViewManager(subViews[i]); } } else { Debug.LogError("Find Invalid sub view in one FduClusterView.View id :" + view.ViewId + " Object name:" + view.name + ". Please press the Refresh Button in Inspector"); } } } if (_waitForCreateList.Count == 0) { levelPrefix = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; } _waitForCreateList.Add(para); }
//Executed on both Master node and slave node Independently //Called In Start of FduClusterViewManager and LevelLoadManager internal static void AllocateSceneObjectViewId() { Debug.Log("start allocate scene view id"); Scene s = SceneManager.GetActiveScene(); if (s.isLoaded) { Debug.Log("scene name " + s.name); var allGameObjects = s.GetRootGameObjects(); for (int j = 0; j < allGameObjects.Length; j++) { var go = allGameObjects[j]; foreach (FduClusterView view in (go.GetComponentsInChildren <FduClusterView>(true))) { view.ObjectID = FduSyncBaseIDManager.ApplyNextAvaliableId(); FduClusterViewManager.RegistToViewManager(view); } ; } _allocateFlag = false; } else { Debug.LogWarning("This scene is not loaded yet"); } }
public override NetworkState.NETWORK_STATE_TYPE Deserialize() { if (this == null) //由于跨场景时 在新的view 没有在start中完成注册之前 旧的view会接收数据 { return(NetworkState.NETWORK_STATE_TYPE.SUCCESS); } if (ViewId == FduSyncBaseIDManager.getInvalidSyncId()) { return(NetworkState.NETWORK_STATE_TYPE.SUCCESS); } UnityEngine.Profiling.Profiler.BeginSample("OnReceiveData"); NetworkState.NETWORK_STATE_TYPE networkState = NetworkState.NETWORK_STATE_TYPE.SUCCESS; FduObserverBase observer = null; for (index = 0; index < observerList.Count; ++index) { try { observer = observerList[index]; #if !UNSAFE_MODE if (observer != null) { bool receiveOrNot = BufferedNetworkUtilsClient.ReadBool(ref networkState); if (receiveOrNot) { observer.OnReceiveData(ref networkState); FduClusterViewManager.updateSentDataObserverCount(); } } #else if (observer.getDataTransmitStrategy().receiveOrNot()) { observer.OnReceiveData(ref networkState); #if DEBUG FduClusterViewManager.updateSentDataObserverCount(); #endif } #endif } catch (System.NullReferenceException) { } catch (System.Exception e) { string erroMessage = string.Format("An error occured when observer {0} call OnReceiveDataMethod. Game Object Name:{1},View Id:{2}, Error Message:{3}, Stack Trace:{4}", observer.GetType().Name, observer.name, ViewId, e.Message, e.StackTrace); Debug.LogError(erroMessage); throw; } if (networkState == NetworkState.NETWORK_STATE_TYPE.FORMAT_ERROR) { Debug.LogError("Data length not match in this observer! Observer name" + observer.GetType().FullName + " View id " + ViewId + " Game Object name " + observer.gameObject.name); } } UnityEngine.Profiling.Profiler.EndSample(); return(networkState); }
void LateUpdate() { if (_server != null && IsAutomaticllySend) { _server.SendState(ViewId, this, resendPriority, this.IsImmediatelyDeserialize); } #if DEBUG FduClusterViewManager.updateRunningViewCount(); #endif }
public override void Serialize() { if (ViewId == FduSyncBaseIDManager.getInvalidSyncId()) { return; } FduObserverBase observer = null; for (index = 0; index < observerList.Count; ++index) { try { observer = observerList[index]; #if !UNSAFE_MODE if (observer != null) { bool send = false; if (observer.getDataTransmitStrategy() != null) { send = observer.getDataTransmitStrategy().sendOrNot(); } BufferedNetworkUtilsServer.SendBool(send); if (send) { FduClusterViewManager.updateSentDataObserverCount(); observer.OnSendData(); } } #else if (observer.getDataTransmitStrategy().sendOrNot()) { #if DEBUG FduClusterViewManager.updateSentDataObserverCount(); #endif observer.OnSendData(); } #endif } catch (System.NullReferenceException) { } catch (System.Exception e) { string erroMessage = string.Format("An error occured when observer {0} call OnSendData method. Game Object Name:{1},View Id:{2}, Error Message:{3}, Stack Trace:{4}", observer.GetType().Name, observer.name, ViewId, e.Message, e.StackTrace); Debug.LogError(erroMessage); throw; } } }
public void RefreshData(int viewCount, int activeViewCount, int observerCount) { Debug.Assert(_viewCountQueue.Count == _activeViewCountQueue.Count, "ClusterViewStatisticClass assert not passed"); if (isRunnig && ClusterHelper.Instance != null) { if (_viewCountQueue.Count >= MAX_FRAME_COUNT) { _viewCountQueue.Dequeue(); _activeViewCountQueue.Dequeue(); _activeObserverCountQueue.Dequeue(); _observerCountQueue.Dequeue(); _frameNumberQueue.Dequeue(); } _viewCountQueue.Enqueue(viewCount); _activeViewCountQueue.Enqueue(activeViewCount); _observerCountQueue.Enqueue(FduClusterViewManager.getTotalObserverCount()); _activeObserverCountQueue.Enqueue(observerCount); _frameNumberQueue.Enqueue(ClusterHelper.Instance.FrameCount); } }
public void LateUpdateFunc() { if (_client != null) { return; } //每帧遍历检测激活状态 Dictionary <int, FduClusterView> .Enumerator enumerator = FduClusterViewManager.getClusterViews(); while (enumerator.MoveNext()) { FduClusterView view = enumerator.Current.Value; if (view != null && view.gameObject != null) { if (view.getObserveActiveState()) //该view必须设置是否监控激活状态 { if (view.gameObject.activeSelf != viewActiveStates[enumerator.Current.Key] || flushedCount > 0) //如果激活状态更改 或者flushedCount大于0 则发送数据 { var para = new ActiveSynPara(); para.viewId = enumerator.Current.Key; para.obFrameCount = view.getAllFrameCountForEveryNFrameDTS(); if (enumerator.Current.Value.gameObject.activeSelf) { _WaitForActiveList.Add(para); } else { _WaitForInActiveList.Add(para); } viewActiveStates[enumerator.Current.Key] = view.gameObject.activeSelf; } } } } flushedCount = flushedCount > 0 ? flushedCount - 1 : flushedCount; _server.SendState(ObjectID, this); //_server.SendState(ObjectID, this,false); }
//SyncBase Strat函数执行前执行的函数 在这里需要监测该场景中的静态物体是否分配了ID 如果不是静态分配的Id 则判定为运行时创建的 则动态申请ID //而对于从节点 如果不是静态物体 则ID必须从主节点获取 赋值过程在此函数执行前 所以如果此时从节点上该view还没有分配ID 就说明前面的机制发生了错误 protected override void BeforeInit() { if (FduSyncBaseIDManager.needsAllocateSceneViewId() && FduClusterLevelLoader.Instance.isSceneLoaded()) { Debug.Log("first happen " + name); FduClusterViewManager.ClearUnusedViews(); FduSyncBaseIDManager.AllocateSceneObjectViewId(); } if (ClusterHelper.Instance.Server != null) { if (ObjectID == FduSyncBaseIDManager.getInvalidSyncId()) { ObjectID = FduSyncBaseIDManager.ApplyNextAvaliableId(); } if (IsObservingCreation) //如果监控这个view的创建 { if (FduClusterAssetManager.Instance.validateId(AssetId)) { FduClusterViewManager.NotifyOneNewViewAppear(AssetId, this); } else { Debug.LogError("This Prefab is not added to FduClusterAssetManager! Name:" + gameObject.name); } } else { FduClusterViewManager.NotifyOneNewViewAppear(this); } //FduClusterViewManager.RegistToViewManager(this); } else { FduClusterViewManager.RegistToViewManager(this); //如果此时从节点没有被分配id 会被放到一个等待列表中 当收到主节点的id信息后进行赋值 } //检测是否有空的observer存在 checkObserverExist(); }
public override NetworkState.NETWORK_STATE_TYPE Deserialize() { NetworkState.NETWORK_STATE_TYPE state = NetworkState.NETWORK_STATE_TYPE.SUCCESS; //active部分数据 int count = BufferedNetworkUtilsClient.ReadInt(ref state); int viewId, obCount; FduClusterView view; int obId, obFrameCount; for (int i = 0; i < count; ++i) { viewId = BufferedNetworkUtilsClient.ReadInt(ref state); obCount = BufferedNetworkUtilsClient.ReadInt(ref state); view = FduClusterViewManager.getClusterView(viewId); if (view != null) { try { for (int j = 0; j < obCount; ++j) { obId = BufferedNetworkUtilsClient.ReadInt(ref state); obFrameCount = BufferedNetworkUtilsClient.ReadInt(ref state); view.setFrameCountForEveryNFrameDTS(obId, obFrameCount); } view.gameObject.SetActive(true); } catch (System.Exception e) { Debug.LogError(e.Message); } } else { //view是空的也要读完 for (int j = 0; j < obCount; ++j) { obId = BufferedNetworkUtilsClient.ReadInt(ref state); obFrameCount = BufferedNetworkUtilsClient.ReadInt(ref state); } Debug.LogWarning("[FduActiveSyncManager-active]Can not find a view with ViewId " + viewId); } } //Inactive部分数据 count = BufferedNetworkUtilsClient.ReadInt(ref state); for (int i = 0; i < count; ++i) { viewId = BufferedNetworkUtilsClient.ReadInt(ref state); obCount = BufferedNetworkUtilsClient.ReadInt(ref state); view = FduClusterViewManager.getClusterView(viewId); if (view != null) { try { for (int j = 0; j < obCount; ++j) { obId = BufferedNetworkUtilsClient.ReadInt(ref state); obFrameCount = BufferedNetworkUtilsClient.ReadInt(ref state); view.setFrameCountForEveryNFrameDTS(obId, obFrameCount); } view.gameObject.SetActive(false); } catch (System.Exception e) { Debug.LogError(e.Message); } } else { //view是空的也要读完 for (int j = 0; j < obCount; ++j) { obId = BufferedNetworkUtilsClient.ReadInt(ref state); obFrameCount = BufferedNetworkUtilsClient.ReadInt(ref state); } Debug.LogWarning("[FduActiveSyncManager-Inactive]Can not find a view with ViewId " + viewId); } } if (BufferedNetworkUtilsClient.ReadString(ref state) != "FduActieSyncManagerEndFlag") { Debug.LogError("Wrong end of FduActiveSyncManager!"); } return(state); }
//根据rpc数据执行对应的rpc方法 public object executeRpc(Dictionary <byte, object> rpcdata) { object returnValue = null; int viewId = (int)rpcdata[(byte)0]; string methodName = (string)rpcdata[(byte)1]; int paraCount = (int)rpcdata[(byte)2]; object[] parameters = (object[])rpcdata[(byte)3]; FduClusterView view = FduClusterViewManager.getClusterView(viewId); if (view == null) { Debug.LogWarning("[FduRpc]FduSyncView not exist .View id is " + viewId + " method Name is " + methodName); return(returnValue); } bool isSent = false; List <FduObserverBase> .Enumerator observerEnum = view.getObservers(); var monos = view.GetComponents <MonoBehaviour>(); HashSet <MonoBehaviour> monoset = new HashSet <MonoBehaviour>(monos); while (observerEnum.MoveNext()) { monoset.Add(observerEnum.Current); } foreach (MonoBehaviour mono in monoset) { List <MethodInfo> methodInfo = GetMethods(mono.GetType(), typeof(FduRPC)); if (methodInfo == null) { return(returnValue); } Type[] argTypes = new Type[paraCount]; for (int i = 0; i < paraCount; i++) { argTypes[i] = parameters[i].GetType(); } for (int i = 0; i < methodInfo.Count; ++i) { MethodInfo mi = methodInfo[i]; if (mi.Name.Equals(methodName)) { ParameterInfo[] paraInfo = mi.GetParameters(); if (paraInfo.Length == parameters.Length) { if (this.CheckTypeMatch(paraInfo, argTypes)) { if (!isSent) { returnValue = mi.Invoke((object)mono, parameters); isSent = true; } else { Debug.LogWarning("[FduRpc]More than one function can match the method name and parameters. Please check."); } } } } } } if (!isSent) { Debug.LogWarning("[FduRpc]Parameters not matched for FduRpc Call. Method Name:" + methodName); } return(returnValue); }
//反序列化一个可传输的参数 public static object deserializeOneParameter(ref NetworkState.NETWORK_STATE_TYPE state) { FduSendableParameter typeCode = (FduSendableParameter)BufferedNetworkUtilsClient.ReadByte(ref state); object result; switch (typeCode) { case FduSendableParameter.Int: result = BufferedNetworkUtilsClient.ReadInt(ref state); break; case FduSendableParameter.IntArray: result = BufferedNetworkUtilsClient.ReadIntArray(ref state); break; case FduSendableParameter.Byte: result = BufferedNetworkUtilsClient.ReadByte(ref state); break; case FduSendableParameter.ByteArray: result = BufferedNetworkUtilsClient.ReadByteArray(ref state); break; case FduSendableParameter.Float: result = BufferedNetworkUtilsClient.ReadFloat(ref state); break; case FduSendableParameter.FloatArray: result = BufferedNetworkUtilsClient.ReadFloatArray(ref state); break; case FduSendableParameter.Bool: result = BufferedNetworkUtilsClient.ReadBool(ref state); break; case FduSendableParameter.BoolArray: int bollen = BufferedNetworkUtilsClient.ReadInt(ref state); bool[] bolarr = new bool[bollen]; for (int i = 0; i < bollen; ++i) { bolarr[i] = BufferedNetworkUtilsClient.ReadBool(ref state); } result = bolarr; break; case FduSendableParameter.String: result = BufferedNetworkUtilsClient.ReadString(ref state); break; case FduSendableParameter.StringArray: int strlen = BufferedNetworkUtilsClient.ReadInt(ref state); string[] strarr = new string[strlen]; for (int i = 0; i < strlen; ++i) { strarr[i] = BufferedNetworkUtilsClient.ReadString(ref state); } result = strarr; break; case FduSendableParameter.Vector2: result = BufferedNetworkUtilsClient.ReadVector2(ref state); break; case FduSendableParameter.Vector2Array: int v2len = BufferedNetworkUtilsClient.ReadInt(ref state); Vector2[] v2arr = new Vector2[v2len]; for (int i = 0; i < v2len; ++i) { v2arr[i] = BufferedNetworkUtilsClient.ReadVector2(ref state); } result = v2arr; break; case FduSendableParameter.Vector3: result = BufferedNetworkUtilsClient.ReadVector3(ref state); break; case FduSendableParameter.Vector3Array: int v3len = BufferedNetworkUtilsClient.ReadInt(ref state); Vector3[] v3arr = new Vector3[v3len]; for (int i = 0; i < v3len; ++i) { v3arr[i] = BufferedNetworkUtilsClient.ReadVector3(ref state); } result = v3arr; break; case FduSendableParameter.Vector4: result = BufferedNetworkUtilsClient.ReadVector4(ref state); break; case FduSendableParameter.Vector4Array: int v4len = BufferedNetworkUtilsClient.ReadInt(ref state); Vector4[] v4arr = new Vector4[v4len]; for (int i = 0; i < v4len; ++i) { v4arr[i] = BufferedNetworkUtilsClient.ReadVector4(ref state); } result = v4arr; break; case FduSendableParameter.Color: result = BufferedNetworkUtilsClient.ReadColor(ref state); break; case FduSendableParameter.ColorArray: int clen = BufferedNetworkUtilsClient.ReadInt(ref state); Color[] carray = new Color[clen]; for (int i = 0; i < clen; ++i) { carray[i] = BufferedNetworkUtilsClient.ReadColor(ref state); } result = carray; break; case FduSendableParameter.Quaternion: result = BufferedNetworkUtilsClient.ReadQuaternion(ref state); break; case FduSendableParameter.QuaternionArray: int qlen = BufferedNetworkUtilsClient.ReadInt(ref state); Quaternion[] qarr = new Quaternion[qlen]; for (int i = 0; i < qlen; i++) { qarr[i] = BufferedNetworkUtilsClient.ReadQuaternion(ref state); } result = qarr; break; case FduSendableParameter.Matrix4X4: result = BufferedNetworkUtilsClient.ReadMatrix4x4(ref state); break; case FduSendableParameter.Matrix4X4Array: int matlen = BufferedNetworkUtilsClient.ReadInt(ref state); Matrix4x4 [] matArr = new Matrix4x4[matlen]; for (int i = 0; i < matlen; ++i) { matArr[i] = BufferedNetworkUtilsClient.ReadMatrix4x4(ref state); } result = matArr; break; case FduSendableParameter.Rect: result = BufferedNetworkUtilsClient.ReadRect(ref state); break; case FduSendableParameter.RectArray: int rectlen = BufferedNetworkUtilsClient.ReadInt(ref state); Rect[] rectArr = new Rect[rectlen]; for (int i = 0; i < rectlen; ++i) { rectArr[i] = BufferedNetworkUtilsClient.ReadRect(ref state); } result = rectArr; break; case FduSendableParameter.GameObject: bool goType = BufferedNetworkUtilsClient.ReadBool(ref state); if (goType) //有clusterview的物体 { var view = FduClusterViewManager.getClusterView(BufferedNetworkUtilsClient.ReadInt(ref state)); if (view != null) { result = view.gameObject; } else { result = null; } } else //有唯一路径的gameobject { string path = BufferedNetworkUtilsClient.ReadString(ref state); result = FduSupportClass.getGameObjectByPath(path); } break; case FduSendableParameter.ClusterView: result = FduClusterViewManager.getClusterView(BufferedNetworkUtilsClient.ReadInt(ref state)); break; case FduSendableParameter.Struct: try { string typeName = BufferedNetworkUtilsClient.ReadString(ref state); System.Type type = System.Type.GetType(typeName); result = BufferedNetworkUtilsClient.ReadStruct(type, ref state); } catch (System.Exception e) { Debug.LogError("Error occured in reading struct data. Details: " + e.Message); throw; } break; case FduSendableParameter.SerializableClass: result = BufferedNetworkUtilsClient.ReadSerializableClass(ref state); break; case FduSendableParameter.Enum: result = BufferedNetworkUtilsClient.ReadInt(ref state); break; default: throw new InvalidSendableDataException("Received unsendable data type, type code:" + typeCode); } return(result); }