|
@@ -2,7 +2,6 @@
|
|
using Expressive;
|
|
using Expressive;
|
|
using InABox.Core;
|
|
using InABox.Core;
|
|
using InABox.Database;
|
|
using InABox.Database;
|
|
-using Org.BouncyCastle.Asn1.X509.Qualified;
|
|
|
|
using System;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Generic;
|
|
@@ -70,7 +69,7 @@ public class EventData<T, TDataModel> : IEventData
|
|
var nActions = reader.ReadInt32();
|
|
var nActions = reader.ReadInt32();
|
|
for(int i = 0; i < nActions; ++i)
|
|
for(int i = 0; i < nActions; ++i)
|
|
{
|
|
{
|
|
- var action = EventUtils.DeserializeObject<IEventAction<T>>(EventUtils.GetTriggerType, reader);
|
|
|
|
|
|
+ var action = EventUtils.DeserializeObject<IEventAction<T>>(EventUtils.GetActionType, reader);
|
|
Actions.Add(action);
|
|
Actions.Add(action);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -306,6 +305,101 @@ public static class EventUtils
|
|
}
|
|
}
|
|
|
|
|
|
#endregion
|
|
#endregion
|
|
|
|
+
|
|
|
|
+ #region Event Cache
|
|
|
|
+
|
|
|
|
+ private static bool _loadedCache = false;
|
|
|
|
+ private static Dictionary<EventType, Dictionary<Type, List<(Event Event, IEventData EventData)>>> _entityEvents = new();
|
|
|
|
+ private static Dictionary<Guid, (EventType, Type)> _entityEventMap = new();
|
|
|
|
+
|
|
|
|
+ public static void ReloadCache(IProvider provider)
|
|
|
|
+ {
|
|
|
|
+ _entityEvents.Clear();
|
|
|
|
+ _entityEventMap.Clear();
|
|
|
|
+ var events = provider.Query(null, Columns.None<Event>().Add(x => x.ID).Add(x => x.Code).Add(x => x.EventType).Add(x => x.Data))
|
|
|
|
+ .ToObjects<Event>();
|
|
|
|
+ foreach(var ev in events)
|
|
|
|
+ {
|
|
|
|
+ AddEvent(provider, ev);
|
|
|
|
+ }
|
|
|
|
+ _loadedCache = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static void AddEntityEvent(Event ev)
|
|
|
|
+ {
|
|
|
|
+ if(ev.Data.Length != 0)
|
|
|
|
+ {
|
|
|
|
+ using var stream = new MemoryStream(ev.Data);
|
|
|
|
+ var reader = new CoreBinaryReader(stream, BinarySerializationSettings.Latest);
|
|
|
|
+ var data = Deserialize(reader);
|
|
|
|
+
|
|
|
|
+ var entityType = data.Event.GetType().GenericTypeArguments[0];
|
|
|
|
+ _entityEvents.GetValueOrAdd(ev.EventType).GetValueOrAdd(entityType).Add((ev, data));
|
|
|
|
+ _entityEventMap[ev.ID] = (ev.EventType, entityType);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ private static void RemoveEntityEvent(Event ev)
|
|
|
|
+ {
|
|
|
|
+ if(_entityEventMap.TryGetValue(ev.ID, out var item))
|
|
|
|
+ {
|
|
|
|
+ if(_entityEvents.TryGetValue(item.Item1, out var eventTypeEvents))
|
|
|
|
+ {
|
|
|
|
+ if(eventTypeEvents.TryGetValue(item.Item2, out var entityEvents))
|
|
|
|
+ {
|
|
|
|
+ entityEvents.RemoveAll(x => x.Event.ID == ev.ID);
|
|
|
|
+ if(entityEvents.Count == 0)
|
|
|
|
+ {
|
|
|
|
+ eventTypeEvents.Remove(item.Item2);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(eventTypeEvents.Count == 0)
|
|
|
|
+ {
|
|
|
|
+ _entityEvents.Remove(item.Item1);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ _entityEventMap.Remove(ev.ID);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static void RemoveEvent(IProvider provider, Event ev)
|
|
|
|
+ {
|
|
|
|
+ if (!_loadedCache) ReloadCache(provider);
|
|
|
|
+
|
|
|
|
+ switch (ev.EventType)
|
|
|
|
+ {
|
|
|
|
+ case EventType.AfterSave:
|
|
|
|
+ RemoveEntityEvent(ev);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ public static void AddEvent(IProvider provider, Event ev)
|
|
|
|
+ {
|
|
|
|
+ if (!_loadedCache) ReloadCache(provider);
|
|
|
|
+
|
|
|
|
+ switch (ev.EventType)
|
|
|
|
+ {
|
|
|
|
+ case EventType.AfterSave:
|
|
|
|
+ AddEntityEvent(ev);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static void AfterSave<T>(IStore store, T entity)
|
|
|
|
+ where T : Entity
|
|
|
|
+ {
|
|
|
|
+ if (!_loadedCache) ReloadCache(store.Provider);
|
|
|
|
+
|
|
|
|
+ var events = _entityEvents.GetValueOrDefault(EventType.AfterSave)
|
|
|
|
+ ?.GetValueOrDefault(typeof(T));
|
|
|
|
+ if (events is null) return;
|
|
|
|
+
|
|
|
|
+ foreach(var ev in events)
|
|
|
|
+ {
|
|
|
|
+ Run(store, ev.Event, (ev.EventData as EventData<SaveEvent<T>, SaveEventDataModel<T>>)!, new SaveEventDataModel<T>(entity));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #endregion
|
|
}
|
|
}
|
|
|
|
|
|
#region DataModel Definition
|
|
#region DataModel Definition
|