2020-03-22 20:41:55 +00:00
|
|
|
using System;
|
2019-12-06 20:01:56 +00:00
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
namespace Encompass
|
|
|
|
{
|
|
|
|
internal abstract class TypedMessageStore
|
|
|
|
{
|
|
|
|
public abstract void ProcessDelayedMessages(double dilatedDelta, double realtimeDelta);
|
|
|
|
public abstract void Clear();
|
|
|
|
}
|
|
|
|
|
2021-02-05 03:39:58 +00:00
|
|
|
internal class TypedMessageStore<TMessage> : TypedMessageStore where TMessage : struct
|
2019-12-06 20:01:56 +00:00
|
|
|
{
|
2020-03-22 20:41:55 +00:00
|
|
|
// messages are placed in a contiguous region
|
|
|
|
// so we can return the collection as a Span
|
|
|
|
private int _nextIndex = 0;
|
2020-03-22 23:07:58 +00:00
|
|
|
private TMessage[] _store = new TMessage[128];
|
2020-03-20 07:09:57 +00:00
|
|
|
private readonly List<(TMessage, double)> _delayedStore = new List<(TMessage, double)>(128);
|
|
|
|
private readonly List<(TMessage, double)> _delayedStoreIgnoringTimeDilation = new List<(TMessage, double)>(128);
|
2020-03-22 20:53:23 +00:00
|
|
|
private readonly Dictionary<int, List<int>> _entityToIndices = new Dictionary<int, List<int>>();
|
2019-12-06 20:01:56 +00:00
|
|
|
|
|
|
|
public override void ProcessDelayedMessages(double dilatedDelta, double realtimeDelta)
|
|
|
|
{
|
2020-03-20 07:09:57 +00:00
|
|
|
for (var i = _delayedStore.Count - 1; i >= 0; i--)
|
2019-12-06 20:01:56 +00:00
|
|
|
{
|
2020-03-20 07:09:57 +00:00
|
|
|
var (message, time) = _delayedStore[i];
|
2019-12-06 20:01:56 +00:00
|
|
|
|
|
|
|
var updatedTime = time - dilatedDelta;
|
|
|
|
|
|
|
|
if (updatedTime <= 0)
|
|
|
|
{
|
|
|
|
Add(message);
|
2020-03-20 07:09:57 +00:00
|
|
|
_delayedStore.RemoveAt(i);
|
2019-12-06 20:01:56 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-03-20 07:09:57 +00:00
|
|
|
_delayedStore[i] = (message, updatedTime);
|
2019-12-06 20:01:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-20 07:09:57 +00:00
|
|
|
for (var i = _delayedStoreIgnoringTimeDilation.Count - 1; i >= 0; i--)
|
2019-12-06 20:01:56 +00:00
|
|
|
{
|
2020-03-20 07:09:57 +00:00
|
|
|
var (message, time) = _delayedStoreIgnoringTimeDilation[i];
|
2019-12-06 20:01:56 +00:00
|
|
|
|
|
|
|
var updatedTime = time - realtimeDelta;
|
|
|
|
|
|
|
|
if (updatedTime <= 0)
|
|
|
|
{
|
|
|
|
Add(message);
|
2020-03-20 07:09:57 +00:00
|
|
|
_delayedStoreIgnoringTimeDilation.RemoveAt(i);
|
2019-12-06 20:01:56 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-03-20 07:09:57 +00:00
|
|
|
_delayedStoreIgnoringTimeDilation[i] = (message, updatedTime);
|
2019-12-06 20:01:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-22 19:12:26 +00:00
|
|
|
public void Add(in TMessage message)
|
2019-12-06 20:01:56 +00:00
|
|
|
{
|
2020-03-22 20:41:55 +00:00
|
|
|
var index = _nextIndex++;
|
2020-03-22 23:07:58 +00:00
|
|
|
if (index >= _store.Length)
|
|
|
|
{
|
|
|
|
Array.Resize(ref _store, _store.Length * 2);
|
|
|
|
}
|
2020-03-22 19:12:26 +00:00
|
|
|
_store[index] = message;
|
2019-12-30 04:36:23 +00:00
|
|
|
if (message is IHasEntity entityMessage)
|
|
|
|
{
|
|
|
|
var entityID = entityMessage.Entity.ID;
|
2020-03-22 20:53:23 +00:00
|
|
|
if (!_entityToIndices.ContainsKey(entityID)) { _entityToIndices.Add(entityID, new List<int>()); }
|
2020-03-22 19:12:26 +00:00
|
|
|
_entityToIndices[entityID].Add(index);
|
2019-12-30 04:36:23 +00:00
|
|
|
}
|
2019-12-06 20:01:56 +00:00
|
|
|
}
|
|
|
|
|
2020-03-22 19:12:26 +00:00
|
|
|
public void Add(in TMessage message, double time)
|
2019-12-06 20:01:56 +00:00
|
|
|
{
|
2020-03-20 07:09:57 +00:00
|
|
|
_delayedStore.Add((message, time));
|
2019-12-06 20:01:56 +00:00
|
|
|
}
|
|
|
|
|
2020-03-22 19:12:26 +00:00
|
|
|
public void AddIgnoringTimeDilation(in TMessage message, double time)
|
2019-12-06 20:01:56 +00:00
|
|
|
{
|
2020-03-20 07:09:57 +00:00
|
|
|
_delayedStoreIgnoringTimeDilation.Add((message, time));
|
2019-12-06 20:01:56 +00:00
|
|
|
}
|
|
|
|
|
2020-03-22 21:20:22 +00:00
|
|
|
public ref readonly TMessage First()
|
2019-12-06 20:01:56 +00:00
|
|
|
{
|
2020-03-22 21:20:22 +00:00
|
|
|
return ref _store[0];
|
2019-12-06 20:01:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public bool Any()
|
|
|
|
{
|
2020-03-22 20:41:55 +00:00
|
|
|
return _nextIndex != 0;
|
2019-12-06 20:01:56 +00:00
|
|
|
}
|
|
|
|
|
2020-11-16 07:21:51 +00:00
|
|
|
public ReadOnlySpan<TMessage> All()
|
2019-12-06 20:01:56 +00:00
|
|
|
{
|
2020-11-16 07:21:51 +00:00
|
|
|
return new ReadOnlySpan<TMessage>(_store, 0, _nextIndex);
|
2019-12-06 20:01:56 +00:00
|
|
|
}
|
|
|
|
|
2019-12-30 04:36:23 +00:00
|
|
|
public IEnumerable<TMessage> WithEntity(int entityID)
|
|
|
|
{
|
2020-03-22 19:12:26 +00:00
|
|
|
if (_entityToIndices.ContainsKey(entityID))
|
|
|
|
{
|
|
|
|
foreach (var index in _entityToIndices[entityID])
|
|
|
|
{
|
|
|
|
yield return _store[index];
|
|
|
|
}
|
|
|
|
}
|
2019-12-30 04:36:23 +00:00
|
|
|
}
|
|
|
|
|
2020-03-22 20:53:23 +00:00
|
|
|
public ref readonly TMessage FirstWithEntity(int entityID)
|
|
|
|
{
|
|
|
|
return ref _store[_entityToIndices[entityID][0]];
|
|
|
|
}
|
|
|
|
|
2020-01-13 22:59:18 +00:00
|
|
|
public bool SomeWithEntity(int entityID)
|
|
|
|
{
|
2020-03-22 19:12:26 +00:00
|
|
|
return _entityToIndices.ContainsKey(entityID) && _entityToIndices[entityID].Count > 0;
|
2020-01-13 22:59:18 +00:00
|
|
|
}
|
|
|
|
|
2019-12-06 20:01:56 +00:00
|
|
|
public override void Clear()
|
|
|
|
{
|
2020-03-22 20:41:55 +00:00
|
|
|
_nextIndex = 0;
|
2020-03-22 19:12:26 +00:00
|
|
|
foreach (var set in _entityToIndices.Values)
|
2019-12-30 04:36:23 +00:00
|
|
|
{
|
|
|
|
set.Clear();
|
|
|
|
}
|
2019-12-06 20:01:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|