Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cancelable base events #40

Merged
merged 1 commit into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions MonkeyLoader.Resonite.Integration/Events/CancelableBuildUIEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using FrooxEngine.UIX;
using MonkeyLoader.Events;

namespace MonkeyLoader.Resonite.Events
{
/// <summary>
/// Abstract base class for all sorts of cancelable UI-generation events.
/// </summary>
public abstract class CancelableBuildUIEvent : CancelableSyncEvent
{
/// <summary>
/// Gets the <see cref="UIBuilder"/> that should be used to generate extra UI elements.
/// </summary>
/// <remarks>
/// The style and <see cref="UIBuilder.Current"/> target should be the same after handling the event.<br/>
/// Use <see cref="UIBuilder.PushStyle"/> before making style changes,
/// and revert them by using <see cref="UIBuilder.PopStyle"/> once done.
/// </remarks>
public UIBuilder UI { get; }

/// <summary>
/// Creates a new UI-generation event instance with the given <see cref="UIBuilder"/>.
/// </summary>
/// <param name="ui">The <see cref="UIBuilder"/> to use while generating extra UI elements.</param>
protected CancelableBuildUIEvent(UIBuilder ui)
{
UI = ui;
}
}
}
101 changes: 101 additions & 0 deletions MonkeyLoader.Resonite.Integration/Events/CancelableSortedItemsEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MonkeyLoader.Resonite.Events
{
/// <summary>
/// Abstract base class for all sorts of cancelable events that focus on adding a (sorted) list of unique items.
/// </summary>
/// <typeparam name="T">The type of the items.</typeparam>
public abstract class CancelableSortedItemsEvent<T>
{
/// <summary>
/// The items that have been added to the event.
/// </summary>
protected readonly Dictionary<T, int> sortableItems;

/// <summary>
/// Gets the unique items as sorted by their sort order values.
/// </summary>
public virtual IEnumerable<T> Items => sortableItems.OrderBy(entry => entry.Value).Select(entry => entry.Key);

/// <summary>
/// Creates a new instance with no items.
/// </summary>
protected CancelableSortedItemsEvent()
{
sortableItems = new();
}

/// <summary>
/// Creates a new instance with the given items,
/// setting their sort order values to <c>0</c>.
/// </summary>
/// <param name="items">The items to start with.</param>
protected CancelableSortedItemsEvent(IEnumerable<T> items) : this(items, item => 0)
{ }

/// <summary>
/// Creates a new instance with the given items, using the
/// <paramref name="getSortOrder"/> function to determine their sort order values.
/// </summary>
/// <param name="items">The items to start with.</param>
/// <param name="getSortOrder">The function to map items to a sort order value.</param>
protected CancelableSortedItemsEvent(IEnumerable<T> items, Func<T, int> getSortOrder)
{
sortableItems = items.ToDictionary(item => item, getSortOrder);
}

/// <summary>
/// Adds the given item with the given sort order.<br/>
/// If it's already present, the sort order is only changed to the given one,
/// when <paramref name="updateOrder"/> is <c>true</c>.
/// </summary>
/// <param name="item">The item to add.</param>
/// <param name="sortOrder">The sort order value for the item.</param>
/// <param name="updateOrder">Whether to update the sort order value if the item is already present.</param>
/// <returns><c>true</c> if the item is now present as defined; otherwise, <c>false</c>.</returns>
public bool AddItem(T item, int sortOrder = 0, bool updateOrder = false)
{
if (sortableItems.ContainsKey(item))
{
if (updateOrder)
sortableItems[item] = sortOrder;

return updateOrder;
}

sortableItems.Add(item, sortOrder);
return true;
}

/// <summary>
/// Checks whether the given item is already present.
/// </summary>
/// <param name="item">The item to check for.</param>
/// <param name="sortOrder">The sort order value of the item, if it is present.</param>
/// <returns><c>true</c> if the item is present; otherwise, <c>false</c>.</returns>
public bool HasItem(T item, [NotNullWhen(true)] out int? sortOrder)
{
if (sortableItems.TryGetValue(item, out var order))
{
sortOrder = order;
return true;
}

sortOrder = null;
return false;
}

/// <summary>
/// Removes the given item.
/// </summary>
/// <param name="item">The item to remove.</param>
/// <returns><c>true</c> if the item was found and removed; otherwise <c>false</c>.</returns>
public bool RemoveItem(T item) => sortableItems.Remove(item);
}
}
Loading