mirror of
https://github.com/Ale32bit/Capy64.git
synced 2025-01-18 18:46:43 +00:00
Make WebSocketClient use ObjectManager
This commit is contained in:
parent
f9f56c8063
commit
4143417947
2 changed files with 101 additions and 42 deletions
|
@ -5,7 +5,6 @@ using KeraLua;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
|
@ -19,7 +18,7 @@ public class HTTP : IPlugin
|
||||||
private static IGame _game;
|
private static IGame _game;
|
||||||
private static HttpClient _httpClient;
|
private static HttpClient _httpClient;
|
||||||
private static long _requestId;
|
private static long _requestId;
|
||||||
public static readonly HashSet<WebSocketClient> WebSocketConnections = new();
|
public static readonly HashSet<WebSocketClient.Client> WebSocketConnections = new();
|
||||||
|
|
||||||
public static readonly string UserAgent = $"Capy64/{Capy64.Version}";
|
public static readonly string UserAgent = $"Capy64/{Capy64.Version}";
|
||||||
|
|
||||||
|
@ -336,14 +335,15 @@ public class HTTP : IPlugin
|
||||||
|
|
||||||
await task;
|
await task;
|
||||||
|
|
||||||
var handle = new WebSocketClient(wsClient, requestId);
|
var handle = new WebSocketClient.Client(wsClient, requestId);
|
||||||
WebSocketConnections.Add(handle);
|
WebSocketConnections.Add(handle);
|
||||||
|
|
||||||
_game.LuaRuntime.QueueEvent("websocket_connect", LK =>
|
_game.LuaRuntime.QueueEvent("websocket_connect", LK =>
|
||||||
{
|
{
|
||||||
LK.PushInteger(requestId);
|
LK.PushInteger(requestId);
|
||||||
|
|
||||||
handle.Push(LK);
|
ObjectManager.PushObject(LK, handle);
|
||||||
|
LK.SetMetaTable(WebSocketClient.ObjectType);
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Capy64.Runtime.Libraries;
|
using Capy64.API;
|
||||||
|
using Capy64.Runtime.Libraries;
|
||||||
using KeraLua;
|
using KeraLua;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -7,17 +8,72 @@ using System.Threading;
|
||||||
|
|
||||||
namespace Capy64.Runtime.Objects;
|
namespace Capy64.Runtime.Objects;
|
||||||
|
|
||||||
public class WebSocketClient
|
public class WebSocketClient : IPlugin
|
||||||
{
|
{
|
||||||
public const string ObjectType = "WebSocketClient";
|
public const string ObjectType = "WebSocketClient";
|
||||||
private readonly ClientWebSocket _socket;
|
|
||||||
private readonly long _requestId;
|
public record Client(ClientWebSocket Socket, long RequestId);
|
||||||
public WebSocketClient(ClientWebSocket socket, long requestId)
|
|
||||||
|
public void LuaInit(Lua L)
|
||||||
{
|
{
|
||||||
_socket = socket;
|
CreateMeta(L);
|
||||||
_requestId = requestId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void CreateMeta(Lua L)
|
||||||
|
{
|
||||||
|
L.NewMetaTable(ObjectType);
|
||||||
|
L.SetFuncs(MetaMethods, 0);
|
||||||
|
L.NewLibTable(Methods);
|
||||||
|
L.SetFuncs(Methods, 0);
|
||||||
|
L.SetField(-2, "__index");
|
||||||
|
L.Pop(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static LuaRegister[] Methods = new LuaRegister[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "getRequestID",
|
||||||
|
function = L_GetRequestId,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "send",
|
||||||
|
function = L_Send,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "closeAsync",
|
||||||
|
function = L_CloseAsync,
|
||||||
|
},
|
||||||
|
new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
internal static LuaRegister[] MetaMethods = new LuaRegister[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "__index",
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "__gc",
|
||||||
|
function = L_CloseAsync,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "__close",
|
||||||
|
function = L_CloseAsync,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "__tostring",
|
||||||
|
function = LM_ToString,
|
||||||
|
},
|
||||||
|
|
||||||
|
new(),
|
||||||
|
};
|
||||||
|
|
||||||
private static readonly Dictionary<string, LuaFunction> functions = new()
|
private static readonly Dictionary<string, LuaFunction> functions = new()
|
||||||
{
|
{
|
||||||
["getRequestID"] = L_GetRequestId,
|
["getRequestID"] = L_GetRequestId,
|
||||||
|
@ -25,41 +81,29 @@ public class WebSocketClient
|
||||||
["closeAsync"] = L_CloseAsync,
|
["closeAsync"] = L_CloseAsync,
|
||||||
};
|
};
|
||||||
|
|
||||||
public void Push(Lua L)
|
public static Client ToObject(Lua L, bool gc = false)
|
||||||
{
|
{
|
||||||
L.PushObject(this);
|
return ObjectManager.ToObject<Client>(L, 1, gc);
|
||||||
|
}
|
||||||
|
|
||||||
if (L.NewMetaTable(ObjectType))
|
public static Client CheckObject(Lua L, bool gc = false)
|
||||||
|
{
|
||||||
|
var obj = ObjectManager.CheckObject<Client>(L, 1, ObjectType, gc);
|
||||||
|
if (obj is null)
|
||||||
{
|
{
|
||||||
L.PushString("__index");
|
L.Error("attempt to use a closed object");
|
||||||
L.NewTable();
|
return null;
|
||||||
foreach (var pair in functions)
|
|
||||||
{
|
|
||||||
L.PushString(pair.Key);
|
|
||||||
L.PushCFunction(pair.Value);
|
|
||||||
L.SetTable(-3);
|
|
||||||
}
|
|
||||||
L.SetTable(-3);
|
|
||||||
|
|
||||||
L.PushString("__close");
|
|
||||||
L.PushCFunction(L_CloseAsync);
|
|
||||||
L.SetTable(-3);
|
|
||||||
|
|
||||||
L.PushString("__gc");
|
|
||||||
L.PushCFunction(L_CloseAsync);
|
|
||||||
L.SetTable(-3);
|
|
||||||
}
|
}
|
||||||
|
return obj;
|
||||||
L.SetMetaTable(-2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int L_GetRequestId(IntPtr state)
|
private static int L_GetRequestId(IntPtr state)
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
var client = L.CheckObject<WebSocketClient>(1, ObjectType, false);
|
var client = CheckObject(L, false);
|
||||||
|
|
||||||
L.PushInteger(client._requestId);
|
L.PushInteger(client.RequestId);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -68,14 +112,14 @@ public class WebSocketClient
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
var client = L.CheckObject<WebSocketClient>(1, ObjectType, false);
|
var client = CheckObject(L, false);
|
||||||
|
|
||||||
var data = L.CheckBuffer(2);
|
var data = L.CheckBuffer(2);
|
||||||
|
|
||||||
if (client is null || client._socket.State == WebSocketState.Closed)
|
if (client is null || client.Socket.State == WebSocketState.Closed)
|
||||||
L.Error("connection is closed");
|
L.Error("connection is closed");
|
||||||
|
|
||||||
client._socket.SendAsync(data, WebSocketMessageType.Text, true, CancellationToken.None);
|
client.Socket.SendAsync(data, WebSocketMessageType.Text, true, CancellationToken.None);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -84,18 +128,18 @@ public class WebSocketClient
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
var client = L.CheckObject<WebSocketClient>(1, ObjectType, true);
|
var client = ToObject(L, true);
|
||||||
|
|
||||||
if (client is null || client._socket.State == WebSocketState.Closed)
|
if (client is null || client.Socket.State == WebSocketState.Closed)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
client._socket.CloseAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None)
|
client.Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None)
|
||||||
.ContinueWith(async task =>
|
.ContinueWith(async task =>
|
||||||
{
|
{
|
||||||
await task;
|
await task;
|
||||||
Capy64.Instance.LuaRuntime.QueueEvent("websocket_close", LK =>
|
Capy64.Instance.LuaRuntime.QueueEvent("websocket_close", LK =>
|
||||||
{
|
{
|
||||||
LK.PushInteger(client._requestId);
|
LK.PushInteger(client.RequestId);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
@ -105,4 +149,19 @@ public class WebSocketClient
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static unsafe int LM_ToString(IntPtr state)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
var buffer = ToObject(L);
|
||||||
|
if (buffer is not null)
|
||||||
|
{
|
||||||
|
L.PushString("GPUBuffer ({0:X})", (ulong)&buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
L.PushString("GPUBuffer (closed)");
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue