using Amphora; using System; namespace Susurrus.XAudio2 { /// /// Interprets failures that carry the name of the call that failed in Ref and its HRESULT in Bits. /// public class HResultFailureKind : FailureKind { public const int InvalidArgument = unchecked((int)0x80070057); public const int OutOfMemory = unchecked((int)0x8007000E); public const int InvalidCall = unchecked((int)0x88960001); public const int DeviceInvalidated = unchecked((int)0x88960004); public HResultFailureKind(string name) : base(name) { } public Status Fail(string call, int hresult) { if (call == null) { throw new ArgumentNullException(nameof(call)); } return Status.FromWire(this, call, hresult); } /// /// Returns the HRESULT the failed , which has to be of this kind, carries. /// public int HResultOf(in Status status) { if (status.Kind != this) { ThrowWrongKind(status.Kind); } return (int)status.Bits; } /// /// Returns the name of the call that failed in , which has to be of this kind. /// public string CallOf(in Status status) { if (status.Kind != this) { ThrowWrongKind(status.Kind); } return (string)status.Ref; } public override string Describe(in Status status, object context) { int hresult = HResultOf(in status); string call = CallOf(in status); string hex = "0x" + hresult.ToString("X8"); switch (hresult) { case InvalidArgument: return $"{call} was given an invalid argument ({hex})."; case OutOfMemory: return $"{call} ran out of memory ({hex})."; case InvalidCall: return $"{call} isn't allowed in the engine's current state ({hex})."; case DeviceInvalidated: return $"{call} failed because the audio device went away or can't be used ({hex})."; default: return $"{call} failed with HRESULT {hex}."; } } } }