All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.tunjid.treenav.Node.kt Maven / Gradle / Ivy

/*
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.tunjid.treenav

/**
 * A representation of a navigation node with child nodes [children]
 */
interface Node {
    val id: String

    val children: List get() = listOf()
}

/**
 * A navigation node that represents a navigation destination on the screen.
 */
interface Route : Node

sealed class Order {
    object BreadthFirst : Order()
    object DepthFirst : Order()
}

/**
 * Traverses each node in the tree with [this] as a parent
 */

inline fun Node.traverse(order: Order, crossinline onNodeVisited: (Node) -> Unit) = when (order) {
    Order.BreadthFirst -> {
        val queue = mutableListOf(this)
        while (queue.isNotEmpty()) {
            // deque.
            val node = queue.removeAt(0)
            // Visit node.
            onNodeVisited(node)
            // Push child nodes on the queue.
            for (element in node.children) queue.add(element)
        }
    }
    Order.DepthFirst -> {
        val stack = mutableListOf(this)
        while (stack.isNotEmpty()) {
            // Pop off end of stack.
            val node = stack.removeAt(stack.lastIndex)
            // Visit node.
            onNodeVisited(node)
            // Push child nodes on the stack.
            for (i in node.children.lastIndex downTo 0) stack.add(node.children[i])
        }
    }
}

/**
 * Returns a [List] of all [Node]s in the tree with [this] as a parent
 */
fun Node.flatten(order: Order): List {
    val result = mutableListOf()
    traverse(order, result::add)
    return result
}

/**
 * Returns the set of nodes in [this] that are not present in [node]
 */
operator fun Node.minus(node: Node): Set {
    val left = mutableSetOf().let { set ->
        this.traverse(Order.BreadthFirst, set::add)
        set - this
    }
    val right = mutableSetOf().let { set ->
        node.traverse(Order.BreadthFirst, set::add)
        set - node
    }
    return left - right
}







© 2015 - 2025 Weber Informatics LLC | Privacy Policy