Add support for data collection events

This commit is contained in:
Jet the Hawk 2023-03-01 16:00:08 -05:00
parent 607bcb06d5
commit 4b9a9bb78f
13 changed files with 262 additions and 6 deletions

View file

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
namespace Core.DataManagement
{
public class CreateEvent
{
public delegate void CreateCallback<TDataElement>(TDataElement subject)
where TDataElement : struct, IDataWithId;
private Dictionary<Type, List<object>> invocationLists = new Dictionary<Type, List<object>>();
public void AddCallback<TDataElement>(CreateCallback<TDataElement> callback)
where TDataElement : struct, IDataWithId
{
Type type = typeof(TDataElement);
if (!invocationLists.TryGetValue(type, out List<object> invocationList))
{
invocationList = new List<object>();
invocationLists.Add(type, invocationList);
}
invocationList.Add(callback);
}
public void RemoveCallback<TDataElement>(CreateCallback<TDataElement> callback)
where TDataElement : struct, IDataWithId
{
Type type = typeof(TDataElement);
if (!invocationLists.TryGetValue(type, out List<object> invocationList))
return;
invocationList.Remove(callback);
if (invocationList.Count == 0)
invocationLists.Remove(type);
}
public void Invoke<TDataElement>(TDataElement data)
where TDataElement : struct, IDataWithId
{
Type type = typeof(TDataElement);
if (!invocationLists.TryGetValue(type, out List<object> invocationList))
return;
foreach (object invocation in invocationList)
{
if (invocation is CreateCallback<TDataElement> callback)
callback(data);
}
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 495862aaa58f4f9d957f43e26ba8c98e
timeCreated: 1677703541

View file

@ -0,0 +1,48 @@
namespace Core.DataManagement
{
public class DataCallbacks
{
private readonly DataEventDispatcher eventDispatcher;
public DataCallbacks(DataEventDispatcher eventDispatcher)
{
this.eventDispatcher = eventDispatcher;
}
public void AddCreateCallback<TDataElement>(CreateEvent.CreateCallback<TDataElement> callback)
where TDataElement : struct, IDataWithId
{
eventDispatcher.Create.AddCallback(callback);
}
public void RemoveCreateCallback<TDataElement>(CreateEvent.CreateCallback<TDataElement> callback)
where TDataElement : struct, IDataWithId
{
eventDispatcher.Create.RemoveCallback(callback);
}
public void AddDeleteCallback<TDataElement>(DeleteEvent.DeleteCallback<TDataElement> callback)
where TDataElement : struct, IDataWithId
{
eventDispatcher.Delete.AddCallback(callback);
}
public void RemoveDeleteCallback<TDataElement>(DeleteEvent.DeleteCallback<TDataElement> callback)
where TDataElement : struct, IDataWithId
{
eventDispatcher.Delete.RemoveCallback(callback);
}
public void AddModifyCallback<TDataElement>(ModifyEvent.ModifyCallback<TDataElement> callback)
where TDataElement : struct, IDataWithId
{
eventDispatcher.Modify.AddCallback(callback);
}
public void RemoveModifyCallback<TDataElement>(ModifyEvent.ModifyCallback<TDataElement> callback)
where TDataElement : struct, IDataWithId
{
eventDispatcher.Modify.RemoveCallback(callback);
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 89d5f9a513ce4caf927d5a9647d715af
timeCreated: 1677703541

View file

@ -0,0 +1,13 @@
namespace Core.DataManagement
{
public class DataEventDispatcher
{
private readonly CreateEvent createEvent = new CreateEvent();
private readonly DeleteEvent deleteEvent = new DeleteEvent();
private readonly ModifyEvent modifyEvent = new ModifyEvent();
public CreateEvent Create => createEvent;
public DeleteEvent Delete => deleteEvent;
public ModifyEvent Modify => modifyEvent;
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c9d98f982b6a4fdba2c4e406cdac0412
timeCreated: 1677703541

View file

@ -12,6 +12,7 @@ namespace Core.DataManagement
private UniqueIntGenerator instanceIdGenerator;
private List<TDataElement> dataElements = new List<TDataElement>();
private Dictionary<ObjectId, int> dataIndexMap = new Dictionary<ObjectId, int>();
private readonly DataEventDispatcher eventDispatcher;
public TDataElement this[ObjectId instanceId]
{
@ -24,9 +25,10 @@ namespace Core.DataManagement
}
}
public DataTable(UniqueIntGenerator instanceIdgenerator)
public DataTable(UniqueIntGenerator instanceIdgenerator, DataEventDispatcher eventDispatcher)
{
this.instanceIdGenerator = instanceIdgenerator;
this.eventDispatcher = eventDispatcher;
}
public void Add(TDataElement data)
@ -39,6 +41,8 @@ namespace Core.DataManagement
dataIndexMap.Add(data.InstanceId, dataElements.Count);
dataElements.Add(data);
eventDispatcher.Create.Invoke(data);
}
public void Remove(TDataElement data)
@ -48,6 +52,7 @@ namespace Core.DataManagement
dataElements.RemoveAt(index);
dataIndexMap.Remove(data.InstanceId);
eventDispatcher.Delete.Invoke(data);
}
public void Modify(TDataElement data)
@ -55,11 +60,12 @@ namespace Core.DataManagement
if (!dataIndexMap.TryGetValue(data.InstanceId, out int index))
throw new InvalidOperationException($"Instance ID not found: {data.InstanceId.Id}");
TDataElement previous = dataElements[index];
dataElements[index] = data;
instanceIdGenerator.DeclareUnused(data.InstanceId.Id);
eventDispatcher.Modify.Invoke(previous, data);
}
/// <inheritdoc />
public void Serialize(IRevisionedSerializer<TRevision> serializer, TRevision revision)
{
// How many elements do we have in the data table?

View file

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
namespace Core.DataManagement
{
public class DeleteEvent
{
public delegate void DeleteCallback<TDataElement>(TDataElement subject)
where TDataElement : struct, IDataWithId;
private Dictionary<Type, List<object>> invocationLists = new Dictionary<Type, List<object>>();
public void AddCallback<TDataElement>(DeleteCallback<TDataElement> callback)
where TDataElement : struct, IDataWithId
{
Type type = typeof(TDataElement);
if (!invocationLists.TryGetValue(type, out List<object> invocationList))
{
invocationList = new List<object>();
invocationLists.Add(type, invocationList);
}
invocationList.Add(callback);
}
public void RemoveCallback<TDataElement>(DeleteCallback<TDataElement> callback)
where TDataElement : struct, IDataWithId
{
Type type = typeof(TDataElement);
if (!invocationLists.TryGetValue(type, out List<object> invocationList))
return;
invocationList.Remove(callback);
if (invocationList.Count == 0)
invocationLists.Remove(type);
}
public void Invoke<TDataElement>(TDataElement data)
where TDataElement : struct, IDataWithId
{
Type type = typeof(TDataElement);
if (!invocationLists.TryGetValue(type, out List<object> invocationList))
return;
foreach (object invocation in invocationList)
{
if (invocation is DeleteCallback<TDataElement> callback)
callback(data);
}
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 92c99810b07e4bec8f19ddd342508e05
timeCreated: 1677703541

View file

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
namespace Core.DataManagement
{
public class ModifyEvent
{
public delegate void ModifyCallback<TDataElement>(TDataElement subjectPrevious, TDataElement subjectNew)
where TDataElement : struct, IDataWithId;
private Dictionary<Type, List<object>> invocationLists = new Dictionary<Type, List<object>>();
public void AddCallback<TDataElement>(ModifyCallback<TDataElement> callback)
where TDataElement : struct, IDataWithId
{
Type type = typeof(TDataElement);
if (!invocationLists.TryGetValue(type, out List<object> invocationList))
{
invocationList = new List<object>();
invocationLists.Add(type, invocationList);
}
invocationList.Add(callback);
}
public void RemoveCallback<TDataElement>(ModifyCallback<TDataElement> callback)
where TDataElement : struct, IDataWithId
{
Type type = typeof(TDataElement);
if (!invocationLists.TryGetValue(type, out List<object> invocationList))
return;
invocationList.Remove(callback);
if (invocationList.Count == 0)
invocationLists.Remove(type);
}
public void Invoke<TDataElement>(TDataElement subjectPrevious, TDataElement subjectNew)
where TDataElement : struct, IDataWithId
{
Type type = typeof(TDataElement);
if (!invocationLists.TryGetValue(type, out List<object> invocationList))
return;
foreach (object invocation in invocationList)
{
if (invocation is ModifyCallback<TDataElement> callback)
callback(subjectPrevious, subjectNew);
}
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b4125ec3ea934168ac29c381ba8662db
timeCreated: 1677703739

View file

@ -11,9 +11,9 @@ namespace Core.WorldData
{
public readonly DataTable<WorldComputerData, WorldRevision> Computers;
public World(UniqueIntGenerator instanceIdGenerator)
public World(UniqueIntGenerator instanceIdGenerator, DataEventDispatcher eventDispatcher)
{
Computers = new DataTable<WorldComputerData, WorldRevision>(instanceIdGenerator);
Computers = new DataTable<WorldComputerData, WorldRevision>(instanceIdGenerator, eventDispatcher);
}
public void Serialize(IRevisionedSerializer<WorldRevision> serializer)

View file

@ -10,13 +10,19 @@ namespace Core
{
private World world;
private UniqueIntGenerator instanceIdGenerator;
private DataEventDispatcher eventDispatcher;
private DataCallbacks dataCallbacks;
public World World => world;
public DataCallbacks Callbacks => dataCallbacks;
public WorldManager()
{
eventDispatcher = new DataEventDispatcher();
instanceIdGenerator = new UniqueIntGenerator();
world = new World(instanceIdGenerator);
dataCallbacks = new DataCallbacks(eventDispatcher);
world = new World(instanceIdGenerator, eventDispatcher);
}
public ObjectId GetNextObjectId()