Skip to content
This repository has been archived by the owner on Jan 19, 2025. It is now read-only.

Review #2764

Open
wants to merge 19 commits into
base: dev
Choose a base branch
from
Open

Review #2764

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
4 changes: 2 additions & 2 deletions Exiled.API/Enums/UEBranchType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ public class UEBranchType : UnmanagedEnumClass<sbyte, UEBranchType>
public static readonly UEBranchType Alpha = new(4);

/// <summary>
/// The prealpha branch.
/// The pre alpha branch.
/// </summary>
public static readonly UEBranchType Prealpha = new(5);
public static readonly UEBranchType PreAlpha = new(5);

/// <summary>
/// The unstable branch.
Expand Down
2 changes: 1 addition & 1 deletion Exiled.API/Features/Core/Components/TickComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public sealed class TickComponent : EObject
/// The default fixed tick rate (60 per second).
/// </summary>
#pragma warning disable SA1310
public const float DEFAULT_FIXED_TICK_RATE = 0.016f;
public const float DEFAULT_FIXED_TICK_RATE = 1f / 60f;
warquys marked this conversation as resolved.
Show resolved Hide resolved
#pragma warning restore SA1310

private readonly HashSet<CoroutineHandle> boundHandles;
Expand Down
4 changes: 1 addition & 3 deletions Exiled.API/Features/Core/ConstProperty.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// <copyright file="ConstProperty.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
Expand Down Expand Up @@ -48,8 +48,6 @@ public ConstProperty(T constantValue, Type[] typesToPatch, MethodInfo[] skipMeth
/// </summary>
~ConstProperty()
{
List.Remove(this);

foreach (MethodInfo methodInfo in PatchedMethods)
{
try
Expand Down
13 changes: 6 additions & 7 deletions Exiled.API/Features/Core/Generic/EBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,13 @@ protected virtual void FindOwner()
{
MethodInfo method = typeof(T).GetMethod("Get", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(GameObject) }, null);

if (method != null)
{
Owner = (T)method.Invoke(null, new object[] { Base });
}
else
{
if (method == null)
throw new MissingMethodException($"Method 'Get(GameObject)' not found in class '{typeof(T).Name}'.");
}

if (typeof(T).IsAssignableFrom(method.ReturnType))
throw new MissingMethodException($"Method 'Get(GameObject)' in class '{typeof(T).Name}' do not return an instance of {typeof(T).Name} but {method.ReturnType}.");

Owner = (T)method.Invoke(null, new object[] { Base });
}

/// <inheritdoc/>
Expand Down
42 changes: 29 additions & 13 deletions Exiled.API/Features/Core/Generic/EnumClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace Exiled.API.Features.Core.Generic
/// </summary>
/// <typeparam name="TSource">The type of the source object to handle the instance of.</typeparam>
/// <typeparam name="TObject">The type of the child object to handle the instance of.</typeparam>
public abstract class EnumClass<TSource, TObject> : IComparable, IEquatable<TObject>, IComparable<TObject>, IComparer<TObject>, IEnumClass
public abstract class EnumClass<TSource, TObject> : IComparable, IEquatable<TObject>, IComparable<TObject>, IEnumClass
where TSource : Enum
where TObject : EnumClass<TSource, TObject>
{
Expand Down Expand Up @@ -205,17 +205,29 @@ public static bool SafeCast(IEnumerable<TSource> values, out IEnumerable<TObject
/// <summary>
/// Determines whether the specified object is equal to the current object.
/// </summary>
/// <param name="obj">The object to compare.</param>
/// <param name="other">The object to compare.</param>
/// <returns><see langword="true"/> if the object was equal; otherwise, <see langword="false"/>.</returns>
public override bool Equals(object obj) =>
obj != null && (obj is TSource value ? Value.Equals(value) : obj is TObject derived && Value.Equals(derived.Value));
public bool Equals(TSource other) => Value.Equals(other);

/// <summary>
/// Determines whether the specified object is equal to the current object.
/// </summary>
/// <param name="other">The object to compare.</param>
/// <returns><see langword="true"/> if the object was equal; otherwise, <see langword="false"/>.</returns>
public bool Equals(TObject other) => Value.Equals(other.Value);
public bool Equals(TObject other)
{
if (other is null)
return false;

return Equals(other.Value);
}

/// <summary>
/// Determines whether the specified object is equal to the current object.
/// </summary>
/// <param name="obj">The object to compare.</param>
/// <returns><see langword="true"/> if the object was equal; otherwise, <see langword="false"/>.</returns>
public override bool Equals(object obj) => obj is TSource value ? Equals(value) : Equals(obj as TObject);

/// <summary>
/// Returns a the 32-bit signed hash code of the current object instance.
Expand All @@ -235,36 +247,40 @@ public override bool Equals(object obj) =>
/// Zero This instance occurs in the same position in the sort order as other.
/// Greater than zero This instance follows other in the sort order.
/// </returns>
public int CompareTo(TObject other) => Value.CompareTo(other.Value);
public int CompareTo(TSource other) => Comparer<TSource>.Default.Compare(Value, other);

/// <summary>
/// Compares the current instance with another object of the same type and returns
/// an integer that indicates whether the current instance precedes, follows, or
/// occurs in the same position in the sort order as the other object.
/// </summary>
/// <param name="obj">An object to compare with this instance.</param>
/// <param name="other">An object to compare with this instance.</param>
/// <returns>
/// A value that indicates the relative order of the objects being compared.
/// The return value has these meanings: Value Meaning Less than zero This instance precedes other in the sort order.
/// Zero This instance occurs in the same position in the sort order as other.
/// Greater than zero This instance follows other in the sort order.
/// </returns>
public int CompareTo(object obj) =>
obj == null ? -1 : obj is TSource value ? Value.CompareTo(value) : obj is TObject derived ? Value.CompareTo(derived.Value) : -1;
public int CompareTo(TObject other)
{
if (other is null)
return 1;

return CompareTo(other.Value);
}

/// <summary>
/// Compares the specified object instance with another object of the same type and returns
/// Compares the current instance with another object of the same type and returns
/// an integer that indicates whether the current instance precedes, follows, or
/// occurs in the same position in the sort order as the other object.
/// </summary>
/// <param name="x">An object to compare.</param>
/// <param name="y">Another object to compare.</param>
/// <param name="obj">An object to compare with this instance.</param>
/// <returns>
/// A value that indicates the relative order of the objects being compared.
/// The return value has these meanings: Value Meaning Less than zero This instance precedes other in the sort order.
/// Zero This instance occurs in the same position in the sort order as other.
/// Greater than zero This instance follows other in the sort order.
/// </returns>
public int Compare(TObject x, TObject y) => x == null ? -1 : y == null ? 1 : x.Value.CompareTo(y.Value);
public int CompareTo(object obj) => obj is TSource value ? CompareTo(value) : CompareTo(obj as TObject);
}
}
65 changes: 26 additions & 39 deletions Exiled.API/Features/Core/Generic/Singleton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,66 +19,53 @@ namespace Exiled.API.Features.Core.Generic
public sealed class Singleton<T> : TypeCastObject<T>
where T : class
{
private static readonly Dictionary<T, Singleton<T>> Instances = new();

/// <summary>
/// Initializes a new instance of the <see cref="Singleton{T}"/> class.
/// </summary>
/// <param name="value">The branch to instantiate.</param>
public Singleton(T value)
{
Destroy(value);
Value = value;
Instances.Add(value, this);
}

/// <summary>
/// Finalizes an instance of the <see cref="Singleton{T}"/> class.
/// </summary>
~Singleton() => Instances.Remove(Value);

/// <summary>
/// Gets the relative value.
/// </summary>
public static T Instance => Instances.FirstOrDefault(@object => @object.Key.GetType() == typeof(T)).Value;

/// <summary>
/// Gets the singleton value.
/// </summary>
internal T Value { get; private set; }

/// <summary>
/// Converts the given <see cref="Singleton{T}"/> instance into <typeparamref name="T"/>.
/// </summary>
/// <param name="instance">The <see cref="Singleton{T}"/> instance to convert.</param>
public static implicit operator T(Singleton<T> instance) => instance?.Value;
public static T Instance { get; private set; }

/// <summary>
/// Tries to get the relative value.
/// </summary>
/// <typeparam name="TObject">The type of the object.</typeparam>
/// <param name="instance">The object instance.</param>
/// <returns><see langword="true"/> if the object instance is not null and can be casted as the specified type; otherwise, <see langword="false"/>.</returns>
public static bool TryGet<TObject>(out TObject instance)
where TObject : class => (instance = Instance as TObject) is not null;
public static bool TryGet(out T instance)
=> (instance = Instance) is not null;

/// <inheritdoc cref="Singleton{T}"/>
public static void Create(T @object) => new Singleton<T>(@object);
/// <summary>
/// Define the value of the <see cref="Instance"/> if not already defined.
/// If you want to replace first call <see cref="Destroy()"/>.
/// </summary>
/// <param name="object">The object use to create the singleton.</param>
public static void Create(T @object)
{
if (Instance is not null)
return;
Instance = @object;
}

/// <summary>
/// Destroys the given <typeparamref name="T"/> instance.
/// Set to null <see cref="Instance"/> if <paramref name="object"/> is the same.
/// </summary>
/// <param name="object">The object to destroy.</param>
/// <returns><see langword="true"/> if the instance was destroyed; otherwise, <see langword="false"/>.</returns>
public static bool Destroy(T @object)
{
if (Instances.TryGetValue(@object, out Singleton<T> _))
if (Instance == @object)
{
Instances[@object] = null;
return Instances.Remove(@object);
Instance = null;
return true;
}

return false;
}

/// <summary>
/// Set to null <see cref="Instance"/>.
/// </summary>
public static void Destroy()
{
Instance = null;
}
}
}
64 changes: 41 additions & 23 deletions Exiled.API/Features/Core/Generic/UniqueUnmanagedEnumClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Exiled.API.Features.Core.Generic
using Exiled.API.Features.Core.Generic.Pools;
using Exiled.API.Interfaces;
using LiteNetLib.Utils;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Serialization;

/// <summary>
Expand All @@ -23,37 +24,38 @@ namespace Exiled.API.Features.Core.Generic
/// </summary>
/// <typeparam name="TSource">The type of the <see langword="unmanaged"/> source object to handle the instance of.</typeparam>
/// <typeparam name="TObject">The type of the child object to handle the instance of.</typeparam>
public abstract class UniqueUnmanagedEnumClass<TSource, TObject> : IComparable, IEquatable<TObject>, IComparable<TObject>, IComparer<TObject>, IConvertible, IEnumClass
public abstract class UniqueUnmanagedEnumClass<TSource, TObject> : IComparable, IEquatable<TObject>, IComparable<TObject>, IConvertible, IEnumClass
where TSource : unmanaged, IComparable, IFormattable, IConvertible, IComparable<TSource>, IEquatable<TSource>
where TObject : UniqueUnmanagedEnumClass<TSource, TObject>
{
private static SortedList<TSource, TObject> values;
private static int nextValue = int.MinValue;
private static long nextValue;
private static bool isDefined;

private string name;

static UniqueUnmanagedEnumClass()
{
values = new SortedList<TSource, TObject>();
nextValue = (int)typeof(TSource).GetField("MinValue").GetValue(null);
}

/// <summary>
/// Initializes a new instance of the <see cref="UniqueUnmanagedEnumClass{TSource, TObject}"/> class.
/// </summary>
public UniqueUnmanagedEnumClass()
internal protected UniqueUnmanagedEnumClass()
{
values ??= new();
TypeCode code = Convert.GetTypeCode(typeof(TSource).GetField("MinValue").GetValue(null));

if (code is TypeCode.UInt16 or TypeCode.UInt32 or TypeCode.UInt64)
nextValue = 0;

lock (values)
{
TSource value;
do
{
value = (TSource)Convert.ChangeType(nextValue++, code);
value = (TSource)Convert.ChangeType(nextValue++, Value.GetTypeCode());
}
while (values.ContainsKey(value));

Value = value;

values.Add(value, (TObject)this);
}
}
Expand Down Expand Up @@ -227,17 +229,29 @@ public static TObject Parse(string obj)
/// <summary>
/// Determines whether the specified object is equal to the current object.
/// </summary>
/// <param name="obj">The object to compare.</param>
/// <param name="other">The object to compare.</param>
/// <returns><see langword="true"/> if the object was equal; otherwise, <see langword="false"/>.</returns>
public override bool Equals(object obj) =>
obj != null && (obj is TSource value ? Value.Equals(value) : obj is TObject derived && Value.Equals(derived.Value));
public bool Equals(TSource other) => Value.Equals(other);

/// <summary>
/// Determines whether the specified object is equal to the current object.
/// </summary>
/// <param name="other">The object to compare.</param>
/// <returns><see langword="true"/> if the object was equal; otherwise, <see langword="false"/>.</returns>
public bool Equals(TObject other) => Value.Equals(other.Value);
public bool Equals(TObject other)
{
if (other is null)
return false;

return Equals(other.Value);
}

/// <summary>
/// Determines whether the specified object is equal to the current object.
/// </summary>
/// <param name="obj">The object to compare.</param>
/// <returns><see langword="true"/> if the object was equal; otherwise, <see langword="false"/>.</returns>
public override bool Equals(object obj) => obj is TSource value ? Equals(value) : Equals(obj as TObject);

/// <summary>
/// Returns a the 32-bit signed hash code of the current object instance.
Expand All @@ -257,39 +271,43 @@ public override bool Equals(object obj) =>
/// Zero This instance occurs in the same position in the sort order as other.
/// Greater than zero This instance follows other in the sort order.
/// </returns>
public int CompareTo(TObject other) => Value.CompareTo(other.Value);
public int CompareTo(TSource other) => Comparer<TSource>.Default.Compare(Value, other);

/// <summary>
/// Compares the current instance with another object of the same type and returns
/// an integer that indicates whether the current instance precedes, follows, or
/// occurs in the same position in the sort order as the other object.
/// </summary>
/// <param name="obj">An object to compare with this instance.</param>
/// <param name="other">An object to compare with this instance.</param>
/// <returns>
/// A value that indicates the relative order of the objects being compared.
/// The return value has these meanings: Value Meaning Less than zero This instance precedes other in the sort order.
/// Zero This instance occurs in the same position in the sort order as other.
/// Greater than zero This instance follows other in the sort order.
/// </returns>
public int CompareTo(object obj) =>
obj == null ? -1 : obj is TSource value ? Value.CompareTo(value) : obj is TObject derived ? Value.CompareTo(derived.Value) : -1;
public int CompareTo(TObject other)
{
if (other is null)
return 1;

return CompareTo(other.Value);
}

/// <summary>
/// Compares the specified object instance with another object of the same type and returns
/// Compares the current instance with another object of the same type and returns
/// an integer that indicates whether the current instance precedes, follows, or
/// occurs in the same position in the sort order as the other object.
/// </summary>
/// <param name="x">An object to compare.</param>
/// <param name="y">Another object to compare.</param>
/// <param name="obj">An object to compare with this instance.</param>
/// <returns>
/// A value that indicates the relative order of the objects being compared.
/// The return value has these meanings: Value Meaning Less than zero This instance precedes other in the sort order.
/// Zero This instance occurs in the same position in the sort order as other.
/// Greater than zero This instance follows other in the sort order.
/// </returns>
public int Compare(TObject x, TObject y) => x == null ? -1 : y == null ? 1 : x.Value.CompareTo(y.Value);
public int CompareTo(object obj) => obj is TSource value ? CompareTo(value) : CompareTo(obj as TObject);

/// <inheritdoc/>
/// <inheritdoc/>
TypeCode IConvertible.GetTypeCode() => Value.GetTypeCode();

/// <inheritdoc/>
Expand Down
Loading
Loading