Skip to content

Commit ffccf93

Browse files
committed
Chip away at Swift 6
1 parent 04c7ecc commit ffccf93

File tree

19 files changed

+101
-60
lines changed

19 files changed

+101
-60
lines changed

Sources/GateEngine/Resources/Animation/ObjectAnimation3D.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ extension ResourceManager {
214214

215215
func objectAnimation3DImporterForPath(_ path: String) async throws(GateEngineError) -> any ObjectAnimation3DImporter {
216216
for type in self.importers.objectAnimation3DImporters {
217-
if type.canProcessFile(path) {
217+
if type.canProcessFile(at: path) {
218218
return try await self.importers.getImporter(path: path, type: type)
219219
}
220220
}
@@ -337,7 +337,7 @@ extension ResourceManager {
337337
func _reloadObjectAnimation3D(for key: Cache.ObjectAnimation3DKey, isFirstLoad: Bool) {
338338
Game.unsafeShared.resourceManager.incrementLoading(path: key.requestedPath)
339339
let cache = self.cache
340-
Task.detached {
340+
Task {
341341
let path = key.requestedPath
342342

343343
do {

Sources/GateEngine/Resources/CollisionMesh/CollisionMesh.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ extension ResourceManager {
167167

168168
func collisionMeshImporterForPath(_ path: String) async throws(GateEngineError) -> any CollisionMeshImporter {
169169
for type in self.importers.collisionMeshImporters {
170-
if type.canProcessFile(path) {
170+
if type.canProcessFile(at: path) {
171171
return try await self.importers.getImporter(path: path, type: type)
172172
}
173173
}
@@ -290,7 +290,7 @@ extension ResourceManager {
290290
@MainActor func _reloadCollisionMesh(for key: Cache.CollisionMeshKey, isFirstLoad: Bool) {
291291
Game.unsafeShared.resourceManager.incrementLoading(path: key.requestedPath)
292292
let cache = self.cache
293-
Task.detached {
293+
Task {
294294
let path = key.requestedPath
295295

296296
do {

Sources/GateEngine/Resources/Geometry/Geometry.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ extension ResourceManager {
180180

181181
func geometryImporterForPath(_ path: String) async throws(GateEngineError) -> any GeometryImporter {
182182
for type in self.importers.geometryImporters {
183-
if type.canProcessFile(path) {
183+
if type.canProcessFile(at: path) {
184184
return try await self.importers.getImporter(path: path, type: type)
185185
}
186186
}
@@ -270,7 +270,7 @@ extension ResourceManager {
270270
if cache.geometries[key] == nil {
271271
cache.geometries[key] = Cache.GeometryCache()
272272
Game.unsafeShared.resourceManager.incrementLoading(path: key.requestedPath)
273-
Task.detached {
273+
Task {
274274
do {
275275
let geometry = try await RawGeometry(path: path, options: options)
276276
Task { @MainActor in
@@ -341,7 +341,7 @@ extension ResourceManager {
341341
guard key.requestedPath.first != "$" && key.requestedPath.first != "@" else { return }
342342
guard self.geometryNeedsReload(key: key) else { return }
343343
let cache = self.cache
344-
Task.detached {
344+
Task {
345345
let geometry = try await RawGeometry(
346346
path: key.requestedPath,
347347
options: key.geometryOptions

Sources/GateEngine/Resources/Geometry/Lines.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ extension ResourceManager {
8484
if cache.geometries[key] == nil {
8585
cache.geometries[key] = Cache.GeometryCache()
8686
Game.unsafeShared.resourceManager.incrementLoading(path: key.requestedPath)
87-
Task.detached {
87+
Task {
8888
do {
8989
let geometry = try await RawGeometry(path: path, options: options)
9090
let lines = RawLines(wireframeFrom: geometry)

Sources/GateEngine/Resources/Geometry/Points.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ extension ResourceManager {
8484
if cache.geometries[key] == nil {
8585
cache.geometries[key] = Cache.GeometryCache()
8686
Game.unsafeShared.resourceManager.incrementLoading(path: key.requestedPath)
87-
Task.detached {
87+
Task {
8888
do {
8989
let geometry = try await RawGeometry(path: path, options: options)
9090
let points = RawPoints(pointCloudFrom: geometry)

Sources/GateEngine/Resources/Geometry/SkinnedGeometry.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ extension ResourceManager {
155155
if cache.skinnedGeometries[key] == nil {
156156
cache.skinnedGeometries[key] = Cache.SkinnedGeometryCache()
157157
Game.unsafeShared.resourceManager.incrementLoading(path: key.requestedPath)
158-
Task.detached {
158+
Task {
159159
do {
160160
let geometry = try await RawGeometry(path: path, options: geometryOptions)
161161
let skin = try await Skin(path: key.requestedPath, options: skinOptions)
@@ -233,7 +233,7 @@ extension ResourceManager {
233233
guard key.requestedPath[key.requestedPath.startIndex] != "$" else { return }
234234
guard self.skinnedGeometryNeedsReload(key: key) else { return }
235235
let cache = self.cache
236-
Task.detached {
236+
Task {
237237
let geometry = try await RawGeometry(
238238
path: key.requestedPath,
239239
options: key.geometryOptions

Sources/GateEngine/Resources/Import & Export/Importers/ApplePlatformImageImporter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public struct ApplePlatformImageImporter: TextureImporter {
6161
return try synchronousLoadTexture(options: options)
6262
}
6363

64-
public static func canProcessFile(_ path: String) -> Bool {
64+
public static func canProcessFile(at path: String) -> Bool {
6565
let pathExtension = URL(fileURLWithPath: path).pathExtension
6666
guard pathExtension.isEmpty == false else {return false}
6767
guard let uttype = UTType(tag: pathExtension, tagClass: .filenameExtension, conformingTo: .image) else {

Sources/GateEngine/Resources/Import & Export/Importers/ApplePlatformModelImporter.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public struct ApplePlatformModelImporter: GeometryImporter {
145145
public mutating func prepareToImportResourceFrom(path: String) async throws(GateEngineError) {
146146
guard let path = await Platform.current.locateResource(from: path) else {throw .failedToLocate(resource: path, nil) }
147147
self.asset = await withCheckedContinuation { continuation in
148-
Task.detached {
148+
Task {
149149
let asset = MDLAsset(url: URL(fileURLWithPath: path))
150150
continuation.resume(returning: asset)
151151
}
@@ -178,7 +178,7 @@ public struct ApplePlatformModelImporter: GeometryImporter {
178178
throw GateEngineError.failedToDecode("Failed to locate model.")
179179
}
180180

181-
public static func canProcessFile(_ path: String) -> Bool {
181+
public static func canProcessFile(at path: String) -> Bool {
182182
return MDLAsset.canImportFileExtension(URL(fileURLWithPath: path).pathExtension)
183183
}
184184
}

Sources/GateEngine/Resources/ResourceManager.swift

Lines changed: 72 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,31 @@ public protocol ResourceImporter: Sendable {
1313
init()
1414

1515
#if GATEENGINE_PLATFORM_HAS_SynchronousFileSystem
16+
/// Preloads the ResourceImporters data in preparation for decoding.
1617
mutating func synchronousPrepareToImportResourceFrom(path: String) throws(GateEngineError)
1718
#endif
1819
#if GATEENGINE_PLATFORM_HAS_AsynchronousFileSystem
20+
/// Preloads the ResourceImporters data in preparation for decoding.
1921
mutating func prepareToImportResourceFrom(path: String) async throws(GateEngineError)
2022
#endif
2123

24+
/// A list of file extensions that this resource importer is able to process.
2225
static func supportedFileExtensions() -> [String]
23-
static func canProcessFile(_ path: String) -> Bool
26+
27+
/**
28+
Checks if a file can be processed by this resource importer.
29+
- parameter path: The resource path of a file to check
30+
- returns: `true` if this resource importer can load a resource from the file at `path`
31+
- warning: This function is an advanced option rarely needed. Please implement `supportedFileExtensions()` instead.
32+
- seeAlso: `supportedFileExtensions()`
33+
*/
34+
static func canProcessFile(at path: String) -> Bool
2435

2536
/**
2637
Importers can report if they are capable of returning multiple resource instances from the same file.
2738

2839
Properly returning `true` or `false` will effect performance. If the importer can decode multiple resources,
29-
it will be kept in memory for a period of time allowing it to deocde more resources from the already accessed file data.
40+
it will be kept in memory for a period of time allowing it to deocde more resources from the already loaded file data.
3041
- returns: `true` if this importer is able to return more then one resources from a single file, otherwise `false`.
3142
*/
3243
mutating func currentFileContainsMutipleResources() -> Bool
@@ -46,9 +57,9 @@ public extension ResourceImporter {
4657
return []
4758
}
4859

49-
static func canProcessFile(_ path: String) -> Bool {
60+
static func canProcessFile(at path: String) -> Bool {
5061
let supportedExtensions = self.supportedFileExtensions()
51-
precondition(supportedExtensions.isEmpty == false, "Imporers must implement `supportedFileExtensions()` or `canProcessFile(_:)`.")
62+
precondition(supportedExtensions.isEmpty == false, "Imporers must implement `supportedFileExtensions()` or `canProcessFile(at:)`.")
5263
let fileExtension = URL(fileURLWithPath: path).pathExtension
5364
guard fileExtension.isEmpty == false else {return false}
5465
for supportedFileExtension in supportedExtensions {
@@ -107,38 +118,68 @@ extension ResourceManager {
107118
TiledTMJImporter.self,
108119
]
109120

110-
private var activeImporters: [ActiveImporterKey : ActiveImporter] = [:]
111-
private struct ActiveImporterKey: Hashable, Sendable {
112-
let path: String
113-
}
114-
private struct ActiveImporter: Sendable {
115-
let importer: any ResourceImporter
116-
var lastAccessed: Date = .now
117-
}
118-
119-
internal mutating func getImporter<I: ResourceImporter>(path: String, type: I.Type) async throws(GateEngineError) -> I {
120-
let key = ActiveImporterKey(path: path)
121-
if let existing = activeImporters[key] {
122-
// Make sure the importer can be the type requested
123-
if let importer = existing.importer as? I {
124-
activeImporters[key]?.lastAccessed = .now
125-
return importer
121+
/**
122+
Isolated cache of resource importers. Importers are mutable, but no changes are saved outside of the scode they are made.
123+
*/
124+
actor ActiveImporters {
125+
struct Key: Hashable, Sendable {
126+
let path: String
127+
}
128+
struct Importer: Sendable {
129+
let importer: any ResourceImporter
130+
var lastAccessed: Date = .now
131+
}
132+
var activeImporters: [Key : Importer] = [:]
133+
134+
subscript (_ key: Key) -> Importer? {
135+
get {
136+
return self.activeImporters[key]
137+
}
138+
set {
139+
self.activeImporters[key] = newValue
140+
}
141+
}
142+
143+
func setLastAccessed(for key: Key) {
144+
self.activeImporters[key]?.lastAccessed = .now
145+
}
146+
147+
func getImporter<I: ResourceImporter>(for path: String, type: I.Type) async throws(GateEngineError) -> I {
148+
let key = Key(path: path)
149+
if let existing = activeImporters[key] {
150+
// Make sure the importer can be the type requested
151+
if let importer = existing.importer as? I {
152+
activeImporters[key]?.lastAccessed = .now
153+
return importer
154+
}
155+
}
156+
var importer = type.init()
157+
try await importer.prepareToImportResourceFrom(path: path)
158+
if importer.currentFileContainsMutipleResources() {
159+
let active = ActiveImporters.Importer(importer: importer, lastAccessed: .now)
160+
activeImporters[key] = active
126161
}
162+
return importer
127163
}
128-
var importer = type.init()
129-
try await importer.prepareToImportResourceFrom(path: path)
130-
if importer.currentFileContainsMutipleResources() {
131-
let active = ActiveImporter(importer: importer, lastAccessed: .now)
132-
activeImporters[key] = active
164+
165+
func clean() {
166+
for key in activeImporters.keys {
167+
if activeImporters[key]!.lastAccessed.timeIntervalSinceNow < -5 {
168+
activeImporters.removeValue(forKey: key)
169+
}
170+
}
133171
}
134-
return importer
135172
}
173+
var activeImporters: ActiveImporters = .init()
136174

137-
internal mutating func clean() {
138-
for key in activeImporters.keys {
139-
if activeImporters[key]!.lastAccessed.timeIntervalSinceNow < -60 {
140-
activeImporters.removeValue(forKey: key)
141-
}
175+
internal func getImporter<I: ResourceImporter>(path: String, type: I.Type) async throws(GateEngineError) -> I {
176+
return try await activeImporters.getImporter(for: path, type: type)
177+
}
178+
179+
internal func clean() {
180+
let activeImporters = activeImporters
181+
Task {
182+
await activeImporters.clean()
142183
}
143184
}
144185
}

Sources/GateEngine/Resources/Skinning/SkeletalAnimation.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ extension ResourceManager {
319319

320320
func skeletalAnimationImporterForPath(_ path: String) async throws(GateEngineError) -> any SkeletalAnimationImporter {
321321
for type in self.importers.skeletalAnimationImporters {
322-
if type.canProcessFile(path) {
322+
if type.canProcessFile(at: path) {
323323
return try await self.importers.getImporter(path: path, type: type)
324324
}
325325
}
@@ -451,7 +451,7 @@ extension ResourceManager {
451451
func _reloadSkeletalAnimation(for key: Cache.SkeletalAnimationKey, isFirstLoad: Bool) {
452452
Game.unsafeShared.resourceManager.incrementLoading(path: key.requestedPath)
453453
let cache = self.cache
454-
Task.detached {
454+
Task {
455455
let path = key.requestedPath
456456

457457
do {

0 commit comments

Comments
 (0)