Result.cs
1 using System; 2 3 namespace Ryujinx.Horizon.Common 4 { 5 public struct Result : IEquatable<Result> 6 { 7 private const int ModuleBits = 9; 8 private const int DescriptionBits = 13; 9 private const int ModuleMax = 1 << ModuleBits; 10 private const int DescriptionMax = 1 << DescriptionBits; 11 12 public static Result Success { get; } = new Result(0, 0); 13 14 public int ErrorCode { get; } 15 16 public readonly bool IsSuccess => ErrorCode == 0; 17 public readonly bool IsFailure => ErrorCode != 0; 18 19 public readonly int Module => ErrorCode & (ModuleMax - 1); 20 public readonly int Description => (ErrorCode >> ModuleBits) & (DescriptionMax - 1); 21 22 public readonly string PrintableResult => $"{2000 + Module:D4}-{Description:D4}"; 23 24 public Result(int module, int description) 25 { 26 if ((uint)module >= ModuleMax) 27 { 28 throw new ArgumentOutOfRangeException(nameof(module)); 29 } 30 31 if ((uint)description >= DescriptionMax) 32 { 33 throw new ArgumentOutOfRangeException(nameof(description)); 34 } 35 36 ErrorCode = module | (description << ModuleBits); 37 } 38 39 public Result(int errorCode) 40 { 41 ErrorCode = errorCode; 42 } 43 44 public readonly override bool Equals(object obj) 45 { 46 return obj is Result result && result.Equals(this); 47 } 48 49 public readonly bool Equals(Result other) 50 { 51 return other.ErrorCode == ErrorCode; 52 } 53 54 public readonly override int GetHashCode() 55 { 56 return ErrorCode; 57 } 58 59 public static bool operator ==(Result lhs, Result rhs) 60 { 61 return lhs.Equals(rhs); 62 } 63 64 public static bool operator !=(Result lhs, Result rhs) 65 { 66 return !lhs.Equals(rhs); 67 } 68 69 public readonly bool InRange(int minInclusive, int maxInclusive) 70 { 71 return (uint)(Description - minInclusive) <= (uint)(maxInclusive - minInclusive); 72 } 73 74 public void AbortOnSuccess() 75 { 76 if (IsSuccess) 77 { 78 ThrowInvalidResult(); 79 } 80 } 81 82 public void AbortOnFailure() 83 { 84 if (this == KernelResult.ThreadTerminating) 85 { 86 throw new ThreadTerminatedException(); 87 } 88 89 AbortUnless(Success); 90 } 91 92 public void AbortUnless(Result result) 93 { 94 if (this != result) 95 { 96 ThrowInvalidResult(); 97 } 98 } 99 100 public void AbortUnless(Result result, Result result2) 101 { 102 if (this != result && this != result2) 103 { 104 ThrowInvalidResult(); 105 } 106 } 107 108 private void ThrowInvalidResult() 109 { 110 throw new InvalidResultException(this); 111 } 112 113 public readonly override string ToString() 114 { 115 if (ResultNames.TryGet(ErrorCode, out string name)) 116 { 117 return name; 118 } 119 120 return PrintableResult; 121 } 122 } 123 }