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