I am trying to create classes within a class in swift so I can more easily access variables by their category. For example my renderer has many pipelines so it might be nice to be able to go pipelines.<whateverPipelineINeed>
or my builder might have various pipelines it can build so I might want to go Builder.pipelines.<whatEverPipelineINeed>()
.
This has prompted me to generate code looking like the following
class Renderer: NSObject, MTKViewDelegate {
let device:MTLDevice!
let queue:MTLCommandQueue!
let depth:MTLDepthStencilState!
class Pipelines {
static var defaultTriangles:MTLRenderPipelineState!
static var fancyTriangles:MTLRenderPipelineState!
}
.......
}
or
class Builder {
class func loadTexture(device: MTLDevice,
textureName: String) -> MTLTexture? {
...
}
class PipelineStates {
class func blankTriangle(device: MTLDevice) -> MTLRenderPipelineState? {
...
}
class func fancyTriangle(device: MTLDevice) -> MTLRenderPipelineState? {
...
}
}
}
Of course there are much more than just 2 of these pipelines and I am using this pattern for other objects. Additionally there is not a pattern where = builder.() as some of the objects get initialized frequently. Additionally I do check for errors in the compilation with the optional type.
Is this an ok way to do things in swift? Is there any cost of inefficiency related to doing things like this that I should know about?
Additionally is there any better way to do this?
You can wrap it into enums
public enum Pipeline {
public enum PipelineName: String {
case defaultTriangles
case fancyTriangles
}
case defaultTriangles(MTLRenderPipelineState)
case fancyTriangles(MTLRenderPipelineState)
public var pipelineState: MTLRenderPipelineState {
switch self {
case .defaultTriangles(let pipeline): return pipeline
case .fancyTriangles(let pipeline): return pipeline
}
}
public init?(withDevice device: MTLDevice,
library: MTLLibrary,
pipelineName: PipelineName) {
switch pipelineName {
case .defaultTriangles:
let pipelineDescriptor = MTLRenderPipelineDescriptor()
// Set descriptor properties
guard
let pipelineState = try? device.makeRenderPipelineState(descriptor: pipelineDescriptor)
else {
return
}
self = .defaultTriangles(pipelineState)
case .fancyTriangles:
let pipelineDescriptor = MTLRenderPipelineDescriptor()
// Set descriptor properties
guard
let pipelineState = try? device.makeRenderPipelineState(descriptor: pipelineDescriptor)
else {
return
}
self = .defaultTriangles(pipelineState)
}
}
}
Then initialize like so:
guard
let pipeline = Pipeline(withDevice: device,
library: library,
pipelineName: .defaultTriangles)
else { return }
self.defaultPipeline = pipeline
Then later on when you need to render access the pipeline like so:
self.defaultPipeline.pipeline
/// Execute commands and set arguments / etc.
Also what would be cool to do would be to define a render pass with infix operators:
defaultTriangles |--> triangleComputationPipeline |--> fancyTriangles
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.