1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
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<T>
{
public void* Data { get; }
public nint Len { get; }
public Span<T> AsSpan() => new Span<T>(Data, Len.ToInt32());
public ReadOnlySpan<T> AsReadOnlySpan() => new ReadOnlySpan<T>(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<Components> Metadata { get; }
public OdinSlice<Ball> Balls { get; }
public OdinSlice<PlayerInput> 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);
|