-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #35 from chenhaiteng/develop
Prepare release
- Loading branch information
Showing
26 changed files
with
901 additions
and
272 deletions.
There are no files selected for viewing
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
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
File renamed without changes.
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,61 @@ | ||
## Clamping | ||
|
||
### Purpose: | ||
1. For values that have upper and lower bound, provide a way to not write duplicate code. | ||
2. In swift, when one try to preprocess an property before apply it, it needs following code: | ||
```swift | ||
private var _computedVarStorage: Int | ||
public var computedVar: Int { | ||
get { | ||
return _computedVarStorage | ||
} | ||
set { | ||
_computedVarStorage = newValue*10 | ||
} | ||
} | ||
``` | ||
Because the get/set syntax will change variable to computed variable, it always need write a getter, even through we want a write-only property. | ||
|
||
Also, to keep the modified value, a extra storage variable is needed, and it looks ugly. | ||
|
||
3. In additionally, we also want the solution could be apply to protocol. | ||
|
||
### Solution: | ||
1. Use @propertyWrapper to apply clamp; replace max, min and degree into one declaration. | ||
```swift | ||
@Clamping(max: 0.0, min: 360.0) var degree = 0.0 | ||
@Clamping(0.0...1.0) var value = 0.5 | ||
``` | ||
2. In some situation, it need modify the range later, property wrapper use projectedValue to implement this requirement: | ||
```swift | ||
@Clamping(0.0...1.0) var value = 0.5 | ||
$value = 0.0...10.0 | ||
``` | ||
3. Although @propertyWrapper is useful, it hard to apply this mechanism to protocol. However, there has a workaround: | ||
```swift | ||
protocol ClampProtocol { | ||
var degree: Double // Can declare as @Clamping | ||
var range: ClosedRange<Double> // Can map to projectedValue in @Clamping | ||
} | ||
|
||
struct ClampStruct { | ||
@Clamping(0.0...360.0) var degree = 0.0 | ||
var range: ClosedRange<Double> { | ||
get { $degree } | ||
set { $degree = newValue } | ||
} | ||
} | ||
``` | ||
With this workaround, all class/struct implement ClampProtocol can apply @Clamping to simplify the effort to write clamp function, and keep it interface clear. | ||
|
||
The detail about the implementation of @Clamping could be refer to : [Clamping.swift](Clamping.swift) | ||
|
||
### References: | ||
|
||
[Property Wrapper - Swift Doc](https://docs.swift.org/swift-book/LanguageGuide/Properties.html#ID617) | ||
|
||
[Property Wrapper(SE-0258) - Swift Evolution](https://github.com/apple/swift-evolution/blob/master/proposals/0258-property-wrappers.md) | ||
|
||
[Swift: Why does a variable with a setter must also have a getter? - stackoverflow](https://stackoverflow.com/a/34677538/505763) | ||
|
||
[PropertyWrappers and protocol declaration? - stackoverflow](https://stackoverflow.com/a/57657870/505763) |
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,46 @@ | ||
// | ||
// Clamping.swift | ||
// | ||
// | ||
// Created by Chen-Hai Teng on 2021/6/11. | ||
// | ||
|
||
import Foundation | ||
|
||
@propertyWrapper | ||
public struct Clamping<T> where T:Comparable { | ||
private(set) var value: T | ||
var range: ClosedRange<T> | ||
public var wrappedValue: T { | ||
get { | ||
return value | ||
} | ||
set { | ||
value = clamp(newValue) | ||
} | ||
} | ||
|
||
public var projectedValue: ClosedRange<T> { | ||
get { range } | ||
set { | ||
range = newValue | ||
value = clamp(value) | ||
} | ||
} | ||
|
||
private func clamp(_ v: T) -> T { | ||
max(min(v, range.upperBound), range.lowerBound) | ||
} | ||
|
||
public init(wrappedValue: T, _ range: ClosedRange<T>) { | ||
self.range = range | ||
value = wrappedValue // 1st phase, initialize properties. | ||
value = clamp(wrappedValue) // 2nd phase, custom the value of property | ||
} | ||
|
||
public init(wrappedValue: T, max: T, min: T) { | ||
self.range = min...max | ||
value = wrappedValue | ||
value = clamp(wrappedValue) | ||
} | ||
} |
File renamed without changes.
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
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
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
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
Oops, something went wrong.