protected override void BeginUpdatingFrame(NetworkConnectionDelta connectionDelta) { base.BeginUpdatingFrame(connectionDelta); // Messages for hierarchies need to be sent from root to leaf to ensure // that Canvas construction on the other end happens in the correct order. CachedParentTransform?.OnFrameCompleted(connectionDelta); }
protected virtual void BeginUpdatingFrame(NetworkConnectionDelta connectionDelta) { if (PerformanceComponentName != string.Empty && StateSynchronizationPerformanceMonitor.Instance != null) { perfMonitoringInstance = StateSynchronizationPerformanceMonitor.Instance.MeasureEventDuration(PerformanceComponentName, "FrameUpdateDuration"); } }
/// <inheritdoc /> public void ProcessNewConnections(NetworkConnectionDelta connectionDelta) { if (!isInitialized) { ProcessNewConnections(connectionDelta.AddedConnections.Concat(connectionDelta.ContinuedConnections)); } else { ProcessNewConnections(connectionDelta.AddedConnections); } }
private void UpdateDestroyedComponents(NetworkConnectionDelta connectionDelta) { using (StateSynchronizationPerformanceMonitor.Instance.MeasureEventDuration(nameof(StateSynchronizationSceneManager), nameof(UpdateDestroyedComponents))) { for (int i = broadcasterComponents.Count - 1; i >= 0; i--) { if (IsComponentDestroyed(broadcasterComponents[i])) { SendComponentDestruction(connectionDelta.ContinuedConnections, broadcasterComponents[i]); broadcasterComponents.RemoveAt(i); } } } }
public void OnFrameCompleted(NetworkConnectionDelta connectionDelta) { using (StateSynchronizationPerformanceMonitor.Instance.MeasureEventDuration(nameof(GlobalShaderPropertiesBroadcaster), nameof(OnFrameCompleted))) { if (assetCache?.CustomGlobalShaderProperties != null) { if (previousValues == null) { InitializeValues(); } if (connectionDelta.AddedConnections.Count > 0) { StateSynchronizationSceneManager.Instance.SendGlobalShaderProperties(assetCache.CustomGlobalShaderProperties, connectionDelta.AddedConnections); } if (connectionDelta.ContinuedConnections.Count > 0) { changedProperties.Clear(); for (int i = 0; i < assetCache.CustomGlobalShaderProperties.Length; i++) { object newValue = assetCache.CustomGlobalShaderProperties[i].GetValue(); if (!Equals(previousValues[i], newValue)) { previousValues[i] = newValue; changedProperties.Add(assetCache.CustomGlobalShaderProperties[i]); } } if (changedProperties.Count > 0) { StateSynchronizationSceneManager.Instance.SendGlobalShaderProperties(changedProperties, connectionDelta.ContinuedConnections); } } } } }
/// <inheritdoc /> public void OnFrameCompleted(NetworkConnectionDelta connectionDelta) { if (!isUpdatedThisFrame) { isUpdatedThisFrame = true; if (TransformBroadcaster != null && (isActiveAndEnabled || UpdateWhenDisabled)) { // Make sure the transform syncs before any other components sync if (TransformBroadcaster != this) { TransformBroadcaster.OnFrameCompleted(connectionDelta); } BeginUpdatingFrame(connectionDelta); // The TransformBroadcaster might detect that this component is destroyed. // If so, don't continue updating. if (this.enabled) { EnsureComponentInitialized(); IReadOnlyList <INetworkConnection> connectionsNeedingCompleteChanges; IReadOnlyList <INetworkConnection> filteredEndpointsNeedingDeltaChanges; IReadOnlyList <INetworkConnection> filteredEndpointsNeedingCompleteChanges; using (StateSynchronizationPerformanceMonitor.Instance.MeasureEventDuration(PerformanceComponentName, "ProcessConnectionDelta")) { TransformBroadcaster.ProcessConnectionDelta(connectionDelta, out connectionsNeedingCompleteChanges, out filteredEndpointsNeedingDeltaChanges, out filteredEndpointsNeedingCompleteChanges); } if (connectionsNeedingCompleteChanges != null && connectionsNeedingCompleteChanges.Count > 0) { SendComponentCreation(connectionsNeedingCompleteChanges); } if (filteredEndpointsNeedingDeltaChanges != null && filteredEndpointsNeedingDeltaChanges.Count > 0) { TChangeFlags changeFlags = CalculateDeltaChanges(); if (HasChanges(changeFlags)) { SendDeltaChanges(filteredEndpointsNeedingDeltaChanges, changeFlags); } } if (filteredEndpointsNeedingCompleteChanges != null && filteredEndpointsNeedingCompleteChanges.Count > 0) { SendCompleteChanges(filteredEndpointsNeedingCompleteChanges); } if (connectionDelta.RemovedConnections != null && connectionDelta.RemovedConnections.Count > 0) { RemoveDisconnectedEndpoints(connectionDelta.RemovedConnections); } EndUpdatingFrame(); } } } }
public void ProcessConnectionDelta(NetworkConnectionDelta connectionDelta, out IReadOnlyList <INetworkConnection> needingCompleteChanges, out IReadOnlyList <INetworkConnection> filteredNeedingDeltaChanged, out IReadOnlyList <INetworkConnection> filteredNeedingCompleteChanges) { if (shouldProcessConnectionDelta) { shouldProcessConnectionDelta = false; StateSynchronizationPerformanceMonitor.Instance.IncrementEventCount(PerformanceComponentName, "ProcessConnectionDelta.UpdatedCache"); using (StateSynchronizationPerformanceMonitor.Instance.MeasureEventDuration(PerformanceComponentName, "EndpointAssessment")) { connectionsNeedingCompleteChanges.Clear(); connectionsNeedingDeltaChanges.Clear(); filteredEndpointsNeedingCompleteChanges.Clear(); filteredEndpointsNeedingDeltaChanges.Clear(); foreach (INetworkConnection connection in connectionDelta.AddedConnections) { connectionsNeedingCompleteChanges.Add(connection); if (ShouldSendChanges(connection)) { filteredEndpointsNeedingCompleteChanges.Add(connection); } } foreach (INetworkConnection connection in connectionDelta.ContinuedConnections) { if (fullyInitializedEndpoints.Contains(connection)) { connectionsNeedingDeltaChanges.Add(connection); if (ShouldSendChanges(connection)) { filteredEndpointsNeedingDeltaChanges.Add(connection); } } else { connectionsNeedingCompleteChanges.Add(connection); if (ShouldSendChanges(connection)) { filteredEndpointsNeedingCompleteChanges.Add(connection); } } } if (filteredEndpointsNeedingCompleteChanges.Count > 0) { foreach (INetworkConnection connection in filteredEndpointsNeedingCompleteChanges) { fullyInitializedEndpoints.Add(connection); } } foreach (INetworkConnection connection in connectionsNeedingDeltaChanges) { if (!ShouldSendChanges(connection)) { fullyInitializedEndpoints.Remove(connection); } } if (connectionDelta.RemovedConnections.Count > 0) { foreach (INetworkConnection connection in connectionDelta.RemovedConnections) { fullyInitializedEndpoints.Remove(connection); } } } } else { StateSynchronizationPerformanceMonitor.Instance.IncrementEventCount(PerformanceComponentName, "ProcessConnectionDelta.UsedCache"); } needingCompleteChanges = connectionsNeedingCompleteChanges; filteredNeedingDeltaChanged = filteredEndpointsNeedingDeltaChanges; filteredNeedingCompleteChanges = filteredEndpointsNeedingCompleteChanges; }
private IEnumerator RunEndOfFrameUpdates() { while (this != null && this.isActiveAndEnabled) { yield return(new WaitForEndOfFrame()); using (StateSynchronizationPerformanceMonitor.Instance.MeasureEventDuration(nameof(StateSynchronizationSceneManager), nameof(RunEndOfFrameUpdates))) { if (framesToSkipForBuffering == 0) { if (StateSynchronizationBroadcaster.IsInitialized && StateSynchronizationBroadcaster.Instance != null) { int bytesQueued = StateSynchronizationBroadcaster.Instance.OutputBytesQueued; if (bytesQueued > MaximumQueuedByteCount) { framesToSkipForBuffering = frameSkippingStride; // We are about to render a frame but the buffer is too full, so we're going to skip more frames. // Count this frame as a vote to increase the number of frames we skip each time this happens. UpdateFrameSkippingVotes(1); } else if (frameSkippingStride > 1) { // We would be skipping more than one frame, but we just finished a frame without an expanded buffer. // Count this frame as a vote to decrease the number of frames we skip each time this happens. UpdateFrameSkippingVotes(-1); } StateSynchronizationBroadcaster.Instance.OnFrameCompleted(); } NetworkConnectionDelta connectionDelta = GetFrameConnectionDelta(); // Any GameObjects destroyed since last update should be culled first before attempting to update // components UpdateDestroyedComponents(connectionDelta); using (StateSynchronizationPerformanceMonitor.Instance.MeasureEventDuration(nameof(StateSynchronizationSceneManager), "ResetFrame")) { for (int i = broadcasterComponents.Count - 1; i >= 0; i--) { broadcasterComponents[i].ResetFrame(); } } if (connectionDelta.HasConnections) { if (GlobalShaderPropertiesBroadcaster.IsInitialized && GlobalShaderPropertiesBroadcaster.Instance != null) { GlobalShaderPropertiesBroadcaster.Instance.OnFrameCompleted(connectionDelta); } using (StateSynchronizationPerformanceMonitor.Instance.MeasureEventDuration(nameof(StateSynchronizationSceneManager), "ProcessNewConnections")) { for (int i = 0; i < broadcasterComponents.Count; i++) { if (!IsComponentDestroyed(broadcasterComponents[i])) { broadcasterComponents[i].ProcessNewConnections(connectionDelta); } } } using (StateSynchronizationPerformanceMonitor.Instance.MeasureEventDuration(nameof(StateSynchronizationSceneManager), "OnFrameCompleted")) { for (int i = 0; i < broadcasterComponents.Count; i++) { if (!IsComponentDestroyed(broadcasterComponents[i])) { broadcasterComponents[i].OnFrameCompleted(connectionDelta); } } } } // Any components detected as removed should be destroyed and removed this frame. UpdateDestroyedComponents(connectionDelta); ApplyFrameConnectionDelta(); CheckForFinalDisconnect(); } else { StateSynchronizationPerformanceMonitor.Instance.IncrementEventCount(nameof(StateSynchronizationSceneManager), "FrameSkipped"); framesToSkipForBuffering--; int bytesQueued = StateSynchronizationBroadcaster.Instance.OutputBytesQueued; if (bytesQueued <= MaximumQueuedByteCount) { // We're about to skip a frame but the buffer is currently under the capacity threshold for skipping. // Count this frame as a vote to decrease the number of frames we skip each time this happens. UpdateFrameSkippingVotes(-1); } } } } }