further ehancement and reach

This commit is contained in:
Kyle Matthew Hedden 2021-03-22 12:26:33 -04:00
parent 790a19b34f
commit 0c0fff22bb
7 changed files with 72 additions and 41 deletions

View File

@ -9,7 +9,7 @@
import UIKit import UIKit
public class TwoButtonViewModel: MoleculeModelProtocol { public class TwoButtonViewModel: ParentMoleculeModelProtocol {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
@ -19,6 +19,10 @@ public class TwoButtonViewModel: MoleculeModelProtocol {
public var primaryButton: ButtonModel? public var primaryButton: ButtonModel?
public var secondaryButton: ButtonModel? public var secondaryButton: ButtonModel?
public var children: [MoleculeModelProtocol] {
return [primaryButton, secondaryButton].compactMap { $0 }
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Keys // MARK: - Keys
//-------------------------------------------------- //--------------------------------------------------

View File

@ -9,7 +9,7 @@
import Foundation import Foundation
@objcMembers open class HeadlineBodyModel: MoleculeModelProtocol { @objcMembers open class HeadlineBodyModel: ParentMoleculeModelProtocol {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
@ -21,6 +21,10 @@ import Foundation
public var style: Style? public var style: Style?
public var backgroundColor: Color? public var backgroundColor: Color?
public var children: [MoleculeModelProtocol] {
return [headline, body].compactMap { $0 }
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Enum // MARK: - Enum
//-------------------------------------------------- //--------------------------------------------------

View File

@ -9,7 +9,7 @@
import UIKit import UIKit
@objcMembers public class CarouselModel: MoleculeModelProtocol, FormFieldProtocol { @objcMembers public class CarouselModel: ParentMoleculeModelProtocol, FormFieldProtocol {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
@ -144,3 +144,11 @@ import UIKit
try container.encode(selectedIndex, forKey: .selectedIndex) try container.encode(selectedIndex, forKey: .selectedIndex)
} }
} }
extension CarouselModel {
public var children: [MoleculeModelProtocol] {
return molecules
}
}

View File

@ -23,28 +23,29 @@ public extension MoleculeModelProtocol {
public extension MoleculeModelProtocol { public extension MoleculeModelProtocol {
func reduceDepthFirstTraverse<Result>(initialResult:Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result { // Base case. No additional children to traverse.
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result {
return nextPartialResult(initialResult, self) return nextPartialResult(initialResult, self)
} }
func depthFirstTraverse(callback: (MoleculeModelProtocol)->Void) { // Base case. No additional children to traverse.
callback(self) func depthFirstTraverse(options: TreeTraversalOptions, onVisit: (MoleculeModelProtocol)->Void) {
onVisit(self)
} }
} }
public extension Array where Element == MoleculeModelProtocol { public extension Array where Element == MoleculeModelProtocol {
func reduceDepthFirstTraverse<Result>(initialResult:Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result { func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result {
return reduce(initialResult) { (result, molecule) -> Result in return reduce(initialResult) { (result, molecule) -> Result in
return molecule.reduceDepthFirstTraverse(initialResult: result, nextPartialResult: nextPartialResult) return molecule.reduceDepthFirstTraverse(options: options, initialResult: result, nextPartialResult: nextPartialResult)
} }
} }
func depthFirstTraverse(callback: (MoleculeModelProtocol)->Void) { func depthFirstTraverse(options: TreeTraversalOptions, callback: (MoleculeModelProtocol)->Void) {
forEach { (molecule) in forEach { (molecule) in
molecule.depthFirstTraverse(callback: callback) molecule.depthFirstTraverse(options: options, onVisit: callback)
} }
} }
} }

View File

@ -16,24 +16,39 @@ public protocol ParentMoleculeModelProtocol: MoleculeModelProtocol {
public extension ParentMoleculeModelProtocol { public extension ParentMoleculeModelProtocol {
func reduceDepthFirstTraverse<Result>(initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol) -> Result) -> Result { func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol) -> Result) -> Result {
var result = initialResult
let result = children.reduce(initialResult) { (result, molecule) -> Result in if (options == .parentFirst) {
if let additionalParent = molecule as? ParentMoleculeModelProtocol { result = nextPartialResult(result, self)
return additionalParent.reduceDepthFirstTraverse(initialResult: result, nextPartialResult: nextPartialResult)
}
return molecule.reduceDepthFirstTraverse(initialResult: result, nextPartialResult: nextPartialResult)
} }
return nextPartialResult(result, self) 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 molecule.reduceDepthFirstTraverse(options: options, initialResult: result, nextPartialResult: nextPartialResult)
}
if (options == .childFirst) {
result = nextPartialResult(result, self)
}
// if options == .leafOnly don't call on self.
return result
} }
func depthFirstTraverse(callback: (MoleculeModelProtocol)->Void) { func depthFirstTraverse(options: TreeTraversalOptions, onVisit: (MoleculeModelProtocol)->Void) {
if (options == .parentFirst) {
onVisit(self)
}
children.forEach { (molecule) in children.forEach { (molecule) in
if let additionalParent = molecule as? ParentMoleculeModelProtocol { if let additionalParent = molecule as? ParentMoleculeModelProtocol {
additionalParent.depthFirstTraverse(callback: callback) // Safety net to make sure the ParentMoleculeModelProtocol's method extension is called over the base MoleculeModelProtocol.
additionalParent.depthFirstTraverse(options: options, onVisit: onVisit)
} }
molecule.depthFirstTraverse(callback: callback) molecule.depthFirstTraverse(options: options, onVisit: onVisit)
} }
callback(self) if (options == .childFirst) {
onVisit(self)
}
// if options == .leafOnly don't call on self.
} }
} }

View File

@ -7,13 +7,19 @@
// Copyright © 2021 Verizon Wireless. All rights reserved. // Copyright © 2021 Verizon Wireless. All rights reserved.
// //
public enum TreeTraversalOptions {
case parentFirst
case childFirst
case leafNodesOnly
}
public protocol MoleculeTreeTraversalProtocol { public protocol MoleculeTreeTraversalProtocol {
// Future options -- Parent first depth first, leaves only. // Future options -- Parent first depth first, leaves only.
func reduceDepthFirstTraverse<Result>(initialResult:Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result
func depthFirstTraverse(callback: (MoleculeModelProtocol)->Void) func depthFirstTraverse(options: TreeTraversalOptions, onVisit: (MoleculeModelProtocol)->Void)
//func breadthFirstTraverse() //func breadthFirstTraverse()
} }
@ -24,20 +30,20 @@ public protocol MoleculeTreeTraversalProtocol {
extension MoleculeTreeTraversalProtocol { extension MoleculeTreeTraversalProtocol {
func countMolecules() -> Int { func countMolecules(options: TreeTraversalOptions = .parentFirst) -> Int {
return reduceDepthFirstTraverse(initialResult: 0) { (accumulator, molecule) in return reduceDepthFirstTraverse(options: options, initialResult: 0) { (accumulator, molecule) in
return accumulator + 1 return accumulator + 1
} }
} }
func printMolecules() { func printMolecules(options: TreeTraversalOptions = .parentFirst) {
depthFirstTraverse { (molecule) in depthFirstTraverse(options: options) { (molecule) in
print(molecule) print("\"\(molecule.moleculeName)\" [\(molecule)]")
} }
} }
func allMoleculesOfType<T>() -> [T] { func allMoleculesOfType<T>(options: TreeTraversalOptions = .parentFirst) -> [T] {
return reduceDepthFirstTraverse(initialResult: []) { (accumulator, molecule) in return reduceDepthFirstTraverse(options: options, initialResult: []) { (accumulator, molecule) in
if let typedMolecule = molecule as? T { if let typedMolecule = molecule as? T {
return accumulator + [typedMolecule] return accumulator + [typedMolecule]
} }

View File

@ -16,14 +16,7 @@ import Foundation
public var footer: MoleculeModelProtocol? public var footer: MoleculeModelProtocol?
public override var rootMolecules: [MoleculeModelProtocol] { public override var rootMolecules: [MoleculeModelProtocol] {
var rootMolecules:[MoleculeModelProtocol] = [] return [header, footer].compactMap { $0 }
if let header = header {
rootMolecules.append(header)
}
if let footer = footer {
rootMolecules.append(footer)
}
return rootMolecules
} }
public override init(pageType: String) { public override init(pageType: String) {