Reset other nodes' fixed state when fixing a node

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
This commit is contained in:
Lukhnos Liu 2020-10-09 21:17:42 -07:00
parent f31a57c997
commit fa224c2657
2 changed files with 15 additions and 1 deletions

View File

@ -182,6 +182,10 @@ namespace Formosa {
vector<NodeAnchor> 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<Node*>(nodeAnchor.node)->resetCandidate();
for (size_t i = 0, c = candidates.size(); i < c; ++i) {
if (candidates[i].value == value) {
const_cast<Node*>(nodeAnchor.node)->selectCandidateAtIndex(i);

View File

@ -46,6 +46,7 @@ namespace Formosa {
bool isCandidateFixed() const;
const vector<KeyValuePair>& 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
{