From fa224c26573eb304b20f9277a89394bdd0d64673 Mon Sep 17 00:00:00 2001 From: Lukhnos Liu Date: Fri, 9 Oct 2020 21:17:42 -0700 Subject: [PATCH] Reset other nodes' fixed state when fixing a node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a bug that, when a span covers several nodes and a long node has already been candidate-fixed, fixing a short node does not cause the walk to reflect the result. A concrete example: 1. type 高中生. 2. move the cursor to 中 and change to 鐘聲: 高鐘聲. 3. with cursor position unchanged, select the candidate to 忠. 4. the expected result should be 高忠生 but instead it is stuck with 高鐘聲 due to the node representing "鐘聲" is still fixed. Fixes #54 --- Source/Engine/Gramambular/Grid.h | 4 ++++ Source/Engine/Gramambular/Node.h | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Gramambular/Grid.h b/Source/Engine/Gramambular/Grid.h index ee5a3bf3..e13c8eab 100644 --- a/Source/Engine/Gramambular/Grid.h +++ b/Source/Engine/Gramambular/Grid.h @@ -182,6 +182,10 @@ namespace Formosa { vector nodes = nodesCrossingOrEndingAt(location); for (auto nodeAnchor : nodes) { auto candidates = nodeAnchor.node->candidates(); + + // Reset the candidate-fixed state of every node at the location. + const_cast(nodeAnchor.node)->resetCandidate(); + for (size_t i = 0, c = candidates.size(); i < c; ++i) { if (candidates[i].value == value) { const_cast(nodeAnchor.node)->selectCandidateAtIndex(i); diff --git a/Source/Engine/Gramambular/Node.h b/Source/Engine/Gramambular/Node.h index d4b7b432..89a74813 100644 --- a/Source/Engine/Gramambular/Node.h +++ b/Source/Engine/Gramambular/Node.h @@ -46,6 +46,7 @@ namespace Formosa { bool isCandidateFixed() const; const vector& candidates() const; void selectCandidateAtIndex(size_t inIndex = 0, bool inFix = true); + void resetCandidate(); const string& key() const; double score() const; @@ -164,7 +165,16 @@ namespace Formosa { m_candidateFixed = inFix; m_score = 99; - } + } + + inline void Node::resetCandidate() + { + m_selectedUnigramIndex = 0; + m_candidateFixed = 0; + if (m_unigrams.size()) { + m_score = m_unigrams[0].score; + } + } inline const string& Node::key() const {