mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-03-25 10:51:41 +01:00
refactor: clean up
This commit is contained in:
@@ -8,7 +8,8 @@
|
||||
import MetalKit
|
||||
import Foundation
|
||||
|
||||
protocol Stroke: AnyObject, Drawable {
|
||||
protocol Stroke: AnyObject, Drawable, Hashable, Equatable {
|
||||
var id: UUID { get set }
|
||||
var bounds: [CGFloat] { get set }
|
||||
var color: [CGFloat] { get set }
|
||||
var style: StrokeStyle { get set }
|
||||
@@ -30,7 +31,6 @@ protocol Stroke: AnyObject, Drawable {
|
||||
func append(to point: CGPoint)
|
||||
func finish(at point: CGPoint)
|
||||
|
||||
func loadQuads()
|
||||
func addQuad(at point: CGPoint, rotation: CGFloat, shape: QuadShape)
|
||||
func removeQuads(from index: Int)
|
||||
func saveQuads(to index: Int)
|
||||
@@ -50,7 +50,9 @@ extension Stroke {
|
||||
func isVisible(in bounds: CGRect) -> Bool {
|
||||
bounds.contains(strokeBounds) || bounds.intersects(strokeBounds)
|
||||
}
|
||||
}
|
||||
|
||||
extension Stroke {
|
||||
func begin(at point: CGPoint) {
|
||||
penStyle.generator.begin(at: point, on: self)
|
||||
}
|
||||
@@ -63,7 +65,9 @@ extension Stroke {
|
||||
penStyle.generator.finish(at: point, on: self)
|
||||
keyPoints.removeAll()
|
||||
}
|
||||
}
|
||||
|
||||
extension Stroke {
|
||||
func addQuad(at point: CGPoint, rotation: CGFloat, shape: QuadShape) {
|
||||
let quad = Quad(
|
||||
origin: point,
|
||||
@@ -83,7 +87,7 @@ extension Stroke {
|
||||
|
||||
extension Stroke {
|
||||
func prepare(device: MTLDevice) {
|
||||
guard texture != nil else { return }
|
||||
guard texture == nil else { return }
|
||||
texture = penStyle.loadTexture(on: device)
|
||||
}
|
||||
|
||||
@@ -103,3 +107,13 @@ extension Stroke {
|
||||
self.indexBuffer = nil
|
||||
}
|
||||
}
|
||||
|
||||
extension Stroke {
|
||||
static func == (lhs: Self, rhs: Self) -> Bool {
|
||||
lhs.id == rhs.id
|
||||
}
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ protocol StrokeGenerator {
|
||||
|
||||
var configuration: Configuration { get set }
|
||||
|
||||
func begin(at point: CGPoint, on stroke: Stroke)
|
||||
func append(to point: CGPoint, on stroke: Stroke)
|
||||
func finish(at point: CGPoint, on stroke: Stroke)
|
||||
func begin(at point: CGPoint, on stroke: any Stroke)
|
||||
func append(to point: CGPoint, on stroke: any Stroke)
|
||||
func finish(at point: CGPoint, on stroke: any Stroke)
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ import Foundation
|
||||
struct SolidPointStrokeGenerator: StrokeGenerator {
|
||||
var configuration: Configuration
|
||||
|
||||
func begin(at point: CGPoint, on stroke: Stroke) {
|
||||
func begin(at point: CGPoint, on stroke: any Stroke) {
|
||||
let point = stroke.movingAverage.addPoint(point)
|
||||
stroke.keyPoints.append(point)
|
||||
addPoint(point, on: stroke)
|
||||
}
|
||||
|
||||
func append(to point: CGPoint, on stroke: Stroke) {
|
||||
func append(to point: CGPoint, on stroke: any Stroke) {
|
||||
guard stroke.keyPoints.endIndex > 0 else {
|
||||
return
|
||||
}
|
||||
@@ -29,7 +29,9 @@ struct SolidPointStrokeGenerator: StrokeGenerator {
|
||||
let control = CGPoint.middle(p1: start, p2: end)
|
||||
addCurve(from: start, to: end, by: control, on: stroke)
|
||||
case 3:
|
||||
stroke.removeQuads(from: stroke.quadIndex + 1)
|
||||
let quadIndex = stroke.quadIndex + 1
|
||||
stroke.removeQuads(from: quadIndex)
|
||||
stroke.saveQuads(to: quadIndex)
|
||||
let index = stroke.keyPoints.endIndex - 1
|
||||
var start = stroke.keyPoints[index - 2]
|
||||
var end = CGPoint.middle(p1: stroke.keyPoints[index - 2], p2: stroke.keyPoints[index - 1])
|
||||
@@ -49,7 +51,7 @@ struct SolidPointStrokeGenerator: StrokeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
func finish(at point: CGPoint, on stroke: Stroke) {
|
||||
func finish(at point: CGPoint, on stroke: any Stroke) {
|
||||
switch stroke.keyPoints.endIndex {
|
||||
case 0...1:
|
||||
break
|
||||
@@ -58,8 +60,10 @@ struct SolidPointStrokeGenerator: StrokeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private func smoothOutPath(on stroke: Stroke) {
|
||||
stroke.removeQuads(from: stroke.quadIndex + 1)
|
||||
private func smoothOutPath(on stroke: any Stroke) {
|
||||
let quadIndex = stroke.quadIndex + 1
|
||||
stroke.removeQuads(from: quadIndex)
|
||||
stroke.saveQuads(to: quadIndex)
|
||||
adjustKeyPoint(on: stroke)
|
||||
switch stroke.keyPoints.endIndex {
|
||||
case 4:
|
||||
@@ -79,7 +83,7 @@ struct SolidPointStrokeGenerator: StrokeGenerator {
|
||||
stroke.quadIndex = stroke.quads.endIndex - 1
|
||||
}
|
||||
|
||||
private func adjustKeyPoint(on stroke: Stroke) {
|
||||
private func adjustKeyPoint(on stroke: any Stroke) {
|
||||
let index = stroke.keyPoints.endIndex - 1
|
||||
let prev = stroke.keyPoints[index - 1]
|
||||
let current = stroke.keyPoints[index]
|
||||
@@ -89,7 +93,7 @@ struct SolidPointStrokeGenerator: StrokeGenerator {
|
||||
stroke.keyPoints[index] = point
|
||||
}
|
||||
|
||||
private func addPoint(_ point: CGPoint, on stroke: Stroke) {
|
||||
private func addPoint(_ point: CGPoint, on stroke: any Stroke) {
|
||||
let rotation: CGFloat
|
||||
switch configuration.rotation {
|
||||
case .fixed:
|
||||
@@ -100,7 +104,7 @@ struct SolidPointStrokeGenerator: StrokeGenerator {
|
||||
stroke.addQuad(at: point, rotation: rotation, shape: .rounded)
|
||||
}
|
||||
|
||||
private func addCurve(from start: CGPoint, to end: CGPoint, by control: CGPoint, on stroke: Stroke) {
|
||||
private func addCurve(from start: CGPoint, to end: CGPoint, by control: CGPoint, on stroke: any Stroke) {
|
||||
let distance = start.distance(to: end)
|
||||
let factor: CGFloat
|
||||
switch configuration.granularity {
|
||||
|
||||
@@ -9,5 +9,42 @@ import MetalKit
|
||||
import Foundation
|
||||
|
||||
final class EraserStroke: Stroke, @unchecked Sendable {
|
||||
|
||||
var id: UUID = UUID()
|
||||
var bounds: [CGFloat]
|
||||
var color: [CGFloat]
|
||||
var style: StrokeStyle
|
||||
var createdAt: Date
|
||||
var thickness: CGFloat
|
||||
var quads: [Quad]
|
||||
var penStyle: any PenStyle
|
||||
|
||||
var batchIndex: Int = 0
|
||||
var quadIndex: Int = -1
|
||||
var keyPoints: [CGPoint] = []
|
||||
var movingAverage: MovingAverage = MovingAverage(windowSize: 3)
|
||||
|
||||
var texture: (any MTLTexture)?
|
||||
var indexBuffer: (any MTLBuffer)?
|
||||
var vertexBuffer: (any MTLBuffer)?
|
||||
|
||||
init(
|
||||
bounds: [CGFloat],
|
||||
color: [CGFloat],
|
||||
style: StrokeStyle,
|
||||
createdAt: Date,
|
||||
thickness: CGFloat,
|
||||
quads: [Quad] = []
|
||||
) {
|
||||
self.bounds = bounds
|
||||
self.color = color
|
||||
self.style = style
|
||||
self.createdAt = createdAt
|
||||
self.thickness = thickness
|
||||
self.quads = quads
|
||||
self.penStyle = style.penStyle
|
||||
}
|
||||
|
||||
func saveQuads(to index: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import CoreData
|
||||
import Foundation
|
||||
|
||||
final class PenStroke: Stroke, @unchecked Sendable {
|
||||
var id: UUID = UUID()
|
||||
var bounds: [CGFloat]
|
||||
var color: [CGFloat]
|
||||
var style: StrokeStyle
|
||||
@@ -70,12 +71,6 @@ final class PenStroke: Stroke, @unchecked Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
func removeQuads(from index: Int) {
|
||||
let dropCount = quads.endIndex - max(1, index)
|
||||
quads.removeLast(dropCount)
|
||||
saveQuads(to: index)
|
||||
}
|
||||
|
||||
func saveQuads(to index: Int) {
|
||||
let quads = Array(quads[batchIndex..<index])
|
||||
batchIndex = index
|
||||
|
||||
Reference in New Issue
Block a user