將用戶選字記憶機制整合入 InputMethodController
This commit is contained in:
parent
d672136843
commit
3e0e859feb
|
@ -47,10 +47,12 @@ namespace Formosa {
|
|||
const vector<KeyValuePair>& candidates() const;
|
||||
void selectCandidateAtIndex(size_t inIndex = 0, bool inFix = true);
|
||||
void resetCandidate();
|
||||
void selectFloatingCandidateAtIndex(size_t index, double score);
|
||||
|
||||
const string& key() const;
|
||||
double score() const;
|
||||
const KeyValuePair currentKeyValue() const;
|
||||
double highestUnigramScore() const;
|
||||
|
||||
protected:
|
||||
const LanguageModel* m_LM;
|
||||
|
@ -175,6 +177,16 @@ namespace Formosa {
|
|||
m_score = m_unigrams[0].score;
|
||||
}
|
||||
}
|
||||
|
||||
inline void Node::selectFloatingCandidateAtIndex(size_t index, double score) {
|
||||
if (index >= m_unigrams.size()) {
|
||||
m_selectedUnigramIndex = 0;
|
||||
} else {
|
||||
m_selectedUnigramIndex = index;
|
||||
}
|
||||
m_candidateFixed = false;
|
||||
m_score = score;
|
||||
}
|
||||
|
||||
inline const string& Node::key() const
|
||||
{
|
||||
|
@ -185,6 +197,13 @@ namespace Formosa {
|
|||
{
|
||||
return m_score;
|
||||
}
|
||||
|
||||
inline double Node::highestUnigramScore() const {
|
||||
if (m_unigrams.empty()) {
|
||||
return 0.0;
|
||||
}
|
||||
return m_unigrams[0].score;
|
||||
}
|
||||
|
||||
inline const KeyValuePair Node::currentKeyValue() const
|
||||
{
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#import "Mandarin.h"
|
||||
#import "Gramambular.h"
|
||||
#import "FastLM.h"
|
||||
#import "UserOverrideModel.h"
|
||||
|
||||
@interface McBopomofoInputMethodController : IMKInputController
|
||||
{
|
||||
|
@ -53,6 +54,9 @@
|
|||
// latest walked path (trellis) using the Viterbi algorithm
|
||||
std::vector<Formosa::Gramambular::NodeAnchor> _walkedNodes;
|
||||
|
||||
// user override model
|
||||
McBopomofo::UserOverrideModel *_uom;
|
||||
|
||||
// the latest composing buffer that is updated to the foreground app
|
||||
NSMutableString *_composingBuffer;
|
||||
NSInteger _latestReadingCursor;
|
||||
|
|
|
@ -114,6 +114,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/McBopomofo-visualization.dot
|
|||
// shared language model object that stores our phrase-term probability database
|
||||
FastLM gLanguageModel;
|
||||
FastLM gLanguageModelPlainBopomofo;
|
||||
McBopomofo::UserOverrideModel gUserOverrideModel(200, 60.0);
|
||||
|
||||
// https://clang-analyzer.llvm.org/faq.html
|
||||
__attribute__((annotate("returns_localized_nsstring")))
|
||||
|
@ -176,6 +177,7 @@ public:
|
|||
// create the lattice builder
|
||||
_languageModel = &gLanguageModel;
|
||||
_builder = new BlockReadingBuilder(_languageModel);
|
||||
_uom = &gUserOverrideModel;
|
||||
|
||||
// each Mandarin syllable is separated by a hyphen
|
||||
_builder->setJoinSeparator("-");
|
||||
|
@ -659,6 +661,33 @@ public:
|
|||
// then walk the lattice
|
||||
[self popOverflowComposingTextAndWalk:client];
|
||||
|
||||
// get user override model suggestion
|
||||
string overrideCandidate = _uom->suggest(_walkedNodes, _builder->cursorIndex(), [[NSDate date] timeIntervalSince1970]);
|
||||
if (!overrideCandidate.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// then update the text
|
||||
_bpmfReadingBuffer->clear();
|
||||
[self updateClientComposingBuffer:client];
|
||||
|
@ -1373,6 +1402,7 @@ public:
|
|||
|
||||
size_t cursorIndex = [self actualCandidateCursorIndex];
|
||||
_builder->grid().fixNodeSelectedCandidate(cursorIndex, selectedValue);
|
||||
_uom->observe(_walkedNodes, cursorIndex, selectedValue, [[NSDate date] timeIntervalSince1970]);
|
||||
|
||||
[_candidates removeAllObjects];
|
||||
|
||||
|
|
Loading…
Reference in New Issue