Extend RpcCallback

thumb
Identextend.extend_rpc
Typelibrary
Created
Updated
Latest Version 115931 27.6 KB ~7
Links s&box
SummaryAsync RPC Callback for s&box – Call server methods with await, [RpcCallback] handles the round-trip automatically.
Description
# Extend RPC Library A library for **s&box** that makes it easy to send RPC calls and receive **asynchronous callbacks**. It simplifies **client ↔ server** communication while taking full advantage of async/await. ## 🚀 Features - Asynchronous RPC calls - Receive callbacks using `async/await` - Simplified error and timeout handling - Supported return types: ✅ **Primitives** (int, float, bool, string, etc.) ✅ **structs** ✅ **records** ✅ **List<>** ## 📦 Installation Clone or download this repository and add its content directly into your **s&box** project at Libraries/extend.extend_rpc folder. ## 🛠 Basic Usage Example [RpcCallback] public async Task<int> Compute(int a, int b) { return a + b; } protected override void OnStart() { Task.RunInThreadAsync(async () => { var result = await Compute(1, 4); Log.Info("Result is: " + result); }); } ## 🛠 List Usage Example [RpcCallback] public async Task<List<int>> Compute(int a, int b) { return [a + b]; } protected override void OnStart() { Task.RunInThreadAsync(async () => { var results = await Compute(1, 4); Log.Info("Result is: " + string.Join(", ", results)); }); } ## 🛠 Using a struct as return type protected override void OnStart() { Task.RunInThreadAsync(async () => { var stats = await GetPlayerStats("Player_42"); Log.Info($"Kills: {stats.Kills}, Deaths: {stats.Deaths}, Accuracy: {stats.Accuracy}"); }); } [RpcCallback] public async Task<PlayerStats> GetPlayerStats(string playerId) { // Simulate database fetch await Task.Delay(100); return new PlayerStats { Kills = 10, Deaths = 3, Accuracy = 0.75f }; } public struct PlayerStats { public int Kills { get; set; } public int Deaths { get; set; } public float Accuracy { get; set; } } ## 🛠 Using a record as return type // Primary constructors are not supported yet when serializing / deserializing in s&box public record InventoryItem( string Name, int Quantity ); // Instead, use this way public record InventoryItem { public string Name { get; set; } public int Quantity { get; set; } public InventoryItem( string name, int quantity ) { Name = name; Quantity = quantity; } } [RpcCallback] public async Task<InventoryItem> GetInventoryItem(string itemId) { await Task.Delay(50); return new InventoryItem("Health Potion", 5); } protected override void OnStart() { Task.RunInThreadAsync(async () => { var item = await GetInventoryItem("potion_health"); Log.Info($"Item: {item.Name}, Quantity: {item.Quantity}"); }); } ## ⚙️ How it works Functions marked with the [RpcCallback] attribute are **wrapped automatically**. When you call them: 1. The wrapper sends an **RPC to the server**. 2. The server executes the **original method**. 3. The return value is captured. 4. Another **RPC is sent back to the caller (client)** with the result. This makes it possible to await the call just like a local async function. The caller receives the result as a Task<T> (async/await). Any return type is supported as long as it’s a primitive, a struct, or a record that can be serialized. Collections (List<T>, arrays, etc.) are also supported if T is a valid type. The library handles serialization, network transport, and automatic value return. Configurable timeout (default: 5s). ## 📖 Quick Reference [RpcCallback] → Marks a method as an asynchronous RPC. Task.RunInThreadAsync(...) → Runs a task outside the main game thread. Exceptions are automatically propagated back to the caller. ## 🤝 Contributing Pull Requests are welcome! Please follow C# best practices. Unit tests is optional.
# Extend RPC Library A library for **s&box** that makes it easy to send RPC calls and receive **asynchronous callbacks**. It simplifies **client ↔ server** communication while taking full advantage of async/await. ## 🚀 Features - Asynchronous RPC calls - Receive callbacks using `async/await` - Simplified error and timeout handling - Supported return types: ✅ **Primitives** (int, float, bool, string, etc.) ✅ **structs** ✅ **records** ✅ **List<>** ## 📦 Installation Clone or download this repository and add its content directly into your **s&box** project at Libraries/extend.extend_rpc folder. ## 🛠 Basic Usage Example [RpcCallback] public async Task<int> Compute(int a, int b) { return a + b; } protected override void OnStart() { Task.RunInThreadAsync(async () => { var result = await Compute(1, 4); Log.Info("Result is: " + result); }); } ## 🛠 List Usage Example [RpcCallback] public async Task<List<int>> Compute(int a, int b) { return [a + b]; } protected override void OnStart() { Task.RunInThreadAsync(async () => { var results = await Compute(1, 4); Log.Info("Result is: " + string.Join(", ", results)); }); } ## 🛠 Using a struct as return type protected override void OnStart() { Task.RunInThreadAsync(async () => { var stats = await GetPlayerStats("Player_42"); Log.Info($"Kills: {stats.Kills}, Deaths: {stats.Deaths}, Accuracy: {stats.Accuracy}"); }); } [RpcCallback] public async Task<PlayerStats> GetPlayerStats(string playerId) { // Simulate database fetch await Task.Delay(100); return new PlayerStats { Kills = 10, Deaths = 3, Accuracy = 0.75f }; } public struct PlayerStats { public int Kills { get; set; } public int Deaths { get; set; } public float Accuracy { get; set; } } ## 🛠 Using a record as return type // Primary constructors are not supported yet when serializing / deserializing in s&box public record InventoryItem( string Name, int Quantity ); // Instead, use this way public record InventoryItem { public string Name { get; set; } public int Quantity { get; set; } public InventoryItem( string name, int quantity ) { Name = name; Quantity = quantity; } } [RpcCallback] public async Task<InventoryItem> GetInventoryItem(string itemId) { await Task.Delay(50); return new InventoryItem("Health Potion", 5); } protected override void OnStart() { Task.RunInThreadAsync(async () => { var item = await GetInventoryItem("potion_health"); Log.Info($"Item: {item.Name}, Quantity: {item.Quantity}"); }); } ## ⚙️ How it works Functions marked with the [RpcCallback] attribute are **wrapped automatically**. When you call them: 1. The wrapper sends an **RPC to the server**. 2. The server executes the **original method**. 3. The return value is captured. 4. Another **RPC is sent back to the caller (client)** with the result. This makes it possible to await the call just like a local async function. The caller receives the result as a Task<T> (async/await). Any return type is supported as long as it’s a primitive, a struct, or a record that can be serialized. Collections (List<T>, arrays, etc.) are also supported if T is a valid type. The library handles serialization, network transport, and automatic value return. Configurable timeout (default: 5s). ## 📖 Quick Reference [RpcCallback] → Marks a method as an asynchronous RPC. Task.RunInThreadAsync(...) → Runs a task outside the main game thread. Exceptions are automatically propagated back to the caller. ## 🤝 Contributing Pull Requests are welcome! Please follow C# best practices. Unit tests is optional.
Votes 0 0 0
Error Rate0%
Data
{}