-
Notifications
You must be signed in to change notification settings - Fork 6
/
GLLSceneDrawer.swift
122 lines (101 loc) · 4.14 KB
/
GLLSceneDrawer.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//
// GLLSceneDrawer.swift
// GLLara
//
// Created by Torsten Kammer on 06.07.22.
// Copyright © 2022 Torsten Kammer. All rights reserved.
//
import Cocoa
import CoreData
import Combine
@objc class GLLSceneDrawer: NSObject, ObservableObject {
@objc init(document: GLLDocument) {
self.document = document
skeletonDrawer = GLLSkeletonDrawer(resourceManager: GLLResourceManager.shared)
super.init()
managedObjectContextObserver = NotificationCenter.default.addObserver(forName: Notification.Name.NSManagedObjectContextObjectsDidChange, object: document.managedObjectContext, queue: OperationQueue.main) { [weak self] notification in
guard let self = self else {
return
}
let deletedObjects = notification.userInfo?[NSDeletedObjectsKey] as? NSSet
if let deletedObjects = deletedObjects {
self.itemDrawers.removeAll { drawer in
deletedObjects.contains(drawer.item)
}
}
if let insertedObjects = notification.userInfo?[NSInsertedObjectsKey] as? NSSet {
for newItem in insertedObjects {
if let deletedObjects = deletedObjects, deletedObjects.contains(newItem) {
continue;
}
if let gllitem = newItem as? GLLItem {
self.addDrawer(for: gllitem);
}
}
}
self.needsUpdate = true
}
drawStateNotificationObserver = NotificationCenter.default.addObserver(forName: Notification.Name.GLLDrawStateChanged, object: nil, queue: OperationQueue.main) { [weak self] notification in
self?.needsUpdate = true
}
// Load existing items
let allItemsRequest = NSFetchRequest<GLLItem>()
allItemsRequest.entity = NSEntityDescription.entity(forEntityName: "GLLItem", in: document.managedObjectContext!)
let allItems = try! document.managedObjectContext!.fetch(allItemsRequest)
for item in allItems {
addDrawer(for: item)
}
}
deinit {
if let observer = managedObjectContextObserver {
NotificationCenter.default.removeObserver(observer)
}
if let observer = drawStateNotificationObserver {
NotificationCenter.default.removeObserver(observer)
}
}
weak var document: GLLDocument?
@objc var managedObjectContext: NSManagedObjectContext? {
return document?.managedObjectContext
}
@objc var resourceManager: GLLResourceManager {
return GLLResourceManager.shared
}
@objc var selectedBones: [GLLItemBone] {
set {
skeletonDrawer.selectedBones = newValue
needsUpdate = true
}
get {
return skeletonDrawer.selectedBones
}
}
func draw(into commandEncoder: MTLRenderCommandEncoder, blended: Bool) {
for itemDrawer in itemDrawers {
itemDrawer.draw(into: commandEncoder, blended: blended)
}
}
func drawSelection(int commandEncoder: MTLRenderCommandEncoder) {
skeletonDrawer.draw(into: commandEncoder)
}
@Published var needsUpdate = false
private var itemDrawers: [GLLItemDrawer] = []
private let skeletonDrawer: GLLSkeletonDrawer
private var drawStateNotificationObserver: Any? = nil
private var managedObjectContextObserver: Any? = nil
private func addDrawer(for item: GLLItem) {
do {
let drawer = try GLLItemDrawer(item: item, sceneDrawer: self)
if drawer.replacedTextures.count > 0 {
document!.notifyTexturesNotLoaded(drawer.replacedTextures)
}
itemDrawers.append(drawer)
} catch {
NSApp.presentError(error)
if item.objectID.isTemporaryID {
// Temporary ID means this was not loaded from a file. Get rid of it.
item.managedObjectContext?.delete(item)
}
}
}
}