// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; namespace Microsoft.ClearScript.Util { internal interface IScope: IDisposable { TValue Value { get; } } internal static class Scope { public static IDisposable Create(Action enterAction, Action exitAction) { enterAction?.Invoke(); return new ScopeImpl(exitAction); } public static IDisposable Create(Action enterAction, Action exitAction, in TArg arg) { enterAction?.Invoke(arg); return new ScopeImpl(exitAction); } public static IScope Create(Func enterFunc, Action exitAction) { var value = (enterFunc is not null) ? enterFunc() : default; return new ScopeImpl(value, exitAction); } public static IScope Create(Func enterFunc, Action exitAction, in TArg arg) { var value = (enterFunc is not null) ? enterFunc(arg) : default; return new ScopeImpl(value, exitAction); } #region Nested type: ScopeImpl private sealed class ScopeImpl : IDisposable { private readonly Action exitAction; private readonly OneWayFlag disposedFlag = new(); public ScopeImpl(Action exitAction) { this.exitAction = exitAction; } #region IDisposable implementation public void Dispose() { if (disposedFlag.Set()) { exitAction?.Invoke(); } } #endregion } #endregion #region Nested type: ScopeImpl private sealed class ScopeImpl : IScope { private readonly Action exitAction; private readonly OneWayFlag disposedFlag = new(); public ScopeImpl(TValue value, Action exitAction) { this.exitAction = exitAction; Value = value; } #region IScope implementation public TValue Value { get; } public void Dispose() { if (disposedFlag.Set()) { exitAction?.Invoke(Value); } } #endregion } #endregion } }