mirror of
https://github.com/clockworklabs/SpacetimeDB.git
synced 2026-05-22 07:32:16 -04:00
120 lines
3.7 KiB
C#
120 lines
3.7 KiB
C#
namespace SpacetimeDB;
|
|
|
|
using System.Runtime.CompilerServices;
|
|
using SpacetimeDB.BSATN;
|
|
using SpacetimeDB.Internal;
|
|
using static System.Text.Encoding;
|
|
|
|
public class ReducerContext
|
|
{
|
|
public readonly Identity Sender;
|
|
public readonly DateTimeOffset Time;
|
|
public readonly Address? Address;
|
|
|
|
internal ReducerContext(
|
|
Identity senderIdentity,
|
|
Address? senderAddress,
|
|
DateTimeOffset timestamp
|
|
)
|
|
{
|
|
Sender = senderIdentity;
|
|
Address = senderAddress;
|
|
Time = timestamp;
|
|
}
|
|
}
|
|
|
|
// [SpacetimeDB.Type] - we have custom representation of time in microseconds, so implementing BSATN manually
|
|
public abstract partial record ScheduleAt
|
|
: SpacetimeDB.TaggedEnum<(DateTimeOffset Time, TimeSpan Interval)>
|
|
{
|
|
public static implicit operator ScheduleAt(DateTimeOffset time) => new Time(time);
|
|
|
|
public static implicit operator ScheduleAt(TimeSpan interval) => new Interval(interval);
|
|
|
|
// Manual expansion of what would be otherwise generated by the [SpacetimeDB.Type] codegen,
|
|
// except we forward to/from a `ScheduleAtRepr` that has the actual generated implementation.
|
|
|
|
private ScheduleAt() { }
|
|
|
|
[SpacetimeDB.Type]
|
|
private partial record ScheduleAtRepr
|
|
: SpacetimeDB.TaggedEnum<(DateTimeOffsetRepr Time, TimeSpanRepr Interval)>;
|
|
|
|
public sealed record Time(DateTimeOffset Time_) : ScheduleAt
|
|
{
|
|
public override void WriteFields(BinaryWriter writer) =>
|
|
new ScheduleAtRepr.Time(new(Time_)).WriteFields(writer);
|
|
}
|
|
|
|
public sealed record Interval(TimeSpan Interval_) : ScheduleAt
|
|
{
|
|
public override void WriteFields(BinaryWriter writer) =>
|
|
new ScheduleAtRepr.Interval(new(Interval_)).WriteFields(writer);
|
|
}
|
|
|
|
public readonly partial struct BSATN : IReadWrite<ScheduleAt>
|
|
{
|
|
private static readonly ScheduleAtRepr.BSATN ReprBSATN = new();
|
|
|
|
public ScheduleAt Read(BinaryReader reader) =>
|
|
ReprBSATN.Read(reader) switch
|
|
{
|
|
ScheduleAtRepr.Time(var timeRepr) => new Time(timeRepr.ToStd()),
|
|
ScheduleAtRepr.Interval(var intervalRepr) => new Interval(intervalRepr.ToStd()),
|
|
_ => throw new SwitchExpressionException(),
|
|
};
|
|
|
|
public void Write(BinaryWriter writer, ScheduleAt value) => value.WriteFields(writer);
|
|
|
|
public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) =>
|
|
// Constructing a custom one instead of ScheduleAtRepr.GetAlgebraicType()
|
|
// to avoid leaking the internal *Repr wrappers in generated SATS.
|
|
new AlgebraicType.Sum(
|
|
[
|
|
new(nameof(Time), new AlgebraicType.U64(default)),
|
|
new(nameof(Interval), new AlgebraicType.U64(default)),
|
|
]
|
|
);
|
|
}
|
|
}
|
|
|
|
public static class Runtime
|
|
{
|
|
public enum LogLevel : byte
|
|
{
|
|
Error,
|
|
Warn,
|
|
Info,
|
|
Debug,
|
|
Trace,
|
|
Panic,
|
|
}
|
|
|
|
public static void Log(
|
|
string text,
|
|
LogLevel level = LogLevel.Info,
|
|
[CallerMemberName] string target = "",
|
|
[CallerFilePath] string filename = "",
|
|
[CallerLineNumber] uint lineNumber = 0
|
|
)
|
|
{
|
|
var target_bytes = UTF8.GetBytes(target);
|
|
var filename_bytes = UTF8.GetBytes(filename);
|
|
var text_bytes = UTF8.GetBytes(text);
|
|
|
|
FFI._console_log(
|
|
(byte)level,
|
|
target_bytes,
|
|
(uint)target_bytes.Length,
|
|
filename_bytes,
|
|
(uint)filename_bytes.Length,
|
|
lineNumber,
|
|
text_bytes,
|
|
(uint)text_bytes.Length
|
|
);
|
|
}
|
|
|
|
// An instance of `System.Random` that is reseeded by each reducer's timestamp.
|
|
public static Random Random { get; internal set; } = new();
|
|
}
|