mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-04-23 17:18:42 +02:00
feat: fetch eraser objects instead of loading from stroke
This commit is contained in:
@@ -160,7 +160,7 @@ extension GraphicContext {
|
|||||||
thickness: pen.thickness
|
thickness: pen.thickness
|
||||||
)
|
)
|
||||||
eraserStroke.graphicContext = self
|
eraserStroke.graphicContext = self
|
||||||
withPersistence(\.backgroundContext) { [_stroke = eraserStroke] context in
|
withPersistence(\.backgroundContext) { [graphicContext = object, _stroke = eraserStroke] context in
|
||||||
let stroke = EraserObject(\.backgroundContext)
|
let stroke = EraserObject(\.backgroundContext)
|
||||||
stroke.bounds = _stroke.bounds
|
stroke.bounds = _stroke.bounds
|
||||||
stroke.color = _stroke.color
|
stroke.color = _stroke.color
|
||||||
@@ -169,6 +169,8 @@ extension GraphicContext {
|
|||||||
stroke.createdAt = _stroke.createdAt
|
stroke.createdAt = _stroke.createdAt
|
||||||
stroke.quads = []
|
stroke.quads = []
|
||||||
stroke.strokes = .init()
|
stroke.strokes = .init()
|
||||||
|
stroke.graphicContext = graphicContext
|
||||||
|
graphicContext?.erasers.add(stroke)
|
||||||
_stroke.object = stroke
|
_stroke.object = stroke
|
||||||
try context.saveIfNeeded()
|
try context.saveIfNeeded()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ final class PenStroke: Stroke, @unchecked Sendable {
|
|||||||
guard let quad = quad as? QuadObject else { return nil }
|
guard let quad = quad as? QuadObject else { return nil }
|
||||||
return Quad(object: quad)
|
return Quad(object: quad)
|
||||||
}
|
}
|
||||||
eraserStrokes = Set(object.erasers.compactMap { [graphicContext] eraser -> EraserStroke? in
|
let erasers = fetchErasers(of: object)
|
||||||
guard let eraser = eraser as? EraserObject else { return nil }
|
eraserStrokes = Set(erasers.compactMap { [graphicContext] eraser -> EraserStroke? in
|
||||||
let url = eraser.objectID.uriRepresentation()
|
let url = eraser.objectID.uriRepresentation()
|
||||||
return graphicContext.barrierQueue.sync(flags: .barrier) {
|
return graphicContext.barrierQueue.sync(flags: .barrier) {
|
||||||
if graphicContext.erasers[url] == nil {
|
if graphicContext.erasers[url] == nil {
|
||||||
@@ -96,6 +96,19 @@ final class PenStroke: Stroke, @unchecked Sendable {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fetchErasers(of stroke: StrokeObject) -> [EraserObject] {
|
||||||
|
let fetchRequest: NSFetchRequest<EraserObject> = .init(entityName: "EraserObject")
|
||||||
|
fetchRequest.predicate = NSPredicate(format: "ANY strokes == %@", stroke)
|
||||||
|
|
||||||
|
do {
|
||||||
|
let erasers = try Persistence.shared.backgroundContext.fetch(fetchRequest)
|
||||||
|
return erasers
|
||||||
|
} catch {
|
||||||
|
NSLog("[Memola] - \(error.localizedDescription)")
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ struct MemosView: View {
|
|||||||
|
|
||||||
let graphicContextObject = GraphicContextObject(\.viewContext)
|
let graphicContextObject = GraphicContextObject(\.viewContext)
|
||||||
graphicContextObject.strokes = []
|
graphicContextObject.strokes = []
|
||||||
|
graphicContextObject.erasers = .init()
|
||||||
|
|
||||||
memoObject.canvas = canvasObject
|
memoObject.canvas = canvasObject
|
||||||
memoObject.tool = toolObject
|
memoObject.tool = toolObject
|
||||||
|
|||||||
@@ -17,4 +17,5 @@ final class EraserObject: NSManagedObject {
|
|||||||
@NSManaged var thickness: CGFloat
|
@NSManaged var thickness: CGFloat
|
||||||
@NSManaged var quads: NSMutableOrderedSet
|
@NSManaged var quads: NSMutableOrderedSet
|
||||||
@NSManaged var strokes: NSMutableSet
|
@NSManaged var strokes: NSMutableSet
|
||||||
|
@NSManaged var graphicContext: GraphicContextObject?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,4 +12,5 @@ import Foundation
|
|||||||
final class GraphicContextObject: NSManagedObject {
|
final class GraphicContextObject: NSManagedObject {
|
||||||
@NSManaged var canvas: CanvasObject?
|
@NSManaged var canvas: CanvasObject?
|
||||||
@NSManaged var strokes: NSMutableOrderedSet
|
@NSManaged var strokes: NSMutableOrderedSet
|
||||||
|
@NSManaged var erasers: NSMutableSet
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,13 @@
|
|||||||
<attribute name="createdAt" attributeType="Date" usesScalarValueType="NO"/>
|
<attribute name="createdAt" attributeType="Date" usesScalarValueType="NO"/>
|
||||||
<attribute name="style" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
<attribute name="style" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
<attribute name="thickness" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
<attribute name="thickness" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||||
|
<relationship name="graphicContext" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="GraphicContextObject" inverseName="erasers" inverseEntity="GraphicContextObject"/>
|
||||||
<relationship name="quads" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="QuadObject" inverseName="eraser" inverseEntity="QuadObject"/>
|
<relationship name="quads" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="QuadObject" inverseName="eraser" inverseEntity="QuadObject"/>
|
||||||
<relationship name="strokes" toMany="YES" deletionRule="Nullify" destinationEntity="StrokeObject" inverseName="erasers" inverseEntity="StrokeObject"/>
|
<relationship name="strokes" toMany="YES" deletionRule="Nullify" destinationEntity="StrokeObject" inverseName="erasers" inverseEntity="StrokeObject"/>
|
||||||
</entity>
|
</entity>
|
||||||
<entity name="GraphicContextObject" representedClassName="GraphicContextObject" syncable="YES">
|
<entity name="GraphicContextObject" representedClassName="GraphicContextObject" syncable="YES">
|
||||||
<relationship name="canvas" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="CanvasObject" inverseName="graphicContext" inverseEntity="CanvasObject"/>
|
<relationship name="canvas" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="CanvasObject" inverseName="graphicContext" inverseEntity="CanvasObject"/>
|
||||||
|
<relationship name="erasers" toMany="YES" deletionRule="Cascade" destinationEntity="EraserObject" inverseName="graphicContext" inverseEntity="EraserObject"/>
|
||||||
<relationship name="strokes" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="StrokeObject" inverseName="graphicContext" inverseEntity="StrokeObject"/>
|
<relationship name="strokes" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="StrokeObject" inverseName="graphicContext" inverseEntity="StrokeObject"/>
|
||||||
</entity>
|
</entity>
|
||||||
<entity name="MemoObject" representedClassName="MemoObject" syncable="YES">
|
<entity name="MemoObject" representedClassName="MemoObject" syncable="YES">
|
||||||
|
|||||||
Reference in New Issue
Block a user