diff --git a/Generator/Sources/CodeWriters/Swift/SyntaxWriters/Members.swift b/Generator/Sources/CodeWriters/Swift/SyntaxWriters/Members.swift index cde78922..033e354e 100644 --- a/Generator/Sources/CodeWriters/Swift/SyntaxWriters/Members.swift +++ b/Generator/Sources/CodeWriters/Swift/SyntaxWriters/Members.swift @@ -92,6 +92,7 @@ extension SwiftDeclarationWriter { visibility: SwiftVisibility = .implicit, static: Bool = false, override: Bool = false, + mutating: Bool = false, name: String, typeParams: [String] = [], params: [SwiftParam] = [], @@ -106,6 +107,7 @@ extension SwiftDeclarationWriter { visibility: visibility, static: `static`, override: `override`, + mutating: `mutating`, name: name, typeParams: typeParams, params: params, diff --git a/Generator/Sources/CodeWriters/Swift/SyntaxWriters/Protocols.swift b/Generator/Sources/CodeWriters/Swift/SyntaxWriters/Protocols.swift index ae4ef910..afc0eb4e 100644 --- a/Generator/Sources/CodeWriters/Swift/SyntaxWriters/Protocols.swift +++ b/Generator/Sources/CodeWriters/Swift/SyntaxWriters/Protocols.swift @@ -69,6 +69,7 @@ public struct SwiftProtocolBodyWriter: SwiftSyntaxWriter { documentation: SwiftDocumentationComment? = nil, isPropertySetter: Bool = false, static: Bool = false, + mutating: Bool = false, name: String, typeParams: [String] = [], params: [SwiftParam] = [], @@ -81,6 +82,7 @@ public struct SwiftProtocolBodyWriter: SwiftSyntaxWriter { writeFuncHeader( visibility: .implicit, static: `static`, + mutating: `mutating`, name: name, typeParams: typeParams, params: params, diff --git a/Generator/Sources/CodeWriters/Swift/SyntaxWriters/SourceFile.swift b/Generator/Sources/CodeWriters/Swift/SyntaxWriters/SourceFile.swift index 98b47b38..d38b5b36 100644 --- a/Generator/Sources/CodeWriters/Swift/SyntaxWriters/SourceFile.swift +++ b/Generator/Sources/CodeWriters/Swift/SyntaxWriters/SourceFile.swift @@ -5,18 +5,22 @@ public struct SwiftSourceFileWriter: SwiftDeclarationWriter { self.output = IndentedTextOutputStream(inner: output, indent: indent) } - public func writeImport(module: String) { + public func writeImport(exported: Bool = false, module: String) { output.beginLine(grouping: .withName("import")) + if exported { output.write("@_exported ") } output.write("import ") output.write(module, endLine: true) } - public func writeImport(module: String, struct: String) { + public func writeImport(exported: Bool = false, kind: SwiftImportKind, module: String, symbolName: String) { output.beginLine(grouping: .withName("import")) - output.write("import struct ") + if exported { output.write("@_exported ") } + output.write("import ") + output.write(String(describing: kind)) + output.write(" ") output.write(module) output.write(".") - output.write(`struct`, endLine: true) + output.write(symbolName, endLine: true) } public func writeExtension( diff --git a/Generator/Sources/CodeWriters/Swift/SyntaxWriters/Statements.swift b/Generator/Sources/CodeWriters/Swift/SyntaxWriters/Statements.swift index 49edd626..7618d7fb 100644 --- a/Generator/Sources/CodeWriters/Swift/SyntaxWriters/Statements.swift +++ b/Generator/Sources/CodeWriters/Swift/SyntaxWriters/Statements.swift @@ -61,4 +61,34 @@ public struct SwiftStatementWriter: SwiftSyntaxWriter { try body(SwiftStatementWriter(output: output)) } } + + public func writeIf( + conditions: [String], + then: (_ writer: SwiftStatementWriter) throws -> Void, + else: ((_ writer: SwiftStatementWriter) throws -> Void)? = nil) rethrows { + precondition(!conditions.isEmpty) + output.write("if ") + for (index, condition) in conditions.enumerated() { + if index > 0 { output.write(", ") } + output.write(condition) + } + output.write(" {", endLine: true) + try output.writeIndentedBlock { try then(SwiftStatementWriter(output: output)) } + output.endLine() + output.write("}") + if let `else` { + output.write(" else {", endLine: true) + try output.writeIndentedBlock { try `else`(SwiftStatementWriter(output: output)) } + output.endLine() + output.write("}") + } + output.endLine() + } + + public func writeIf( + _ condition: String, + then: (_ writer: SwiftStatementWriter) throws -> Void, + else: ((_ writer: SwiftStatementWriter) throws -> Void)? = nil) rethrows { + try writeIf(conditions: [condition], then: then, else: `else`) + } } \ No newline at end of file diff --git a/Generator/Sources/CodeWriters/Swift/SyntaxWriters/SwiftImportKind.swift b/Generator/Sources/CodeWriters/Swift/SyntaxWriters/SwiftImportKind.swift new file mode 100644 index 00000000..9f997a06 --- /dev/null +++ b/Generator/Sources/CodeWriters/Swift/SyntaxWriters/SwiftImportKind.swift @@ -0,0 +1,10 @@ +public enum SwiftImportKind: Hashable { + case `typealias` + case `struct` + case `class` + case `enum` + case `protocol` + case `let` + case `var` + case `func` +} \ No newline at end of file diff --git a/Generator/Sources/CodeWriters/Swift/SyntaxWriters/SyntaxWriters.swift b/Generator/Sources/CodeWriters/Swift/SyntaxWriters/SyntaxWriters.swift index 59e95ec2..81032139 100644 --- a/Generator/Sources/CodeWriters/Swift/SyntaxWriters/SyntaxWriters.swift +++ b/Generator/Sources/CodeWriters/Swift/SyntaxWriters/SyntaxWriters.swift @@ -60,6 +60,7 @@ extension SwiftSyntaxWriter { visibility: SwiftVisibility = .implicit, static: Bool = false, override: Bool = false, + mutating: Bool = false, name: String, typeParams: [String] = [], params: [SwiftParam] = [], @@ -71,6 +72,7 @@ extension SwiftSyntaxWriter { visibility.write(to: &output, trailingSpace: true) if `static` { output.write("static ") } if `override` { output.write("override ") } + if `mutating` { output.write("mutating ") } output.write("func ") SwiftIdentifier.write(name, to: &output) writeTypeParams(typeParams) diff --git a/Generator/Sources/ProjectionModel/SupportModules.swift b/Generator/Sources/ProjectionModel/SupportModules.swift index c1917e4c..4ba7cead 100644 --- a/Generator/Sources/ProjectionModel/SupportModules.swift +++ b/Generator/Sources/ProjectionModel/SupportModules.swift @@ -91,14 +91,44 @@ extension SupportModules.WinRT { public static var winRTClassLoader: SwiftType { .chain(moduleName, "WinRTClassLoader") } } +public enum BuiltInTypeKind { + /// Indicates that the support module has special support for this type, + /// and no definition or projection should be generated. + case special + /// Indicates that the support module exposes a definition for this type, but no projection. + case definitionOnly + /// Indicates that the support module exposes both a definition and a projection for this type. + case definitionAndProjection +} + extension SupportModules.WinRT { - public static func hasBuiltInProjection(_ typeDefinition: TypeDefinition) -> Bool { - if typeDefinition.namespace == "Windows.Foundation" { - switch typeDefinition.name { - case "EventRegistrationToken", "HResult", "IReference`1": return true - default: return false - } + private enum BuiltInTypes { + internal static let windowsFoundation: Dictionary = [ + "DateTime": .definitionOnly, + "EventRegistrationToken": .special, + "HResult": .special, + "IPropertyValue": .definitionOnly, + "IReference`1": .definitionAndProjection, + "IStringable": .definitionAndProjection, + "Point": .definitionOnly, + "PropertyType": .definitionOnly, + "Rect": .definitionOnly, + "Size": .definitionOnly, + "TimeSpan": .definitionOnly + ] + internal static let windowsFoundationCollections = [ + "IIterable`1", + "IIterator`1" + ] + } + + public static func getBuiltInTypeKind(_ typeDefinition: TypeDefinition) -> BuiltInTypeKind? { + switch typeDefinition.namespace { + case "Windows.Foundation": + return BuiltInTypes.windowsFoundation[typeDefinition.name] + case "Windows.Foundation.Collections": + return BuiltInTypes.windowsFoundationCollections.contains(typeDefinition.name) ? .definitionOnly : nil + default: return nil } - return false } } \ No newline at end of file diff --git a/Generator/Sources/SwiftWinRT/Writing/ABIProjectionType.swift b/Generator/Sources/SwiftWinRT/Writing/ABIProjectionType.swift index 701294bf..61760bb8 100644 --- a/Generator/Sources/SwiftWinRT/Writing/ABIProjectionType.swift +++ b/Generator/Sources/SwiftWinRT/Writing/ABIProjectionType.swift @@ -14,7 +14,7 @@ internal func writeABIProjectionsFile(module: SwiftProjection.Module, toPath pat for typeDefinition in typeDefinitions.sorted(by: { $0.fullName < $1.fullName }) { if let classDefinition = typeDefinition as? ClassDefinition, classDefinition.isStatic { continue } guard typeDefinition.isPublic, - !SupportModules.WinRT.hasBuiltInProjection(typeDefinition), + SupportModules.WinRT.getBuiltInTypeKind(typeDefinition) != .special, try !typeDefinition.hasAttribute(ApiContractAttribute.self) else { continue } writer.writeMarkComment(typeDefinition.fullName) @@ -25,7 +25,7 @@ internal func writeABIProjectionsFile(module: SwiftProjection.Module, toPath pat let closedGenericTypesByDefinition = module.closedGenericTypesByDefinition .sorted { $0.key.fullName < $1.key.fullName } for (typeDefinition, instantiations) in closedGenericTypesByDefinition { - guard !SupportModules.WinRT.hasBuiltInProjection(typeDefinition) else { continue } + guard SupportModules.WinRT.getBuiltInTypeKind(typeDefinition) != .special else { continue } for genericArgs in instantiations { writer.writeMarkComment(try WinRTTypeName.from(type: typeDefinition.bindType(genericArgs: genericArgs)).description) @@ -36,6 +36,15 @@ internal func writeABIProjectionsFile(module: SwiftProjection.Module, toPath pat /// Writes a type or extension providing the ABIProjection conformance for a given projected WinRT type. internal func writeABIProjectionConformance(_ typeDefinition: TypeDefinition, genericArgs: [TypeNode]?, projection: SwiftProjection, to writer: SwiftSourceFileWriter) throws { + if SupportModules.WinRT.getBuiltInTypeKind(typeDefinition) == .definitionAndProjection { + // The support module already defines a projection, just import and reexport it. + if typeDefinition.isReferenceType { + let projectionTypeName = try projection.toProjectionTypeName(typeDefinition) + writer.writeImport(exported: true, kind: .enum, module: SupportModules.WinRT.moduleName, symbolName: projectionTypeName) + } + return + } + if let structDefinition = typeDefinition as? StructDefinition { assert(genericArgs == nil) try writeStructProjectionExtension(structDefinition, projection: projection, to: writer) diff --git a/Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift index 90e0d165..903334f9 100644 --- a/Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift @@ -15,19 +15,20 @@ import WindowsMetadata // // var foo: IFoo? = getFoo() internal func writeInterfaceDefinition(_ interface: InterfaceDefinition, projection: SwiftProjection, to writer: SwiftSourceFileWriter) throws { - try writeProtocolTypeAlias(interface, projection: projection, to: writer) - try writeProtocol(interface, projection: projection, to: writer) + if SupportModules.WinRT.getBuiltInTypeKind(interface) != nil { + // Defined in WindowsRuntime, merely reexport it here. + let protocolName = try projection.toProtocolName(interface) + writer.writeImport(exported: true, kind: .protocol, module: SupportModules.WinRT.moduleName, symbolName: protocolName) - let typeName = try projection.toProtocolName(interface) - switch interface.name { - case "IAsyncAction", "IAsyncActionWithProgress`1": - try writeIAsyncExtensions(protocolName: typeName, resultType: nil, to: writer) - case "IAsyncOperation`1", "IAsyncOperationWithProgress`2": - try writeIAsyncExtensions( - protocolName: typeName, - resultType: .identifier(name: String(interface.genericParams[0].name)), - to: writer) - default: break + // Import the existential typealias as a protocol to work around compiler bug https://github.com/apple/swift/issues/72724: + // "'IFoo' was imported as 'typealias', but is a protocol" + let typeName = try projection.toTypeName(interface) + writer.writeImport(exported: true, kind: .protocol, module: SupportModules.WinRT.moduleName, symbolName: typeName) + } + else { + try writeProtocolTypeAlias(interface, projection: projection, to: writer) + try writeProtocol(interface, projection: projection, to: writer) + try writeInterfaceExtensions(interface, projection: projection, to: writer) } } @@ -136,21 +137,3 @@ fileprivate func writeProtocolTypeAlias(_ interfaceDefinition: InterfaceDefiniti name: try projection.toProtocolName(interfaceDefinition), genericArgs: interfaceDefinition.genericParams.map { .identifier(name: $0.name) })) } - -fileprivate func writeIAsyncExtensions(protocolName: String, resultType: SwiftType?, to writer: SwiftSourceFileWriter) throws { - writer.writeExtension(type: .identifier(protocolName)) { writer in - // public get() async throws - writer.writeFunc(visibility: .public, name: "get", async: true, throws: true, returnType: resultType) { writer in - writer.output.writeIndentedBlock(header: "if try _status() == .started {", footer: "}") { - // We can't await if the completed handler is already set - writer.writeStatement("guard try \(SupportModules.COM.nullResult).catch(_completed()) == nil else { throw \(SupportModules.COM.hresult).Error.illegalMethodCall }") - writer.writeStatement("let awaiter = WindowsRuntime.AsyncAwaiter()") - writer.writeStatement("try _completed({ _, _ in _Concurrency.Task { await awaiter.signal() } })") - writer.writeStatement("await awaiter.wait()") - } - - // Handles exceptions and cancelation - writer.writeStatement("return try getResults()") - } - } -} \ No newline at end of file diff --git a/Generator/Sources/SwiftWinRT/Writing/InterfaceExtensions.swift b/Generator/Sources/SwiftWinRT/Writing/InterfaceExtensions.swift new file mode 100644 index 00000000..f34b8082 --- /dev/null +++ b/Generator/Sources/SwiftWinRT/Writing/InterfaceExtensions.swift @@ -0,0 +1,40 @@ +import CodeWriters +import DotNetMetadata +import WindowsMetadata +import ProjectionModel + +internal func writeInterfaceExtensions(_ interface: InterfaceDefinition, projection: SwiftProjection, to writer: SwiftSourceFileWriter) throws { + switch interface.namespace { + case "Windows.Foundation": + let typeName = try projection.toProtocolName(interface) + switch interface.name { + case "IAsyncAction", "IAsyncActionWithProgress`1": + try writeIAsyncExtensions(protocolName: typeName, resultType: nil, to: writer) + case "IAsyncOperation`1", "IAsyncOperationWithProgress`2": + try writeIAsyncExtensions( + protocolName: typeName, + resultType: .identifier(name: String(interface.genericParams[0].name)), + to: writer) + default: break + } + default: break + } +} + +internal func writeIAsyncExtensions(protocolName: String, resultType: SwiftType?, to writer: SwiftSourceFileWriter) throws { + writer.writeExtension(type: .identifier(protocolName)) { writer in + // public get() async throws + writer.writeFunc(visibility: .public, name: "get", async: true, throws: true, returnType: resultType) { writer in + writer.output.writeIndentedBlock(header: "if try _status() == .started {", footer: "}") { + // We can't await if the completed handler is already set + writer.writeStatement("guard try \(SupportModules.COM.nullResult).catch(_completed()) == nil else { throw \(SupportModules.COM.hresult).Error.illegalMethodCall }") + writer.writeStatement("let awaiter = WindowsRuntime.AsyncAwaiter()") + writer.writeStatement("try _completed({ _, _ in _Concurrency.Task { await awaiter.signal() } })") + writer.writeStatement("await awaiter.wait()") + } + + // Handles exceptions and cancelation + writer.writeStatement("return try getResults()") + } + } +} diff --git a/Generator/Sources/SwiftWinRT/Writing/SourcePreamble.swift b/Generator/Sources/SwiftWinRT/Writing/SourcePreamble.swift index 3ec2e1aa..7ffd9806 100644 --- a/Generator/Sources/SwiftWinRT/Writing/SourcePreamble.swift +++ b/Generator/Sources/SwiftWinRT/Writing/SourcePreamble.swift @@ -15,5 +15,5 @@ internal func writeModulePreamble(_ module: SwiftProjection.Module, to writer: S writer.writeImport(module: referencedModule.name) } - writer.writeImport(module: "Foundation", struct: "UUID") + writer.writeImport(kind: .struct, module: "Foundation", symbolName: "UUID") } \ No newline at end of file diff --git a/Generator/Sources/SwiftWinRT/Writing/StructDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/StructDefinition.swift index 180bcc21..ed7939d1 100644 --- a/Generator/Sources/SwiftWinRT/Writing/StructDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/StructDefinition.swift @@ -4,22 +4,21 @@ import ProjectionModel import WindowsMetadata internal func writeStructDefinition(_ structDefinition: StructDefinition, projection: SwiftProjection, to writer: SwiftSourceFileWriter) throws { - try writer.writeStruct( - documentation: projection.getDocumentationComment(structDefinition), - visibility: SwiftProjection.toVisibility(structDefinition.visibility), - name: try projection.toTypeName(structDefinition), - typeParams: structDefinition.genericParams.map { $0.name }, - protocolConformances: [ .identifier("Hashable"), .identifier("Codable") ]) { writer throws in - try writeStructFields(structDefinition, projection: projection, to: writer) - try writeDefaultInitializer(structDefinition, projection: projection, to: writer) - try writeFieldwiseInitializer(structDefinition, projection: projection, to: writer) - } - - if structDefinition.fullName == "Windows.Foundation.DateTime" { - try writeDateTimeExtensions(typeName: try projection.toTypeName(structDefinition), to: writer) - } - else if structDefinition.fullName == "Windows.Foundation.TimeSpan" { - try writeTimeSpanExtensions(typeName: try projection.toTypeName(structDefinition), to: writer) + if SupportModules.WinRT.getBuiltInTypeKind(structDefinition) != nil { + // Defined in WindowsRuntime, merely reexport it here. + let typeName = try projection.toTypeName(structDefinition) + writer.writeImport(exported: true, kind: .struct, module: SupportModules.WinRT.moduleName, symbolName: typeName) + } else { + try writer.writeStruct( + documentation: projection.getDocumentationComment(structDefinition), + visibility: SwiftProjection.toVisibility(structDefinition.visibility), + name: try projection.toTypeName(structDefinition), + typeParams: structDefinition.genericParams.map { $0.name }, + protocolConformances: [ .identifier("Hashable"), .identifier("Codable") ]) { writer throws in + try writeStructFields(structDefinition, projection: projection, to: writer) + try writeDefaultInitializer(structDefinition, projection: projection, to: writer) + try writeFieldwiseInitializer(structDefinition, projection: projection, to: writer) + } } } @@ -77,47 +76,3 @@ fileprivate func writeFieldwiseInitializer(_ structDefinition: StructDefinition, } } } - -fileprivate func writeDateTimeExtensions(typeName: String, to writer: SwiftSourceFileWriter) throws { - writer.writeImport(module: "Foundation", struct: "Date") - - writer.writeExtension(type: .identifier(typeName)) { writer in - // public init(foundationDate: Date) - writer.writeInit(visibility: .public, - params: [.init(name: "foundationDate", type: .chain("Foundation", "Date"))]) { writer in - // TimeInterval has limited precision to work with (it is a Double), so explicitly work at millisecond precision - writer.writeStatement("self.init(universalTime: (Int64(foundationDate.timeIntervalSince1970 * 1000) + 11_644_473_600_000) * 10_000)") - } - - // public var foundationDate: Date - writer.writeComputedProperty(visibility: .public, name: "foundationDate", type: .chain("Foundation", "Date"), - get: { writer in - // TimeInterval has limited precision to work with (it is a Double), so explicitly work at millisecond precision - writer.writeStatement("Date(timeIntervalSince1970: Double(universalTime / 10_000) / 1000 - 11_644_473_600)") - }, - set: { writer in - writer.writeStatement("self = Self(foundationDate: newValue)") - }) - } -} - -fileprivate func writeTimeSpanExtensions(typeName: String, to writer: SwiftSourceFileWriter) throws { - writer.writeImport(module: "Foundation", struct: "TimeInterval") - - writer.writeExtension(type: .identifier(typeName)) { writer in - // public init(timeInterval: TimeInterval) - writer.writeInit(visibility: .public, - params: [.init(name: "timeInterval", type: .chain("Foundation", "TimeInterval"))]) { writer in - writer.writeStatement("self.init(duration: Int64(timeInterval * 10_000_000))") - } - - // public var timeInterval: TimeInterval - writer.writeComputedProperty(visibility: .public, name: "timeInterval", type: .chain("Foundation", "TimeInterval"), - get: { writer in - writer.writeStatement("Double(duration) / 10_000_000") - }, - set: { writer in - writer.writeStatement("self = Self(timeInterval: newValue)") - }) - } -} \ No newline at end of file diff --git a/Generator/Sources/SwiftWinRT/Writing/TypeDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/TypeDefinition.swift index 2144c0da..dfc5102e 100644 --- a/Generator/Sources/SwiftWinRT/Writing/TypeDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/TypeDefinition.swift @@ -20,6 +20,13 @@ internal func writeTypeDefinition(_ typeDefinition: TypeDefinition, projection: } fileprivate func writeEnumDefinition(_ enumDefinition: EnumDefinition, projection: SwiftProjection, to writer: SwiftSourceFileWriter) throws { + if SupportModules.WinRT.getBuiltInTypeKind(enumDefinition) != nil { + // Defined in WindowsRuntime, merely reexport it here. + let typeName = try projection.toTypeName(enumDefinition) + writer.writeImport(exported: true, kind: .struct, module: SupportModules.WinRT.moduleName, symbolName: typeName) + return + } + // Enums are syntactic sugar for integers in .NET, // so we cannot guarantee that the enumerants are exhaustive, // therefore we cannot project them to Swift enums diff --git a/Generator/Sources/SwiftWinRT/writeProjectionFiles.swift b/Generator/Sources/SwiftWinRT/writeProjectionFiles.swift index 61b0c84a..2d0dc47a 100644 --- a/Generator/Sources/SwiftWinRT/writeProjectionFiles.swift +++ b/Generator/Sources/SwiftWinRT/writeProjectionFiles.swift @@ -28,7 +28,7 @@ internal func writeProjectionFiles(_ projection: SwiftProjection, generateComman var typeDefinitions = Array(typeDefinitions) try typeDefinitions.removeAll { - try !$0.isPublic || SupportModules.WinRT.hasBuiltInProjection($0) || $0.hasAttribute(ApiContractAttribute.self) + try !$0.isPublic || SupportModules.WinRT.getBuiltInTypeKind($0) == .special || $0.hasAttribute(ApiContractAttribute.self) } typeDefinitions.sort { $0.fullName < $1.fullName } diff --git a/InteropTests/Tests/CollectionTests.swift b/InteropTests/Tests/CollectionTests.swift new file mode 100644 index 00000000..3f93a9cd --- /dev/null +++ b/InteropTests/Tests/CollectionTests.swift @@ -0,0 +1,16 @@ +import XCTest +import WinRTComponent + +class CollectionTests: WinRTTestCase { + func testIteration() throws { + let iterable = try Collections.createIterable([3, 2, 1]) + let iterator = try iterable.first() + XCTAssert(try iterator._hasCurrent()) + XCTAssertEqual(try iterator._current(), 3) + XCTAssert(try iterator.moveNext()) + XCTAssertEqual(try iterator._current(), 2) + XCTAssert(try iterator.moveNext()) + XCTAssertEqual(try iterator._current(), 1) + XCTAssertFalse(try iterator.moveNext()) + } +} \ No newline at end of file diff --git a/InteropTests/WinRTComponent/Collections.cpp b/InteropTests/WinRTComponent/Collections.cpp new file mode 100644 index 00000000..c2c48531 --- /dev/null +++ b/InteropTests/WinRTComponent/Collections.cpp @@ -0,0 +1,22 @@ +#include "pch.h" +#include "Collections.h" +#include "Collections.g.cpp" + +namespace winrt::WinRTComponent::implementation +{ + winrt::Windows::Foundation::Collections::IIterable Collections::CreateIterable(array_view values) + { + return winrt::single_threaded_vector(std::vector(values.begin(), values.end())); + } + winrt::Windows::Foundation::Collections::IVector Collections::CreateVector(array_view values) + { + return winrt::single_threaded_vector(std::vector(values.begin(), values.end())); + } + com_array Collections::IterableToArray(winrt::Windows::Foundation::Collections::IIterable const& iterable) + { + std::vector result; + for (auto iterator = iterable.First(); iterator.HasCurrent(); iterator.MoveNext()) + result.push_back(iterator.Current()); + return com_array(result); + } +} diff --git a/InteropTests/WinRTComponent/Collections.h b/InteropTests/WinRTComponent/Collections.h new file mode 100644 index 00000000..8456fc3c --- /dev/null +++ b/InteropTests/WinRTComponent/Collections.h @@ -0,0 +1,20 @@ +#pragma once +#include "Collections.g.h" + +namespace winrt::WinRTComponent::implementation +{ + struct Collections + { + Collections() = default; + + static winrt::Windows::Foundation::Collections::IIterable CreateIterable(array_view values); + static winrt::Windows::Foundation::Collections::IVector CreateVector(array_view values); + static com_array IterableToArray(winrt::Windows::Foundation::Collections::IIterable const& iterable); + }; +} +namespace winrt::WinRTComponent::factory_implementation +{ + struct Collections : CollectionsT + { + }; +} diff --git a/InteropTests/WinRTComponent/Collections.idl b/InteropTests/WinRTComponent/Collections.idl new file mode 100644 index 00000000..f67910f7 --- /dev/null +++ b/InteropTests/WinRTComponent/Collections.idl @@ -0,0 +1,10 @@ +namespace WinRTComponent +{ + static runtimeclass Collections + { + static Windows.Foundation.Collections.IIterable CreateIterable(Int32[] values); + static Windows.Foundation.Collections.IVector CreateVector(Int32[] values); + + static Int32[] IterableToArray(Windows.Foundation.Collections.IIterable iterable); + }; +} \ No newline at end of file diff --git a/InteropTests/WinRTComponent/WinRTComponent.vcxproj b/InteropTests/WinRTComponent/WinRTComponent.vcxproj index 5feb26a8..be8e77de 100644 --- a/InteropTests/WinRTComponent/WinRTComponent.vcxproj +++ b/InteropTests/WinRTComponent/WinRTComponent.vcxproj @@ -115,8 +115,8 @@ Arrays.idl - - InspectableBoxing.idl + + Collections.idl DateTimes.idl @@ -130,6 +130,9 @@ Errors.idl + + InspectableBoxing.idl + Int32Wrapper.idl @@ -180,8 +183,8 @@ Arrays.idl - - InspectableBoxing.idl + + Collections.idl DateTimes.idl @@ -195,6 +198,9 @@ Errors.idl + + InspectableBoxing.idl + Int32Wrapper.idl @@ -237,11 +243,12 @@ - + + diff --git a/Support/Sources/WindowsRuntime/ReferenceBox.swift b/Support/Sources/WindowsRuntime/ReferenceBox.swift index 9fdf111d..09ef2f65 100644 --- a/Support/Sources/WindowsRuntime/ReferenceBox.swift +++ b/Support/Sources/WindowsRuntime/ReferenceBox.swift @@ -14,6 +14,10 @@ internal class ReferenceBox super.init() } + // IPropertyValue members + public func _type() throws -> WindowsFoundation_PropertyType { .otherType } + public func _isNumericScalar() throws -> Bool { false } + public func _value() throws -> T { value } public func _getABIValue(_ pointer: UnsafeMutableRawPointer) throws { pointer.bindMemory(to: BoxableProjection.ABIValue.self, capacity: 1).pointee = try BoxableProjection.toABI(value) diff --git a/Support/Sources/WindowsRuntime/WindowsFoundation/DateTime.swift b/Support/Sources/WindowsRuntime/WindowsFoundation/DateTime.swift new file mode 100644 index 00000000..aa7b7cb3 --- /dev/null +++ b/Support/Sources/WindowsRuntime/WindowsFoundation/DateTime.swift @@ -0,0 +1,30 @@ +/// Represents an instant in time, typically expressed as a date and time of day. +public struct WindowsFoundation_DateTime: Hashable, Codable { + /// A 64-bit signed integer that represents a point in time as the number of 100-nanosecond intervals prior to or after midnight on January 1, 1601 (according to the Gregorian Calendar). + public var universalTime: Swift.Int64 + + public init() { + self.universalTime = 0 + } + + public init(universalTime: Swift.Int64) { + self.universalTime = universalTime + } +} + +import struct Foundation.Date + +extension WindowsFoundation_DateTime { + public init(foundationDate: Foundation.Date) { + self.init(universalTime: (Int64(foundationDate.timeIntervalSince1970 * 1000) + 11_644_473_600_000) * 10_000) + } + + public var foundationDate: Foundation.Date { + get { + Date(timeIntervalSince1970: Double(universalTime / 10_000) / 1000 - 11_644_473_600) + } + set { + self = Self(foundationDate: newValue) + } + } +} \ No newline at end of file diff --git a/Support/Sources/WindowsRuntime/WindowsFoundation/IIterable.swift b/Support/Sources/WindowsRuntime/WindowsFoundation/IIterable.swift new file mode 100644 index 00000000..d2dbee01 --- /dev/null +++ b/Support/Sources/WindowsRuntime/WindowsFoundation/IIterable.swift @@ -0,0 +1,38 @@ +/// Exposes an iterator that supports simple iteration over a collection of a specified type. +public typealias WindowsFoundationCollections_IIterable = any WindowsFoundationCollections_IIterableProtocol + +/// Exposes an iterator that supports simple iteration over a collection of a specified type. +public protocol WindowsFoundationCollections_IIterableProtocol: IInspectableProtocol { + associatedtype T + + /// Returns an iterator for the items in the collection. + /// - Returns: The iterator. + func first() throws -> WindowsFoundationCollections_IIterator +} + +extension WindowsFoundationCollections_IIterableProtocol { + /// Gets a Swift iterator for this WinRt IIterable. + public func makeIterator() throws -> WinRTIterator { + WinRTIterator(try first()) + } +} + +/// Implements the Swift IteratorProtocol for a WinRT IIterable. +public struct WinRTIterator: Swift.IteratorProtocol { + private let iterator: WindowsFoundationCollections_IIterator + private var first: Bool = true + + internal init(_ iterator: WindowsFoundationCollections_IIterator) { + self.iterator = iterator + } + + public mutating func next() -> Element? { + if first { + first = false + guard (try? iterator._hasCurrent()) ?? false else { return nil } + } else { + guard (try? iterator.moveNext()) ?? false else { return nil } + } + return try? iterator._current() + } +} \ No newline at end of file diff --git a/Support/Sources/WindowsRuntime/WindowsFoundation/IIterator.swift b/Support/Sources/WindowsRuntime/WindowsFoundation/IIterator.swift new file mode 100644 index 00000000..347e8533 --- /dev/null +++ b/Support/Sources/WindowsRuntime/WindowsFoundation/IIterator.swift @@ -0,0 +1,38 @@ +/// Supports simple iteration over a collection. +public typealias WindowsFoundationCollections_IIterator = any WindowsFoundationCollections_IIteratorProtocol + +/// Supports simple iteration over a collection. +public protocol WindowsFoundationCollections_IIteratorProtocol: IInspectableProtocol { + associatedtype T + + /// Advances the iterator to the next item in the collection. + /// - Returns: True if the iterator refers to a valid item in the collection; false if the iterator passes the end of the collection. + func moveNext() throws -> Swift.Bool + + /// Retrieves all items in the collection. + /// - Parameter items: The items in the collection. + /// - Returns: The number of items in the collection. + func getMany(_ items: [T]) throws -> Swift.UInt32 + + /// Gets the current item in the collection. + /// - Returns: The current item in the collection. + func _current() throws -> T + + /// Gets a value that indicates whether the iterator refers to a current item or is at the end of the collection. + /// - Returns: True if the iterator refers to a valid item in the collection; otherwise, false. + func _hasCurrent() throws -> Swift.Bool +} + +extension WindowsFoundationCollections_IIteratorProtocol { + /// Gets the current item in the collection. + /// - Returns: The current item in the collection. + public var current: T { + try! self._current() + } + + /// Gets a value that indicates whether the iterator refers to a current item or is at the end of the collection. + /// - Returns: True if the iterator refers to a valid item in the collection; otherwise, false. + public var hasCurrent: Swift.Bool { + try! self._hasCurrent() + } +} \ No newline at end of file diff --git a/Support/Sources/WindowsRuntime/WindowsFoundation/IPropertyValue.swift b/Support/Sources/WindowsRuntime/WindowsFoundation/IPropertyValue.swift index 47192658..4dc1182f 100644 --- a/Support/Sources/WindowsRuntime/WindowsFoundation/IPropertyValue.swift +++ b/Support/Sources/WindowsRuntime/WindowsFoundation/IPropertyValue.swift @@ -1,9 +1,17 @@ +import WindowsRuntime_ABI import struct Foundation.UUID +/// Represents a value in a property store. You can't implement this interface, see Remarks. public typealias WindowsFoundation_IPropertyValue = any WindowsFoundation_IPropertyValueProtocol + +/// Represents a value in a property store. You can't implement this interface, see Remarks. public protocol WindowsFoundation_IPropertyValueProtocol: IInspectableProtocol { - // var type: SWRT_WindowsFoundation_PropertyType { get } - // var isNumericScalar: Bool { get } + /// Returns the type stored in the property value. + func _type() throws -> WindowsFoundation_PropertyType + + /// Gets a value that indicates whether the property value is a scalar value. + func _isNumericScalar() throws -> Bool + func getUInt8() throws -> UInt8 func getInt16() throws -> Int16 func getUInt16() throws -> UInt16 @@ -17,33 +25,36 @@ public protocol WindowsFoundation_IPropertyValueProtocol: IInspectableProtocol { func getBoolean() throws -> Bool func getString() throws -> String func getGuid() throws -> UUID - // func getDateTime() throws -> WindowsFoundation_DateTime - // func getTimeSpan() throws -> WindowsFoundation_TimeSpan - // func getPoint() throws -> WindowsFoundation_Point - // func getSize() throws -> WindowsFoundation_Size - // func getRect() throws -> WindowsFoundation_Rect - func getUInt8Array() throws -> [UInt8] - func getInt16Array() throws -> [Int16] - func getUInt16Array() throws -> [UInt16] - func getInt32Array() throws -> [Int32] - func getUInt32Array() throws -> [UInt32] - func getInt64Array() throws -> [Int64] - func getUInt64Array() throws -> [UInt64] - func getSingleArray() throws -> [Float] - func getDoubleArray() throws -> [Double] - func getChar16Array() throws -> [Char16] - func getBooleanArray() throws -> [Bool] - func getStringArray() throws -> [String] - func getInspectableArray() throws -> [IInspectable] - func getGuidArray() throws -> [UUID] - // func getDateTimeArray() throws -> [WindowsFoundation_DateTime] - // func getTimeSpanArray() throws -> [WindowsFoundation_TimeSpan] - // func getPointArray() throws -> [WindowsFoundation_Point] - // func getSizeArray() throws -> [WindowsFoundation_Size] - // func getRectArray() throws -> [WindowsFoundation_Rect] + func getDateTime() throws -> WindowsFoundation_DateTime + func getTimeSpan() throws -> WindowsFoundation_TimeSpan + func getPoint() throws -> WindowsFoundation_Point + func getSize() throws -> WindowsFoundation_Size + func getRect() throws -> WindowsFoundation_Rect + func getUInt8Array(_ value: inout [UInt8]) throws + func getInt16Array(_ value: inout [Int16]) throws + func getUInt16Array(_ value: inout [UInt16]) throws + func getInt32Array(_ value: inout [Int32]) throws + func getUInt32Array(_ value: inout [UInt32]) throws + func getInt64Array(_ value: inout [Int64]) throws + func getUInt64Array(_ value: inout [UInt64]) throws + func getSingleArray(_ value: inout [Float]) throws + func getDoubleArray(_ value: inout [Double]) throws + func getChar16Array(_ value: inout [Char16]) throws + func getBooleanArray(_ value: inout [Bool]) throws + func getStringArray(_ value: inout [String]) throws + func getInspectableArray(_ value: inout [IInspectable?]) throws + func getGuidArray(_ value: inout [UUID]) throws + func getDateTimeArray(_ value: inout [WindowsFoundation_DateTime]) throws + func getTimeSpanArray(_ value: inout [WindowsFoundation_TimeSpan]) throws + func getPointArray(_ value: inout [WindowsFoundation_Point]) throws + func getSizeArray(_ value: inout [WindowsFoundation_Size]) throws + func getRectArray(_ value: inout [WindowsFoundation_Rect]) throws } extension WindowsFoundation_IPropertyValueProtocol { + public var type: WindowsFoundation_PropertyType { try! _type() } + public var isNumericScalar: Bool { try! _isNumericScalar() } + public func getUInt8() throws -> UInt8 { throw HResult.Error.notImpl } public func getInt16() throws -> Int16 { throw HResult.Error.notImpl } public func getUInt16() throws -> UInt16 { throw HResult.Error.notImpl } @@ -57,18 +68,48 @@ extension WindowsFoundation_IPropertyValueProtocol { public func getBoolean() throws -> Bool { throw HResult.Error.notImpl } public func getString() throws -> String { throw HResult.Error.notImpl } public func getGuid() throws -> UUID { throw HResult.Error.notImpl } - public func getUInt8Array() throws -> [UInt8] { throw HResult.Error.notImpl } - public func getInt16Array() throws -> [Int16] { throw HResult.Error.notImpl } - public func getUInt16Array() throws -> [UInt16] { throw HResult.Error.notImpl } - public func getInt32Array() throws -> [Int32] { throw HResult.Error.notImpl } - public func getUInt32Array() throws -> [UInt32] { throw HResult.Error.notImpl } - public func getInt64Array() throws -> [Int64] { throw HResult.Error.notImpl } - public func getUInt64Array() throws -> [UInt64] { throw HResult.Error.notImpl } - public func getSingleArray() throws -> [Float] { throw HResult.Error.notImpl } - public func getDoubleArray() throws -> [Double] { throw HResult.Error.notImpl } - public func getChar16Array() throws -> [Char16] { throw HResult.Error.notImpl } - public func getBooleanArray() throws -> [Bool] { throw HResult.Error.notImpl } - public func getStringArray() throws -> [String] { throw HResult.Error.notImpl } - public func getInspectableArray() throws -> [IInspectable] { throw HResult.Error.notImpl } - public func getGuidArray() throws -> [UUID] { throw HResult.Error.notImpl } + public func getDateTime() throws -> WindowsFoundation_DateTime { throw HResult.Error.notImpl } + public func getTimeSpan() throws -> WindowsFoundation_TimeSpan { throw HResult.Error.notImpl } + public func getPoint() throws -> WindowsFoundation_Point { throw HResult.Error.notImpl } + public func getSize() throws -> WindowsFoundation_Size { throw HResult.Error.notImpl } + public func getRect() throws -> WindowsFoundation_Rect { throw HResult.Error.notImpl } + public func getUInt8Array(_ value: inout [UInt8]) throws { throw HResult.Error.notImpl } + public func getInt16Array(_ value: inout [Int16]) throws { throw HResult.Error.notImpl } + public func getUInt16Array(_ value: inout [UInt16]) throws { throw HResult.Error.notImpl } + public func getInt32Array(_ value: inout [Int32]) throws { throw HResult.Error.notImpl } + public func getUInt32Array(_ value: inout [UInt32]) throws { throw HResult.Error.notImpl } + public func getInt64Array(_ value: inout [Int64]) throws { throw HResult.Error.notImpl } + public func getUInt64Array(_ value: inout [UInt64]) throws { throw HResult.Error.notImpl } + public func getSingleArray(_ value: inout [Float]) throws { throw HResult.Error.notImpl } + public func getDoubleArray(_ value: inout [Double]) throws { throw HResult.Error.notImpl } + public func getChar16Array(_ value: inout [Char16]) throws { throw HResult.Error.notImpl } + public func getBooleanArray(_ value: inout [Bool]) throws { throw HResult.Error.notImpl } + public func getStringArray(_ value: inout [String]) throws { throw HResult.Error.notImpl } + public func getInspectableArray(_ value: inout [IInspectable?]) throws { throw HResult.Error.notImpl } + public func getGuidArray(_ value: inout [UUID]) throws { throw HResult.Error.notImpl } + public func getDateTimeArray(_ value: inout [WindowsFoundation_DateTime]) throws { throw HResult.Error.notImpl } + public func getTimeSpanArray(_ value: inout [WindowsFoundation_TimeSpan]) throws { throw HResult.Error.notImpl } + public func getPointArray(_ value: inout [WindowsFoundation_Point]) throws { throw HResult.Error.notImpl } + public func getSizeArray(_ value: inout [WindowsFoundation_Size]) throws { throw HResult.Error.notImpl } + public func getRectArray(_ value: inout [WindowsFoundation_Rect]) throws { throw HResult.Error.notImpl } +} + +#if swift(>=5.10) +extension WindowsRuntime_ABI.SWRT_WindowsFoundation_IPropertyValue: @retroactive WindowsRuntime.COMIInspectableStruct {} +#else +extension WindowsRuntime_ABI.SWRT_WindowsFoundation_IPropertyValue: WindowsRuntime.COMIInspectableStruct {} +#endif + +extension WindowsRuntime_ABI.SWRT_WindowsFoundation_IPropertyValue { + public static let iid = COMInterfaceID(0x4BD682DD, 0x7554, 0x40E9, 0x9A9B, 0x82654EDE7E62) +} + +extension COMInterop where Interface == WindowsRuntime_ABI.SWRT_WindowsFoundation_IPropertyValue { + internal func get_Type() throws -> WindowsFoundation_PropertyType { + fatalError("Not implemented") + } + + internal func get_IsNumericScalar() throws -> Bool { + fatalError("Not implemented") + } } \ No newline at end of file diff --git a/Support/Sources/WindowsRuntime/WindowsFoundation/IReference.swift b/Support/Sources/WindowsRuntime/WindowsFoundation/IReference.swift index eae55af7..80301f7f 100644 --- a/Support/Sources/WindowsRuntime/WindowsFoundation/IReference.swift +++ b/Support/Sources/WindowsRuntime/WindowsFoundation/IReference.swift @@ -1,20 +1,24 @@ import WindowsRuntime_ABI import struct Foundation.UUID -import class Foundation.NSLock +/// Enables arbitrary enumerations, structures, and delegate types to be used as property values. public typealias WindowsFoundation_IReference = any WindowsFoundation_IReferenceProtocol -/// Allows nongeneric uses of the protocol (see virtual table). +/// Allows nongeneric uses of the IReference protocol. public protocol WindowsFoundation_IReferenceProtocolABI { func _getABIValue(_ pointer: UnsafeMutableRawPointer) throws } +/// Enables arbitrary enumerations, structures, and delegate types to be used as property values. public protocol WindowsFoundation_IReferenceProtocol: WindowsFoundation_IPropertyValueProtocol, WindowsFoundation_IReferenceProtocolABI { associatedtype T + + /// Gets the type that is represented as an IPropertyValue. func _value() throws -> T } extension WindowsFoundation_IReferenceProtocol { + /// Gets the type that is represented as an IPropertyValue. var value: T { try! _value() } } @@ -40,6 +44,24 @@ public enum WindowsFoundation_IReferenceProjection = .init() + public var _ipropertyValue: COMInterop { + get throws { + try _lazyIPropertyValue.getInterop { + try _queryInterface(WindowsRuntime_ABI.SWRT_WindowsFoundation_IPropertyValue.iid) + .reinterpret(to: WindowsRuntime_ABI.SWRT_WindowsFoundation_IPropertyValue.self) + } + } + } + + public func _type() throws -> WindowsFoundation_PropertyType { + try _ipropertyValue.get_Type() + } + + public func _isNumericScalar() throws -> Bool { + try _ipropertyValue.get_IsNumericScalar() + } + public func _value() throws -> T { var abiValue = TProjection.abiDefaultValue try withUnsafeMutablePointer(to: &abiValue) { abiValuePointer in @@ -73,7 +95,9 @@ fileprivate var virtualTable: WindowsRuntime_ABI.SWRT_WindowsFoundation_IReferen }) #if swift(>=5.10) -extension WindowsRuntime_ABI.SWRT_WindowsFoundation_IReference: @retroactive COMIUnknownStruct {} +extension WindowsRuntime_ABI.SWRT_WindowsFoundation_IReference: @retroactive WindowsRuntime.COMIInspectableStruct {} +#else +extension WindowsRuntime_ABI.SWRT_WindowsFoundation_IReference: WindowsRuntime.COMIInspectableStruct {} #endif extension COMInterop where Interface == WindowsRuntime_ABI.SWRT_WindowsFoundation_IReference { diff --git a/Support/Sources/WindowsRuntime/WindowsFoundation/IStringable.swift b/Support/Sources/WindowsRuntime/WindowsFoundation/IStringable.swift index 84e4ba7a..6ed8c464 100644 --- a/Support/Sources/WindowsRuntime/WindowsFoundation/IStringable.swift +++ b/Support/Sources/WindowsRuntime/WindowsFoundation/IStringable.swift @@ -1,7 +1,11 @@ import WindowsRuntime_ABI +/// Provides a way to represent the current object as a string. public typealias WindowsFoundation_IStringable = any WindowsFoundation_IStringableProtocol + +/// Provides a way to represent the current object as a string. public protocol WindowsFoundation_IStringableProtocol: IInspectableProtocol { + /// Gets a string that represents the current object. func toString() throws -> String } diff --git a/Support/Sources/WindowsRuntime/WindowsFoundation/Point.swift b/Support/Sources/WindowsRuntime/WindowsFoundation/Point.swift new file mode 100644 index 00000000..9eded109 --- /dev/null +++ b/Support/Sources/WindowsRuntime/WindowsFoundation/Point.swift @@ -0,0 +1,18 @@ +/// Represents x- and y-coordinate values that define a point in a two-dimensional plane. +public struct WindowsFoundation_Point: Hashable, Codable { + /// The horizontal position of the point. + public var x: Swift.Float + + /// The vertical position of the point. + public var y: Swift.Float + + public init() { + self.x = 0 + self.y = 0 + } + + public init(x: Swift.Float, y: Swift.Float) { + self.x = x + self.y = y + } +} \ No newline at end of file diff --git a/Support/Sources/WindowsRuntime/WindowsFoundation/PropertyType.swift b/Support/Sources/WindowsRuntime/WindowsFoundation/PropertyType.swift new file mode 100644 index 00000000..c0411593 --- /dev/null +++ b/Support/Sources/WindowsRuntime/WindowsFoundation/PropertyType.swift @@ -0,0 +1,133 @@ +import struct Foundation.UUID + +/// Specifies property value types. +public struct WindowsFoundation_PropertyType: RawRepresentable, Hashable, Codable { + public var rawValue: Swift.Int32 + + public init(rawValue: Swift.Int32 = 0) { + self.rawValue = rawValue + } + + /// No type is specified. + public static let empty = Self() + + /// A byte. + public static let uint8 = Self(rawValue: 1) + + /// A signed 16-bit (2-byte) integer. + public static let int16 = Self(rawValue: 2) + + /// An unsigned 16-bit (2-byte) integer. + public static let uint16 = Self(rawValue: 3) + + /// A signed 32-bit (4-byte) integer. + public static let int32 = Self(rawValue: 4) + + /// An unsigned 32-bit (4-byte) integer. + public static let uint32 = Self(rawValue: 5) + + /// A signed 64-bit (8-byte) integer. + public static let int64 = Self(rawValue: 6) + + /// An unsigned 64-bit (8-byte) integer. + public static let uint64 = Self(rawValue: 7) + + /// A signed 32-bit (4-byte) floating-point number. + public static let single = Self(rawValue: 8) + + /// A signed 64-bit (8-byte) floating-point number. + public static let double = Self(rawValue: 9) + + /// An unsigned 16-bit (2-byte) code point. + public static let char16 = Self(rawValue: 10) + + /// A value that can be only true or false. + public static let boolean = Self(rawValue: 11) + + /// A Windows Runtime HSTRING. + public static let string = Self(rawValue: 12) + + /// An object implementing the IInspectable interface. + public static let inspectable = Self(rawValue: 13) + + /// An instant in time, typically expressed as a date and time of day. + public static let dateTime = Self(rawValue: 14) + + /// A time interval. + public static let timeSpan = Self(rawValue: 15) + + /// A globally unique identifier. + public static let guid = Self(rawValue: 16) + + /// An ordered pair of floating-point x- and y-coordinates that defines a point in a two-dimensional plane. + public static let point = Self(rawValue: 17) + + /// An ordered pair of float-point numbers that specify a height and width. + public static let size = Self(rawValue: 18) + + /// A set of four floating-point numbers that represent the location and size of a rectangle. + public static let rect = Self(rawValue: 19) + + /// A type not specified in this enumeration. + public static let otherType = Self(rawValue: 20) + + /// An array of Byte values. + public static let uint8Array = Self(rawValue: 1025) + + /// An array of Int16 values. + public static let int16Array = Self(rawValue: 1026) + + /// An array of UInt16 values. + public static let uint16Array = Self(rawValue: 1027) + + /// An array of Int32 values. + public static let int32Array = Self(rawValue: 1028) + + /// An array of UInt32 values. + public static let uint32Array = Self(rawValue: 1029) + + /// An array of Int64 values. + public static let int64Array = Self(rawValue: 1030) + + /// An array of UInt64 values. + public static let uint64Array = Self(rawValue: 1031) + + /// An array of Single values. + public static let singleArray = Self(rawValue: 1032) + + /// An array of Double values. + public static let doubleArray = Self(rawValue: 1033) + + /// An array of Char values. + public static let char16Array = Self(rawValue: 1034) + + /// An array of Boolean values. + public static let booleanArray = Self(rawValue: 1035) + + /// An array of String values. + public static let stringArray = Self(rawValue: 1036) + + /// An array of **Inspectable** values. + public static let inspectableArray = Self(rawValue: 1037) + + /// An array of DateTime values. + public static let dateTimeArray = Self(rawValue: 1038) + + /// An array of TimeSpan values. + public static let timeSpanArray = Self(rawValue: 1039) + + /// An array of Guid values. + public static let guidArray = Self(rawValue: 1040) + + /// An array of Point structures. + public static let pointArray = Self(rawValue: 1041) + + /// An array of Size structures. + public static let sizeArray = Self(rawValue: 1042) + + /// An array of Rect structures. + public static let rectArray = Self(rawValue: 1043) + + /// An array of an unspecified type. + public static let otherTypeArray = Self(rawValue: 1044) +} \ No newline at end of file diff --git a/Support/Sources/WindowsRuntime/WindowsFoundation/Rect.swift b/Support/Sources/WindowsRuntime/WindowsFoundation/Rect.swift new file mode 100644 index 00000000..94b7a00f --- /dev/null +++ b/Support/Sources/WindowsRuntime/WindowsFoundation/Rect.swift @@ -0,0 +1,28 @@ +/// Contains number values that represent the location and size of a rectangle. +public struct WindowsFoundation_Rect: Hashable, Codable { + /// The x-coordinate of the upper-left corner of the rectangle. + public var x: Swift.Float + + /// The y-coordinate of the upper-left corner of the rectangle. + public var y: Swift.Float + + /// The width of the rectangle, in pixels. + public var width: Swift.Float + + /// The height of the rectangle, in pixels. + public var height: Swift.Float + + public init() { + self.x = 0 + self.y = 0 + self.width = 0 + self.height = 0 + } + + public init(x: Swift.Float, y: Swift.Float, width: Swift.Float, height: Swift.Float) { + self.x = x + self.y = y + self.width = width + self.height = height + } +} \ No newline at end of file diff --git a/Support/Sources/WindowsRuntime/WindowsFoundation/Size.swift b/Support/Sources/WindowsRuntime/WindowsFoundation/Size.swift new file mode 100644 index 00000000..d99c67a5 --- /dev/null +++ b/Support/Sources/WindowsRuntime/WindowsFoundation/Size.swift @@ -0,0 +1,18 @@ +/// Represents number values that specify a height and width. +public struct WindowsFoundation_Size: Hashable, Codable { + /// The width. + public var width: Swift.Float + + /// The height. + public var height: Swift.Float + + public init() { + self.width = 0 + self.height = 0 + } + + public init(width: Swift.Float, height: Swift.Float) { + self.width = width + self.height = height + } +} \ No newline at end of file diff --git a/Support/Sources/WindowsRuntime/WindowsFoundation/TimeSpan.swift b/Support/Sources/WindowsRuntime/WindowsFoundation/TimeSpan.swift new file mode 100644 index 00000000..1ce8f629 --- /dev/null +++ b/Support/Sources/WindowsRuntime/WindowsFoundation/TimeSpan.swift @@ -0,0 +1,30 @@ +/// Represents a time interval as a signed 64-bit integer value. +public struct WindowsFoundation_TimeSpan: Hashable, Codable { + /// A time period expressed in 100-nanosecond units. + public var duration: Swift.Int64 + + public init() { + self.duration = 0 + } + + public init(duration: Swift.Int64) { + self.duration = duration + } +} + +import struct Foundation.TimeInterval + +extension WindowsFoundation_TimeSpan { + public init(timeInterval: Foundation.TimeInterval) { + self.init(duration: Int64(timeInterval * 10_000_000)) + } + + public var timeInterval: Foundation.TimeInterval { + get { + Double(duration) / 10_000_000 + } + set { + self = Self(timeInterval: newValue) + } + } +} \ No newline at end of file