Created
September 20, 2019 00:46
-
-
Save AlexanderBollbach/1c52fb31135fb0c69c73b5dbba08434d to your computer and use it in GitHub Desktop.
edge reducer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum EdgeAction { | |
case add(EdgeList.EdgeSpec) | |
case select(EdgeList.EdgeSpec) | |
case deleteSelected(EdgeList.EdgeSpec.Node, NodeType) | |
} | |
enum NodeType { | |
case workspace | |
case project | |
case layer | |
case effect | |
} | |
struct EdgeList { | |
struct EdgeSpec { | |
struct Node { | |
let type: NodeType | |
let id: Int | |
} | |
let from: Node | |
let to: Node | |
} | |
struct Edges { | |
var all: [Int] = [] | |
var selected: [Int] = [] | |
mutating func select(id: Int) { | |
if selected.contains(id) { | |
selected = selected.filter { $0 != id} | |
} else { | |
selected.append(id) | |
} | |
} | |
mutating func deleteSelected() { | |
all = all.filter { !selected.contains($0) } | |
selected = [] | |
} | |
} | |
private var mapping: [NodeType: [Int: [NodeType: Edges]]] = [:] | |
mutating func ensureCreated(spec: EdgeSpec) { | |
if mapping[spec.from.type] == nil { | |
mapping[spec.from.type] = [Int: [NodeType: Edges]]() | |
} | |
if mapping[spec.from.type]?[spec.from.id] == nil { | |
mapping[spec.from.type]?[spec.from.id] = [NodeType: Edges]() | |
} | |
if mapping[spec.from.type]?[spec.from.id]?[spec.to.type] == nil { | |
mapping[spec.from.type]?[spec.from.id]?[spec.to.type] = Edges() | |
} | |
} | |
mutating func createEdge(spec: EdgeSpec) { | |
ensureCreated(spec: spec) | |
mapping[spec.from.type]?[spec.from.id]?[spec.to.type]?.all.append(spec.to.id) | |
} | |
mutating func selectEdge(spec: EdgeSpec) { | |
ensureCreated(spec: spec) | |
mapping[spec.from.type]?[spec.from.id]?[spec.to.type]?.select(id: spec.to.id) | |
} | |
mutating func deleteSelected(from: EdgeSpec.Node, to: NodeType) { | |
mapping[from.type]?[from.id]?[to]?.deleteSelected() | |
} | |
func queryEdges(nodeTypeA: NodeType, id: Int, nodeTypeB: NodeType) -> Edges? { | |
mapping[nodeTypeA]?[id]?[nodeTypeB] | |
} | |
} | |
func edgeReducer(state: EdgeList, action: EdgeAction) -> EdgeList { | |
var state = state | |
switch action { | |
case let .add(spec): | |
state.createEdge(spec: spec) | |
case let .select(spec): | |
state.selectEdge(spec: spec) | |
case let .deleteSelected(node, nodeType): | |
state.deleteSelected(from: node, to: nodeType) | |
} | |
return state | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment