Improve the usability of Result<T, E> and add new job schedule method to EntityQuery.
Added implicate conversion to Result<T, E> and RefResult<T, E>; Added new ScheduleChunkParallel in EntityQuery; Remove Ghost.SparseEntity from solution file. It's now completlty replaced by Ghost.Entities;
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
using Misaki.HighPerformance.LowLevel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Ghost.Core;
|
||||
|
||||
public readonly struct Result
|
||||
{
|
||||
private readonly bool _isSuccess;
|
||||
private readonly string? _message;
|
||||
|
||||
public readonly bool IsSuccess => _isSuccess;
|
||||
public readonly bool IsFailure => !_isSuccess;
|
||||
private readonly bool _isSuccess;
|
||||
|
||||
public readonly string? Message => _message;
|
||||
public readonly bool IsSuccess => _isSuccess;
|
||||
public readonly bool IsFailure => !_isSuccess;
|
||||
|
||||
public Result(bool success, string? message = null)
|
||||
{
|
||||
@@ -38,16 +38,10 @@ public readonly struct Result
|
||||
return Result<T>.Failure(message);
|
||||
}
|
||||
|
||||
public static Result<T, S> Create<T, S>(T value, S status)
|
||||
where S : Enum
|
||||
public void Deconstruct(out bool success, out string? message)
|
||||
{
|
||||
return new Result<T, S>(value, status);
|
||||
}
|
||||
|
||||
public static RefResult<T, S> CreateRef<T, S>(ref T value, S status)
|
||||
where S : Enum
|
||||
{
|
||||
return new RefResult<T, S>(ref value, status);
|
||||
success = IsSuccess;
|
||||
message = Message;
|
||||
}
|
||||
|
||||
public override string ToString() => IsSuccess ? "OK" : $"Error: {Message}";
|
||||
@@ -57,15 +51,14 @@ public readonly struct Result
|
||||
|
||||
public readonly struct Result<T>
|
||||
{
|
||||
private readonly bool _isSuccess;
|
||||
private readonly T _value;
|
||||
private readonly string? _message;
|
||||
|
||||
public readonly bool IsSuccess => _isSuccess;
|
||||
public readonly bool IsFailure => !_isSuccess;
|
||||
private readonly bool _isSuccess;
|
||||
|
||||
public readonly T Value => _value;
|
||||
public readonly string? Message => _message;
|
||||
public readonly bool IsSuccess => _isSuccess;
|
||||
public readonly bool IsFailure => !_isSuccess;
|
||||
|
||||
public Result(bool success, T value, string? message = null)
|
||||
{
|
||||
@@ -84,6 +77,13 @@ public readonly struct Result<T>
|
||||
return new Result<T>(false, default!, message);
|
||||
}
|
||||
|
||||
public void Deconstruct(out bool success, out T value, out string? message)
|
||||
{
|
||||
success = IsSuccess;
|
||||
value = Value;
|
||||
message = Message;
|
||||
}
|
||||
|
||||
public override string ToString() => IsSuccess ? $"OK: {Value}" : $"Error: {Message}";
|
||||
|
||||
public static implicit operator Result<T>(T? data) => data is not null ? Success(data) : Failure(null);
|
||||
@@ -91,9 +91,9 @@ public readonly struct Result<T>
|
||||
public static implicit operator bool(Result<T> result) => result.IsSuccess;
|
||||
}
|
||||
|
||||
public enum ResultStatus : byte
|
||||
public enum ErrorStatus : byte
|
||||
{
|
||||
Success,
|
||||
None,
|
||||
NotFound,
|
||||
InvalidArgument,
|
||||
InvalidState,
|
||||
@@ -106,57 +106,97 @@ public enum ResultStatus : byte
|
||||
UnknownError
|
||||
}
|
||||
|
||||
public readonly struct Result<T, S>
|
||||
where S : Enum
|
||||
public readonly struct Result<T, E>
|
||||
where E : struct, Enum
|
||||
{
|
||||
private readonly T _value;
|
||||
private readonly S _status;
|
||||
private readonly E _error;
|
||||
private readonly bool _isSuccess;
|
||||
|
||||
public T Value => _value;
|
||||
public S Status => _status;
|
||||
public E Error => _error;
|
||||
public bool IsSuccess => _isSuccess;
|
||||
public bool IsFailure => !_isSuccess;
|
||||
|
||||
public Result(T value, S status)
|
||||
public Result(T value, E status, bool isSuccess)
|
||||
{
|
||||
_value = value;
|
||||
_status = status;
|
||||
_error = status;
|
||||
_isSuccess = isSuccess;
|
||||
}
|
||||
|
||||
public static Result<T, S> Create(T value, S status)
|
||||
public static Result<T, E> Success(T value)
|
||||
{
|
||||
return new Result<T, S>(value, status);
|
||||
return new Result<T, E>(value, default, true);
|
||||
}
|
||||
|
||||
public override string ToString() => $"Value: {_value}, Status: {_status}";
|
||||
public static Result<T, E> Failure(E status)
|
||||
{
|
||||
return new Result<T, E>(default!, status, false);
|
||||
}
|
||||
|
||||
public void Deconstruct(out bool success, out T value, out E status)
|
||||
{
|
||||
success = IsSuccess;
|
||||
value = Value;
|
||||
status = Error;
|
||||
}
|
||||
|
||||
public override string ToString() => $"Value: {_value}, Status: {_error}";
|
||||
|
||||
public static implicit operator Result<T, E>(T data) => new(data, default, true);
|
||||
public static implicit operator Result<T, E>(E status) => new(default!, status, false);
|
||||
public static implicit operator bool(Result<T, E> result) => result.IsSuccess;
|
||||
}
|
||||
|
||||
public readonly ref struct RefResult<T, S>
|
||||
where S : Enum
|
||||
public readonly ref struct RefResult<T, E>
|
||||
where E : struct, Enum
|
||||
{
|
||||
private readonly ref T _value;
|
||||
private readonly S _status;
|
||||
private readonly E _error;
|
||||
private readonly bool _isSuccess;
|
||||
|
||||
public ref T Value => ref _value;
|
||||
public S Status => _status;
|
||||
public E Error => _error;
|
||||
public bool IsSuccess => _isSuccess;
|
||||
public bool IsFailure => !_isSuccess;
|
||||
|
||||
public RefResult(ref T value, S status)
|
||||
public RefResult(ref T value, E error, bool isSuccess)
|
||||
{
|
||||
_value = ref value;
|
||||
_status = status;
|
||||
_error = error;
|
||||
_isSuccess = isSuccess;
|
||||
}
|
||||
|
||||
public static RefResult<T, S> Create(ref T value, S status)
|
||||
public static RefResult<T, E> Success(ref T value)
|
||||
{
|
||||
return new RefResult<T, S>(ref value, status);
|
||||
return new RefResult<T, E>(ref value, default, true);
|
||||
}
|
||||
|
||||
public override string ToString() => $"Value: {_value}, Status: {_status}";
|
||||
public static RefResult<T, E> Failure(E error)
|
||||
{
|
||||
return new RefResult<T, E>(ref Unsafe.NullRef<T>(), error, false);
|
||||
}
|
||||
|
||||
public void Deconstruct(out bool success, out Ref<T> value, out E status)
|
||||
{
|
||||
success = IsSuccess;
|
||||
value = new Ref<T>(ref Value);
|
||||
status = Error;
|
||||
}
|
||||
|
||||
public override string ToString() => $"Value: {_value}, Status: {_error}";
|
||||
|
||||
public static implicit operator RefResult<T, E>(Ref<T> data) => new(ref data.Get(), default, true);
|
||||
public static implicit operator RefResult<T, E>(E error) => new(ref Unsafe.NullRef<T>(), error, false);
|
||||
public static implicit operator bool(RefResult<T, E> result) => result.IsSuccess;
|
||||
}
|
||||
|
||||
public static class ResultExtensions
|
||||
{
|
||||
public static void ThrowIfFailed(this ResultStatus result, [CallerArgumentExpression(nameof(result))] string? op = null)
|
||||
public static void ThrowIfFailed(this ErrorStatus result, [CallerArgumentExpression(nameof(result))] string? op = null)
|
||||
{
|
||||
if (result != ResultStatus.Success)
|
||||
if (result != ErrorStatus.None)
|
||||
{
|
||||
throw new InvalidOperationException($"{op} failed: {result}");
|
||||
}
|
||||
@@ -180,12 +220,12 @@ public static class ResultExtensions
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public static T GetValueOrThrow<T, S>(this Result<T, S> result, S expect, [CallerArgumentExpression(nameof(result))] string? op = null)
|
||||
where S : Enum
|
||||
public static T GetValueOrThrow<T, S>(this Result<T, S> result, [CallerArgumentExpression(nameof(result))] string? op = null)
|
||||
where S : struct, Enum
|
||||
{
|
||||
if (!EqualityComparer<S>.Default.Equals(result.Status, expect))
|
||||
if (!result.IsSuccess)
|
||||
{
|
||||
throw new InvalidOperationException($"{op} failed: expected status {expect}, but got {result.Status}");
|
||||
throw new InvalidOperationException($"{op} failed: status {result.Error}");
|
||||
}
|
||||
|
||||
return result.Value;
|
||||
@@ -196,10 +236,10 @@ public static class ResultExtensions
|
||||
return result.IsSuccess ? result.Value : defaultValue;
|
||||
}
|
||||
|
||||
public static T? GetValueOrDefault<T, S>(this Result<T, S> result, S expect, T? defaultValue = default)
|
||||
where S : Enum
|
||||
public static T? GetValueOrDefault<T, S>(this Result<T, S> result, T? defaultValue = default)
|
||||
where S : struct, Enum
|
||||
{
|
||||
return (result.Status?.Equals(expect) ?? false) ? defaultValue : result.Value;
|
||||
return result.IsSuccess ? result.Value : defaultValue;
|
||||
}
|
||||
|
||||
public static bool TryGetValue<T>(this Result<T> result, out T value)
|
||||
@@ -214,10 +254,10 @@ public static class ResultExtensions
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryGetValue<T, S>(this Result<T, S> result, S expect, out T value)
|
||||
where S : Enum
|
||||
public static bool TryGetValue<T, S>(this Result<T, S> result, out T value)
|
||||
where S : struct, Enum
|
||||
{
|
||||
if (EqualityComparer<S>.Default.Equals(result.Status, expect))
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
value = result.Value;
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user