Skip to content

Commit fae876b

Browse files
authored
Merge pull request #1 from fireblade-engine/feature/storage-buffer
Storage buffer + extensions
2 parents 4c5cb85 + d3670da commit fae876b

11 files changed

Lines changed: 188 additions & 107 deletions

File tree

.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: macOS-latest
1212
strategy:
1313
matrix:
14-
xcode: ["11.6", "12_beta"]
14+
xcode: ["11.7", "12"]
1515
steps:
1616
- name: Checkout
1717
uses: actions/checkout@master
@@ -20,7 +20,7 @@ jobs:
2020
- name: Swift version
2121
run: swift --version
2222
- name: Test
23-
run: swift test --skip-update --parallel --enable-test-discovery --enable-code-coverage
23+
run: swift test -v --skip-update --parallel --enable-test-discovery --enable-code-coverage
2424
env:
2525
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
2626
- name: Build Release
@@ -47,7 +47,7 @@ jobs:
4747
- name: Swift version
4848
run: swift --version
4949
- name: Test
50-
run: swift test --skip-update --parallel --enable-test-discovery --enable-code-coverage
50+
run: swift test -v --skip-update --parallel --enable-test-discovery --enable-code-coverage
5151
- name: Build Release
5252
run: swift build -c release
5353

@@ -60,6 +60,6 @@ jobs:
6060
- name: Swift version
6161
run: swift --version
6262
- name: Build
63-
uses: swiftwasm/swiftwasm-action@master
63+
uses: swiftwasm/swiftwasm-action@v5.3
6464
with:
65-
shell-action: swift build --triple wasm32-unknown-wasi
65+
shell-action: carton test

Sources/FirebladeMath/Functions/length.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public func length(_ x: SIMD2<Double>) -> Double {
2121
return simd_length(x)
2222
#else
2323
return sqrt(x.x * x.x +
24-
x.y * x.y)
24+
x.y * x.y)
2525
#endif
2626
}
2727

@@ -35,7 +35,7 @@ public func length(_ x: SIMD2<Float>) -> Float {
3535
return simd_length(x)
3636
#else
3737
return sqrt(x.x * x.x +
38-
x.y * x.y)
38+
x.y * x.y)
3939
#endif
4040
}
4141

@@ -49,8 +49,8 @@ public func length(_ x: SIMD3<Double>) -> Double {
4949
return simd_length(x)
5050
#else
5151
return sqrt(x.x * x.x +
52-
x.y * x.y +
53-
x.z * x.z)
52+
x.y * x.y +
53+
x.z * x.z)
5454
#endif
5555
}
5656

@@ -64,8 +64,8 @@ public func length(_ x: SIMD3<Float>) -> Float {
6464
return simd_length(x)
6565
#else
6666
return sqrt(x.x * x.x +
67-
x.y * x.y +
68-
x.z * x.z)
67+
x.y * x.y +
68+
x.z * x.z)
6969
#endif
7070
}
7171

@@ -79,9 +79,9 @@ public func length(_ x: SIMD4<Double>) -> Double {
7979
return simd_length(x)
8080
#else
8181
return sqrt(x.x * x.x +
82-
x.y * x.y +
83-
x.z * x.z +
84-
x.w * x.w)
82+
x.y * x.y +
83+
x.z * x.z +
84+
x.w * x.w)
8585
#endif
8686
}
8787

@@ -95,9 +95,9 @@ public func length(_ x: SIMD4<Float>) -> Float {
9595
return simd_length(x)
9696
#else
9797
return sqrt(x.x * x.x +
98-
x.y * x.y +
99-
x.z * x.z +
100-
x.w * x.w)
98+
x.y * x.y +
99+
x.z * x.z +
100+
x.w * x.w)
101101
#endif
102102
}
103103

@@ -111,9 +111,9 @@ public func length(_ x: Quat4f) -> Float {
111111
return simd_length(x.storage)
112112
#else
113113
return sqrt(x.x * x.x +
114-
x.y * x.y +
115-
x.z * x.z +
116-
x.w * x.w)
114+
x.y * x.y +
115+
x.z * x.z +
116+
x.w * x.w)
117117
#endif
118118
}
119119

@@ -127,8 +127,8 @@ public func length(_ x: Quat4d) -> Double {
127127
return simd_length(x.storage)
128128
#else
129129
return sqrt(x.x * x.x +
130-
x.y * x.y +
131-
x.z * x.z +
132-
x.w * x.w)
130+
x.y * x.y +
131+
x.z * x.z +
132+
x.w * x.w)
133133
#endif
134134
}

Sources/FirebladeMath/Matrix/Matrix3x3.swift

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,24 @@
55
// Created by Christian Treffs on 05.09.19.
66
//
77

