From 87529da15f6039bdf179fe9f95b2a0629c0834bb Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Mon, 11 Sep 2017 18:55:59 -0700 Subject: [PATCH] Precompute all the transitions ahead of time. --- .../nwapw/abacus/number/PromotionManager.kt | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/core/src/main/kotlin/org/nwapw/abacus/number/PromotionManager.kt b/core/src/main/kotlin/org/nwapw/abacus/number/PromotionManager.kt index 421d642..a49a61c 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/number/PromotionManager.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/number/PromotionManager.kt @@ -37,21 +37,6 @@ class PromotionManager(val abacus: Abacus) : PluginListener { return null } - /** - * If a path between the given implementations has already been computed, uses - * the already calculated path. Otherwise, calls [computePathBetween] to compute a new - * path. - * - * @param from the implementation to start from. - * @param to the implementation to get to. - * @return the resulting promotion path, or null if it is not found - */ - fun getPathBetween(from: NumberImplementation, to: NumberImplementation): PromotionPath? { - return computePaths.computeIfAbsent(from to to, { - computePathBetween(it.first, it.second) - }) - } - /** * Promote all the numbers in the list to the same number implementation, to ensure * they can be used with each other. Finds the highest priority implementation @@ -66,16 +51,26 @@ class PromotionManager(val abacus: Abacus) : PluginListener { val highestPriority = implementations.sortedBy { it.priority }.last() return PromotionResult(items = numbers.map { if(it.javaClass == highestPriority.implementation) it - else getPathBetween(pluginManager.interfaceImplementationFor(it.javaClass), highestPriority) + else computePaths[pluginManager.interfaceImplementationFor(it.javaClass) to highestPriority] ?.promote(it) ?: return null }.toTypedArray(), promotedTo = highestPriority) } - override fun onLoad(manager: PluginManager?) { + override fun onLoad(manager: PluginManager) { + val implementations = manager.allNumberImplementations.map { manager.numberImplementationFor(it) } + for((index, value) in implementations.withIndex()){ + for(i in index until implementations.size){ + val other = implementations[i] + val promoteFrom = if(other.priority > value.priority) value else other + val promoteTo = if(other.priority > value.priority) other else value + val path = computePathBetween(promoteFrom, promoteTo) + computePaths.put(promoteFrom to promoteTo, path) + } + } } - override fun onUnload(manager: PluginManager?) { + override fun onUnload(manager: PluginManager) { computePaths.clear() }