kotlin-jupyter icon indicating copy to clipboard operation
kotlin-jupyter copied to clipboard

Renderer resolution order

Open altavir opened this issue 3 years ago • 3 comments

Consider the following situation: two jupyter integration have a renderer for the same type and are imported to the classpath. Currently, there are no wats to find, which one will be used. Obviously, the situation is not far-fetched. There could be different renderers for commonly used classes like a Map.

In VisionForge I am solving a similar problem by assigning a rating number and then selecting a renderer with the highest rating:

https://github.com/mipt-npm/visionforge/blob/3caa22f8bf0bad62ea9d2b123e4f60a1b89eeaf1/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/elementOutput.kt#L15

Libraries could declare renderers with higher than default rating allowing developers to declare that one renderer is better than the default one. There could be other solutions as well.

altavir avatar Dec 16 '21 16:12 altavir

Maybe more generic approach

interface ComparableRenderer : Comparable<Renderer>, Renderer

fun compare(r1: Renderer, r2: Renderer): Int {
    return if (r1 is ComparableRenderer) {
         r1.compareTo(r2)
    } else {
         if (r2 is ComparableRenderer) -r2.compareTo(r1)
         else 0
    }
}

abstract class PriorityComparableRenderer(val priority: Int = 10) : ComparableRenderer {
    override fun compareTo(other: Renderer): Int {
       return if (other is PriorityComparableRenderer) return priority.compareTo(other.priority)
       else 0
    }
}

ileasile avatar Dec 17 '21 04:12 ileasile

"Electors" approach

fun interface RenderersElector {
    fun elect(renderers: Collection<Renderer>): Collection<Renderer>
}

fun electMax(renderers: Collection<Renderer>): Renderer {
    return electors.fold(renderers) { acc, elector -> elector.elect(acc) }.first() // in ideal case, should remain single
}

ileasile avatar Dec 17 '21 06:12 ileasile

Both these approaches compare renderers without any knowledge about the object being rendered. If we are talking about generic, it probably would be better to provide an actual object for the selector. Also, it is not clear, who will select a selector. If the user just loads two integrations (libraries? plugins? do we have an official name?), he won't have any prompt on choosing which to use. An overriding strategy would be nice, but by default, he would expect that they will decide themselves.

altavir avatar Dec 17 '21 06:12 altavir