GraniteNavigation
public final class GraniteNavigation: ObservableObject {
public struct Router {
...
}
public var asRouter: Router
let isMain: Bool
private var children: [String : GraniteNavigation] = [:]
public init(isMain: Bool)
//Main data source
internal var isActive = [String : Bool]()
private var paths: [String: () -> AnyView] = [:]
private var stack: [String] = []
var level: Int
//Internal hierarchy management
func addChild(_ key: String, navigation: GraniteNavigation)
@discardableResult
func removeChild(_ key: String) -> GraniteNavigation?
func child(_ key: String) -> GraniteNavigation?
//Main Control logics
func addressHeap<T: AnyObject>(o: T) -> Int
@discardableResult
func set<Component : GraniteComponent>(destinationStyle: GraniteNavigationDestinationStyle = .init(),
@ViewBuilder _ component: @escaping (() -> Component)) -> String
func push(_ addr: String,
window: GraniteRouteWindowProperties? = nil)
func pop()
func releaseStack()
}Essentially, this is the command center for GraniteNavigation instances that are created per GraniteNavigationView.
When an instance is created it will automatically "id" itself depending on the count available and if a main router has been set or not.
On macOS, each window should have its own
main, while child routers are nested within.
When a GraniteComponent or View is Pushed, they are wrapped in a NavigationComponent, which is then wrapped into a Navigation Screen.
I am still considering the need for 2 layers of nesting. Going directly into a Screen would be less intensive. But, having access to EnvironmentValues in a layer between presentation or building could be helpful for further needs customization.
The target view is never "built" until the screen presents. Being passed as Builders/handlers, i.e. () -> Content. The screen finally manages the creation. Since the screen is of a class type, we use its heap's memory address to act as the key when storing in the stack. The array of these addresses act as the stack's ordering, while the map, paths, is used for retrieval. GraniteRouter shows how they are displayed at the final stage of the navigation flow.
GraniteNavigation.Router | GraniteRouter
These are 2 different structs. But, GraniteNavigation.Router essentially helps assign the next path for GraniteRouter to display on the front-end. By connecting the target View with the proper GraniteNavigation instance.