@@ -12,33 +12,91 @@ import LiveViewNative
12
12
final class AsyncEntity : Entity {
13
13
var setupTask : Task < ( ) , Error > ? = nil
14
14
15
+ static var entityCache = [ URL: Entity] ( )
16
+
15
17
init < E: EntityRegistry , C: ComponentRegistry > (
16
18
from element: ElementNode ,
17
19
in context: EntityContentBuilder < E , C > . Context < some RootRegistry >
18
- ) {
20
+ ) throws {
19
21
AsyncEntityComponent . registerComponent ( )
20
22
21
23
super. init ( )
22
24
25
+ let loadSync = element. attributeBoolean ( for: " loadSync " )
26
+
23
27
if let url = element. attributeValue ( for: " url " ) . flatMap ( { URL ( string: $0, relativeTo: context. url) } ) {
24
- setupTask = Task { [ weak self] in
25
- let ( fileURL, _) = try await URLSession . shared. download ( from: url)
26
- let correctedExtensionURL = fileURL. deletingPathExtension ( ) . appendingPathExtension ( for: . usdz)
27
- try FileManager . default. moveItem ( at: fileURL, to: correctedExtensionURL)
28
+ if let cached = Self . entityCache [ url] {
29
+ let entity = cached. clone ( recursive: true )
30
+ entity. components. set ( AsyncEntityComponent . remote ( url) )
31
+ self . addChild ( entity)
32
+ } else if loadSync {
33
+ let group = DispatchGroup ( )
34
+ group. enter ( )
28
35
29
- do {
30
- let entity = try await Entity ( contentsOf: correctedExtensionURL)
31
- entity. components. set ( AsyncEntityComponent . remote ( url) )
32
- self ? . addChild ( entity)
33
-
34
- try self ? . updateResolvedEntity ( with: element, in: context)
36
+ var fileURL : Result < URL , Error > !
37
+
38
+ let downloadTask = URLSession . shared. downloadTask ( with: url) { result, _, error in
39
+ if let result {
40
+ fileURL = . success( result)
41
+ } else {
42
+ fileURL = . failure( error!)
43
+ }
44
+ group. leave ( )
35
45
}
46
+ downloadTask. resume ( )
36
47
37
- try FileManager . default. removeItem ( at: correctedExtensionURL)
48
+ group. wait ( )
49
+
50
+ switch fileURL! {
51
+ case . success( let fileURL) :
52
+ let correctedExtensionURL = fileURL. deletingPathExtension ( ) . appendingPathExtension ( for: . usdz)
53
+ try FileManager . default. moveItem ( at: fileURL, to: correctedExtensionURL)
54
+
55
+ do {
56
+ let entity = try Entity . load ( contentsOf: correctedExtensionURL)
57
+ Self . entityCache [ url] = entity. clone ( recursive: true )
58
+ entity. components. set ( AsyncEntityComponent . remote ( url) )
59
+ self . addChild ( entity)
60
+
61
+ try self . updateResolvedEntity ( with: element, in: context)
62
+ } catch {
63
+ try FileManager . default. removeItem ( at: correctedExtensionURL)
64
+ throw error
65
+ }
66
+
67
+ try FileManager . default. removeItem ( at: correctedExtensionURL)
68
+ case . failure( let error) :
69
+ throw error
70
+ }
71
+ } else {
72
+ setupTask = Task { [ weak self] in
73
+ let ( fileURL, _) = try await URLSession . shared. download ( from: url)
74
+ let correctedExtensionURL = fileURL. deletingPathExtension ( ) . appendingPathExtension ( for: . usdz)
75
+ try FileManager . default. moveItem ( at: fileURL, to: correctedExtensionURL)
76
+
77
+ do {
78
+ let entity = try await Entity ( contentsOf: correctedExtensionURL)
79
+ Self . entityCache [ url] = entity. clone ( recursive: true )
80
+ entity. components. set ( AsyncEntityComponent . remote ( url) )
81
+ self ? . addChild ( entity)
82
+
83
+ try self ? . updateResolvedEntity ( with: element, in: context)
84
+ } catch {
85
+ try FileManager . default. removeItem ( at: correctedExtensionURL)
86
+ throw error
87
+ }
88
+ try FileManager . default. removeItem ( at: correctedExtensionURL)
89
+ }
38
90
}
39
91
} else if let named = element. attributeValue ( for: " named " ) {
40
- setupTask = Task { [ weak self] in
41
- do {
92
+ if loadSync {
93
+ let entity = try Entity . load ( named: named)
94
+ entity. components. set ( AsyncEntityComponent . named ( named) )
95
+ self . addChild ( entity)
96
+
97
+ try self . updateResolvedEntity ( with: element, in: context)
98
+ } else {
99
+ setupTask = Task { [ weak self] in
42
100
let entity = try await Entity ( named: named)
43
101
entity. components. set ( AsyncEntityComponent . named ( named) )
44
102
self ? . addChild ( entity)
0 commit comments