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()
|
||||
while (iterator.hasNext()) {
|
||||
val block = iterator.next()
|
||||
val activationScore = block.applyTimeFade()
|
||||
if (activationScore <= 0.0) {
|
||||
val fadedScore = block.applyTimeFade()
|
||||
if (fadedScore <= 0.0) {
|
||||
iterator.remove()
|
||||
continue
|
||||
}
|
||||
@@ -51,6 +51,12 @@ class ContextWorkspace {
|
||||
continue
|
||||
}
|
||||
|
||||
val activationScore = block.activate()
|
||||
if (activationScore <= 0.0) {
|
||||
iterator.remove()
|
||||
continue
|
||||
}
|
||||
|
||||
activeBlocks += ResolvedContextBlock(
|
||||
block = block,
|
||||
domainWeight = matchedDomains.sumOf { domainWeights.getValue(it) },
|
||||
@@ -67,16 +73,26 @@ class ContextWorkspace {
|
||||
.thenBy { it.activationScore }
|
||||
.thenBy { it.block.blockContent.encodeToXmlString() }
|
||||
)
|
||||
.map { resolved ->
|
||||
if (resolved.forceFullRender) {
|
||||
resolved.block.blockContent
|
||||
.groupBy { it.block.sourceKey }
|
||||
.values
|
||||
.map { groupedBlocks ->
|
||||
if (groupedBlocks.size == 1) {
|
||||
renderResolvedBlock(groupedBlocks.first())
|
||||
} else {
|
||||
resolved.block.render()
|
||||
AggregatedBlockContent(groupedBlocks)
|
||||
}
|
||||
}
|
||||
ResolvedContext(blocks)
|
||||
}
|
||||
|
||||
private fun renderResolvedBlock(resolved: ResolvedContextBlock): BlockContent {
|
||||
return if (resolved.forceFullRender) {
|
||||
resolved.block.blockContent
|
||||
} else {
|
||||
resolved.block.render()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param contextBlock 注册的新上下文块
|
||||
@@ -159,25 +175,29 @@ data class ContextBlock @JvmOverloads constructor(
|
||||
get() = SourceKey(blockContent.blockName, blockContent.source)
|
||||
|
||||
fun applyTimeFade(): Double {
|
||||
val now = Instant.now()
|
||||
val elapsedSeconds = Duration.between(lastTouchedAt, now).toMillis() / 1000.0
|
||||
activationScore = max(0.0, activationScore - elapsedSeconds * (timeFadeFactor / 60.0))
|
||||
lastTouchedAt = now
|
||||
refreshByElapsedTime()
|
||||
return activationScore
|
||||
}
|
||||
|
||||
fun applyReplaceFade(): Double {
|
||||
applyTimeFade()
|
||||
refreshByElapsedTime()
|
||||
activationScore = max(0.0, activationScore - replaceFadeFactor)
|
||||
return activationScore
|
||||
}
|
||||
|
||||
fun activate(): Double {
|
||||
applyTimeFade()
|
||||
refreshByElapsedTime()
|
||||
activationScore = min(100.0, activationScore + activateFactor)
|
||||
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 {
|
||||
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(
|
||||
val blockName: String,
|
||||
val source: String,
|
||||
|
||||
Reference in New Issue
Block a user