/// <summary> /// add a command /// </summary> /// <param name="commandid">command id</param> /// <param name="deserialize"></param> public void AddCommand(uint commandid, DeserializePacketHandler <object> deserialize) { if (commandid > Constants.USER_COMMAND_LIMIT) { throw new ArgumentOutOfRangeException( $"{nameof(commandid)} is restricted to 0 - {Constants.USER_COMMAND_LIMIT}"); } if (deserialize == null) { throw new ArgumentNullException(nameof(deserialize)); } bool lockTaken = false; try { _dataReceivedCallbacksLock.Enter(ref lockTaken); if (!_dataReceivedCallbacks.TryGetValue(commandid, out ClientEventEntry buffer)) { buffer = new ClientEventEntry(deserialize); _dataReceivedCallbacks.Add(commandid, buffer); } } finally { if (lockTaken) { _dataReceivedCallbacksLock.Exit(false); } } }
internal static ServerClientEventEntry <TServerClient> Create <T>(DeserializePacketHandler <T> deserialize) { ServerClientEventEntry <TServerClient, T> entry = new ServerClientEventEntry <TServerClient, T>(); entry._deserializeAndRaise = (in Packet packet, IServer <TServerClient> server, TServerClient client, ushort responseID, out object?result) => { if (deserialize(in packet, out T value)) { ByteArrayPool.Return(packet.Buffer); entry.Raise(server, client, value, responseID); // ReSharper disable once HeapView.PossibleBoxingAllocation result = value; return(true); } ByteArrayPool.Return(packet.Buffer); result = null; return(false); }; return(entry); }
/// <inheritdoc /> public async Task <Response <TResult> > SendR <TResult>(uint commandid, byte[] data, int offset, int length, DeserializePacketHandler <TResult> deserialize, TimeSpan timeout) { if (deserialize == null) { throw new ArgumentNullException(nameof(deserialize)); } TaskCompletionSource <Packet> tcs = new TaskCompletionSource <Packet>(TaskCreationOptions.None); using (CancellationTokenSource cts = new CancellationTokenSource(timeout)) { uint responseID; bool lockTaken = false; try { _lockTaskCompletionSources.Enter(ref lockTaken); responseID = _responseID++; if (responseID == 0) { responseID++; } _taskCompletionSources.Add(responseID, tcs); } finally { if (lockTaken) { _lockTaskCompletionSources.Exit(false); } } cts.Token.Register( delegate { bool lockTaken1 = false; try { _lockTaskCompletionSources.Enter(ref lockTaken1); _taskCompletionSources.Remove(_responseID); } finally { if (lockTaken1) { _lockTaskCompletionSources.Exit(false); } } tcs.TrySetResult(default);
/// <inheritdoc /> public Task <Response <TResult> > SendR <TResult>(uint commandid, byte[] data, int offset, int length, DeserializePacketHandler <TResult> deserialize) { return(SendR(commandid, data, offset, length, deserialize, s_defaultTimeout)); }
/// <summary> /// Initializes a new instance of the <see cref="ClientEventEntry" /> class. /// </summary> /// <param name="deserialize"> The deserialize. </param> public ClientEventEntry(DeserializePacketHandler <object> deserialize) { _dataReceived = new Event <DataReceivedHandler>(); _deserialize = deserialize; }
/// <summary> /// Initializes a new instance of the <see cref="ServerClientEventEntry{TServerClient}" /> class. /// </summary> /// <param name="deserialize"> The deserialize. </param> public ServerClientEventEntry(DeserializePacketHandler <object> deserialize) { _deserialize = deserialize; _dataReceived = new Event <ClientDataReceivedHandler <TServerClient> >(); }