diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift index f7927a1b..4b432c2e 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift @@ -24,28 +24,28 @@ public extension MoleculeModelProtocol { public extension MoleculeModelProtocol { // Base case. No additional children to traverse. - func reduceDepthFirstTraverse(options: TreeTraversalOptions, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result { - return nextPartialResult(initialResult, self) + func reduceDepthFirstTraverse(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result { + return nextPartialResult(initialResult, self, depth) } // Base case. No additional children to traverse. - func depthFirstTraverse(options: TreeTraversalOptions, onVisit: (MoleculeModelProtocol)->Void) { - onVisit(self) + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) { + onVisit(depth, self) } } public extension Array where Element == MoleculeModelProtocol { - func reduceDepthFirstTraverse(options: TreeTraversalOptions, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result { + func reduceDepthFirstTraverse(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result { return reduce(initialResult) { (result, molecule) -> Result in - return molecule.reduceDepthFirstTraverse(options: options, initialResult: result, nextPartialResult: nextPartialResult) + return molecule.reduceDepthFirstTraverse(options: options, depth: depth, initialResult: result, nextPartialResult: nextPartialResult) } } - func depthFirstTraverse(options: TreeTraversalOptions, callback: (MoleculeModelProtocol)->Void) { + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, callback: (Int, MoleculeModelProtocol)->Void) { forEach { (molecule) in - molecule.depthFirstTraverse(options: options, onVisit: callback) + molecule.depthFirstTraverse(options: options, depth: depth, onVisit: callback) } } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift index a1d9d225..2ec05db4 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift @@ -16,38 +16,39 @@ public protocol ParentMoleculeModelProtocol: MoleculeModelProtocol { public extension ParentMoleculeModelProtocol { - func reduceDepthFirstTraverse(options: TreeTraversalOptions, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol) -> Result) -> Result { + func reduceDepthFirstTraverse(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int) -> Result) -> Result { var result = initialResult if (options == .parentFirst) { - result = nextPartialResult(result, self) + result = nextPartialResult(result, self, depth) } result = children.reduce(result) { (result, molecule) -> Result in if let additionalParent = molecule as? ParentMoleculeModelProtocol { // Safety net to make sure the ParentMoleculeModelProtocol's method extension is called over the base MoleculeModelProtocol. - return additionalParent.reduceDepthFirstTraverse(options: options, initialResult: result, nextPartialResult: nextPartialResult) + return additionalParent.reduceDepthFirstTraverse(options: options, depth: depth + 1, initialResult: result, nextPartialResult: nextPartialResult) } - return molecule.reduceDepthFirstTraverse(options: options, initialResult: result, nextPartialResult: nextPartialResult) + return molecule.reduceDepthFirstTraverse(options: options, depth: depth + 1, initialResult: result, nextPartialResult: nextPartialResult) } if (options == .childFirst) { - result = nextPartialResult(result, self) + result = nextPartialResult(result, self, depth) } // if options == .leafOnly don't call on self. return result } - func depthFirstTraverse(options: TreeTraversalOptions, onVisit: (MoleculeModelProtocol)->Void) { + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) { if (options == .parentFirst) { - onVisit(self) + onVisit(depth, self) } children.forEach { (molecule) in if let additionalParent = molecule as? ParentMoleculeModelProtocol { // Safety net to make sure the ParentMoleculeModelProtocol's method extension is called over the base MoleculeModelProtocol. - additionalParent.depthFirstTraverse(options: options, onVisit: onVisit) + additionalParent.depthFirstTraverse(options: options, depth: depth + 1, onVisit: onVisit) + } else { + molecule.depthFirstTraverse(options: options, depth: depth + 1, onVisit: onVisit) } - molecule.depthFirstTraverse(options: options, onVisit: onVisit) } if (options == .childFirst) { - onVisit(self) + onVisit(depth, self) } // if options == .leafOnly don't call on self. } diff --git a/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift b/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift index 137d8a77..4e7efabb 100644 --- a/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift @@ -17,9 +17,9 @@ public protocol MoleculeTreeTraversalProtocol { // Future options -- Parent first depth first, leaves only. - func reduceDepthFirstTraverse(options: TreeTraversalOptions, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result + func reduceDepthFirstTraverse(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result - func depthFirstTraverse(options: TreeTraversalOptions, onVisit: (MoleculeModelProtocol)->Void) + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) //func breadthFirstTraverse() } @@ -31,19 +31,19 @@ public protocol MoleculeTreeTraversalProtocol { extension MoleculeTreeTraversalProtocol { func countMolecules(options: TreeTraversalOptions = .parentFirst) -> Int { - return reduceDepthFirstTraverse(options: options, initialResult: 0) { (accumulator, molecule) in + return reduceDepthFirstTraverse(options: options, depth: 0, initialResult: 0) { (accumulator, molecule, depth) in return accumulator + 1 } } func printMolecules(options: TreeTraversalOptions = .parentFirst) { - depthFirstTraverse(options: options) { (molecule) in - print("\"\(molecule.moleculeName)\" [\(molecule)]") + depthFirstTraverse(options: options, depth: 1) { (depth, molecule) in + print("\(String(repeating: ">>", count: depth)) \"\(molecule.moleculeName)\" [\(molecule)]") } } func allMoleculesOfType(options: TreeTraversalOptions = .parentFirst) -> [T] { - return reduceDepthFirstTraverse(options: options, initialResult: []) { (accumulator, molecule) in + return reduceDepthFirstTraverse(options: options, depth: 0, initialResult: []) { (accumulator, molecule, depth) in if let typedMolecule = molecule as? T { return accumulator + [typedMolecule] }