initial progress

This commit is contained in:
Kyle Matthew Hedden 2021-03-19 17:04:21 -04:00
parent 7a8a28a121
commit 790a19b34f
16 changed files with 223 additions and 5 deletions

View File

@ -123,6 +123,8 @@
0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB423FF18D2004C5109 /* Arrow.swift */; };
0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB623FF18E9004C5109 /* ArrowModel.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 /* PageBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F973522466074500CAB5C5 /* PageBehavior.swift */; };
27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */; };
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; };
@ -679,6 +681,8 @@
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>"; };
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 /* PageBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehavior.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>"; };
@ -1147,6 +1151,7 @@
D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */,
D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */,
D28BA74C248589C800B75CB8 /* TabPageModelProtocol.swift */,
27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */,
);
path = ModelProtocols;
sourceTree = "<group>";
@ -2275,6 +2280,7 @@
isa = PBXGroup;
children = (
012A88C7238DB02000FE3DA1 /* MoleculeDelegateProtocol.swift */,
27F6B08726051831008529AA /* MoleculeTreeTraversalProtocol.swift */,
017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */,
D20F3B43252E00E4004B3F56 /* PageProtocol.swift */,
012A88AC238C418100FE3DA1 /* TemplateProtocol.swift */,
@ -2820,6 +2826,7 @@
0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */,
D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */,
AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */,
27F6B08826051831008529AA /* MoleculeTreeTraversalProtocol.swift in Sources */,
D2D3957A252FDBB300047B11 /* ModalSectionListTemplate.swift in Sources */,
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */,
D28BA741248025A300B75CB8 /* TabBarModel.swift in Sources */,
@ -2945,6 +2952,7 @@
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */,
27F6B08C26052AFF008529AA /* ParentMoleculeModelProtocol.swift in Sources */,
0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */,
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */,

View File

@ -12,7 +12,7 @@ public class TabsListItemModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "tabsListItem"
var tabs: TabsModel
var molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]
private enum CodingKeys: String, CodingKey {
case moleculeName
case tabs

View File

@ -48,4 +48,14 @@ open class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtoco
try container.encodeModel(molecule, forKey: .molecule)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
}
public func reduceDepthFirstTraverse<Result>(initialResult:Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result {
let result = nextPartialResult(initialResult, molecule)
return nextPartialResult(result, self)
}
public func depthFirstTraverse(_ cb: (MoleculeModelProtocol)->Void) {
cb(molecule)
cb(self)
}
}

View File

@ -8,6 +8,14 @@
import Foundation
public protocol MoleculeContainerModelProtocol: ContainerModelProtocol {
public protocol MoleculeContainerModelProtocol: ContainerModelProtocol, ParentMoleculeModelProtocol {
var molecule: MoleculeModelProtocol { get set }
}
public extension MoleculeContainerModelProtocol {
var children: [MoleculeModelProtocol] {
return [molecule]
}
}

View File

@ -7,7 +7,8 @@
//
@objcMembers public class StackModel: ContainerModel, StackModelProtocol, MoleculeModelProtocol {
@objcMembers public class StackModel: ContainerModel, StackModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -24,6 +25,10 @@
public var spacing: CGFloat = StackModel.defaultSpacing
public var useStackSpacingBeforeFirstItem = false
public var children: [MoleculeModelProtocol] {
return molecules
}
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
@ -77,4 +82,5 @@
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
}
}

View File

