Skip to content
This repository was archived by the owner on Oct 20, 2021. It is now read-only.

Commit efb4444

Browse files
authored
Remove reactive components (#155)
* Refactor systems to no longer use reactive components
1 parent 0b31b7f commit efb4444

File tree

5 files changed

+182
-138
lines changed

5 files changed

+182
-138
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Changed
66

77
- Updated the `ConnectionController` and `ClientWorkerConnector` to make full use of the updated Player Lifecycle Feature Module.
8+
- Reactive Components are no longer used. They have been disabled by adding the `DISABLE_REACTIVE_COMPONENTS` define symbol.
89

910
### Internal
1011

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,60 @@
11
using Improbable.Gdk.Core;
22
using Improbable.Gdk.Health;
3-
using Unity.Collections;
43
using Unity.Entities;
54

65
namespace Improbable.Gdk.Guns
76
{
87
[UpdateInGroup(typeof(SpatialOSUpdateGroup))]
98
public class ServerShootingSystem : ComponentSystem
109
{
11-
private struct PlayersShooting
10+
private WorkerSystem workerSystem;
11+
private CommandSystem commandSystem;
12+
private ComponentUpdateSystem componentUpdateSystem;
13+
14+
protected override void OnCreateManager()
1215
{
13-
public readonly int Length;
14-
public ComponentDataArray<HealthComponent.CommandSenders.ModifyHealth> ModifyHealthCommandSenders;
15-
[ReadOnly] public ComponentDataArray<SpatialEntityId> EntityId;
16-
[ReadOnly] public ComponentDataArray<ShootingComponent.ReceivedEvents.Shots> Shots;
17-
[ReadOnly] public ComponentDataArray<GunComponent.Component> Gun;
18-
}
16+
base.OnCreateManager();
1917

20-
[Inject] private PlayersShooting playersShooting;
18+
workerSystem = World.GetExistingManager<WorkerSystem>();
19+
commandSystem = World.GetExistingManager<CommandSystem>();
20+
componentUpdateSystem = World.GetExistingManager<ComponentUpdateSystem>();
21+
}
2122

2223
protected override void OnUpdate()
2324
{
24-
for (var i = 0; i < playersShooting.Length; i++)
25-
{
26-
var commandSender = playersShooting.ModifyHealthCommandSenders[i];
27-
var commandSent = false;
28-
var gunId = playersShooting.Gun[i].GunId;
29-
var gunSettings = GunDictionary.Get(gunId);
30-
var damage = gunSettings.ShotDamage;
25+
var events = componentUpdateSystem.GetEventsReceived<ShootingComponent.Shots.Event>();
26+
var gunDataForEntity = GetComponentDataFromEntity<GunComponent.Component>();
3127

32-
foreach (var shot in playersShooting.Shots[i].Events)
28+
for (var i = 0; i < events.Count; ++i)
29+
{
30+
ref readonly var shotEvent = ref events[i];
31+
var shotInfo = shotEvent.Event.Payload;
32+
if (!shotInfo.HitSomething || shotInfo.EntityId <= 0)
3333
{
34-
var shotInfo = shot;
35-
if (!ValidateShot(shotInfo))
36-
{
37-
continue;
38-
}
39-
40-
// Send command to entity being shot.
41-
var modifyHealthRequest = new HealthComponent.ModifyHealth.Request(
42-
new EntityId(shotInfo.EntityId),
43-
new HealthModifier()
44-
{
45-
Amount = -damage,
46-
Origin = shotInfo.HitOrigin,
47-
AppliedLocation = shotInfo.HitLocation
48-
});
49-
commandSender.RequestsToSend.Add(modifyHealthRequest);
50-
commandSent = true;
34+
continue;
5135
}
5236

53-
if (commandSent)
37+
var shooterSpatialID = new EntityId(shotInfo.EntityId);
38+
if (!workerSystem.TryGetEntity(shooterSpatialID, out var shooterEntity))
5439
{
55-
playersShooting.ModifyHealthCommandSenders[i] = commandSender;
40+
continue;
5641
}
57-
}
58-
}
5942

60-
private bool ValidateShot(ShotInfo shot)
61-
{
62-
return shot.HitSomething && shot.EntityId > 0;
43+
var gunComponent = gunDataForEntity[shooterEntity];
44+
var damage = GunDictionary.Get(gunComponent.GunId).ShotDamage;
45+
46+
var modifyHealthRequest = new HealthComponent.ModifyHealth.Request(
47+
new EntityId(shotInfo.EntityId),
48+
new HealthModifier()
49+
{
50+
Amount = -damage,
51+
Origin = shotInfo.HitOrigin,
52+
AppliedLocation = shotInfo.HitLocation
53+
}
54+
);
55+
56+
commandSystem.SendCommand(modifyHealthRequest);
57+
}
6358
}
6459
}
6560
}

