I'm trying to implement a custom comparison infix operator ==^
as a slimmed down version of the standard equality operator ==
My app is mostly protocol oriented and therefor I'm trying to implement the default method static func ==^
inside the protocol extension. However when I make my class conform to the protocol I'm getting a Type 'MySourceNode' does not conform to protocol 'SourceNodeType'
error and Xcode offers me to add the static func ==^
protocol stub.
My question is, how do I properly write the default implementation inside the protocol extension?
I've tried to find answers on SO but most of them are older and only talk about generic methods that are defined outside the protocol extension. But that doesn't seem to work in my case.
Here is a playground file with a simplified version of my protocol. There is a bit of background info after the code. If something is unclear please let me know in the comments and I'll update my question accordingly.
import Foundation
import SpriteKit
infix operator ==^: ComparisonPrecedence
protocol SourceNodeType: SKShapeNode {
var constrainZRotation: SKConstraint! { get set }
func setConstraints()
static func ==^ (lhs: SourceNodeType, rhs: SourceNodeType) -> Bool
}
extension SourceNodeType {
func setConstraints() {
print("Setting constraints")
}
static func ==^ (lhs: SourceNodeType, rhs: SourceNodeType) -> Bool {
lhs.frame == rhs.frame &&
lhs.position == rhs.position &&
lhs.constrainZRotation == rhs.constrainZRotation
}
}
class MySourceNode: SKShapeNode, SourceNodeType {
var constrainZRotation: SKConstraint!
}
To explain the reason behind this custom infix operator. I need it because I'm comparing subclasses of SpriteKit's SKShapeNodes with each other quite often. But I don't want every variable in the class like the accessibility label or name to be compared as I'm changing these values when I added the nodes to the scene, which is partially after the comparison.
I realized putting the func ==^
method outside of the protocol and only implementing it with the SourceNodeType
protocol as rhs
and lhs
types was exactly what I needed!
This answer solved my problem:
https://stackoverflow.com/a/41390111/12764795
Maybe someone could confirm that this is the current and correct way to go?
import Foundation
import SpriteKit
infix operator ==^: ComparisonPrecedence
func ==^ (lhs: SourceNodeType, rhs: SourceNodeType) -> Bool {
lhs.frame == rhs.frame &&
lhs.position == rhs.position &&
lhs.constrainZRotation == rhs.constrainZRotation
}
protocol SourceNodeType: SKShapeNode {
var constrainZRotation: SKConstraint! { get set }
func setConstraints()
}
extension SourceNodeType {
func setConstraints() {
print("Setting constraints")
}
}
class MySourceNode: SKShapeNode, SourceNodeType {
var constrainZRotation: SKConstraint!
}
let lhsSourceNode = MySourceNode(circleOfRadius: 10)
var rhsSourceNode = MySourceNode(circleOfRadius: 10)
print(lhsSourceNode ==^ rhsSourceNode) // TRUE
rhsSourceNode.name = "Name used for testing"
print(lhsSourceNode ==^ rhsSourceNode) // TRUE
rhsSourceNode.position.y += 100
print(lhsSourceNode ==^ rhsSourceNode) // FALSE