This repository has been archived by the owner on Jan 18, 2022. It is now read-only.
/
CommandMetaData.cs
132 lines (109 loc) · 4.64 KB
/
CommandMetaData.cs
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;
using System.Collections.Generic;
using Unity.Entities;
namespace Improbable.Gdk.Core
{
public readonly struct CommandContext<T>
{
public readonly Entity SendingEntity;
public readonly T Request;
public readonly object Context;
public readonly long RequestId;
public CommandContext(Entity sendingEntity, T request, object context, long requestId)
{
SendingEntity = sendingEntity;
Request = request;
Context = context;
RequestId = requestId;
}
}
public class CommandMetaData
{
// Cache the types needed to instantiate a new CommandMetaData
private static List<Type> storageTypes;
private readonly HashSet<long> internalRequestIds = new HashSet<long>();
private readonly Dictionary<uint, Dictionary<uint, ICommandMetaDataStorage>> componentIdToCommandIdToStorage =
new Dictionary<uint, Dictionary<uint, ICommandMetaDataStorage>>();
private List<CommandIds> requestsToRemove = new List<CommandIds>();
public CommandMetaData()
{
if (storageTypes == null)
{
storageTypes = ReflectionUtility.GetNonAbstractTypes(typeof(ICommandMetaDataStorage));
}
foreach (var type in storageTypes)
{
var instance = (ICommandMetaDataStorage) Activator.CreateInstance(type);
if (!componentIdToCommandIdToStorage.TryGetValue(instance.GetComponentId(),
out var commandIdToStorage))
{
commandIdToStorage = new Dictionary<uint, ICommandMetaDataStorage>();
componentIdToCommandIdToStorage.Add(instance.GetComponentId(), commandIdToStorage);
}
commandIdToStorage.Add(instance.GetCommandId(), instance);
}
}
public void MarkIdForRemoval(uint componentId, uint commandId, long internalRequestId)
{
requestsToRemove.Add(new CommandIds(componentId, commandId, internalRequestId));
}
public void FlushRemovedIds()
{
foreach (var commandIds in requestsToRemove)
{
var s = GetCommandDiffStorage(commandIds.ComponentId, commandIds.CommandId);
s.RemoveMetaData(commandIds.InternalRequestId);
internalRequestIds.Remove(commandIds.InternalRequestId);
}
requestsToRemove.Clear();
}
public void AddRequest<T>(uint componentId, uint commandId, in CommandContext<T> context)
{
var s = (ICommandPayloadStorage<T>) GetCommandDiffStorage(componentId, commandId);
s.AddRequest(in context);
}
public void AddInternalRequestId(uint componentId, uint commandId, long requestId, long internalRequestId)
{
internalRequestIds.Add(internalRequestId);
var s = GetCommandDiffStorage(componentId, commandId);
s.SetInternalRequestId(internalRequestId, requestId);
}
public CommandContext<T> GetContext<T>(uint componentId, uint commandId, long internalRequestId)
{
var s = (ICommandPayloadStorage<T>) GetCommandDiffStorage(componentId, commandId);
return s.GetPayload(internalRequestId);
}
internal bool ContainsCommandMetaData(long internalRequestId)
{
return internalRequestIds.Contains(internalRequestId);
}
internal bool IsEmpty()
{
return internalRequestIds.Count == 0;
}
private ICommandMetaDataStorage GetCommandDiffStorage(uint componentId, uint commandId)
{
if (!componentIdToCommandIdToStorage.TryGetValue(componentId, out var commandIdToStorage))
{
throw new ArgumentException($"Can not find command meta data. Unknown component ID {componentId}");
}
if (!commandIdToStorage.TryGetValue(commandId, out var storage))
{
throw new ArgumentException($"Can not find command meta data storage. Unknown command ID {commandId}");
}
return storage;
}
private readonly struct CommandIds
{
public readonly uint ComponentId;
public readonly uint CommandId;
public readonly long InternalRequestId;
public CommandIds(uint componentId, uint commandId, long internalRequestId)
{
ComponentId = componentId;
CommandId = commandId;
InternalRequestId = internalRequestId;
}
}
}
}