订阅CIFilter时如何减少重复代码?

时间:2019-06-09 15:07:25

标签: swift design-patterns

我的应用程序需要CIFilters,每个都有一个自定义的CIKernel,可以从Metal进行编译。 Swift不允许从自定义内核实例化CIFilter,相反,我必须为我需要的每个自定义过滤器创建基类CIFilter并在计算所得的outputImage属性中使用内核。我已经在符合CIFilterConstructor的类中限定了所有这些子容器,并通过方法提供了所需过滤器的实例

filter(withName name: String) -> CIFilter?

我似乎无法在CIFilter sublcass的外部范围内提供任何可用的东西。这意味着每个过滤器如下所示:

class deuteranopiaFilter: CIFilter {
        var deuteranopiaKernel: CIKernel?

        override var name: String {
            get {
                return "deuteranopia"
            }
            set {}
        }

        override init() {
            super.init()
            guard let url = Bundle.main.url(forResource: "default", withExtension: "metallib"),
                let data = try? Data(contentsOf: url)
                else { fatalError("Unable to get metallib") }

            guard let deuteranopiaKernel: CIColorKernel = try? CIColorKernel(functionName: "deuteranopia",
                                                                             fromMetalLibraryData: data)
                else { fatalError("Couldn't create kernel \(self.name)") }
            self.deuteranopiaKernel = deuteranopiaKernel
        }

        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }

        override class func registerName(_ name: String,
                                         constructor anObject: CIFilterConstructor,
                                         classAttributes attributes: [String : Any] = [:]) {
            CIFilter.registerName("Deuteranopia", constructor: FilterManager(), classAttributes: attributes)
        }

        @objc dynamic var inputImage: CIImage?
        override var outputImage: CIImage? {
            if let input = inputImage {
                let src = CISampler(image: input)
                return self.deuteranopiaKernel?.apply(extent: input.extent, roiCallback: {return $1}, arguments: [src])
            } else {
                return nil
            }
        }
    }

这里有很多重用的代码。创建Metal库和内核,提供name属性,寄存器类函数和输出image属性。对于我将要使用的每个过滤器,我有什么办法可以避免将所有这些粘贴粘贴?

0 个答案:

没有答案