Skip to content

Commit 068f415

Browse files
committed
Harmonize _AttachableImageWrapper and AttachableAs___ across Darwin and Windows.
This PR makes some changes to harmonize the `_AttachableImageWrapper` wrapper type and the `AttachableAsCGImage`/`AttachableAsIWICBitmap` protocols across Darwin and Windows: - `_AttachableImageWrapper` is now a class on both platforms, not just Windows. - The `_makeCopyForAttachment()` function is now named `_copyAttachableValue()` (which is a more accurate name already used on Windows.) - A default implementation of `_copyAttachableValue()` and of `_deinitializeAttachableValue()` is provided for `Sendable` types on Windows.
1 parent f4736a6 commit 068f415

File tree

5 files changed

+28
-13
lines changed

5 files changed

+28
-13
lines changed

Sources/Overlays/_Testing_AppKit/Attachments/NSImage+AttachableAsCGImage.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ extension NSImage: AttachableAsCGImage {
5353
return maxRepWidth ?? 1.0
5454
}
5555

56-
public func _makeCopyForAttachment() -> Self {
56+
public func _copyAttachableValue() -> Self {
5757
// If this image is of an NSImage subclass, we cannot reliably make a deep
5858
// copy of it because we don't know what its `init(data:)` implementation
5959
// might do. Try to make a copy (using NSCopying), but if that doesn't work

Sources/Overlays/_Testing_CoreGraphics/Attachments/AttachableAsCGImage.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,17 @@ public protocol AttachableAsCGImage {
6565
///
6666
/// - Returns: A copy of `self`, or `self` if no copy is needed.
6767
///
68-
/// Several system image types do not conform to `Sendable`; use this
69-
/// function to make copies of such images that will not be shared outside
70-
/// of an attachment and so can be generally safely stored.
68+
/// The testing library uses this function to take ownership of image
69+
/// resources that test authors pass to it. If possible, make a copy of or add
70+
/// a reference to `self`. If this type does not support making copies, return
71+
/// `self` verbatim.
7172
///
7273
/// The default implementation of this function when `Self` conforms to
7374
/// `Sendable` simply returns `self`.
7475
///
7576
/// This function is not part of the public interface of the testing library.
7677
/// It may be removed in a future update.
77-
func _makeCopyForAttachment() -> Self
78+
func _copyAttachableValue() -> Self
7879
}
7980

8081
@available(_uttypesAPI, *)
@@ -90,7 +91,7 @@ extension AttachableAsCGImage {
9091

9192
@available(_uttypesAPI, *)
9293
extension AttachableAsCGImage where Self: Sendable {
93-
public func _makeCopyForAttachment() -> Self {
94+
public func _copyAttachableValue() -> Self {
9495
self
9596
}
9697
}

Sources/Overlays/_Testing_CoreGraphics/Attachments/_AttachableImageWrapper.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,20 @@ import UniformTypeIdentifiers
5454
/// (iOS, watchOS, tvOS, visionOS, and Mac Catalyst)
5555
@_spi(Experimental)
5656
@available(_uttypesAPI, *)
57-
public struct _AttachableImageWrapper<Image>: Sendable where Image: AttachableAsCGImage {
57+
public final class _AttachableImageWrapper<Image>: Sendable where Image: AttachableAsCGImage {
5858
/// The underlying image.
5959
///
6060
/// `CGImage` and `UIImage` are sendable, but `NSImage` is not. `NSImage`
6161
/// instances can be created from closures that are run at rendering time.
6262
/// The AppKit cross-import overlay is responsible for ensuring that any
6363
/// instances of this type it creates hold "safe" `NSImage` instances.
64-
nonisolated(unsafe) var image: Image
64+
nonisolated(unsafe) let image: Image
6565

6666
/// The image format to use when encoding the represented image.
67-
var imageFormat: AttachableImageFormat?
67+
let imageFormat: AttachableImageFormat?
6868

6969
init(image: Image, imageFormat: AttachableImageFormat?) {
70-
self.image = image._makeCopyForAttachment()
70+
self.image = image._copyAttachableValue()
7171
self.imageFormat = imageFormat
7272
}
7373
}
@@ -80,7 +80,7 @@ extension _AttachableImageWrapper: AttachableWrapper {
8080
image
8181
}
8282

83-
public func withUnsafeBytes<R>(for attachment: borrowing Attachment<Self>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
83+
public func withUnsafeBytes<R>(for attachment: borrowing Attachment<_AttachableImageWrapper>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
8484
let data = NSMutableData()
8585

8686
// Convert the image to a CGImage.
@@ -116,7 +116,7 @@ extension _AttachableImageWrapper: AttachableWrapper {
116116
}
117117
}
118118

119-
public borrowing func preferredName(for attachment: borrowing Attachment<Self>, basedOn suggestedName: String) -> String {
119+
public borrowing func preferredName(for attachment: borrowing Attachment<_AttachableImageWrapper>, basedOn suggestedName: String) -> String {
120120
let contentType = AttachableImageFormat.computeContentType(for: imageFormat, withPreferredName: suggestedName)
121121
return (suggestedName as NSString).appendingPathExtension(for: contentType)
122122
}

Sources/Overlays/_Testing_CoreImage/Attachments/CIImage+AttachableAsCGImage.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ extension CIImage: AttachableAsCGImage {
2323
}
2424
}
2525

26-
public func _makeCopyForAttachment() -> Self {
26+
public func _copyAttachableValue() -> Self {
2727
// CIImage is documented as thread-safe, but does not conform to Sendable.
2828
// It conforms to NSCopying but does not actually copy itself, so there's no
2929
// point in calling copy().

Sources/Overlays/_Testing_WinSDK/Attachments/AttachableAsIWICBitmap.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ public protocol AttachableAsIWICBitmap {
138138
/// a reference to `self`. If this type does not support making copies, return
139139
/// `self` verbatim.
140140
///
141+
/// The default implementation of this function when `Self` conforms to
142+
/// `Sendable` simply returns `self`.
143+
///
141144
/// This function is not part of the public interface of the testing library.
142145
/// It may be removed in a future update.
143146
func _copyAttachableValue() -> Self
@@ -151,6 +154,9 @@ public protocol AttachableAsIWICBitmap {
151154
/// This function is not responsible for releasing the image returned from
152155
/// `_copyAttachableIWICBitmap(using:)`.
153156
///
157+
/// The default implementation of this function when `Self` conforms to
158+
/// `Sendable` does nothing.
159+
///
154160
/// This function is not part of the public interface of the testing library.
155161
/// It may be removed in a future update.
156162
func _deinitializeAttachableValue()
@@ -190,4 +196,12 @@ extension AttachableAsIWICBitmap {
190196
}
191197
}
192198
}
199+
200+
extension AttachableAsIWICBitmap where Self: Sendable {
201+
public func _copyAttachableValue() -> Self {
202+
self
203+
}
204+
205+
public func _deinitializeAttachableValue() {}
206+
}
193207
#endif

0 commit comments

Comments
 (0)