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