workers/unity/Packages/com.improbable.gdk.health/Systems/HealthRegenSystem.cs

Lines changed: 103 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,73 @@
1+
using System.Collections.Generic;
12
using Improbable.Gdk.Core;
2-
using Improbable.Gdk.ReactiveComponents;
3-
using Unity.Collections;
3+
using Improbable.Worker.CInterop;
44
using Unity.Entities;
55
using UnityEngine;
66

77
namespace Improbable.Gdk.Health
88
{
99
[UpdateInGroup(typeof(SpatialOSUpdateGroup))]
1010
[UpdateAfter(typeof(ServerHealthModifierSystem))]
11+
[AlwaysUpdateSystem]
1112
public class HealthRegenSystem : ComponentSystem
1213
{
13-
public struct EntitiesNeedingRegenData
14+
private WorkerSystem workerSystem;
15+
private ComponentUpdateSystem componentUpdateSystem;
16+
private CommandSystem commandSystem;
17+
18+
private ComponentGroup initGroup;
19+
private ComponentGroup regenGroup;
20+
21+
private HashSet<EntityId> recentlyDamagedCache = new HashSet<EntityId>();
22+
23+
protected override void OnCreateManager()
1424
{
15-
public readonly int Length;
16-
[ReadOnly] public EntityArray Entities;
17-
[ReadOnly] public ComponentDataArray<HealthRegenComponent.Component> HealthRegenComponents;
18-
[ReadOnly] public SubtractiveComponent<HealthRegenData> DenotesMissingData;
19-
[ReadOnly] public ComponentDataArray<Authoritative<HealthComponent.Component>> DenotesAuthority;
25+
base.OnCreateManager();
26+
27+
workerSystem = World.GetExistingManager<WorkerSystem>();
28+
componentUpdateSystem = World.GetExistingManager<ComponentUpdateSystem>();
29+
commandSystem = World.GetExistingManager<CommandSystem>();
30+
31+
initGroup = GetComponentGroup(
32+
ComponentType.ReadOnly<HealthRegenComponent.Component>(),
33+
ComponentType.Subtractive<HealthRegenData>(),
34+
ComponentType.ReadOnly<HealthComponent.ComponentAuthority>()
35+
);
36+
initGroup.SetFilter(HealthComponent.ComponentAuthority.Authoritative);
37+
38+
regenGroup = GetComponentGroup(
39+
ComponentType.Create<HealthRegenComponent.Component>(),
40+
ComponentType.Create<HealthRegenData>(),
41+
ComponentType.ReadOnly<HealthComponent.Component>(),
42+
ComponentType.ReadOnly<SpatialEntityId>(),
43+
ComponentType.ReadOnly<HealthComponent.ComponentAuthority>()
44+
);
45+
regenGroup.SetFilter(HealthComponent.ComponentAuthority.Authoritative);
2046
}
2147

22-
public struct TakingDamage
48+
protected override void OnUpdate()
2349
{
24-
public readonly int Length;
25-
public ComponentDataArray<HealthRegenData> RegenData;
26-
public ComponentDataArray<HealthRegenComponent.Component> HealthRegenComponents;
27-
[ReadOnly] public ComponentDataArray<HealthComponent.ReceivedEvents.HealthModified> HealthModifiedEvents;
28-
[ReadOnly] public ComponentDataArray<Authoritative<HealthComponent.Component>> DenotesAuthority;
50+
InitializeRegenData();
51+
52+
ProcessDamageEvents();
53+
54+
ApplyHealthRegen();
2955
}
3056

31-
public struct EntitiesToRegen
57+
private void InitializeRegenData()
3258
{
33-
public readonly int Length;
34-
public ComponentDataArray<HealthComponent.CommandSenders.ModifyHealth> ModifyHealthCommandSenders;
35-
public ComponentDataArray<HealthRegenComponent.Component> HealthRegenComponents;
36-
public ComponentDataArray<HealthRegenData> RegenData;
37-
[ReadOnly] public ComponentDataArray<HealthComponent.Component> HealthComponents;
38-
[ReadOnly] public ComponentDataArray<SpatialEntityId> EntityId;
39-
[ReadOnly] public ComponentDataArray<Authoritative<HealthComponent.Component>> DenotesAuthority;
40-
}
59+
if (initGroup.IsEmptyIgnoreFilter)
60+
{
61+
return;
62+
}
4163

42-
[Inject] private EntitiesNeedingRegenData needData;
43-
[Inject] private TakingDamage takingDamage;
44-
[Inject] private EntitiesToRegen toRegen;
64+
var entities = initGroup.GetEntityArray();
65+
var regenComponentData = initGroup.GetComponentDataArray<HealthRegenComponent.Component>();
4566

46-
protected override void OnUpdate()
47-
{
4867
// Add the HealthRegenData if you don't currently have it.
49-
for (var i = 0; i < needData.Length; i++)
68+
for (var i = 0; i < entities.Length; i++)
5069
{
51-
var healthRegenComponent = needData.HealthRegenComponents[i];
70+
var healthRegenComponent = regenComponentData[i];
5271

5372
var regenData = new HealthRegenData();
5473

@@ -58,49 +77,71 @@ protected override void OnUpdate()
5877
regenData.NextSpatialSyncTimer = healthRegenComponent.CooldownSyncInterval;
5978
}
6079

61-
PostUpdateCommands.AddComponent(needData.Entities[i], regenData);
80+
PostUpdateCommands.AddComponent(entities[i], regenData);
6281
}
82+
}
6383

64-
// When the HealthComponent takes a damaging event, reset the DamagedRecently timer.
65-
for (var i = 0; i < takingDamage.Length; i++)
84+
private void ProcessDamageEvents()
85+
{
86+
var healthModifiedEvents = componentUpdateSystem.GetEventsReceived<HealthComponent.HealthModified.Event>();
87+
if (healthModifiedEvents.Count == 0)
6688
{
67-
var healthModifiedEvents = takingDamage.HealthModifiedEvents[i];
68-
var damagedRecently = false;
89+
return;
90+
}
6991

70-
foreach (var modifiedEvent in takingDamage.HealthModifiedEvents[i].Events)
92+
for (var i = 0; i < healthModifiedEvents.Count; ++i)
93+
{
94+
ref readonly var healthEvent = ref healthModifiedEvents[i];
95+
if (componentUpdateSystem.GetAuthority(healthEvent.EntityId, HealthComponent.ComponentId) ==
96+
Authority.NotAuthoritative)
7197
{
72-
var modifier = modifiedEvent.Modifier;
73-
if (modifier.Amount < 0)
74-
{
75-
damagedRecently = true;
76-
break;
77-
}
98+
continue;
7899
}
79-
if (!damagedRecently)
100+
101+
if (healthEvent.Event.Payload.Modifier.Amount < 0)
80102
{
81-
continue;
103+
recentlyDamagedCache.Add(healthEvent.EntityId);
82104
}
105+
}
83106

84-
var regenComponent = takingDamage.HealthRegenComponents[i];
85-
var regenData = takingDamage.RegenData[i];
107+
var healthRegenComponentDataForEntity = GetComponentDataFromEntity<HealthRegenComponent.Component>();
108+
var healthRegenDataForEntity = GetComponentDataFromEntity<HealthRegenData>();
109+
foreach (var entityId in recentlyDamagedCache)
110+
{
111+
workerSystem.TryGetEntity(entityId, out var entity);
112+
var regenComponent = healthRegenComponentDataForEntity[entity];
113+
var regenData = healthRegenDataForEntity[entity];
86114

87115
regenComponent.DamagedRecently = true;
88116
regenComponent.RegenCooldownTimer = regenComponent.RegenPauseTime;
89-
90117
regenData.DamagedRecentlyTimer = regenComponent.RegenPauseTime;
91118
regenData.NextSpatialSyncTimer = regenComponent.CooldownSyncInterval;
92119

93-
takingDamage.HealthRegenComponents[i] = regenComponent;
94-
takingDamage.RegenData[i] = regenData;
120+
healthRegenComponentDataForEntity[entity] = regenComponent;
121+
healthRegenDataForEntity[entity] = regenData;
95122
}
96123

97-
// Count down the timers, and update the HealthComponent accordingly.
98-
for (var i = 0; i < toRegen.Length; i++)
124+
recentlyDamagedCache.Clear();
125+
}
126+
127+
private void ApplyHealthRegen()
128+
{
129+
if (regenGroup.IsEmptyIgnoreFilter)
99130
{
100-
var healthComponent = toRegen.HealthComponents[i];
101-
var regenComponent = toRegen.HealthRegenComponents[i];
131+
return;
132+
}
102133

103-
var regenData = toRegen.RegenData[i];
134+
var spatialIdData = regenGroup.GetComponentDataArray<SpatialEntityId>();
135+
var healthComponentData = regenGroup.GetComponentDataArray<HealthComponent.Component>();
136+
var healthRegenComponentData = regenGroup.GetComponentDataArray<HealthRegenComponent.Component>();
137+
var healthRegenData = regenGroup.GetComponentDataArray<HealthRegenData>();
138+
139+
// Count down the timers, and update the HealthComponent accordingly.
140+
for (var i = 0; i < spatialIdData.Length; i++)
141+
{
142+
var healthComponent = healthComponentData[i];
143+
var regenComponent = healthRegenComponentData[i];
144+
var regenData = healthRegenData[i];
104145

105146
// Don't regen if dead.
106147
if (healthComponent.Health == 0)
@@ -118,7 +159,7 @@ protected override void OnUpdate()
118159
regenData.DamagedRecentlyTimer = 0;
119160
regenComponent.DamagedRecently = false;
120161
regenComponent.RegenCooldownTimer = 0;
121-
toRegen.HealthRegenComponents[i] = regenComponent;
162+
healthRegenComponentData[i] = regenComponent;
122163
}
123164
else
124165
{
@@ -128,11 +169,11 @@ protected override void OnUpdate()
128169
{
129170
regenData.NextSpatialSyncTimer += regenComponent.CooldownSyncInterval;
130171
regenComponent.RegenCooldownTimer = regenData.DamagedRecentlyTimer;
131-
toRegen.HealthRegenComponents[i] = regenComponent;
172+
healthRegenComponentData[i] = regenComponent;
132173
}
133174
}
134175

135-
toRegen.RegenData[i] = regenData;
176+
healthRegenData[i] = regenData;
136177

137178
return;
138179
}
@@ -146,17 +187,17 @@ protected override void OnUpdate()
146187
regenData.NextRegenTimer += regenComponent.RegenInterval;
147188

148189
// Send command to regen entity.
149-
var commandSender = toRegen.ModifyHealthCommandSenders[i];
150190
var modifyHealthRequest = new HealthComponent.ModifyHealth.Request(
151-
toRegen.EntityId[i].EntityId,
191+
spatialIdData[i].EntityId,
152192
new HealthModifier()
153193
{
154194
Amount = regenComponent.RegenAmount
155-
});
156-
commandSender.RequestsToSend.Add(modifyHealthRequest);
195+
}
196+
);
197+
commandSystem.SendCommand(modifyHealthRequest);
157198
}
158199

159-
toRegen.RegenData[i] = regenData;
200+
healthRegenData[i] = regenData;
160201
}
161202
}
162203
}

0 commit comments

Comments
 (0)