File: IntelliSense\Session.cs
Web Access
Project: ..\..\..\src\EditorFeatures\Core\Microsoft.CodeAnalysis.EditorFeatures.csproj (Microsoft.CodeAnalysis.EditorFeatures)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Roslyn.Utilities;
 
namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense
{
    internal class Session<TController, TModel, TPresenterSession> : ISession<TModel>
        where TPresenterSession : IIntelliSensePresenterSession
        where TController : IController<TModel>
        where TModel : class
    {
        public TController Controller { get; }
        public ModelComputation<TModel> Computation { get; }
 
        // The presenter session for the computation we've got going.  It's lifetime is tied 1:1 with
        // the computation.  When the computation starts we make a presenter (note: this does not
        // mean that the user will ever see any UI), and when the computation is stopped, we will
        // end the presentation session.
        public TPresenterSession PresenterSession { get; }
 
        public Session(TController controller, ModelComputation<TModel> computation, TPresenterSession presenterSession)
        {
            this.Controller = controller;
            this.Computation = computation;
            this.PresenterSession = presenterSession;
 
            // If the UI layer dismisses the presenter, then we want to know about it so we can stop
            // doing whatever it is we're doing.
            this.PresenterSession.Dismissed += OnPresenterSessionDismissed;
        }
 
        public TModel InitialUnfilteredModel { get { return this.Computation.InitialUnfilteredModel; } }
 
        private void OnPresenterSessionDismissed(object sender, EventArgs e)
        {
            Computation.ThreadingContext.ThrowIfNotOnUIThread();
            Contract.ThrowIfFalse(ReferenceEquals(this.PresenterSession, sender));
            Controller.StopModelComputation();
        }
 
        public virtual void Stop()
        {
            Computation.ThreadingContext.ThrowIfNotOnUIThread();
            this.Computation.Stop();
            this.PresenterSession.Dismissed -= OnPresenterSessionDismissed;
            this.PresenterSession.Dismiss();
        }
 
        public TModel WaitForController()
        {
            Computation.ThreadingContext.ThrowIfNotOnUIThread();
            return Computation.WaitForController();
        }
    }
}