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  }