This repository has been archived by the owner on Jan 18, 2022. It is now read-only.
/
SetKinematicFromAuthoritySystem.cs
115 lines (95 loc) · 4.02 KB
/
SetKinematicFromAuthoritySystem.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
using System;
using System.Collections.Generic;
using System.Linq;
using Improbable.Gdk.Core;
using Unity.Entities;
using static Improbable.Gdk.TransformSynchronization.TransformUtils;
namespace Improbable.Gdk.TransformSynchronization
{
[DisableAutoCreation]
[AlwaysUpdateSystem]
[UpdateInGroup(typeof(SpatialOSUpdateGroup))]
[UpdateBefore(typeof(ResetForAuthorityGainedSystem))]
public class SetKinematicFromAuthoritySystem : ComponentSystem
{
private ComponentUpdateSystem updateSystem;
private ComponentType[] initBaseComponentTypes;
private ComponentType[] authBaseComponentTypes;
private readonly Dictionary<Type, Action> initKinematicActions = new Dictionary<Type, Action>();
private readonly Dictionary<Type, Action> authKinematicActions = new Dictionary<Type, Action>();
internal delegate void AuthChangeFunc<in T>(ref KinematicStateWhenAuth state, AuthorityChangeReceived auth,
T component)
where T : class;
protected override void OnCreate()
{
base.OnCreate();
updateSystem = World.GetExistingSystem<ComponentUpdateSystem>();
initBaseComponentTypes = new[]
{
ComponentType.ReadWrite<KinematicStateWhenAuth>(),
ComponentType.ReadOnly<NewlyAddedSpatialOSEntity>(),
};
authBaseComponentTypes = new[]
{
ComponentType.ReadWrite<KinematicStateWhenAuth>(),
ComponentType.ReadOnly<SpatialEntityId>(),
};
RegisterTransformSyncType(new RigidbodyTransformSync());
}
internal void RegisterTransformSyncType<T>(ITransformSync<T> impl)
where T : class
{
CreateInitAction((EntityQueryBuilder.F_DC<KinematicStateWhenAuth, T>) impl.InitKinematicState);
CreateAuthChangeAction((AuthChangeFunc<T>) impl.ApplyKinematicStateOnAuthChange);
}
private void CreateInitAction<T>(EntityQueryBuilder.F_DC<KinematicStateWhenAuth, T> initFunc)
where T : class
{
var entityQuery = GetEntityQuery(ConstructEntityQueryDesc<T>(AuthorityRequirements.Exclude, initBaseComponentTypes));
initKinematicActions.Add(typeof(T), () => Entities.With(entityQuery).ForEach(initFunc));
}
private void CreateAuthChangeAction<T>(AuthChangeFunc<T> authFunc)
where T : class
{
var componentQueryDesc = ConstructEntityQueryDesc<T>(AuthorityRequirements.Ignore, authBaseComponentTypes);
componentQueryDesc.None = componentQueryDesc.None
.Append(ComponentType.ReadOnly<NewlyAddedSpatialOSEntity>())
.ToArray();
var entityQuery = GetEntityQuery(componentQueryDesc);
authKinematicActions.Add(typeof(T), () => Entities.With(entityQuery).ForEach(
(
T component,
ref KinematicStateWhenAuth kinematicStateWhenAuth,
ref SpatialEntityId spatialEntityId) =>
{
var changes = updateSystem.GetAuthorityChangesReceived(spatialEntityId.EntityId,
TransformInternal.ComponentId);
if (changes.Count == 0)
{
return;
}
var auth = changes[changes.Count - 1];
authFunc(ref kinematicStateWhenAuth, auth, component);
}));
}
protected override void OnUpdate()
{
UpdateNewEntityGroup();
UpdateAuthChangeGroup();
}
private void UpdateNewEntityGroup()
{
foreach (var initAction in initKinematicActions)
{
initAction.Value();
}
}
private void UpdateAuthChangeGroup()
{
foreach (var authChangeAction in authKinematicActions)
{
authChangeAction.Value();
}
}
}
}