/// <summary> /// Updates the scene (called beside rendering). /// </summary> internal void UpdateBesideRender(SceneRelatedUpdateState updateState) { // Invoke all async action attached to this scene Action actAsyncAction = null; while (m_asyncInvokesUpdateBesideRendering.Dequeue(out actAsyncAction)) { actAsyncAction(); } // Reset all filter flags before continue to next step foreach (var actView in m_registeredViews) { foreach (SceneObjectFilter actFilter in actView.Filters) { actFilter.ConfigurationChanged = actFilter.ConfigurationChangedUI; actFilter.ConfigurationChangedUI = false; } } // Performs update logic beside rendering foreach (SceneLayer actLayer in m_sceneLayers) { actLayer.UpdateBesideRender(updateState); } }
/// <summary> /// Internal method for updating all scene components. /// </summary> /// <param name="updateState">Current update state.</param> internal void UpdateSceneComponents(SceneRelatedUpdateState updateState) { // Update all components int attachedComponentsCount = m_attachedComponents.Count; for (int loop = 0; loop < attachedComponentsCount; loop++) { m_attachedComponents[loop].Component.UpdateInternal( updateState, m_attachedComponents[loop].CorrespondingView, m_attachedComponents[loop].Context); } // Attach all components which are comming in SceneComponentRequest actRequest = default(SceneComponentRequest); int actIndex = 0; while (m_componentRequests.Dequeue(out actRequest)) { SceneComponentInfo actComponent; int actComponentIndex = -1; switch (actRequest.RequestType) { case SceneComponentRequestType.Attach: if (actRequest.Component == null) { continue; } if (TryGetAttachedComponent( actRequest.Component, actRequest.CorrespondingView, out actComponent, out actComponentIndex)) { // We've already attached this component, so skip this request continue; } // Trigger removing of all components with the same group like the new one // (new components replace old components with same group name) if (!string.IsNullOrEmpty(actRequest.Component.ComponentGroup)) { foreach (SceneComponentInfo actObsoleteComponent in GetExistingComponentsByGroup( actRequest.Component.ComponentGroup, actRequest.Component.IsViewSpecific ? actRequest.CorrespondingView : null)) { m_componentRequests.Enqueue(new SceneComponentRequest() { RequestType = SceneComponentRequestType.Detach, Component = actObsoleteComponent.Component, CorrespondingView = actObsoleteComponent.CorrespondingView }); } } SceneManipulator actManipulator = new SceneManipulator(m_owner); actManipulator.IsValid = true; try { SceneComponentInfo newRegisteredComponentInfo = new SceneComponentInfo(); newRegisteredComponentInfo.Component = actRequest.Component; newRegisteredComponentInfo.CorrespondingView = actRequest.CorrespondingView; newRegisteredComponentInfo.Context = actRequest.Component.AttachInternal( actManipulator, actRequest.CorrespondingView); actIndex++; // Register the component on local list of attached ones m_attachedComponents.Add(newRegisteredComponentInfo); } finally { actManipulator.IsValid = false; } break; case SceneComponentRequestType.Detach: if (actRequest.Component == null) { continue; } if (!TryGetAttachedComponent( actRequest.Component, actRequest.CorrespondingView, out actComponent, out actComponentIndex)) { // We don't have any component that is like the requested one continue; } actManipulator = new SceneManipulator(m_owner); actManipulator.IsValid = true; try { actComponent.Component.DetachInternal( actManipulator, actComponent.CorrespondingView, actComponent.Context); // Remove the component m_attachedComponents.RemoveAt(actComponentIndex); } finally { actManipulator.IsValid = false; } break; case SceneComponentRequestType.DetachAll: while (m_attachedComponents.Count > 0) { actManipulator = new SceneManipulator(m_owner); actManipulator.IsValid = true; try { actComponent = m_attachedComponents[0]; actComponent.Component.DetachInternal( actManipulator, actComponent.CorrespondingView, actComponent.Context); // Remove the component m_attachedComponents.RemoveAt(0); } finally { actManipulator.IsValid = false; } } break; } } }
/// <summary> /// Updates the scene. /// </summary> internal void Update(SceneRelatedUpdateState updateState) { // Apply local SynchronizationContext if configured so SynchronizationContext previousSyncContext = null; if (m_syncContext != null) { previousSyncContext = SynchronizationContext.Current; SynchronizationContext.SetSynchronizationContext(m_syncContext); } try { m_perFrameData.Time = m_perFrameData.Time + updateState.UpdateTimeMilliseconds; if (m_perFrameData.Time > Constants.MAX_PER_FRAME_TIME_VALUE) { m_perFrameData.Time = m_perFrameData.Time % Constants.MAX_PER_FRAME_TIME_VALUE; } // Update all scene components first // These may trigger some further manipulation actions m_sceneComponents.UpdateSceneComponents(updateState); // Invoke all async action attached to this scene int asyncActionsBeforeUpdateCount = m_asyncInvokesBeforeUpdate.Count; if (asyncActionsBeforeUpdateCount > 0) { Action actAsyncAction = null; int actIndex = 0; while ((actIndex < asyncActionsBeforeUpdateCount) && m_asyncInvokesBeforeUpdate.Dequeue(out actAsyncAction)) { actAsyncAction(); actIndex++; } } // Render all renderable resources foreach (ResourceDictionary actResourceDict in m_registeredResourceDicts) { foreach (IRenderableResource actRenderableResource in actResourceDict.RenderableResources) { if (actRenderableResource.IsLoaded) { actRenderableResource.Update(updateState); } } } // Update all standard objects. foreach (SceneLayer actLayer in m_sceneLayers) { actLayer.Update(updateState); } } finally { // Discard local SynchronizationContext if (m_syncContext != null) { SynchronizationContext.SetSynchronizationContext(previousSyncContext); } } }
protected override void OnTick(EventArgs eArgs) { base.OnTick(eArgs); if (!GraphicsCore.IsInitialized) { return; } // Query for all input handlers on first tick if (m_globalInputHandlers == null) { m_globalInputHandlers = InputHandlerFactory.CreateInputHandlersForGlobal(); foreach (IInputHandler actInputHandler in m_globalInputHandlers) { actInputHandler.Start(null); } } // Execute all commands within the command queue if (m_commandQueue.Count > 0) { Action actCommand = null; while (m_commandQueue.Dequeue(out actCommand)) { actCommand(); } } // Gather all input data int expectedStateCount = m_lastInputFrame != null ? m_lastInputFrame.CountStates : 6; // Create new InputFrame object or reuse an old one InputFrame newInputFrame = null; if (m_recoveredInputFrames.Dequeue(out newInputFrame)) { newInputFrame.Reset(expectedStateCount, SINGLE_FRAME_DURATION); } else { newInputFrame = new InputFrame(expectedStateCount, SINGLE_FRAME_DURATION); } // Gather all input states foreach (IInputHandler actInputHandler in m_globalInputHandlers) { foreach (InputStateBase actInputState in actInputHandler.GetInputStates()) { actInputState.EnsureNotNull(nameof(actInputState)); newInputFrame.AddCopyOfState(actInputState, null); } } foreach (KeyValuePair <IInputEnabledView, List <IInputHandler> > actViewSpecificHandlers in m_viewInputHandlers) { RenderLoop renderLoop = actViewSpecificHandlers.Key.RenderLoop; if (renderLoop == null) { continue; } foreach (IInputHandler actInputHandler in actViewSpecificHandlers.Value) { foreach (InputStateBase actInputState in actInputHandler.GetInputStates()) { actInputState.EnsureNotNull(nameof(actInputState)); newInputFrame.AddCopyOfState(actInputState, renderLoop.ViewInformation); } } } // Store the generated InputFrame m_lastInputFrame = newInputFrame; m_gatheredInputFrames.Enqueue(newInputFrame); // Ensure that we hold input frames for a maximum time range of a second // (older input is obsolete) while (m_gatheredInputFrames.Count > Constants.INPUT_FRAMES_PER_SECOND) { InputFrame dummyFrame = null; m_gatheredInputFrames.Dequeue(out dummyFrame); } }