2022-04-08 05:52:03 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2023-10-13 20:42:22 +00:00
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using MoonTools.ECS.Collections;
|
2022-03-07 07:17:05 +00:00
|
|
|
|
|
2022-04-08 05:52:03 +00:00
|
|
|
|
namespace MoonTools.ECS
|
2022-03-07 07:17:05 +00:00
|
|
|
|
{
|
2022-04-08 05:52:03 +00:00
|
|
|
|
internal abstract class MessageStorage
|
2022-03-07 07:17:05 +00:00
|
|
|
|
{
|
2022-04-08 05:52:03 +00:00
|
|
|
|
public abstract void Clear();
|
2022-03-07 07:17:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 20:42:22 +00:00
|
|
|
|
internal unsafe class MessageStorage<TMessage> : MessageStorage, IDisposable where TMessage : unmanaged
|
2022-03-07 07:17:05 +00:00
|
|
|
|
{
|
2022-04-08 05:52:03 +00:00
|
|
|
|
private int count = 0;
|
|
|
|
|
private int capacity = 128;
|
2023-10-13 20:42:22 +00:00
|
|
|
|
private TMessage* messages;
|
2023-01-10 00:41:00 +00:00
|
|
|
|
// duplicating storage here for fast iteration
|
2023-10-13 20:42:22 +00:00
|
|
|
|
private Dictionary<int, NativeArray<TMessage>> entityToMessages = new Dictionary<int, NativeArray<TMessage>>();
|
|
|
|
|
private bool disposed;
|
2022-04-08 05:52:03 +00:00
|
|
|
|
|
|
|
|
|
public MessageStorage()
|
2022-03-07 07:17:05 +00:00
|
|
|
|
{
|
2023-10-13 20:42:22 +00:00
|
|
|
|
messages = (TMessage*) NativeMemory.Alloc((nuint) (capacity * Unsafe.SizeOf<TMessage>()));
|
2022-03-07 07:17:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-08 05:52:03 +00:00
|
|
|
|
public void Add(in TMessage message)
|
2022-03-18 19:50:59 +00:00
|
|
|
|
{
|
2022-04-08 05:52:03 +00:00
|
|
|
|
if (count == capacity)
|
2022-03-18 19:50:59 +00:00
|
|
|
|
{
|
2022-04-08 05:52:03 +00:00
|
|
|
|
capacity *= 2;
|
2023-10-13 20:42:22 +00:00
|
|
|
|
messages = (TMessage*) NativeMemory.Realloc(messages, (nuint) (capacity * Unsafe.SizeOf<TMessage>()));
|
2022-03-18 19:50:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-08 05:52:03 +00:00
|
|
|
|
messages[count] = message;
|
2023-01-10 00:41:00 +00:00
|
|
|
|
count += 1;
|
|
|
|
|
}
|
2022-03-18 19:50:59 +00:00
|
|
|
|
|
2023-01-10 00:41:00 +00:00
|
|
|
|
public void Add(int entityID, in TMessage message)
|
|
|
|
|
{
|
|
|
|
|
if (!entityToMessages.ContainsKey(entityID))
|
2022-04-08 05:52:03 +00:00
|
|
|
|
{
|
2023-10-13 20:42:22 +00:00
|
|
|
|
entityToMessages.Add(entityID, new NativeArray<TMessage>());
|
2022-04-08 05:52:03 +00:00
|
|
|
|
}
|
2023-01-10 00:41:00 +00:00
|
|
|
|
entityToMessages[entityID].Add(message);
|
2022-03-07 07:17:05 +00:00
|
|
|
|
|
2023-01-10 00:41:00 +00:00
|
|
|
|
Add(message);
|
2022-04-08 05:52:03 +00:00
|
|
|
|
}
|
2022-03-07 07:17:05 +00:00
|
|
|
|
|
2022-04-08 05:52:03 +00:00
|
|
|
|
public bool Some()
|
|
|
|
|
{
|
|
|
|
|
return count > 0;
|
|
|
|
|
}
|
2022-03-16 07:33:38 +00:00
|
|
|
|
|
2022-04-08 05:52:03 +00:00
|
|
|
|
public ReadOnlySpan<TMessage> All()
|
|
|
|
|
{
|
2023-10-13 20:42:22 +00:00
|
|
|
|
return new ReadOnlySpan<TMessage>(messages, count);
|
2022-04-08 05:52:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TMessage First()
|
|
|
|
|
{
|
|
|
|
|
return messages[0];
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-10 00:41:00 +00:00
|
|
|
|
public ReverseSpanEnumerator<TMessage> WithEntity(int entityID)
|
2022-03-18 19:50:59 +00:00
|
|
|
|
{
|
2023-01-10 00:41:00 +00:00
|
|
|
|
if (entityToMessages.TryGetValue(entityID, out var messages))
|
|
|
|
|
{
|
|
|
|
|
return messages.GetEnumerator();
|
|
|
|
|
}
|
|
|
|
|
else
|
2022-03-18 19:50:59 +00:00
|
|
|
|
{
|
2023-01-10 00:41:00 +00:00
|
|
|
|
return ReverseSpanEnumerator<TMessage>.Empty;
|
2022-03-18 19:50:59 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-08 05:52:03 +00:00
|
|
|
|
public ref readonly TMessage FirstWithEntity(int entityID)
|
|
|
|
|
{
|
2023-01-10 00:41:00 +00:00
|
|
|
|
return ref entityToMessages[entityID][0];
|
2022-04-08 05:52:03 +00:00
|
|
|
|
}
|
2022-03-18 19:50:59 +00:00
|
|
|
|
|
2022-04-08 05:52:03 +00:00
|
|
|
|
public bool SomeWithEntity(int entityID)
|
|
|
|
|
{
|
2023-01-10 00:41:00 +00:00
|
|
|
|
return entityToMessages.ContainsKey(entityID) && entityToMessages[entityID].Count > 0;
|
2022-04-08 05:52:03 +00:00
|
|
|
|
}
|
2022-03-18 19:50:59 +00:00
|
|
|
|
|
2022-04-08 05:52:03 +00:00
|
|
|
|
public override void Clear()
|
2022-03-18 19:50:59 +00:00
|
|
|
|
{
|
2022-04-08 05:52:03 +00:00
|
|
|
|
count = 0;
|
2023-01-10 00:41:00 +00:00
|
|
|
|
foreach (var set in entityToMessages.Values)
|
2022-04-08 05:52:03 +00:00
|
|
|
|
{
|
|
|
|
|
set.Clear();
|
|
|
|
|
}
|
2022-03-18 19:50:59 +00:00
|
|
|
|
}
|
2023-10-13 20:42:22 +00:00
|
|
|
|
|
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
|
|
|
{
|
|
|
|
|
if (!disposed)
|
|
|
|
|
{
|
|
|
|
|
Clear();
|
|
|
|
|
|
|
|
|
|
if (disposing)
|
|
|
|
|
{
|
|
|
|
|
foreach (var array in entityToMessages.Values)
|
|
|
|
|
{
|
|
|
|
|
array.Dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NativeMemory.Free(messages);
|
|
|
|
|
messages = null;
|
|
|
|
|
|
|
|
|
|
disposed = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~MessageStorage()
|
|
|
|
|
{
|
|
|
|
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
|
|
|
|
Dispose(disposing: false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
|
|
|
|
Dispose(disposing: true);
|
|
|
|
|
GC.SuppressFinalize(this);
|
|
|
|
|
}
|
2022-03-07 07:17:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|