@ -8,9 +8,15 @@
import Foundation
public protocol StackModelProtocol {
public protocol StackModelProtocol: ParentMoleculeModelProtocol {
var molecules: [StackItemModelProtocol & MoleculeModelProtocol] { get set }
var axis: NSLayoutConstraint.Axis { get set }
var spacing: CGFloat { get set }
var useStackSpacingBeforeFirstItem: Bool { get set }
}
extension StackModelProtocol {
public var children: [MoleculeModelProtocol] { return molecules }
}

View File

@ -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 backgroundColor: Color? { get set }
}
@ -20,3 +20,54 @@ public extension MoleculeModelProtocol {
static var categoryCodingKey: String { "moleculeName" }
}
public extension MoleculeModelProtocol {
func reduceDepthFirstTraverse<Result>(initialResult:Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result {
return nextPartialResult(initialResult, self)
}
func depthFirstTraverse(callback: (MoleculeModelProtocol)->Void) {
callback(self)
}
}
public extension Array where Element == MoleculeModelProtocol {
func reduceDepthFirstTraverse<Result>(initialResult:Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result {
return reduce(initialResult) { (result, molecule) -> Result in
return molecule.reduceDepthFirstTraverse(initialResult: result, nextPartialResult: nextPartialResult)
}
}
func depthFirstTraverse(callback: (MoleculeModelProtocol)->Void) {
forEach { (molecule) in
molecule.depthFirstTraverse(callback: 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()
}
}
}

View File

@ -0,0 +1,39 @@
//
// 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>(initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol) -> Result) -> Result {
let result = children.reduce(initialResult) { (result, molecule) -> Result in
if let additionalParent = molecule as? ParentMoleculeModelProtocol {
return additionalParent.reduceDepthFirstTraverse(initialResult: result, nextPartialResult: nextPartialResult)
}
return molecule.reduceDepthFirstTraverse(initialResult: result, nextPartialResult: nextPartialResult)
}
return nextPartialResult(result, self)
}
func depthFirstTraverse(callback: (MoleculeModelProtocol)->Void) {
children.forEach { (molecule) in
if let additionalParent = molecule as? ParentMoleculeModelProtocol {
additionalParent.depthFirstTraverse(callback: callback)
}
molecule.depthFirstTraverse(callback: callback)
}
callback(self)
}
}

View File

@ -11,6 +11,7 @@ import Foundation
public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol {
var template: String { get }
var rootMolecules: [MoleculeModelProtocol] { get }
}
public extension TemplateModelProtocol {

View File

@ -0,0 +1,48 @@
//
// TreeTraversalProtocol.swift
// MVMCoreUI
//
// Created by Kyle on 3/19/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
public protocol MoleculeTreeTraversalProtocol {
// Future options -- Parent first depth first, leaves only.
func reduceDepthFirstTraverse<Result>(initialResult:Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result
func depthFirstTraverse(callback: (MoleculeModelProtocol)->Void)
//func breadthFirstTraverse()
}
//
// Helper Extensions
//
extension MoleculeTreeTraversalProtocol {
func countMolecules() -> Int {
return reduceDepthFirstTraverse(initialResult: 0) { (accumulator, molecule) in
return accumulator + 1
}
}
func printMolecules() {
depthFirstTraverse { (molecule) in
print(molecule)
}
}
func allMoleculesOfType<T>() -> [T] {
return reduceDepthFirstTraverse(initialResult: []) { (accumulator, molecule) in
if let typedMolecule = molecule as? T {
return accumulator + [typedMolecule]
}
return accumulator
}
}
}

View File

@ -18,6 +18,13 @@ import Foundation
}
public var molecules: [CollectionItemModelProtocol & MoleculeModelProtocol]?
public var columns: Int?
public override var rootMolecules: [MoleculeModelProtocol] {
if let molecules = molecules {
return super.rootMolecules + molecules
}
return super.rootMolecules
}
//--------------------------------------------------
// MARK: - Initializer

View File

@ -20,6 +20,13 @@ import Foundation
public var line: LineModel?
public var scrollToRowIndex: Int?
public override var rootMolecules: [MoleculeModelProtocol] {
if let molecules = molecules {
return super.rootMolecules + molecules
}
return super.rootMolecules
}
/// This template requires content.
func validateModelHasContent() throws {
if header == nil,

View File

@ -30,6 +30,7 @@ import Foundation
public var navigationBar: (NavigationItemModelProtocol & MoleculeModelProtocol)?
public var formRules: [FormGroupRule]?
public var behaviors: [PageBehaviorProtocol]?
public var rootMolecules: [MoleculeModelProtocol] { [] }
public var tabBarHidden: Bool = false
public var tabBarIndex: Int?

View File

@ -9,11 +9,23 @@
import Foundation
@objcMembers open class ThreeLayerModelBase: TemplateModel, ThreeLayerTemplateModelProtocol {
public var anchorHeader: Bool = false
public var header: MoleculeModelProtocol?
public var anchorFooter: Bool = false
public var footer: MoleculeModelProtocol?
public override var rootMolecules: [MoleculeModelProtocol] {
var rootMolecules:[MoleculeModelProtocol] = []
if let header = header {
rootMolecules.append(header)
}
if let footer = footer {
rootMolecules.append(footer)
}
return rootMolecules
}
public override init(pageType: String) {
super.init(pageType: pageType)
}

View File

@ -14,6 +14,13 @@ import Foundation
}
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?) {
super.init(pageType: pageType)
self.header = header

View File

@ -336,6 +336,13 @@ import UIKit
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()
}