Skip to content

Instantly share code, notes, and snippets.

@AlexanderBollbach
Created September 20, 2019 00:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlexanderBollbach/1c52fb31135fb0c69c73b5dbba08434d to your computer and use it in GitHub Desktop.
Save AlexanderBollbach/1c52fb31135fb0c69c73b5dbba08434d to your computer and use it in GitHub Desktop.
edge reducer
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