-
Notifications
You must be signed in to change notification settings - Fork 1
/
GameBridge.swift
108 lines (86 loc) · 2.88 KB
/
GameBridge.swift
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
import SDPhysicsEngine
class GameBridge {
var entityManager: EntitySyncInterface
var scene: SDScene
var entitiesMap: [EntityId: SDObject]
var objectsMap: [SDObjectId: EntityId]
var modules: [SyncModule]
var creationModule: CreationModule?
init(entityManager: EntitySyncInterface, scene: SDScene) {
self.entityManager = entityManager
self.scene = scene
modules = []
entitiesMap = [:]
objectsMap = [:]
registerModules()
}
func syncFromEntities() {
var toRemove = Set(entitiesMap.keys)
for entity in entityManager.entities {
toRemove.remove(entity.id)
if let object = entitiesMap[entity.id] {
update(object: object, from: entity)
} else {
createObject(from: entity)
}
}
for entityId in toRemove {
removeObject(from: entityId)
}
}
func syncToEntities() {
for (entityId, object) in entitiesMap {
if let entity = entityManager.entity(of: entityId) {
update(entity: entity, from: object)
}
}
}
func entityId(of objectId: SDObjectId) -> EntityId? {
objectsMap[objectId]
}
private func registerModule(_ module: SyncModule) {
modules.append(module)
}
private func registerModules() {
let spriteModule = SpriteModule(entityManager: entityManager)
self.creationModule = spriteModule
registerModule(spriteModule)
registerModule(ObjectModule(entityManager: entityManager))
registerModule(PhysicsModule(entityManager: entityManager))
}
private func update(entity: Entity, from object: SDObject) {
modules.forEach {
$0.sync(entity: entity, from: object)
}
}
private func update(object: SDObject, from entity: Entity) {
modules.forEach {
$0.sync(object: object, from: entity)
}
}
private func createObject(from entity: Entity) {
guard let newObject = creationModule?.createObject(from: entity) else {
return
}
entitiesMap[entity.id] = newObject
objectsMap[newObject.id] = entity.id
modules.forEach {
$0.create(for: newObject, from: entity)
}
if type(of: entity) == Player.self {
if let playerIndex = entityManager.component(ofType: PlayerComponent.self, of: entity.id)?.playerIndex {
self.scene.addPlayerObject(newObject, playerIndex: playerIndex)
}
} else {
self.scene.addObject(newObject)
}
}
private func removeObject(from entityId: EntityId) {
guard let object = entitiesMap[entityId] else {
return
}
entitiesMap[entityId] = nil
objectsMap[object.id] = nil
self.scene.removeObject(object)
}
}