Papaltine.ResoniteLink.RPath
0.3.0
dotnet add package Papaltine.ResoniteLink.RPath --version 0.3.0
NuGet\Install-Package Papaltine.ResoniteLink.RPath -Version 0.3.0
<PackageReference Include="Papaltine.ResoniteLink.RPath" Version="0.3.0" />
<PackageVersion Include="Papaltine.ResoniteLink.RPath" Version="0.3.0" />
<PackageReference Include="Papaltine.ResoniteLink.RPath" />
paket add Papaltine.ResoniteLink.RPath --version 0.3.0
#r "nuget: Papaltine.ResoniteLink.RPath, 0.3.0"
#:package Papaltine.ResoniteLink.RPath@0.3.0
#addin nuget:?package=Papaltine.ResoniteLink.RPath&version=0.3.0
#tool nuget:?package=Papaltine.ResoniteLink.RPath&version=0.3.0
RPath
A query EDSL that allows querying ResoniteLink with more ergonomic operations. Similar in style to LINQ to XML with some differences.
Usage from C# follows a similar pattern to LINQ where you utilize a special type (called RPathBuilder<T> here), and
you perform operations by calling extension methods defined on the type. They can be chained together and composed to
form more complex queries.
using ResoniteLink;
using ResoniteLink.RPath;
// Setup (same as normal)
Console.Write("Connect to (localhost port or ws:// URL): ");
var connectionTarget = Console.ReadLine().Trim();
Uri targetUrl;
if (int.TryParse(connectionTarget, out var port))
{
targetUrl = new Uri($"ws://localhost:{port}");
}
else if (!Uri.TryCreate(connectionTarget, UriKind.Absolute, out targetUrl))
{
Console.WriteLine("Failed to parse URL");
return 1;
}
if (targetUrl.Scheme != "ws")
{
Console.WriteLine("Scheme must be ws (websocket)");
return 1;
}
var link = new LinkInterface();
await link.Connect(targetUrl, CancellationToken.None);
// build and execute query
var query = await link.RPath() // start at root
.Children() // get direct children (egarly fetch component data too)
.Where(x => x.Name.Value == "TestSlot") // filter children with this name
.Components() // get the components for the filtered children
.OfType("FrooxEngine.ReferenceField<FrooxEngine.Slot>") // filter components with the right type
.Member<Reference>("Reference") // get the Reference field and cast to correct type
.DereferenceSlot() // Follow Reference to the slot it points to
.AncestorsShallow() // Get all the parents up to root (no component data)
.Select(x => x.Name.Value) // Get the names from the slots
// .ToListAsync(); // throws exception on error instead of packaging as a result
.ToResultAsync();
// check result
if (query.IsOk)
{
Console.WriteLine("Success!");
Console.WriteLine(string.Join('\n', query.ResultValue.ToArray()));
return 0;
}
else
{
Console.WriteLine("Error!");
Console.WriteLine($"Error: {query.ErrorValue.Message}");
return 1;
}
Items to note
- On demand: It will communicate with ResoniteLink to explore the hierarchy as it needs to.
- No batching of requests: Each request for data is a separate request, so queries that require many fetches of new data will have high latency
- Immutable and composable: when calling a method on the builder a new one is returned instead of modifying the current instance. You can use this to reuse parts of queries to create more complex behavior.
- .NET Standard 2.0: compatible with .NET and .NET Framework (Unity)
FSharp API
The underlying API is implemented in F#, and that API can be utilized directly as well. You can consume the library in multiple ways depending on your preference (including using the extension methods like C#).
One notable difference is that with F# API you define queries without providing the LinkInterface until you want to execute the query (called point free style).
// Using the pipe operator
let nodesPipe =
root
|> bind childrenDeep
|> filter (fun x -> x.Name.Value = "TestSlot")
|> bind components
|> ofType "FrooxEngine.ReferenceField<FrooxEngine.Slot>"
|> getMember<Reference> "Reference"
|> bind dereferenceSlotShallow
|> bind ancestorsShallow
|> map _.Name.Value
|> toArray
|> run link
// Some special operators (>>=/bind and >=>/Kleisli) can be used for extra terseness
// The >>= indicates clearly where new data is fetched from the data model
// |> is an in-memory operation
let nodesOperators =
root
>>= childrenDeep
|> filter (fun x -> x.Name.Value = "TestSlot")
>>= components
|> ofType "FrooxEngine.ReferenceField<FrooxEngine.Slot>"
|> getMember<Reference> "Reference"
>>= dereferenceSlotShallow
>>= ancestorsShallow
|> map _.Name.Value
|> toArray
|> runAsync link
// C# style extension methods
let nodesExtensions =
link
.RPath()
.Children()
.Where(fun x -> x.Name.Value = "TestSlot")
.Components()
.OfType("FrooxEngine.ReferenceField<FrooxEngine.Slot>")
.Member<Reference>("Reference")
.DereferenceSlot()
.AncestorsShallow()
.Select(_.Name.Value)
.ToListAsync()
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- FParsec (>= 1.1.1)
- FSharp.Core (>= 10.0.103)
- YellowDogMan.ResoniteLink (>= 0.9.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.3.0 | 87 | 3/9/2026 |