CommandHandler.cs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. using Ryujinx.Horizon.Common;
  2. using Ryujinx.Horizon.Sdk.Sf.Cmif;
  3. using System;
  4. using System.Runtime.CompilerServices;
  5. using System.Runtime.InteropServices;
  6. namespace Ryujinx.Horizon.Sdk.Sf
  7. {
  8. class CommandHandler
  9. {
  10. public delegate Result MethodInvoke(
  11. ref ServiceDispatchContext context,
  12. HipcCommandProcessor processor,
  13. ServerMessageRuntimeMetadata runtimeMetadata,
  14. ReadOnlySpan<byte> inRawData,
  15. ref Span<CmifOutHeader> outHeader);
  16. private readonly MethodInvoke _invoke;
  17. private readonly HipcCommandProcessor _processor;
  18. public string MethodName => _invoke.Method.Name;
  19. public CommandHandler(MethodInvoke invoke, params CommandArg[] args)
  20. {
  21. _invoke = invoke;
  22. _processor = new HipcCommandProcessor(args);
  23. }
  24. public Result Invoke(ref Span<CmifOutHeader> outHeader, ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData)
  25. {
  26. if (context.Processor == null)
  27. {
  28. context.Processor = _processor;
  29. }
  30. else
  31. {
  32. context.Processor.SetImplementationProcessor(_processor);
  33. }
  34. var runtimeMetadata = context.Processor.GetRuntimeMetadata();
  35. Result result = context.Processor.PrepareForProcess(ref context, runtimeMetadata);
  36. if (result.IsFailure)
  37. {
  38. return result;
  39. }
  40. return _invoke(ref context, _processor, runtimeMetadata, inRawData, ref outHeader);
  41. }
  42. public static void GetCmifOutHeaderPointer(ref Span<CmifOutHeader> outHeader, ref Span<byte> outRawData)
  43. {
  44. outHeader = MemoryMarshal.Cast<byte, CmifOutHeader>(outRawData)[..1];
  45. outRawData = outRawData[Unsafe.SizeOf<CmifOutHeader>()..];
  46. }
  47. }
  48. }