From fc6639b514d0b0b17c35ad5591a24488f5046003 Mon Sep 17 00:00:00 2001 From: dscyrescotti Date: Sat, 25 May 2024 20:08:23 +0700 Subject: [PATCH] refactor: use Stroke protocol annotation in place of PenStroke --- Memola/Canvas/Contexts/GraphicContext.swift | 19 ++++++++++--------- Memola/Canvas/Core/Canvas.swift | 4 ++-- .../Geometries/Stroke/Core/Stroke.swift | 6 ++++++ Memola/Canvas/History/History.swift | 2 +- Memola/Canvas/History/HistoryEvent.swift | 2 +- .../RenderPasses/EraserRenderPass.swift | 2 +- .../RenderPasses/StrokeRenderPass.swift | 2 +- 7 files changed, 22 insertions(+), 15 deletions(-) diff --git a/Memola/Canvas/Contexts/GraphicContext.swift b/Memola/Canvas/Contexts/GraphicContext.swift index 774b8ec..142d852 100644 --- a/Memola/Canvas/Contexts/GraphicContext.swift +++ b/Memola/Canvas/Contexts/GraphicContext.swift @@ -11,11 +11,12 @@ import CoreData import Foundation final class GraphicContext: @unchecked Sendable { - var strokes: [PenStroke] = [] + var strokes: [any Stroke] = [] var object: GraphicContextObject? + + var currentStroke: (any Stroke)? + var previousStroke: (any Stroke)? - var currentStroke: PenStroke? - var previousStroke: PenStroke? var currentPoint: CGPoint? var renderType: RenderType = .finished var vertices: [ViewPortVertex] = [] @@ -40,7 +41,7 @@ final class GraphicContext: @unchecked Sendable { guard !strokes.isEmpty else { return } let stroke = strokes.removeLast() withPersistence(\.backgroundContext) { [stroke] context in - stroke.object?.graphicContext = nil + stroke.stroke(as: PenStroke.self)?.object?.graphicContext = nil try context.saveIfNeeded() } previousStroke = nil @@ -51,7 +52,7 @@ final class GraphicContext: @unchecked Sendable { case .stroke(let stroke): strokes.append(stroke) withPersistence(\.backgroundContext) { [weak self, stroke] context in - stroke.object?.graphicContext = self?.object + stroke.stroke(as: PenStroke.self)?.object?.graphicContext = self?.object try context.saveIfNeeded() } previousStroke = nil @@ -92,7 +93,7 @@ extension GraphicContext { func loadQuads(_ bounds: CGRect) { for stroke in self.strokes { guard stroke.isVisible(in: bounds), stroke.isEmpty else { continue } - stroke.loadQuads() + stroke.stroke(as: PenStroke.self)?.loadQuads() } } } @@ -114,7 +115,7 @@ extension GraphicContext: Drawable { } extension GraphicContext { - func beginStroke(at point: CGPoint, pen: Pen) -> PenStroke { + func beginStroke(at point: CGPoint, pen: Pen) -> any Stroke { let stroke = PenStroke( bounds: [point.x - pen.thickness, point.y - pen.thickness, point.x + pen.thickness, point.y + pen.thickness], color: pen.rgba, @@ -156,7 +157,7 @@ extension GraphicContext { currentStroke.saveQuads(to: currentStroke.quads.endIndex) withPersistence(\.backgroundContext) { context in try context.saveIfNeeded() - if let stroke = currentStroke.object { + if let stroke = currentStroke.stroke(as: PenStroke.self)?.object { context.refresh(stroke, mergeChanges: false) } } @@ -169,7 +170,7 @@ extension GraphicContext { if !strokes.isEmpty { let stroke = strokes.removeLast() withPersistence(\.backgroundContext) { [graphicContext = object, _stroke = stroke] context in - if let stroke = _stroke.object { + if let stroke = _stroke.stroke(as: PenStroke.self)?.object { graphicContext?.strokes.remove(stroke) context.delete(stroke) } diff --git a/Memola/Canvas/Core/Canvas.swift b/Memola/Canvas/Core/Canvas.swift index b3a3a39..477d3d7 100644 --- a/Memola/Canvas/Core/Canvas.swift +++ b/Memola/Canvas/Core/Canvas.swift @@ -104,7 +104,7 @@ extension Canvas { // MARK: - Graphic Context extension Canvas { - func beginTouch(at point: CGPoint, pen: Pen) -> PenStroke { + func beginTouch(at point: CGPoint, pen: Pen) -> any Stroke { graphicContext.beginStroke(at: point, pen: pen) } @@ -124,7 +124,7 @@ extension Canvas { graphicContext.renderType = renderType } - func getNewlyAddedStroke() -> PenStroke? { + func getNewlyAddedStroke() -> (any Stroke)? { graphicContext.strokes.last } } diff --git a/Memola/Canvas/Geometries/Stroke/Core/Stroke.swift b/Memola/Canvas/Geometries/Stroke/Core/Stroke.swift index 077c764..968ab44 100644 --- a/Memola/Canvas/Geometries/Stroke/Core/Stroke.swift +++ b/Memola/Canvas/Geometries/Stroke/Core/Stroke.swift @@ -117,3 +117,9 @@ extension Stroke { hasher.combine(id) } } + +extension Stroke { + func stroke(as type: S.Type) -> S? { + self as? S + } +} diff --git a/Memola/Canvas/History/History.swift b/Memola/Canvas/History/History.swift index 36590dd..501e0af 100644 --- a/Memola/Canvas/History/History.swift +++ b/Memola/Canvas/History/History.swift @@ -53,7 +53,7 @@ class History: ObservableObject { switch event { case .stroke(let _stroke): withPersistence(\.backgroundContext) { context in - if let stroke = _stroke.object { + if let stroke = _stroke.stroke(as: PenStroke.self)?.object { context.delete(stroke) } try context.saveIfNeeded() diff --git a/Memola/Canvas/History/HistoryEvent.swift b/Memola/Canvas/History/HistoryEvent.swift index 1b2c7ce..4fb811f 100644 --- a/Memola/Canvas/History/HistoryEvent.swift +++ b/Memola/Canvas/History/HistoryEvent.swift @@ -8,5 +8,5 @@ import Foundation enum HistoryEvent { - case stroke(PenStroke) + case stroke(any Stroke) } diff --git a/Memola/Canvas/RenderPasses/EraserRenderPass.swift b/Memola/Canvas/RenderPasses/EraserRenderPass.swift index 4854b2b..6eeb0bd 100644 --- a/Memola/Canvas/RenderPasses/EraserRenderPass.swift +++ b/Memola/Canvas/RenderPasses/EraserRenderPass.swift @@ -16,7 +16,7 @@ class EraserRenderPass: RenderPass { var eraserPipelineState: MTLRenderPipelineState? var quadPipelineState: MTLComputePipelineState? - var stroke: PenStroke? + var stroke: (any Stroke)? weak var graphicTexture: MTLTexture? init(renderer: Renderer) { diff --git a/Memola/Canvas/RenderPasses/StrokeRenderPass.swift b/Memola/Canvas/RenderPasses/StrokeRenderPass.swift index c9c6c84..55c2e13 100644 --- a/Memola/Canvas/RenderPasses/StrokeRenderPass.swift +++ b/Memola/Canvas/RenderPasses/StrokeRenderPass.swift @@ -18,7 +18,7 @@ class StrokeRenderPass: RenderPass { var quadPipelineState: MTLComputePipelineState? weak var graphicPipelineState: MTLRenderPipelineState? - var stroke: PenStroke? + var stroke: (any Stroke)? var strokeTexture: MTLTexture? init(renderer: Renderer) {