Skip to content

Commit

Permalink
[ark-ecs-kit, ark-physics-kit, ark-animation-kit] feat: consolidate e…
Browse files Browse the repository at this point in the history
…ntity removal system
  • Loading branch information
markusyeo committed Apr 15, 2024
1 parent 4751944 commit 715e1e6
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@ class TankGameCollisionStrategyManager: CollisionStrategyManager<TankGameActionC

func markEntityForRemoval<ExternalResources: ArkExternalResources>(_ entity: Entity,
in context: ArkActionContext<ExternalResources>) {
guard var physicsComponent = context.ecs.getComponent(ofType: PhysicsComponent.self, for: entity) else {
return
}
physicsComponent.toBeRemoved = true
context.ecs.upsertComponent(physicsComponent, to: entity)
context.ecs.upsertComponent(ToRemoveComponent(toBeRemoved: true), to: entity)
}

func markBallForRemoval<ExternalResources: ArkExternalResources>(_ entity: Entity,
Expand Down
6 changes: 2 additions & 4 deletions ArkGameExample/games/TankGame/TankGameManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -427,12 +427,10 @@ extension TankGameManager {
let eventData = event.eventData
let tankEntity = eventData.tankEntity
guard let tankHpComponent = context.ecs.getComponent(ofType: TankHpComponent.self, for: tankEntity),
tankHpComponent.hp <= 0,
var physicsComponent = context.ecs.getComponent(ofType: PhysicsComponent.self, for: tankEntity) else {
tankHpComponent.hp <= 0 else {
return
}
physicsComponent.toBeRemoved = true
context.ecs.upsertComponent(physicsComponent, to: tankEntity)
context.ecs.upsertComponent(ToRemoveComponent(toBeRemoved: true), to: tankEntity)
if let positionComponent = context.ecs.getComponent(ofType: PositionComponent.self, for: tankEntity) {
ImpactExplosionAnimation(perFrameDuration: 0.1).create(in: ecs, at: positionComponent.position)
}
Expand Down
6 changes: 2 additions & 4 deletions ArkGameExample/games/TankRaceGame/TankRaceEventHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,10 @@ class TankRaceEventHandler {
let eventData = event.eventData
let tankEntity = eventData.tankEntity
guard let tankHpComponent = context.ecs.getComponent(ofType: TankHpComponent.self, for: tankEntity),
tankHpComponent.hp <= 0,
var physicsComponent = context.ecs.getComponent(ofType: PhysicsComponent.self, for: tankEntity) else {
tankHpComponent.hp <= 0 else {
return
}
physicsComponent.toBeRemoved = true
context.ecs.upsertComponent(physicsComponent, to: tankEntity)
context.ecs.upsertComponent(ToRemoveComponent(toBeRemoved: true), to: tankEntity)
if let positionComponent = context.ecs.getComponent(ofType: PositionComponent.self, for: tankEntity) {
ImpactExplosionAnimation(perFrameDuration: 0.1,
width: 256.0,
Expand Down
10 changes: 9 additions & 1 deletion ArkKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@
2812FCC52BC4424200A0FE24 /* TankRaceGameEntityCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2812FCC42BC4424200A0FE24 /* TankRaceGameEntityCreator.swift */; };
2812FCC72BC442BD00A0FE24 /* TankRaceGameTerrainObjectBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2812FCC62BC442BD00A0FE24 /* TankRaceGameTerrainObjectBuilder.swift */; };
282248532BA82E5800850D7F /* SKPhysicsBodyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 282248522BA82E5800850D7F /* SKPhysicsBodyManager.swift */; };
28548F502BCD9CA700C49404 /* ArkEntityRemovalSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28548F4F2BCD9CA700C49404 /* ArkEntityRemovalSystem.swift */; };
28548F522BCD9CB900C49404 /* ToRemoveComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28548F512BCD9CB900C49404 /* ToRemoveComponent.swift */; };
286C09C02BADD0BB000343B1 /* TankGameMapBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 286C09BF2BADD0BB000343B1 /* TankGameMapBuilder.swift */; };
286C09C22BADD5FB000343B1 /* TankGameTerrainObjectBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 286C09C12BADD5FB000343B1 /* TankGameTerrainObjectBuilder.swift */; };
287B00552BC16E6C002F0114 /* TankHPComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287B00542BC16E6C002F0114 /* TankHPComponent.swift */; };
Expand Down Expand Up @@ -449,6 +451,8 @@
2812FCC42BC4424200A0FE24 /* TankRaceGameEntityCreator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TankRaceGameEntityCreator.swift; sourceTree = "<group>"; };
2812FCC62BC442BD00A0FE24 /* TankRaceGameTerrainObjectBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TankRaceGameTerrainObjectBuilder.swift; sourceTree = "<group>"; };
282248522BA82E5800850D7F /* SKPhysicsBodyManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SKPhysicsBodyManager.swift; sourceTree = "<group>"; };
28548F4F2BCD9CA700C49404 /* ArkEntityRemovalSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArkEntityRemovalSystem.swift; sourceTree = "<group>"; };
28548F512BCD9CB900C49404 /* ToRemoveComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToRemoveComponent.swift; sourceTree = "<group>"; };
286C09BF2BADD0BB000343B1 /* TankGameMapBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TankGameMapBuilder.swift; sourceTree = "<group>"; };
286C09C12BADD5FB000343B1 /* TankGameTerrainObjectBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TankGameTerrainObjectBuilder.swift; sourceTree = "<group>"; };
287B00542BC16E6C002F0114 /* TankHPComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TankHPComponent.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1193,6 +1197,7 @@
280CD3DD2BA8045200372C5D /* RotationComponent.swift */,
02C395332BAAF0EC0075F1CA /* WorldComponent.swift */,
28A032DB2BAD4E8200851BFF /* StopWatchComponent.swift */,
28548F512BCD9CB900C49404 /* ToRemoveComponent.swift */,
);
path = InternalComponents;
sourceTree = "<group>";
Expand All @@ -1213,6 +1218,7 @@
children = (
28A032DE2BAD4F2A00851BFF /* ArkTimeSystem.swift */,
0267BA1D2BBB07D80010F729 /* ArkUpdateSystem.swift */,
28548F4F2BCD9CA700C49404 /* ArkEntityRemovalSystem.swift */,
);
path = InternalSystems;
sourceTree = "<group>";
Expand Down Expand Up @@ -1974,6 +1980,7 @@
8FEB21782BADE30F00788E20 /* RenderLayer.swift in Sources */,
945441212BC9639E00E90ECE /* SnakeGameTick.swift in Sources */,
941BE2202BC104D000707997 /* TankGameSounds.swift in Sources */,
28548F502BCD9CA700C49404 /* ArkEntityRemovalSystem.swift in Sources */,
94D053A12BC80E0C000280C6 /* TankGameExplosionAnimationKeyframes.swift in Sources */,
8FEB217C2BADE8A500788E20 /* AbstractRootView.swift in Sources */,
0267BA1C2BBB05B70010F729 /* RuleTrigger.swift in Sources */,
Expand All @@ -1996,7 +2003,7 @@
02C395182BA83FC40075F1CA /* ButtonRenderableComponent.swift in Sources */,
AD6E03652BA1949000974EBF /* ArkEvent.swift in Sources */,
943D418C2BAEBF2E00F9E88F /* ArkSetupContext.swift in Sources */,
ADA847FF2BBC4EA800B19378 /* ArkDataSerializer.swift in Sources */,
ADA847FF2BBC4EA800B19378 /* ArkEventDataSerializer.swift in Sources */,
02B3C6202BCBDFEC002331A0 /* TankRaceEndPedalEvent.swift in Sources */,
ADA847FF2BBC4EA800B19378 /* ArkEventDataSerializer.swift in Sources */,
AD36A7582BAC3223003E938B /* TankGameEntityCreator.swift in Sources */,
Expand Down Expand Up @@ -2058,6 +2065,7 @@
AD2B59B62BB958E400198E99 /* DataWrapper.swift in Sources */,
02B3C62C2BCD19AC002331A0 /* ArkNetworkPublisherDelegate.swift in Sources */,
0230A48E2BB950AF001CFDAF /* OrderedDictionary.swift in Sources */,
28548F522BCD9CB900C49404 /* ToRemoveComponent.swift in Sources */,
9479A3AC2BA951F300F99013 /* AbstractBitmap.swift in Sources */,
945F7F9B2BA8912200933629 /* AbstractPannable.swift in Sources */,
AD6E03682BA1A61200974EBF /* ArkEventManager.swift in Sources */,
Expand Down
2 changes: 2 additions & 0 deletions ArkKit/app/utils/set-up/ArkSetUpStrategy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,13 @@ extension ArkSetUpStrategy {
let canvasSystem = ArkCanvasSystem()
let timeSystem = ArkTimeSystem()
let cameraSystem = ArkCameraSystem()
let entityRemovalSystem = ArkEntityRemovalSystem()
ark.arkState.arkECS.addSystem(timeSystem)
ark.arkState.arkECS.addSystem(physicsSystem)
ark.arkState.arkECS.addSystem(animationSystem)
ark.arkState.arkECS.addSystem(canvasSystem)
ark.arkState.arkECS.addSystem(cameraSystem)
ark.arkState.arkECS.addSystem(entityRemovalSystem)

// inject dependency into game loop
simulator.physicsScene?.sceneContactUpdateDelegate = physicsSystem
Expand Down
1 change: 1 addition & 0 deletions ArkKit/ark-animation-kit/ArkAnimationSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class ArkAnimationSystem: UpdateSystem {
animationInstance.advance(by: deltaTime)
if animationInstance.shouldDestroy {
animationsComponent.removeAnimation(animationInstance)
arkECS.upsertComponent(ToRemoveComponent(toBeRemoved: true), to: entity)
}
}

Expand Down
10 changes: 6 additions & 4 deletions ArkKit/ark-physics-kit/ArkPhysicsSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ class ArkPhysicsSystem: UpdateSystem {
for (entity, physics) in physicsComponents {
handlePhysicsComponentRemovalIfNeeded(for: entity, using: physics, arkECS: arkECS)

guard !physics.toBeRemoved else {
continue }
if let toRemoveComponent = arkECS.getComponent(ofType: ToRemoveComponent.self, for: entity),
toRemoveComponent.toBeRemoved {
return }

guard let positionComponent = arkECS.getComponent(ofType: PositionComponent.self, for: entity),
let rotationComponent = arkECS.getComponent(ofType: RotationComponent.self, for: entity) else {
Expand All @@ -70,8 +71,9 @@ class ArkPhysicsSystem: UpdateSystem {
private func handlePhysicsComponentRemovalIfNeeded(for entity: Entity,
using physics: PhysicsComponent,
arkECS: ArkECS) {
guard physics.toBeRemoved else {
return }
guard let toRemoveComponent = arkECS.getComponent(ofType: ToRemoveComponent.self, for: entity),
toRemoveComponent.toBeRemoved else {
return }

scene?.removePhysicsBody(for: entity)
arkECS.removeEntity(entity)
Expand Down
2 changes: 0 additions & 2 deletions ArkKit/ark-physics-kit/PhysicsComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,4 @@ struct PhysicsComponent: SendableComponent {
var categoryBitMask: UInt32
var collisionBitMask: UInt32
var contactTestBitMask: UInt32

var toBeRemoved = false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Foundation

struct ToRemoveComponent: Component {
var toBeRemoved: Bool
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Foundation

class ArkEntityRemovalSystem: UpdateSystem {
var active: Bool

init(active: Bool = true) {
self.active = active
}

func update(deltaTime: TimeInterval, arkECS: ArkECS) {
let toRemoveEntities = arkECS.getEntities(with: [ToRemoveComponent.self])
for entity in toRemoveEntities {
guard let toRemoveComponent = arkECS.getComponent(ofType: ToRemoveComponent.self,
for: entity),
toRemoveComponent.toBeRemoved else {
continue
}
arkECS.removeEntity(entity)
}
}
}

0 comments on commit 715e1e6

Please sign in to comment.