Skip to content

Commit ae21ed1

Browse files
committed
Finding entities: Handle task cancellation
I can't assume entity fetches will always work, because user might e g close window
1 parent 581b7a6 commit ae21ed1

File tree

3 files changed

+17
-12
lines changed

3 files changed

+17
-12
lines changed

Sources/allonet2/AlloClient.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@ open class AlloClient : AlloSessionDelegate, ObservableObject, Identifiable
2727
guard let aeid = self.avatarId else { return nil }
2828
return place.entities[aeid]
2929
}
30-
public func findAvatar() async -> Entity
30+
/// Fetch the convenience accessor for our own avatar Entity, so that we can modify it. This will only throw in case of task cancellation.
31+
public func findAvatar() async throws -> Entity
3132
{
3233
var avatarId: EntityID? = self.avatarId
33-
while avatarId == nil
34+
var iter = self.$avatarId.values.compactMap({ $0 }).makeAsyncIterator()
35+
while let maybeId = await iter.next()
3436
{
35-
var iter = self.$avatarId.values.makeAsyncIterator()
36-
if let next = await iter.next()
37-
{
38-
avatarId = next
39-
}
37+
try Task.checkCancellation()
38+
if maybeId != nil { avatarId = maybeId; break }
4039
}
41-
return await place.findEntity(id: avatarId!)
40+
try Task.checkCancellation()
41+
return try await place.findEntity(id: avatarId!)
4242
}
4343
@Published public private(set) var isAnnounced: Bool = false
4444
public private(set) var placeName: String?

Sources/allonet2/Place.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ public class Place
2323
}
2424

2525
/// Wait for a specific entity to come in and return its convenience structure.
26-
public func findEntity(id: EntityID) async -> Entity
26+
public func findEntity(id: EntityID) async throws -> Entity
2727
{
28-
let edata = await state.findEntity(id)
28+
let edata = try await state.findEntity(id)
29+
try Task.checkCancellation()
30+
// Cancellation should be the only reason why we get nil back, which should make the below force-unwrap safe with the above check
2931
return entities[edata.id]!
3032
}
3133

Sources/allonet2/PlaceContents.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,16 @@ public class PlaceState
3434
}
3535

3636
/// Wait for a specific entity to come in.
37-
public func findEntity(_ id: EntityID) async -> EntityData
37+
public func findEntity(_ id: EntityID) async throws -> EntityData
3838
{
3939
if let ent = current.entities[id] {
4040
return ent
4141
}
4242
var iter = observers.subjectFor(id).values.makeAsyncIterator()
43-
return await iter.next()!
43+
if let ent = await iter.next() {
44+
return ent
45+
}
46+
throw CancellationError()
4447
}
4548

4649
internal func callChangeObservers()

0 commit comments

Comments
 (0)