mirror of
https://github.com/clockworklabs/SpacetimeDB.git
synced 2026-05-13 11:17:50 -04:00
3340ceea8a
Signed-off-by: Mazdak Farrokhzad <twingoow@gmail.com> Signed-off-by: joshua-spacetime <josh@clockworklabs.io> Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
37 lines
2.9 KiB
Markdown
37 lines
2.9 KiB
Markdown
# SpacetimeDB.Codegen
|
|
|
|
This project contains Roslyn [incremental source generators](https://github.com/dotnet/roslyn/blob/main/docs/features/incremental-generators.md) that augment types and tables with static methods for self-describing and registration. They look for different attributes to know which types to augment:
|
|
|
|
- `[SpacetimeDB.Type]` - generates a `GetSatsTypeInfo()` static method that registers this type with the runtime and returns a `TypeInfo` object. It supports only `struct`s for now to explicitly forbid infinitely recursive types and to make the implementation simpler, as it doesn't need to deal with type references - each table is registered as an entirely self-contained type together with its nested structs if any. This is unlikely to be a problem in common scenarios, but it will be optimised in the future.
|
|
|
|
All the nested fields will be added to the product type. Because it's not possible to implement static extension methods on 3rd-party types (including built-ins) in C#, the codegen is responsible for manually routing different types to their `TypeInfo` descriptors. See various static `TypeInfo` properties and helper methods on `SpacetimeDB.BSATN.AlgebraicType` (`Runtime/AlgebraicType.cs`) and routing logic in `Utils.GetTypeInfo` (`Codegen/Utils.cs`) for more details.
|
|
|
|
Also, for the same reason - absence of static extension methods in C# - the codegen expects that your struct, as well as any of its parents, is `partial` so methods can be added from extra source files generated by the codegen.
|
|
|
|
- `[SpacetimeDB.Type]` - also supports emulation of tagged enums in C#. For that, the struct needs to inherit a marker interface `SpacetimeDB.TaggedEnum<Variants>` where `Variants` is a named tuple of all possible variants, e.g.:
|
|
|
|
```csharp
|
|
[SpacetimeDB.Type]
|
|
partial record Option<T> : SpacetimeDB.TaggedEnum<(T Some, Unit None)>;
|
|
```
|
|
|
|
will generate inherited records `Option.Some(T Some_)` and `Option.None(Unit None_)`. It allows
|
|
you to use tagged enums in C# in a similar way to Rust enums by leveraging C# pattern-matching
|
|
on any instance of `Option<T>`.
|
|
|
|
- `[SpacetimeDB.Table]` - generates code to register this table in the `FFI` upon startup so that they can be enumerated by the `__describe_module__` FFI API. It implies `[SpacetimeDB.Type]`, so you must not specify both attributes on the same struct.
|
|
|
|
The fields can be marked with `[SpacetimeDB.ColumnAttrs]` and those will be detected by the codegen and passed on to the runtime as well. Example:
|
|
|
|
```csharp
|
|
[SpacetimeDB.Table]
|
|
public partial struct Person
|
|
{
|
|
[SpacetimeDB.Column(ColumnAttrs.Identity)]
|
|
public int Id;
|
|
public string Name;
|
|
}
|
|
```
|
|
|
|
- `[SpacetimeDB.Reducer]` - generates code to register a static function as a SpacetimeDB reducer in the `FFI` upon startup and creates a wrapper that will parse SATS binary blob into individual arguments and invoke the underlying function for the `__call_reducer__` FFI API.
|