2017-08-10 16:01:11 +03:00
|
|
|
import Foundation
|
|
|
|
|
2017-08-10 14:26:02 +03:00
|
|
|
#if os(iOS)
|
2018-04-04 17:59:28 +03:00
|
|
|
import UIKit
|
2017-08-10 14:26:02 +03:00
|
|
|
#endif
|
2016-08-24 13:25:14 +03:00
|
|
|
|
|
|
|
let nodesMap = NodesMap()
|
2016-08-25 12:10:27 +03:00
|
|
|
var parentsMap = [Node: Set<Node>]()
|
|
|
|
|
2016-08-24 13:25:14 +03:00
|
|
|
class NodesMap {
|
2017-03-21 14:23:47 +03:00
|
|
|
let map = NSMapTable<Node, MacawView>(keyOptions: NSMapTableWeakMemory, valueOptions: NSMapTableWeakMemory)
|
2016-08-24 13:25:14 +03:00
|
|
|
|
2017-10-16 12:11:41 +03:00
|
|
|
// MARK: - Macaw View
|
|
|
|
func add(_ node: Node, view: MacawView) {
|
2017-03-21 14:23:47 +03:00
|
|
|
map.setObject(view, forKey: node)
|
2016-08-24 13:25:14 +03:00
|
|
|
|
2017-10-16 12:11:41 +03:00
|
|
|
if let group = node as? Group {
|
|
|
|
group.contents.forEach { child in
|
|
|
|
self.add(child, view: view)
|
|
|
|
self.add(child, parent: node)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-24 13:25:14 +03:00
|
|
|
|
2017-10-16 12:11:41 +03:00
|
|
|
func getView(_ node: Node) -> MacawView? {
|
|
|
|
return map.object(forKey: node)
|
|
|
|
}
|
2016-08-24 13:25:14 +03:00
|
|
|
|
2017-10-16 12:11:41 +03:00
|
|
|
func remove(_ node: Node) {
|
2017-03-21 14:23:47 +03:00
|
|
|
map.removeObject(forKey: node)
|
2017-10-16 12:11:41 +03:00
|
|
|
parentsMap.removeValue(forKey: node)
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: - Parents
|
|
|
|
func add(_ node: Node, parent: Node) {
|
|
|
|
if var nodesSet = parentsMap[node] {
|
|
|
|
nodesSet.insert(parent)
|
|
|
|
} else {
|
|
|
|
parentsMap[node] = Set([parent])
|
|
|
|
}
|
|
|
|
|
2017-02-13 14:55:21 +03:00
|
|
|
if let group = node as? Group {
|
|
|
|
group.contents.forEach { child in
|
|
|
|
self.add(child, parent: node)
|
|
|
|
}
|
|
|
|
}
|
2017-10-16 12:11:41 +03:00
|
|
|
}
|
2016-08-25 12:10:27 +03:00
|
|
|
|
2017-10-16 12:11:41 +03:00
|
|
|
func parents(_ node: Node) -> [Node] {
|
|
|
|
guard let nodesSet = parentsMap[node] else {
|
|
|
|
return []
|
|
|
|
}
|
|
|
|
|
|
|
|
return Array(nodesSet)
|
|
|
|
}
|
2016-08-25 12:10:27 +03:00
|
|
|
|
2017-03-01 13:13:30 +03:00
|
|
|
func replace(node: Node, to: Node) {
|
|
|
|
let parents = parentsMap[node]
|
2017-03-21 14:23:47 +03:00
|
|
|
let hostingView = map.object(forKey: node)
|
2017-10-16 12:11:41 +03:00
|
|
|
|
2017-03-01 13:13:30 +03:00
|
|
|
remove(node)
|
2017-10-16 12:11:41 +03:00
|
|
|
|
2017-03-01 13:13:30 +03:00
|
|
|
parents?.forEach { parent in
|
|
|
|
guard let group = parent as? Group else {
|
|
|
|
return
|
|
|
|
}
|
2017-10-16 12:11:41 +03:00
|
|
|
|
2017-03-01 13:13:30 +03:00
|
|
|
var contents = group.contents
|
2017-03-02 12:02:01 +03:00
|
|
|
var indexToInsert = 0
|
2017-03-01 13:13:30 +03:00
|
|
|
if let index = contents.index(of: node) {
|
|
|
|
contents.remove(at: index)
|
2017-03-02 12:02:01 +03:00
|
|
|
indexToInsert = index
|
2017-03-01 13:13:30 +03:00
|
|
|
}
|
2017-10-16 12:11:41 +03:00
|
|
|
|
2017-03-02 12:02:01 +03:00
|
|
|
contents.insert(to, at: indexToInsert)
|
2017-03-01 13:13:30 +03:00
|
|
|
group.contents = contents
|
2017-10-16 12:11:41 +03:00
|
|
|
|
2017-03-01 13:13:30 +03:00
|
|
|
add(to, parent: parent)
|
|
|
|
}
|
2017-10-16 12:11:41 +03:00
|
|
|
|
2017-03-01 13:13:30 +03:00
|
|
|
if let view = hostingView {
|
|
|
|
add(to, view: view)
|
|
|
|
}
|
2017-10-16 12:11:41 +03:00
|
|
|
|
2017-03-22 16:46:20 +03:00
|
|
|
// Replacing node in hosting view if needed
|
2017-10-16 12:11:41 +03:00
|
|
|
guard let hostingNode = hostingView?.node else {
|
2017-03-22 16:46:20 +03:00
|
|
|
return
|
|
|
|
}
|
2017-10-16 12:11:41 +03:00
|
|
|
|
2017-03-22 16:46:20 +03:00
|
|
|
if hostingNode == node {
|
|
|
|
hostingView?.node = to
|
|
|
|
}
|
2017-10-16 12:11:41 +03:00
|
|
|
|
2017-08-02 10:25:13 +03:00
|
|
|
// Replacing id
|
|
|
|
to.id = node.id
|
2017-03-01 13:13:30 +03:00
|
|
|
}
|
2016-08-24 13:25:14 +03:00
|
|
|
}
|