merge kyle branch
This commit is contained in:
commit
7ccc5bcecf
@ -123,6 +123,8 @@
|
|||||||
0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB423FF18D2004C5109 /* Arrow.swift */; };
|
0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB423FF18D2004C5109 /* Arrow.swift */; };
|
||||||
0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB623FF18E9004C5109 /* ArrowModel.swift */; };
|
0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB623FF18E9004C5109 /* ArrowModel.swift */; };
|
||||||
279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */; };
|
279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */; };
|
||||||
|
27F6B08826051831008529AA /* MoleculeTreeTraversalProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F6B08726051831008529AA /* MoleculeTreeTraversalProtocol.swift */; };
|
||||||
|
27F6B08C26052AFF008529AA /* ParentMoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */; };
|
||||||
27F973532466074500CAB5C5 /* PageBehaviorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F973522466074500CAB5C5 /* PageBehaviorProtocol.swift */; };
|
27F973532466074500CAB5C5 /* PageBehaviorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F973522466074500CAB5C5 /* PageBehaviorProtocol.swift */; };
|
||||||
27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */; };
|
27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */; };
|
||||||
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; };
|
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; };
|
||||||
@ -686,6 +688,8 @@
|
|||||||
0AE98BB423FF18D2004C5109 /* Arrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arrow.swift; sourceTree = "<group>"; };
|
0AE98BB423FF18D2004C5109 /* Arrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arrow.swift; sourceTree = "<group>"; };
|
||||||
0AE98BB623FF18E9004C5109 /* ArrowModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowModel.swift; sourceTree = "<group>"; };
|
0AE98BB623FF18E9004C5109 /* ArrowModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowModel.swift; sourceTree = "<group>"; };
|
||||||
279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionModelAdapter.swift; sourceTree = "<group>"; };
|
279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionModelAdapter.swift; sourceTree = "<group>"; };
|
||||||
|
27F6B08726051831008529AA /* MoleculeTreeTraversalProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeTreeTraversalProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParentMoleculeModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
27F973522466074500CAB5C5 /* PageBehaviorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehaviorProtocol.swift; sourceTree = "<group>"; };
|
27F973522466074500CAB5C5 /* PageBehaviorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehaviorProtocol.swift; sourceTree = "<group>"; };
|
||||||
27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBrightnessModifierBehavior.swift; sourceTree = "<group>"; };
|
27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBrightnessModifierBehavior.swift; sourceTree = "<group>"; };
|
||||||
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = "<group>"; };
|
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = "<group>"; };
|
||||||
@ -1161,6 +1165,7 @@
|
|||||||
D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */,
|
D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */,
|
||||||
D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */,
|
D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */,
|
||||||
D28BA74C248589C800B75CB8 /* TabPageModelProtocol.swift */,
|
D28BA74C248589C800B75CB8 /* TabPageModelProtocol.swift */,
|
||||||
|
27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */,
|
||||||
);
|
);
|
||||||
path = ModelProtocols;
|
path = ModelProtocols;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2304,6 +2309,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
012A88C7238DB02000FE3DA1 /* MoleculeDelegateProtocol.swift */,
|
012A88C7238DB02000FE3DA1 /* MoleculeDelegateProtocol.swift */,
|
||||||
|
27F6B08726051831008529AA /* MoleculeTreeTraversalProtocol.swift */,
|
||||||
017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */,
|
017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */,
|
||||||
D20F3B43252E00E4004B3F56 /* PageProtocol.swift */,
|
D20F3B43252E00E4004B3F56 /* PageProtocol.swift */,
|
||||||
012A88AC238C418100FE3DA1 /* TemplateProtocol.swift */,
|
012A88AC238C418100FE3DA1 /* TemplateProtocol.swift */,
|
||||||
@ -2855,6 +2861,7 @@
|
|||||||
0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */,
|
0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */,
|
||||||
D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */,
|
D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */,
|
||||||
AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */,
|
AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */,
|
||||||
|
27F6B08826051831008529AA /* MoleculeTreeTraversalProtocol.swift in Sources */,
|
||||||
D2D3957A252FDBB300047B11 /* ModalSectionListTemplate.swift in Sources */,
|
D2D3957A252FDBB300047B11 /* ModalSectionListTemplate.swift in Sources */,
|
||||||
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */,
|
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */,
|
||||||
D28BA741248025A300B75CB8 /* TabBarModel.swift in Sources */,
|
D28BA741248025A300B75CB8 /* TabBarModel.swift in Sources */,
|
||||||
@ -2980,6 +2987,7 @@
|
|||||||
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
|
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
|
||||||
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
|
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
|
||||||
012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */,
|
012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */,
|
||||||
|
27F6B08C26052AFF008529AA /* ParentMoleculeModelProtocol.swift in Sources */,
|
||||||
0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */,
|
0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */,
|
||||||
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
|
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
|
||||||
94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */,
|
94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */,
|
||||||
|
|||||||
@ -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
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -15,6 +15,10 @@ open class BGVideoImageMoleculeModel: BGImageMoleculeModel {
|
|||||||
|
|
||||||
public var video: VideoModel
|
public var video: VideoModel
|
||||||
|
|
||||||
|
public override var children: [MoleculeModelProtocol] {
|
||||||
|
return [video, molecule]
|
||||||
|
}
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case video
|
case video
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,10 @@ open class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtoco
|
|||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var molecule: MoleculeModelProtocol
|
public var molecule: MoleculeModelProtocol
|
||||||
|
|
||||||
|
public var children: [MoleculeModelProtocol] {
|
||||||
|
return [molecule]
|
||||||
|
}
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case molecule
|
case molecule
|
||||||
|
|||||||
@ -8,6 +8,14 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol MoleculeContainerModelProtocol: ContainerModelProtocol {
|
public protocol MoleculeContainerModelProtocol: ContainerModelProtocol, ParentMoleculeModelProtocol {
|
||||||
var molecule: MoleculeModelProtocol { get set }
|
var molecule: MoleculeModelProtocol { get set }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public extension MoleculeContainerModelProtocol {
|
||||||
|
|
||||||
|
var children: [MoleculeModelProtocol] {
|
||||||
|
return [molecule]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -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
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -7,7 +7,8 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class StackModel: ContainerModel, StackModelProtocol, MoleculeModelProtocol {
|
@objcMembers public class StackModel: ContainerModel, StackModelProtocol {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -24,6 +25,10 @@
|
|||||||
public var spacing: CGFloat = StackModel.defaultSpacing
|
public var spacing: CGFloat = StackModel.defaultSpacing
|
||||||
public var useStackSpacingBeforeFirstItem = false
|
public var useStackSpacingBeforeFirstItem = false
|
||||||
|
|
||||||
|
public var children: [MoleculeModelProtocol] {
|
||||||
|
return molecules
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -77,4 +82,5 @@
|
|||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,9 +8,15 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol StackModelProtocol {
|
public protocol StackModelProtocol: ParentMoleculeModelProtocol {
|
||||||
var molecules: [StackItemModelProtocol & MoleculeModelProtocol] { get set }
|
var molecules: [StackItemModelProtocol & MoleculeModelProtocol] { get set }
|
||||||
var axis: NSLayoutConstraint.Axis { get set }
|
var axis: NSLayoutConstraint.Axis { get set }
|
||||||
var spacing: CGFloat { get set }
|
var spacing: CGFloat { get set }
|
||||||
var useStackSpacingBeforeFirstItem: Bool { get set }
|
var useStackSpacingBeforeFirstItem: Bool { get set }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension StackModelProtocol {
|
||||||
|
|
||||||
|
public var children: [MoleculeModelProtocol] { return molecules }
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ public enum MolecularError: Swift.Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public protocol MoleculeModelProtocol: ModelProtocol, AccessibilityModelProtocol {
|
public protocol MoleculeModelProtocol: ModelProtocol, AccessibilityModelProtocol, MoleculeTreeTraversalProtocol {
|
||||||
var moleculeName: String { get }
|
var moleculeName: String { get }
|
||||||
var backgroundColor: Color? { get set }
|
var backgroundColor: Color? { get set }
|
||||||
}
|
}
|
||||||
@ -34,3 +34,55 @@ extension KeyedDecodingContainer where Key: CodingKey {
|
|||||||
return modelT
|
return modelT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public extension MoleculeModelProtocol {
|
||||||
|
|
||||||
|
// Base case. No additional children to traverse.
|
||||||
|
func reduceDepthFirstTraverse<Result>(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, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) {
|
||||||
|
onVisit(depth, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension Array where Element == MoleculeModelProtocol {
|
||||||
|
|
||||||
|
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result {
|
||||||
|
return reduce(initialResult) { (result, molecule) -> Result in
|
||||||
|
return molecule.reduceDepthFirstTraverse(options: options, depth: depth, initialResult: result, nextPartialResult: nextPartialResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, callback: (Int, MoleculeModelProtocol)->Void) {
|
||||||
|
forEach { (molecule) in
|
||||||
|
molecule.depthFirstTraverse(options: options, depth: depth, onVisit: callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Would prefer these to be defined in MoleculeTreeTraversalProtocol that MoleculeModelProtocol inherits.
|
||||||
|
public extension Array where Element == MoleculeModelProtocol {
|
||||||
|
|
||||||
|
func countMolecules() -> Int {
|
||||||
|
return reduce(0) { (accumulator, molecule) in
|
||||||
|
return accumulator + molecule.countMolecules()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func printMolecules() {
|
||||||
|
forEach { (molecule) in
|
||||||
|
molecule.printMolecules()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func allMoleculesOfType<T>() -> [T] {
|
||||||
|
return reduce([]) { (accumulator, molecule) in
|
||||||
|
return accumulator + molecule.allMoleculesOfType()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// ParentModelProtocol.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kyle on 3/19/21.
|
||||||
|
// Copyright © 2021 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol ParentMoleculeModelProtocol: MoleculeModelProtocol {
|
||||||
|
|
||||||
|
var children: [MoleculeModelProtocol] { get }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension ParentMoleculeModelProtocol {
|
||||||
|
|
||||||
|
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int) -> Result) -> Result {
|
||||||
|
var result = initialResult
|
||||||
|
if (options == .parentFirst) {
|
||||||
|
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, depth: depth + 1, initialResult: result, nextPartialResult: nextPartialResult)
|
||||||
|
}
|
||||||
|
return molecule.reduceDepthFirstTraverse(options: options, depth: depth + 1, initialResult: result, nextPartialResult: nextPartialResult)
|
||||||
|
}
|
||||||
|
if (options == .childFirst) {
|
||||||
|
result = nextPartialResult(result, self, depth)
|
||||||
|
}
|
||||||
|
// if options == .leafOnly don't call on self.
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) {
|
||||||
|
if (options == .parentFirst) {
|
||||||
|
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, depth: depth + 1, onVisit: onVisit)
|
||||||
|
} else {
|
||||||
|
molecule.depthFirstTraverse(options: options, depth: depth + 1, onVisit: onVisit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options == .childFirst) {
|
||||||
|
onVisit(depth, self)
|
||||||
|
}
|
||||||
|
// if options == .leafOnly don't call on self.
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,6 +11,7 @@ import Foundation
|
|||||||
|
|
||||||
public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol {
|
public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol {
|
||||||
var template: String { get }
|
var template: String { get }
|
||||||
|
var rootMolecules: [MoleculeModelProtocol] { get }
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension TemplateModelProtocol {
|
public extension TemplateModelProtocol {
|
||||||
|
|||||||
@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
//
|
||||||
|
// TreeTraversalProtocol.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kyle on 3/19/21.
|
||||||
|
// Copyright © 2021 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
public enum TreeTraversalOptions {
|
||||||
|
case parentFirst
|
||||||
|
case childFirst
|
||||||
|
case leafNodesOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol MoleculeTreeTraversalProtocol {
|
||||||
|
|
||||||
|
// Future options -- Parent first depth first, leaves only.
|
||||||
|
|
||||||
|
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result
|
||||||
|
|
||||||
|
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void)
|
||||||
|
|
||||||
|
//func breadthFirstTraverse()
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helper Extensions
|
||||||
|
//
|
||||||
|
|
||||||
|
extension MoleculeTreeTraversalProtocol {
|
||||||
|
|
||||||
|
func countMolecules(options: TreeTraversalOptions = .parentFirst) -> Int {
|
||||||
|
return reduceDepthFirstTraverse(options: options, depth: 0, initialResult: 0) { (accumulator, molecule, depth) in
|
||||||
|
return accumulator + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func printMolecules(options: TreeTraversalOptions = .parentFirst) {
|
||||||
|
depthFirstTraverse(options: options, depth: 1) { (depth, molecule) in
|
||||||
|
print("\(String(repeating: ">>", count: depth)) \"\(molecule.moleculeName)\" [\(molecule)]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func allMoleculesOfType<T>(options: TreeTraversalOptions = .parentFirst) -> [T] {
|
||||||
|
return reduceDepthFirstTraverse(options: options, depth: 0, initialResult: []) { (accumulator, molecule, depth) in
|
||||||
|
if let typedMolecule = molecule as? T {
|
||||||
|
return accumulator + [typedMolecule]
|
||||||
|
}
|
||||||
|
return accumulator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -19,6 +19,13 @@ import Foundation
|
|||||||
public var molecules: [CollectionItemModelProtocol & MoleculeModelProtocol]?
|
public var molecules: [CollectionItemModelProtocol & MoleculeModelProtocol]?
|
||||||
public var columns: Int?
|
public var columns: Int?
|
||||||
|
|
||||||
|
public override var rootMolecules: [MoleculeModelProtocol] {
|
||||||
|
if let molecules = molecules {
|
||||||
|
return super.rootMolecules + molecules
|
||||||
|
}
|
||||||
|
return super.rootMolecules
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -20,6 +20,13 @@ import Foundation
|
|||||||
public var line: LineModel?
|
public var line: LineModel?
|
||||||
public var scrollToRowIndex: Int?
|
public var scrollToRowIndex: Int?
|
||||||
|
|
||||||
|
public override var rootMolecules: [MoleculeModelProtocol] {
|
||||||
|
if let molecules = molecules {
|
||||||
|
return super.rootMolecules + molecules
|
||||||
|
}
|
||||||
|
return super.rootMolecules
|
||||||
|
}
|
||||||
|
|
||||||
/// This template requires content.
|
/// This template requires content.
|
||||||
func validateModelHasContent() throws {
|
func validateModelHasContent() throws {
|
||||||
if header == nil,
|
if header == nil,
|
||||||
|
|||||||
@ -15,6 +15,10 @@ import Foundation
|
|||||||
}
|
}
|
||||||
public var moleculeStack: StackModel
|
public var moleculeStack: StackModel
|
||||||
|
|
||||||
|
public override var rootMolecules: [MoleculeModelProtocol] {
|
||||||
|
return [header, moleculeStack, footer].compactMap { $0 }
|
||||||
|
}
|
||||||
|
|
||||||
public init(pageType: String, moleculeStack: StackModel) {
|
public init(pageType: String, moleculeStack: StackModel) {
|
||||||
self.moleculeStack = moleculeStack
|
self.moleculeStack = moleculeStack
|
||||||
super.init(pageType: pageType)
|
super.init(pageType: pageType)
|
||||||
|
|||||||
@ -30,6 +30,7 @@ import Foundation
|
|||||||
public var navigationBar: (NavigationItemModelProtocol & MoleculeModelProtocol)?
|
public var navigationBar: (NavigationItemModelProtocol & MoleculeModelProtocol)?
|
||||||
public var formRules: [FormGroupRule]?
|
public var formRules: [FormGroupRule]?
|
||||||
public var behaviors: [PageBehaviorModelProtocol]?
|
public var behaviors: [PageBehaviorModelProtocol]?
|
||||||
|
public var rootMolecules: [MoleculeModelProtocol] { [] }
|
||||||
|
|
||||||
public var tabBarHidden: Bool = false
|
public var tabBarHidden: Bool = false
|
||||||
public var tabBarIndex: Int?
|
public var tabBarIndex: Int?
|
||||||
|
|||||||
@ -9,11 +9,16 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers open class ThreeLayerModelBase: TemplateModel, ThreeLayerTemplateModelProtocol {
|
@objcMembers open class ThreeLayerModelBase: TemplateModel, ThreeLayerTemplateModelProtocol {
|
||||||
|
|
||||||
public var anchorHeader: Bool = false
|
public var anchorHeader: Bool = false
|
||||||
public var header: MoleculeModelProtocol?
|
public var header: MoleculeModelProtocol?
|
||||||
public var anchorFooter: Bool = false
|
public var anchorFooter: Bool = false
|
||||||
public var footer: MoleculeModelProtocol?
|
public var footer: MoleculeModelProtocol?
|
||||||
|
|
||||||
|
public override var rootMolecules: [MoleculeModelProtocol] {
|
||||||
|
return [header, footer].compactMap { $0 }
|
||||||
|
}
|
||||||
|
|
||||||
public override init(pageType: String) {
|
public override init(pageType: String) {
|
||||||
super.init(pageType: pageType)
|
super.init(pageType: pageType)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,13 @@ import Foundation
|
|||||||
}
|
}
|
||||||
public var middle: MoleculeModelProtocol?
|
public var middle: MoleculeModelProtocol?
|
||||||
|
|
||||||
|
public override var rootMolecules: [MoleculeModelProtocol] {
|
||||||
|
if let middle = middle {
|
||||||
|
return super.rootMolecules + [middle]
|
||||||
|
}
|
||||||
|
return super.rootMolecules
|
||||||
|
}
|
||||||
|
|
||||||
public init(pageType: String, header: MoleculeModelProtocol?, middle: MoleculeModelProtocol?, footer: MoleculeModelProtocol?) {
|
public init(pageType: String, header: MoleculeModelProtocol?, middle: MoleculeModelProtocol?, footer: MoleculeModelProtocol?) {
|
||||||
super.init(pageType: pageType)
|
super.init(pageType: pageType)
|
||||||
self.header = header
|
self.header = header
|
||||||
|
|||||||
@ -338,6 +338,13 @@ import UIKit
|
|||||||
initialLoad()
|
initialLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print("total molecules in tree: \(model?.rootMolecules.countMolecules() ?? 0)")
|
||||||
|
|
||||||
|
model?.rootMolecules.printMolecules()
|
||||||
|
|
||||||
|
let allVideoMolecules:[BGVideoImageMoleculeModel] = model?.rootMolecules.allMoleculesOfType() ?? []
|
||||||
|
print("video molecules: \(allVideoMolecules.count)")
|
||||||
|
|
||||||
handleNewDataAndUpdateUI()
|
handleNewDataAndUpdateUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user