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}.";
}
}
}
}