feat: save stroke as soon as it is created at the beginning of touch

This commit is contained in:
dscyrescotti
2024-06-09 14:58:57 +07:00
parent 87b53e069a
commit 99abf94351
3 changed files with 26 additions and 22 deletions

View File

@@ -10,8 +10,6 @@ import MetalKit
import CoreData import CoreData
import Foundation import Foundation
#warning("ISSUE: after closing the canvas, instantly opening the memo misses erasers of a particular stroke")
#warning("TODO: it is required to remove eraser stroke that finishes saving")
#warning("TODO: to update history undo and redo logic") #warning("TODO: to update history undo and redo logic")
final class GraphicContext: @unchecked Sendable { final class GraphicContext: @unchecked Sendable {
var tree: RTree = RTree<AnyStroke>(maxEntries: 8) var tree: RTree = RTree<AnyStroke>(maxEntries: 8)
@@ -91,15 +89,11 @@ extension GraphicContext {
guard let stroke = try? context.existingObject(with: id) as? StrokeObject else { return } guard let stroke = try? context.existingObject(with: id) as? StrokeObject else { return }
_stroke.loadQuads(from: stroke, with: self) _stroke.loadQuads(from: stroke, with: self)
} }
withPersistence(\.backgroundContext) { [stroke] context in
context.refresh(stroke, mergeChanges: false)
}
} }
} else { } else {
withPersistence(\.backgroundContext) { [weak self, stroke] context in withPersistence(\.backgroundContext) { [weak self] context in
guard let self else { return } guard let self else { return }
_stroke.loadQuads(with: self) _stroke.loadQuads(with: self)
context.refresh(stroke, mergeChanges: false)
} }
} }
} }
@@ -154,6 +148,7 @@ extension GraphicContext {
stroke.graphicContext = graphicContext stroke.graphicContext = graphicContext
graphicContext?.strokes.add(stroke) graphicContext?.strokes.add(stroke)
_stroke.object = stroke _stroke.object = stroke
try context.saveIfNeeded()
} }
stroke = penStroke stroke = penStroke
case .eraser: case .eraser:
@@ -175,6 +170,7 @@ extension GraphicContext {
stroke.strokes = .init() stroke.strokes = .init()
graphicContext?.strokes.add(stroke) graphicContext?.strokes.add(stroke)
_stroke.object = stroke _stroke.object = stroke
try context.saveIfNeeded()
} }
eraserStroke.graphicContext = self eraserStroke.graphicContext = self
stroke = eraserStroke stroke = eraserStroke
@@ -220,18 +216,29 @@ extension GraphicContext {
} }
func cancelStroke() { func cancelStroke() {
if !tree.isEmpty, let stroke = currentStroke { if let stroke = currentStroke {
let _stroke = tree.remove(stroke.anyStroke, in: stroke.strokeBox) switch stroke.style {
withPersistence(\.backgroundContext) { [graphicContext = object, _stroke] context in case .marker:
if let stroke = _stroke?.stroke(as: PenStroke.self)?.object { guard !tree.isEmpty else { return }
graphicContext?.strokes.remove(stroke) let _stroke = tree.remove(stroke.anyStroke, in: stroke.strokeBox)
context.delete(stroke) withPersistence(\.backgroundContext) { [graphicContext = object, _stroke] context in
} else if let stroke = _stroke?.stroke(as: EraserStroke.self)?.object { if let stroke = _stroke?.stroke(as: PenStroke.self)?.object {
graphicContext?.strokes.remove(stroke) graphicContext?.strokes.remove(stroke)
context.delete(stroke) context.delete(stroke)
}
try context.saveIfNeeded()
}
case .eraser:
guard let eraserStroke = stroke.stroke(as: EraserStroke.self) else { return }
eraserStrokes.remove(eraserStroke)
withPersistence(\.backgroundContext) { [eraserStroke] context in
if let stroke = eraserStroke.object {
context.delete(stroke)
}
try context.saveIfNeeded()
} }
try context.saveIfNeeded()
} }
} }
currentStroke = nil currentStroke = nil
currentPoint = nil currentPoint = nil

View File

@@ -62,9 +62,6 @@ class CanvasViewController: UIViewController {
override func viewDidDisappear(_ animated: Bool) { override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated) super.viewDidDisappear(animated)
history.resetRedo() history.resetRedo()
withPersistence(\.backgroundContext) { context in
context.refreshAllObjects()
}
} }
} }

View File

@@ -68,8 +68,8 @@ struct MemosView: View {
memoObject.updatedAt = .now memoObject.updatedAt = .now
let canvasObject = CanvasObject(context: managedObjectContext) let canvasObject = CanvasObject(context: managedObjectContext)
canvasObject.width = 8_000 canvasObject.width = 4_000
canvasObject.height = 8_000 canvasObject.height = 4_000
let toolObject = ToolObject(\.viewContext) let toolObject = ToolObject(\.viewContext)
toolObject.pens = [] toolObject.pens = []