Result.cs 3.0 KB

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