mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 16:53:04 +08:00
refactor(context): aggregate resolved blocks by source snapshots and centralize elapsed-time activation refresh
This commit is contained in:
@@ -40,8 +40,8 @@ class ContextWorkspace {
|
|||||||
val iterator = stateSet.iterator()
|
val iterator = stateSet.iterator()
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
val block = iterator.next()
|
val block = iterator.next()
|
||||||
val activationScore = block.applyTimeFade()
|
val fadedScore = block.applyTimeFade()
|
||||||
if (activationScore <= 0.0) {
|
if (fadedScore <= 0.0) {
|
||||||
iterator.remove()
|
iterator.remove()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -51,6 +51,12 @@ class ContextWorkspace {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val activationScore = block.activate()
|
||||||
|
if (activationScore <= 0.0) {
|
||||||
|
iterator.remove()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
activeBlocks += ResolvedContextBlock(
|
activeBlocks += ResolvedContextBlock(
|
||||||
block = block,
|
block = block,
|
||||||
domainWeight = matchedDomains.sumOf { domainWeights.getValue(it) },
|
domainWeight = matchedDomains.sumOf { domainWeights.getValue(it) },
|
||||||
@@ -67,15 +73,25 @@ class ContextWorkspace {
|
|||||||
.thenBy { it.activationScore }
|
.thenBy { it.activationScore }
|
||||||
.thenBy { it.block.blockContent.encodeToXmlString() }
|
.thenBy { it.block.blockContent.encodeToXmlString() }
|
||||||
)
|
)
|
||||||
.map { resolved ->
|
.groupBy { it.block.sourceKey }
|
||||||
if (resolved.forceFullRender) {
|
.values
|
||||||
|
.map { groupedBlocks ->
|
||||||
|
if (groupedBlocks.size == 1) {
|
||||||
|
renderResolvedBlock(groupedBlocks.first())
|
||||||
|
} else {
|
||||||
|
AggregatedBlockContent(groupedBlocks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ResolvedContext(blocks)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderResolvedBlock(resolved: ResolvedContextBlock): BlockContent {
|
||||||
|
return if (resolved.forceFullRender) {
|
||||||
resolved.block.blockContent
|
resolved.block.blockContent
|
||||||
} else {
|
} else {
|
||||||
resolved.block.render()
|
resolved.block.render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResolvedContext(blocks)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -159,25 +175,29 @@ data class ContextBlock @JvmOverloads constructor(
|
|||||||
get() = SourceKey(blockContent.blockName, blockContent.source)
|
get() = SourceKey(blockContent.blockName, blockContent.source)
|
||||||
|
|
||||||
fun applyTimeFade(): Double {
|
fun applyTimeFade(): Double {
|
||||||
val now = Instant.now()
|
refreshByElapsedTime()
|
||||||
val elapsedSeconds = Duration.between(lastTouchedAt, now).toMillis() / 1000.0
|
|
||||||
activationScore = max(0.0, activationScore - elapsedSeconds * (timeFadeFactor / 60.0))
|
|
||||||
lastTouchedAt = now
|
|
||||||
return activationScore
|
return activationScore
|
||||||
}
|
}
|
||||||
|
|
||||||
fun applyReplaceFade(): Double {
|
fun applyReplaceFade(): Double {
|
||||||
applyTimeFade()
|
refreshByElapsedTime()
|
||||||
activationScore = max(0.0, activationScore - replaceFadeFactor)
|
activationScore = max(0.0, activationScore - replaceFadeFactor)
|
||||||
return activationScore
|
return activationScore
|
||||||
}
|
}
|
||||||
|
|
||||||
fun activate(): Double {
|
fun activate(): Double {
|
||||||
applyTimeFade()
|
refreshByElapsedTime()
|
||||||
activationScore = min(100.0, activationScore + activateFactor)
|
activationScore = min(100.0, activationScore + activateFactor)
|
||||||
return activationScore
|
return activationScore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun refreshByElapsedTime() {
|
||||||
|
val now = Instant.now()
|
||||||
|
val elapsedSeconds = Duration.between(lastTouchedAt, now).toMillis() / 1000.0
|
||||||
|
activationScore = max(0.0, activationScore - elapsedSeconds * (timeFadeFactor / 60.0))
|
||||||
|
lastTouchedAt = now
|
||||||
|
}
|
||||||
|
|
||||||
fun sameWith(contextBlock: ContextBlock): Boolean {
|
fun sameWith(contextBlock: ContextBlock): Boolean {
|
||||||
return this.sourceKey == contextBlock.sourceKey
|
return this.sourceKey == contextBlock.sourceKey
|
||||||
}
|
}
|
||||||
@@ -196,6 +216,46 @@ data class ContextBlock @JvmOverloads constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class AggregatedBlockContent(
|
||||||
|
private val groupedBlocks: List<ResolvedContextBlock>
|
||||||
|
) : BlockContent(
|
||||||
|
groupedBlocks.first().block.sourceKey.blockName,
|
||||||
|
groupedBlocks.first().block.sourceKey.source,
|
||||||
|
groupedBlocks.maxByOrNull {
|
||||||
|
if (it.forceFullRender) it.block.blockContent.urgency.ordinal else it.block.render().urgency.ordinal
|
||||||
|
}?.let {
|
||||||
|
if (it.forceFullRender) it.block.blockContent.urgency else it.block.render().urgency
|
||||||
|
} ?: Urgency.NORMAL
|
||||||
|
) {
|
||||||
|
|
||||||
|
override fun fillXml(document: Document, root: Element) {
|
||||||
|
val snapshotIndex = groupedBlocks.withIndex()
|
||||||
|
.maxWithOrNull(
|
||||||
|
compareBy<IndexedValue<ResolvedContextBlock>> { it.value.activationScore }
|
||||||
|
.thenBy { it.index }
|
||||||
|
)?.index ?: 0
|
||||||
|
|
||||||
|
groupedBlocks.forEachIndexed { index, groupedBlock ->
|
||||||
|
val tagName = if (index == snapshotIndex) "snapshot" else "history_snapshot"
|
||||||
|
val wrapper = document.createElement(tagName)
|
||||||
|
val renderedBlock = if (groupedBlock.forceFullRender) {
|
||||||
|
groupedBlock.block.blockContent
|
||||||
|
} else {
|
||||||
|
groupedBlock.block.render()
|
||||||
|
}
|
||||||
|
wrapper.setAttribute("source", renderedBlock.source)
|
||||||
|
wrapper.setAttribute("urgency", renderedBlock.urgency.name.lowercase(Locale.ROOT))
|
||||||
|
root.appendChild(wrapper)
|
||||||
|
|
||||||
|
val encoded = renderedBlock.encodeToXml()
|
||||||
|
val childNodes = encoded.childNodes
|
||||||
|
for (childIndex in 0 until childNodes.length) {
|
||||||
|
wrapper.appendChild(document.importNode(childNodes.item(childIndex), true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract class BlockContent @JvmOverloads protected constructor(
|
abstract class BlockContent @JvmOverloads protected constructor(
|
||||||
val blockName: String,
|
val blockName: String,
|
||||||
val source: String,
|
val source: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user