LuaValueRuntimeExtensions.cs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using System.Buffers;
  2. using System.Runtime.CompilerServices;
  3. using Lua.Internal;
  4. namespace Lua.Runtime;
  5. internal static class LuaRuntimeExtensions
  6. {
  7. public static bool TryGetNumber(this LuaValue value, out double result)
  8. {
  9. if (value.TryRead(out result)) return true;
  10. if (value.TryRead<string>(out var str))
  11. {
  12. var span = str.AsSpan().Trim();
  13. var sign = 1;
  14. if (span.Length > 0 && span[0] == '-')
  15. {
  16. sign = -1;
  17. span = span[1..];
  18. }
  19. if (span.Length > 2 && span[0] is '0' && span[1] is 'x' or 'X')
  20. {
  21. // TODO: optimize
  22. try
  23. {
  24. result = HexConverter.ToDouble(span) * sign;
  25. return true;
  26. }
  27. catch (FormatException)
  28. {
  29. return false;
  30. }
  31. }
  32. else
  33. {
  34. return double.TryParse(str, out result);
  35. }
  36. }
  37. result = default;
  38. return false;
  39. }
  40. public static bool TryGetMetamethod(this LuaValue value, LuaState state, string methodName, out LuaValue result)
  41. {
  42. result = default;
  43. return state.TryGetMetatable(value, out var metatable) &&
  44. metatable.TryGetValue(methodName, out result);
  45. }
  46. #if NET6_0_OR_GREATER
  47. [AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder<>))]
  48. #endif
  49. public static async ValueTask<int> InvokeAsync(this LuaFunction function, LuaFunctionExecutionContext context, CancellationToken cancellationToken)
  50. {
  51. var buffer = ArrayPool<LuaValue>.Shared.Rent(1024);
  52. buffer.AsSpan().Clear();
  53. try
  54. {
  55. return await function.InvokeAsync(context, buffer, cancellationToken);
  56. }
  57. finally
  58. {
  59. ArrayPool<LuaValue>.Shared.Return(buffer);
  60. }
  61. }
  62. }