Files
2024-08-21 16:21:45 +00:00

119 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)>
{
// Manual expansion of what would be otherwise generated by the [SpacetimeDB.Type] codegen.
public sealed record Time(DateTimeOffset Time_) : ScheduleAt;
public sealed record Interval(TimeSpan Interval_) : ScheduleAt;
public static implicit operator ScheduleAt(DateTimeOffset time) => new Time(time);
public static implicit operator ScheduleAt(TimeSpan interval) => new Interval(interval);
public readonly partial struct BSATN : IReadWrite<ScheduleAt>
{
[SpacetimeDB.Type]
private partial record ScheduleAtRepr
: SpacetimeDB.TaggedEnum<(DateTimeOffsetRepr Time, TimeSpanRepr Interval)>;
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)
{
ReprBSATN.Write(
writer,
value switch
{
Time(var time) => new ScheduleAtRepr.Time(new(time)),
Interval(var interval) => new ScheduleAtRepr.Interval(new(interval)),
_ => throw new SwitchExpressionException(),
}
);
}
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("Time", new AlgebraicType.U64(default)),
new("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();
}