8-
public struct Matrix3x3<Storage> where Storage: Storage3x3Protocol {
8+
@frozen
9+
public struct Matrix3x3<Storage>: RandomAccessCollection, MutableCollection where Storage: Storage3x3Protocol, Storage.Value == Storage.Element {
10+
public typealias Element = Storage.Element
11+
public typealias Index = Storage.Index
912
public typealias Value = Storage.Value
1013
public typealias Vector = Storage.Column
1114

1215
@usableFromInline var storage: Storage
1316

14-
public init(storage: Storage) {
17+
public var startIndex: Index { storage.startIndex }
18+
public var endIndex: Index { storage.endIndex }
19+
public func index(after i: Index) -> Index { storage.index(after: i) }
20+
public func index(before i: Index) -> Index { storage.index(before: i) }
21+
22+
@usableFromInline init(storage: Storage) {
1523
self.storage = storage
1624
}
17-
}
1825

19-
extension Matrix3x3 {
2026
public init(diagonal: Vector) {
2127
self.storage = Storage(diagonal: diagonal)
2228
}
@@ -29,56 +35,53 @@ extension Matrix3x3 {
2935
public init(_ column0: Vector, _ column1: Vector, _ column2: Vector) {
3036
self.init([column0, column1, column2])
3137
}
32-
}
3338

34-
extension Matrix3x3 {
3539
public init(_ values: [Storage.Value]) {
3640
precondition(values.count == 9, "Matrix needs exactly 9 values")
3741
self.init([Vector(values[0...2]),
3842
Vector(values[3...5]),
3943
Vector(values[6...8])])
4044
}
41-
}
4245

43-
extension Matrix3x3: ExpressibleByArrayLiteral {
44-
public init(arrayLiteral elements: Storage.Value...) {
45-
self.init(elements)
46+
public subscript(index: Index) -> Element {
47+
get { storage[index] }
48+
set { storage[index] = newValue }
4649
}
47-
}
4850

49-
extension Matrix3x3: Sequence {
50-
public func makeIterator() -> IndexingIterator<[Value]> {
51-
unsafeBitCast(storage.makeIterator(), to: IndexingIterator<[Storage.Value]>.self)
52-
}
53-
54-
@inlinable public var elements: [Value] {
55-
[Value](self)
51+
public subscript(column: Int, row: Int) -> Value {
52+
get { storage[column, row] }
53+
set { storage[column, row] = newValue }
5654
}
57-
}
5855

59-
extension Matrix3x3 {
6056
@inlinable public var columns: (Vector, Vector, Vector) {
6157
storage.columns
6258
}
63-
}
6459

65-
extension Matrix3x3 {
66-
public subscript(column: Int, row: Int) -> Value {
67-
get {
68-
storage[column, row]
69-
}
70-
set {
71-
storage[column, row] = newValue
60+
@inlinable public var elements: [Value] {
61+
[Value](AnyIterator(self.storage.makeIterator()))
62+
}
63+
64+
@inlinable public func withForcedContiguousStorage<R>(_ body: (UnsafeBufferPointer<Element>) -> R) throws -> R? {
65+
// https://forums.swift.org/t/se-0256-introduce-mutable-contiguouscollection-protocol/22569/7
66+
if let result = withContiguousStorageIfAvailable(body) {
67+
return result
7268
}
69+
70+
return ContiguousArray(self).withContiguousStorageIfAvailable(body)
7371
}
7472

75-
public subscript(index: Int) -> Value {
76-
get {
77-
storage[index]
73+
@inlinable public mutating func withForcedContiguousMutableStorage<R>(_ body: (inout UnsafeMutableBufferPointer<Element>) -> R) throws -> R? {
74+
// https://forums.swift.org/t/se-0256-introduce-mutable-contiguouscollection-protocol/22569/7
75+
if let result = withContiguousMutableStorageIfAvailable(body) {
76+
return result
7877
}
79-
set {
80-
storage[index] = newValue
78+
79+
var array = ContiguousArray(self)
80+
let result = array.withContiguousMutableStorageIfAvailable(body)
81+
for (idx, arrayIdx) in zip(self.indices, array.indices) {
82+
self[idx] = array[arrayIdx]
8183
}
84+
return result
8285
}
8386
}
8487

Sources/FirebladeMath/Matrix/Matrix4x4.swift

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,24 @@
55
// Created by Christian Treffs on 05.09.19.
66
//
77

8-
public struct Matrix4x4<Storage> where Storage: Storage4x4Protocol {
8+
@frozen
9+
public struct Matrix4x4<Storage>: RandomAccessCollection, MutableCollection where Storage: Storage4x4Protocol, Storage.Value == Storage.Element {
10+
public typealias Element = Storage.Element
11+
public typealias Index = Storage.Index
912
public typealias Value = Storage.Value
1013
public typealias Vector = Storage.Column
1114

1215
@usableFromInline var storage: Storage
1316

14-
public init(storage: Storage) {
17+
public var startIndex: Index { storage.startIndex }
18+
public var endIndex: Index { storage.endIndex }
19+
public func index(after i: Index) -> Index { storage.index(after: i) }
20+
public func index(before i: Index) -> Index { storage.index(before: i) }
21+
22+
@usableFromInline init(storage: Storage) {
1523
self.storage = storage
1624
}
17-
}
1825

19-
extension Matrix4x4 {
2026
public init(diagonal: Vector) {
2127
self.storage = Storage(diagonal: diagonal)
2228
}
@@ -37,48 +43,52 @@ extension Matrix4x4 {
3743
Vector(values[8...11]),
3844
Vector(values[12...15])])
3945
}
40-
}
4146

42-
extension Matrix4x4 {
47+
public subscript(index: Index) -> Element {
48+
get { storage[index] }
49+
set { storage[index] = newValue }
50+
}
4351
public subscript(column: Int, row: Int) -> Value {
44-
get {
45-
storage[column, row]
46-
}
47-
set {
48-
storage[column, row] = newValue
49-
}
52+
get { storage[column, row] }
53+
set { storage[column, row] = newValue }
5054
}
5155

52-
public subscript(index: Int) -> Value {
53-
get {
54-
storage[index]
55-
}
56-
set {
57-
storage[index] = newValue
58-
}
56+
// swiftlint:disable large_tuple
57+
@inlinable public var columns: (Vector, Vector, Vector, Vector) {
58+
storage.columns
5959
}
60-
}
6160

62-
extension Matrix4x4: ExpressibleByArrayLiteral {
63-
public init(arrayLiteral elements: Value...) {
64-
self.init(elements)
61+
@inlinable public var elements: [Value] {
62+
[Value](AnyIterator(self.storage.makeIterator()))
6563
}
66-
}
6764

68-
extension Matrix4x4: Sequence {
69-
public func makeIterator() -> IndexingIterator<[Storage.Value]> {
70-
unsafeBitCast(storage.makeIterator(), to: IndexingIterator<[Storage.Value]>.self)
65+
@inlinable public func withForcedContiguousStorage<R>(_ body: (UnsafeBufferPointer<Element>) -> R) throws -> R? {
66+
// https://forums.swift.org/t/se-0256-introduce-mutable-contiguouscollection-protocol/22569/7
67+
if let result = withContiguousStorageIfAvailable(body) {
68+
return result
69+
}
70+
71+
return ContiguousArray(self).withContiguousStorageIfAvailable(body)
7172
}
7273

73-
@inlinable public var elements: [Value] {
74-
[Value](self)
74+
@inlinable public mutating func withForcedContiguousMutableStorage<R>(_ body: (inout UnsafeMutableBufferPointer<Element>) -> R) throws -> R? {
75+
// https://forums.swift.org/t/se-0256-introduce-mutable-contiguouscollection-protocol/22569/7
76+
if let result = withContiguousMutableStorageIfAvailable(body) {
77+
return result
78+
}
79+
80+
var array = ContiguousArray(self)
81+
let result = array.withContiguousMutableStorageIfAvailable(body)
82+
for (idx, arrayIdx) in zip(self.indices, array.indices) {
83+
self[idx] = array[arrayIdx]
84+
}
85+
return result
7586
}
7687
}
7788

78-
extension Matrix4x4 {
79-
// swiftlint:disable large_tuple
80-
@inlinable public var columns: (Vector, Vector, Vector, Vector) {
81-
storage.columns
89+
extension Matrix4x4: ExpressibleByArrayLiteral {
90+
public init(arrayLiteral elements: Value...) {
91+
self.init(elements)
8292
}
8393
}
8494

Sources/FirebladeMath/Matrix/MatrixStorage+NO_SIMD.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ public struct Storage3x3<Value>: Storage3x3Protocol where Value: StorageScalar {
3535
column2 = Column(zero, zero, diagonal.z)
3636
}
3737

38+
public init() {
39+
self.init(diagonal: Column(0, 0, 0))
40+
}
41+
3842
public func makeIterator() -> IndexingIterator<[Value]> {
3943
[column0, column1, column2].flatMap { $0 }.makeIterator()
4044
}
@@ -128,6 +132,10 @@ public struct Storage4x4<Value>: Storage4x4Protocol where Value: StorageScalar {
128132
column3 = Column(zero, zero, zero, diagonal.w)
129133
}
130134

135+
public init() {
136+
self.init(diagonal: Column(0, 0, 0, 0))
137+
}
138+
131139
public func makeIterator() -> IndexingIterator<[Value]> {
132140
[column0, column1, column2, column3].flatMap { $0 }.makeIterator()
133141
}

0 commit comments

Comments
 (0)