-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
231 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// swift-tools-version:5.3 | ||
// The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "MetalUI", | ||
platforms: [ | ||
.iOS(.v13), | ||
.macOS(.v10_15) | ||
], | ||
products: [ | ||
// Products define the executables and libraries a package produces, and make them visible to other packages. | ||
.library( | ||
name: "MetalUI", | ||
targets: ["MetalUI"]), | ||
], | ||
dependencies: [ | ||
// Dependencies declare other packages that this package depends on. | ||
// .package(url: /* package url */, from: "1.0.0"), | ||
], | ||
targets: [ | ||
// Targets are the basic building blocks of a package. A target can define a module or a test suite. | ||
// Targets can depend on other targets in this package, and on products in packages this package depends on. | ||
.target( | ||
name: "MetalUI", | ||
dependencies: []), | ||
.testTarget( | ||
name: "MetalUITests", | ||
dependencies: ["MetalUI"]), | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import MetalKit | ||
|
||
public struct MetalRenderingVertex { | ||
public var position: SIMD3<Float> | ||
public var color: SIMD4<Float> | ||
|
||
public init( | ||
position: SIMD3<Float>, | ||
color: SIMD4<Float> | ||
) { | ||
self.position = position | ||
self.color = color | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import MetalKit | ||
|
||
public protocol MetalPresenting: MTKView { | ||
var renderer: MetalRendering! { get set } | ||
|
||
init() | ||
|
||
func configure(device: MTLDevice?) | ||
|
||
func configureMTKView() | ||
func renderer(forDevice device: MTLDevice) -> MetalRendering | ||
} | ||
|
||
public extension MetalPresenting { | ||
|
||
func configure(device: MTLDevice? = MTLCreateSystemDefaultDevice()) { | ||
// Make sure we are on a device that can run metal! | ||
guard let defaultDevice = device else { | ||
fatalError("Device loading error") | ||
} | ||
|
||
self.renderer = renderer(forDevice: defaultDevice) | ||
self.delegate = renderer | ||
self.configureMTKView() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import MetalKit | ||
|
||
public protocol MetalRendering: NSObject, MTKViewDelegate { | ||
var commandQueue: MTLCommandQueue? { get set } | ||
var renderPipelineState: MTLRenderPipelineState? { get set } | ||
var vertexBuffer: MTLBuffer? { get set } | ||
|
||
var vertices: [MetalRenderingVertex] { get set } | ||
|
||
init() | ||
init( | ||
vertices: [MetalRenderingVertex], | ||
device: MTLDevice | ||
) | ||
|
||
func createCommandQueue(device: MTLDevice) | ||
func createPipelineState( | ||
withLibrary library: MTLLibrary?, | ||
forDevice device: MTLDevice | ||
) | ||
func createBuffers(device: MTLDevice) | ||
|
||
// MARK: MTKViewDelegate | ||
func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) | ||
func draw(in view: MTKView) | ||
} | ||
|
||
public extension MetalRendering { | ||
init(vertices: [MetalRenderingVertex], device: MTLDevice) { | ||
self.init() | ||
|
||
self.vertices = vertices | ||
|
||
createCommandQueue(device: device) | ||
createPipelineState(withLibrary: device.makeDefaultLibrary(), forDevice: device) | ||
createBuffers(device: device) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import SwiftUI | ||
import MetalKit | ||
|
||
#if os(iOS) | ||
public struct MetalView<Content>: UIViewRepresentable where Content: MetalPresenting { | ||
public var wrappedView: Content | ||
|
||
private var handleUpdateUIView: ((Content, Context) -> Void)? | ||
private var handleMakeUIView: ((Context) -> Content)? | ||
|
||
public init(closure: () -> Content) { | ||
wrappedView = closure() | ||
} | ||
|
||
public func makeUIView(context: Context) -> Content { | ||
guard let handler = handleMakeUIView else { | ||
return wrappedView | ||
} | ||
|
||
return handler(context) | ||
} | ||
|
||
public func updateUIView(_ uiView: Content, context: Context) { | ||
handleUpdateUIView?(uiView, context) | ||
} | ||
} | ||
|
||
public extension MetalView { | ||
mutating func setMakeUIView(handler: @escaping (Context) -> Content) -> Self { | ||
handleMakeUIView = handler | ||
|
||
return self | ||
} | ||
|
||
mutating func setUpdateUIView(handler: @escaping (Content, Context) -> Void) -> Self { | ||
handleUpdateUIView = handler | ||
|
||
return self | ||
} | ||
} | ||
#elseif os(macOS) | ||
public struct MetalView<Content>: NSViewRepresentable where Content: MetalPresenting { | ||
public typealias NSViewType = Content | ||
|
||
public var wrappedView: Content | ||
|
||
private var handleUpdateNSView: ((Content, Context) -> Void)? | ||
private var handleMakeNSView: ((Context) -> Content)? | ||
|
||
public init(closure: () -> Content) { | ||
wrappedView = closure() | ||
} | ||
|
||
public func makeNSView(context: Context) -> Content { | ||
guard let handler = handleMakeNSView else { | ||
return wrappedView | ||
} | ||
|
||
return handler(context) | ||
} | ||
|
||
public func updateNSView(_ nsView: Content, context: Context) { | ||
handleUpdateNSView?(nsView, context) | ||
} | ||
} | ||
|
||
public extension MetalView { | ||
mutating func setMakeNSView(handler: @escaping (Context) -> Content) -> Self { | ||
handleMakeNSView = handler | ||
|
||
return self | ||
} | ||
|
||
mutating func setUpdateNSView(handler: @escaping (Content, Context) -> Void) -> Self { | ||
handleUpdateNSView = handler | ||
|
||
return self | ||
} | ||
} | ||
|
||
#endif | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import XCTest | ||
|
||
import MetalUITests | ||
|
||
var tests = [XCTestCaseEntry]() | ||
tests += MetalUITests.allTests() | ||
XCTMain(tests) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import XCTest | ||
@testable import MetalUI | ||
|
||
final class MetalUITests: XCTestCase { | ||
func testExample() { | ||
// This is an example of a functional test case. | ||
// Use XCTAssert and related functions to verify your tests produce the correct | ||
// results. | ||
XCTAssertEqual("MetalUI().text", "Hello, World!") | ||
} | ||
|
||
static var allTests = [ | ||
("testExample", testExample), | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import XCTest | ||
|
||
#if !canImport(ObjectiveC) | ||
public func allTests() -> [XCTestCaseEntry] { | ||
return [ | ||
testCase(MetalUITests.allTests), | ||
] | ||
} | ||
#endif |