< Summary

Information
Class: Trailblazer.Support.LifecycleHookHandler
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Support/LifecycleHooks/LifecycleHookHandler.cs
Line coverage
100%
Covered lines: 33
Uncovered lines: 0
Coverable lines: 33
Total lines: 102
Line coverage: 100%
Branch coverage
100%
Covered branches: 8
Total branches: 8
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
RegisterHook(...)100%44100%
UnregisterHook(...)100%11100%
InvokeHooks(...)100%22100%
CompareHook()100%22100%

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Support/LifecycleHooks/LifecycleHookHandler.cs

#LineLine coverage
 1//=======================================================================
 2// LifecycleHookHandler.cs
 3//=======================================================================
 4// MIT License, Copyright (c) 2024-present David Oravsky (mrdav30)
 5// See LICENSE file in the project root for full license information.
 6//=======================================================================
 7
 8using System;
 9using System.Collections.Generic;
 10using SwiftCollections;
 11
 12namespace Trailblazer.Support;
 13
 14/// <summary>
 15/// Provides functionality to register, unregister, and invoke lifecycle hooks in a thread-safe manner.
 16/// </summary>
 17internal sealed class LifecycleHookHandler
 18{
 98919    private readonly object _lifecycleHookLock = new();
 20
 21    /// <summary>
 22    /// Registers a lifecycle hook with the specified owner, order, and callback.
 23    /// Hooks are executed in order of their specified order, and if orders are equal, they are sorted by owner name.
 24    /// The returned IDisposable can be used to unregister the hook when it is no longer needed.
 25    /// </summary>
 26    /// <param name="hooks">The list of hooks to register the new hook with.</param>
 27    /// <param name="owner">The owner of the hook, used to identify and manage the hook.</param>
 28    /// <param name="order">The order in which the hook should be executed relative to other hooks.</param>
 29    /// <param name="callback">The callback to invoke when the hook is executed.</param>
 30    /// <returns>An IDisposable that can be used to unregister the hook.</returns>
 31    /// <exception cref="ArgumentException">Thrown if the owner is null or whitespace.</exception>
 32    /// <exception cref="InvalidOperationException">Thrown if a hook with the same owner is already registered.</excepti
 33    public IDisposable RegisterHook(
 34        SwiftList<OrderedLifecycleHook> hooks,
 35        string owner,
 36        int order,
 37        Action callback)
 38    {
 1539        SwiftThrowHelper.ThrowIfArgument(
 1540            string.IsNullOrWhiteSpace(owner),
 1541            paramName: nameof(owner),
 1542            message: "Lifecycle hook owner cannot be null or whitespace.");
 43
 1444        SwiftThrowHelper.ThrowIfNull(callback, nameof(callback));
 45
 1446        lock (_lifecycleHookLock)
 47        {
 3248            for (int i = 0; i < hooks.Count; i++)
 49            {
 350                SwiftThrowHelper.ThrowIfTrue(
 351                    hooks[i].Owner == owner,
 352                    message: $"Lifecycle hook '{owner}' is already registered.");
 53            }
 54
 1355            hooks.Add(new OrderedLifecycleHook(owner, order, callback));
 1356            hooks.SortInPlace(CompareHook());
 1357        }
 58
 1359        return new LifecycleHookRegistration(() => UnregisterHook(hooks, owner));
 60    }
 61
 62    /// <summary>
 63    /// Unregisters a lifecycle hook based on the specified owner.
 64    /// </summary>
 65    /// <param name="hooks">The list of hooks to unregister the hook from.</param>
 66    /// <param name="owner">The owner of the hook to unregister.</param>
 67    public void UnregisterHook(SwiftList<OrderedLifecycleHook> hooks, string owner)
 68    {
 1369        lock (_lifecycleHookLock)
 70        {
 1371            hooks.RemoveAll(hook => hook.Owner == owner);
 1372        }
 1373    }
 74
 75    /// <summary>
 76    /// Invokes all registered lifecycle hooks in the order they were registered.
 77    /// </summary>
 78    /// <param name="hooks">The list of hooks to invoke.</param>
 79    public void InvokeHooks(SwiftList<OrderedLifecycleHook> hooks)
 80    {
 81        OrderedLifecycleHook[] snapshot;
 882        lock (_lifecycleHookLock)
 83        {
 884            snapshot = hooks.ToArray();
 885        }
 86
 3687        for (int i = 0; i < snapshot.Length; i++)
 1088            snapshot[i].Callback();
 889    }
 90
 91    private static Comparer<OrderedLifecycleHook> CompareHook()
 92    {
 1393        return Comparer<OrderedLifecycleHook>.Create((left, right) =>
 1394        {
 1395            int orderCompare = left.Order.CompareTo(right.Order);
 1396            if (orderCompare != 0)
 1397                return orderCompare;
 1398
 1399            return StringComparer.Ordinal.Compare(left.Owner, right.Owner);
 13100        });
 101    }
 102}