小幅重構重複的程式碼

This commit is contained in:
ovadmin 2017-10-02 00:59:20 +08:00 committed by Lukhnos Liu
parent 2e8e78971c
commit aeb774a8ed
2 changed files with 46 additions and 22 deletions

View File

@ -47,7 +47,18 @@ namespace Formosa {
size_t width() const;
vector<NodeAnchor> nodesEndingAt(size_t inLocation);
vector<NodeAnchor> nodesCrossingOrEndingAt(size_t inLocation);
// "Freeze" the node with the unigram that represents the selected canditate value.
// After this, the node that contains the unigram will always be evaluated to that
// unigram, while all other overlapping nodes will be reset to their initial state
// (that is, if any of those nodes were "frozen" or fixed, they will be unfrozen.)
void fixNodeSelectedCandidate(size_t location, const string& value);
// Similar to fixNodeSelectedCandidate, but instead of "freezing" the node, only
// boost the unigram that represents the value with an overriding score. This
// has the same side effect as fixNodeSelectedCandidate, which is that all other
// overlapping nodes will be reset to their initial state.
void overrideNodeScoreForSelectedCandidate(size_t location, const string& value, float overridingScore);
const string dumpDOT();
@ -194,6 +205,24 @@ namespace Formosa {
}
}
}
inline void Grid::overrideNodeScoreForSelectedCandidate(size_t location, const string& value, float overridingScore)
{
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)->selectFloatingCandidateAtIndex(i, overridingScore);
break;
}
}
}
}
inline const string Grid::dumpDOT()
{

View File

@ -150,6 +150,19 @@ public:
}
};
static const double kEpsilon = 0.000001;
static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon) {
double highestScore = 0.0;
for (auto ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) {
double score = ni->node->highestUnigramScore();
if (score > highestScore) {
highestScore = score;
}
}
return highestScore + epsilon;
}
@implementation McBopomofoInputMethodController
- (void)dealloc
{
@ -665,32 +678,14 @@ public:
[self popOverflowComposingTextAndWalk:client];
// get user override model suggestion
string overrideCandidate =
string overrideValue =
(_inputMode == kPlainBopomofoModeIdentifier) ? "" :
_uom->suggest(_walkedNodes, _builder->cursorIndex(), [[NSDate date] timeIntervalSince1970]);
if (!overrideCandidate.empty()) {
if (!overrideValue.empty()) {
size_t cursorIndex = [self actualCandidateCursorIndex];
vector<NodeAnchor> nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex);
double highestScore = 0.0;
for (auto ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) {
double score = ni->node->highestUnigramScore();
if (score > highestScore) {
highestScore = score;
}
}
highestScore += 0.00001;
for (vector<NodeAnchor>::iterator ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) {
const vector<KeyValuePair>& candidates = (*ni).node->candidates();
for (size_t i = 0, c = candidates.size(); i < c; ++i) {
if (candidates[i].value == overrideCandidate) {
// found our node
const_cast<Node*>((*ni).node)->selectFloatingCandidateAtIndex(i, highestScore);
break;
}
}
}
double highestScore = FindHighestScore(nodes, kEpsilon);
_builder->grid().overrideNodeScoreForSelectedCandidate(cursorIndex, overrideValue, highestScore);
}
// then update the text