I'm building an augmented-reality iPhone application, and it will require a large amount of SceneKit nodes to be rendered. I want to integrate the Flyweight design pattern described in Design Patterns by Gamma, Helm, Johnson, and Vlissides. Also tutorial here Flyweight Design Pattern However, I'm running into issues with the implementation and how Swift handles objects.
TL;DR: Is there a way in Swift where I can add the same SCNNode
to a ARSCNView
more than once and have it be displayed in different positions?
I have a class called Box
which builds SCNBox
s which I want to leverage Flyweight on; the intrinsic state of a Box
is the dimensions. The extrinsic state is its color and position.
Box Class
class Box {
var size:CGFloat
var position:(Float, Float, Float)
var color:UIColor
var node:SCNNode!
init(color:UIColor){
self.color = color
/*Set the following below as default values*/
self.size = CGFloat(0.05) //Side length
self.position = (0,0,0)
self.createBox()
}
private func createBox() -> Void {
/*Creating box and setting its color*/
self.node = SCNNode(geometry: SCNBox(width: size, height: size, length: size, chamferRadius: 0))
self.node.geometry?.firstMaterial?.diffuse.contents = self.color
}
func draw(sceneView: ARSCNView) -> Void {
sceneView.scene.rootNode.addChildNode(self.node)
}
}
I have a factory class which implements the design with a dictionary checking if previous objects of the same color, if so reuse the object, else create a new one.
Factory Class
class BoxFactory{
var hash:[UIColor:Box] = [UIColor:Box]()
func getBox(color c:UIColor) -> Box {
/*Check if box of color c already exists*/
if(self.hash[c] != nil){
return self.hash[c]!
}
/*Create a new box if it does not*/
let b:Box = Box(color: c)
self.hash[c] = b
return b
}
}
And some view controller which hold an ARSCNView
object to display the boxes.
let factory:BoxFactory = BoxFactory()
/*Create two boxes of same color. One on the left and on the right*/
let leftBox:Box = factory.getBox(color: UIColor.green)
leftBox.position = (-0.1,0,0)
leftBox.draw(sceneView: self.sceneView)
let rightBox:Box = factory.getBox(color: UIColor.green)
rightBox.position = (0.1,0,0)
rightBox.draw(sceneView: self.sceneView)
However, this only produces one green box; the right one. The second getBox()
call overrides the first's position Image below. Does anyone have any advice, for the implementation of this pattern, or Swift, that can help achieve this pattern of object reuse?
*Side Note: I don't necessary want to hash the object's position along with its color. Being that I'll have many Box
es of different color and position, it'll defeat the whole idea of reusing the same object.
Aucun commentaire:
Enregistrer un commentaire