using System.Diagnostics; using System.Runtime.InteropServices; namespace Djup.Native; [StructLayout(LayoutKind.Sequential)] public struct EntityId { public int Id { get; } public static readonly EntityId Invalid = new(-1); public EntityId(int id) { Id = id; } public bool IsInvalid => Id < 0; public override string ToString() => $"#{Id}"; public override bool Equals(object? other) { if (other is EntityId id) { return this == id; } return false; } public override int GetHashCode() => Id.GetHashCode(); public static bool operator ==(EntityId a, EntityId b) { if (a < 0) return b < 0; if (b < 0) return false; return a.Id == b.Id; } public static bool operator !=(EntityId a, EntityId b) => !(a == b); public static implicit operator int(EntityId entityId) => entityId.Id; public static implicit operator EntityId(int id) => new(id); } public enum Component : int { Exists, Ball, PlayerInput } [Flags] public enum Components : int { Exists = 1 << Component.Exists, Ball = 1 << Component.Ball, PlayerInput = 1 << Component.PlayerInput } [StructLayout(LayoutKind.Sequential)] public unsafe struct OdinSlice { public void* Data { get; } public nint Len { get; } public Span AsSpan() => new Span(Data, Len.ToInt32()); public ReadOnlySpan AsReadOnlySpan() => new ReadOnlySpan(Data, Len.ToInt32()); } [StructLayout(LayoutKind.Sequential)] public unsafe struct OdinString { public sbyte* Data { get; } public nint Len { get; } public override string ToString() => new string(Data, 0, Len.ToInt32()); } [StructLayout(LayoutKind.Sequential)] public struct Vec2 { public float X { get; set; } public float Y { get; set; } public Vec2(float x, float y) { Debug.Assert(float.IsFinite(x)); Debug.Assert(float.IsFinite(y)); X = x; Y = y; } public override string ToString() => $"({X}, {Y})"; } [StructLayout(LayoutKind.Sequential)] public struct Ball { public Vec2 Position { get; set; } public Vec2 Velocity { get; set; } } [StructLayout(LayoutKind.Sequential)] public struct PlayerInput { public Vec2 Direction { get; set; } } [StructLayout(LayoutKind.Sequential)] public struct Snapshot { private readonly byte active; public uint Tick { get; } public OdinSlice Metadata { get; } public OdinSlice Balls { get; } public OdinSlice PlayerInputs { get; } private IntPtr ctx; } public enum LogLevel { Debug, Info, Warn, Error, Fatal } public delegate void LoggerDelegate(LogLevel level, OdinString message, OdinString procedure, OdinString file, int line); public delegate void AssertDelegate(OdinString prefix, OdinString message, OdinString procedure, OdinString file, int line);