Ejemplo n.º 1
0
        /// <summary>
        /// Triggers scene manipulation using the given lambda action.
        /// The action gets processed directly before scene update process.
        ///
        /// Be careful: The action is called by worker-threads of SeeingSharp!
        /// </summary>
        /// <param name="manipulatorAction">The action which is able to manipulate the scene.</param>
        public Task ManipulateSceneAsync(Action <SceneManipulator> manipulatorAction)
        {
            manipulatorAction.EnsureNotNull(nameof(manipulatorAction));

            var manipulator = new SceneManipulator(this);

            return(this.PerformBeforeUpdateAsync(() =>
            {
                try
                {
                    manipulator.IsValid = true;
                    manipulatorAction(manipulator);
                }
                finally
                {
                    manipulator.IsValid = false;
                }
            }));
        }
Ejemplo n.º 2
0
 internal override void DetachInternal(SceneManipulator manipulator, ViewInformation?correspondingView, object?componentContext)
 {
     this.Detach(manipulator, correspondingView);
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Detaches this component from a scene.
 /// Be careful, this method gets called from a background thread of SeeingSharp!
 /// It may also be called from multiple scenes in parallel.
 /// </summary>
 /// <param name="manipulator">The manipulator of the scene we attach to.</param>
 /// <param name="correspondingView">The view which attached this component.</param>
 protected abstract void Detach(SceneManipulator manipulator, ViewInformation?correspondingView);
Ejemplo n.º 4
0
 internal override object?AttachInternal(SceneManipulator manipulator, ViewInformation?correspondingView)
 {
     this.Attach(manipulator, correspondingView);
     return(null);
 }
Ejemplo n.º 5
0
        /// <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}");
                }
            }
        }