/// <summary> /// Tries the get information about a currently attached component. /// </summary> private bool TryGetAttachedComponent( SceneComponentBase component, ViewInformation?correspondingView, out SceneComponentInfo componentInfo, out int componentIndex) { var attachedComponentCount = _attachedComponents.Count; for (var loop = 0; loop < attachedComponentCount; loop++) { if (component.IsViewSpecific) { if (component == _attachedComponents[loop].Component && correspondingView != null && correspondingView == _attachedComponents[loop].CorrespondingView) { componentInfo = _attachedComponents[loop]; componentIndex = loop; return(true); } } else { if (component == _attachedComponents[loop].Component) { componentInfo = _attachedComponents[loop]; componentIndex = loop; return(true); } } } componentInfo = default; componentIndex = -1; return(false); }
/// <summary> /// Internal method for updating all scene components. /// </summary> /// <param name="updateState">Current update state.</param> internal void UpdateSceneComponents(SceneRelatedUpdateState updateState) { // Update all components var attachedComponentsCount = _attachedComponents.Count; for (var loop = 0; loop < attachedComponentsCount; loop++) { _attachedComponents[loop].Component.UpdateInternal( updateState, _attachedComponents[loop].CorrespondingView, _attachedComponents[loop].Context); } // Attach all components which are coming in while (_componentRequests.TryDequeue(out var actRequest)) { SceneComponentInfo actComponent; int actComponentIndex; switch (actRequest.RequestType) { case SceneComponentRequestType.Attach: if (actRequest.Component == null) { continue; } if (this.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 (var actObsoleteComponent in this.GetExistingComponentsByGroup( actRequest.Component.ComponentGroup, actRequest.Component.IsViewSpecific ? actRequest.CorrespondingView : null)) { _componentRequests.Enqueue(new SceneComponentRequest { RequestType = SceneComponentRequestType.Detach, Component = actObsoleteComponent.Component, CorrespondingView = actObsoleteComponent.CorrespondingView }); } } var actManipulator = new SceneManipulator(_owner); actManipulator.IsValid = true; try { var newRegisteredComponentInfo = new SceneComponentInfo { Component = actRequest.Component, CorrespondingView = actRequest.CorrespondingView, Context = actRequest.Component.AttachInternal( actManipulator, actRequest.CorrespondingView) }; // Register the component on local list of attached ones _attachedComponents.Add(newRegisteredComponentInfo); } finally { actManipulator.IsValid = false; } break; case SceneComponentRequestType.Detach: if (actRequest.Component == null) { continue; } if (!this.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(_owner); actManipulator.IsValid = true; try { actComponent.Component.DetachInternal( actManipulator, actComponent.CorrespondingView, actComponent.Context); // RemoveObject the component _attachedComponents.RemoveAt(actComponentIndex); } finally { actManipulator.IsValid = false; } break; case SceneComponentRequestType.DetachAll: while (_attachedComponents.Count > 0) { actManipulator = new SceneManipulator(_owner) { IsValid = true }; try { actComponent = _attachedComponents[0]; actComponent.Component.DetachInternal( actManipulator, actComponent.CorrespondingView, actComponent.Context); // RemoveObject the component _attachedComponents.RemoveAt(0); } finally { actManipulator.IsValid = false; } } break; default: throw new SeeingSharpException($"Unknown {nameof(SceneComponentRequestType)}: {actRequest.RequestType}"); } } }