Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(language): shared user dictionary per language (Closes #184) #214

Merged
merged 4 commits into from
Aug 2, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions src/rime/dict/user_dictionary.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <boost/lexical_cast.hpp>
#include <boost/scope_exit.hpp>
#include <rime/common.h>
#include <rime/language.h>
#include <rime/schema.h>
#include <rime/service.h>
#include <rime/ticket.h>
Expand Down Expand Up @@ -116,8 +117,8 @@ bool UserDictEntryIterator::Next() {

// UserDictionary members

UserDictionary::UserDictionary(const an<Db>& db)
: db_(db) {
UserDictionary::UserDictionary(const string& name, an<Db> db)
: name_(name), db_(db) {
}

UserDictionary::~UserDictionary() {
Expand Down Expand Up @@ -494,10 +495,8 @@ UserDictionary* UserDictionaryComponent::Create(const Ticket& ticket) {
// user specified name
}
else if (config->GetString(ticket.name_space + "/dictionary", &dict_name)) {
// {dictionary: lunapinyin.extra} implies {user_dict: luna_pinyin}
size_t dot = dict_name.find('.');
if (dot != string::npos && dot != 0)
dict_name.resize(dot);
// {dictionary: luna_pinyin.extra} implies {user_dict: luna_pinyin}
dict_name = Language::get_language_component(dict_name);
}
else {
LOG(ERROR) << ticket.name_space << "/dictionary not specified in schema '"
Expand All @@ -519,7 +518,7 @@ UserDictionary* UserDictionaryComponent::Create(const Ticket& ticket) {
db.reset(component->Create(dict_name));
db_pool_[dict_name] = db;
}
return new UserDictionary(db);
return new UserDictionary(dict_name, db);
}

} // namespace rime
2 changes: 1 addition & 1 deletion src/rime/dict/user_dictionary.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ struct Ticket;

class UserDictionary : public Class<UserDictionary, const Ticket&> {
public:
explicit UserDictionary(const an<Db>& db);
UserDictionary(const string& name, an<Db> db);
virtual ~UserDictionary();

void Attach(const an<Table>& table, const an<Prism>& prism);
Expand Down
13 changes: 10 additions & 3 deletions src/rime/gear/memory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <rime/composition.h>
#include <rime/engine.h>
#include <rime/key_event.h>
#include <rime/language.h>
#include <rime/schema.h>
#include <rime/ticket.h>
#include <rime/dict/dictionary.h>
Expand Down Expand Up @@ -65,6 +66,13 @@ Memory::Memory(const Ticket& ticket) {
}
}

// user dictionary is named after language; dictionary name may have an
// optional suffix separated from the language component by dot.
language_.reset(new Language{
user_dict_ ? user_dict_->name() :
Language::get_language_component(dict_->name())
});

Context* ctx = ticket.engine->context();
commit_connection_ = ctx->commit_notifier().connect(
[this](Context* ctx) { OnCommit(ctx); });
Expand Down Expand Up @@ -100,7 +108,7 @@ void Memory::OnCommit(Context* ctx) {
for (auto& seg : ctx->composition()) {
auto phrase = As<Phrase>(Candidate::GetGenuineCandidate(
seg.GetSelectedCandidate()));
bool recognized = phrase && phrase->language() == language();
bool recognized = Language::intelligible(phrase, this);
if (recognized) {
commit_entry.AppendPhrase(phrase);
}
Expand All @@ -119,8 +127,7 @@ void Memory::OnDeleteEntry(Context* ctx) {
return;
auto phrase = As<Phrase>(Candidate::GetGenuineCandidate(
ctx->GetSelectedCandidate()));
bool recognized = phrase && phrase->language() == language();
if (recognized) {
if (Language::intelligible(phrase, this)) {
const DictEntry& entry(phrase->entry());
LOG(INFO) << "deleting entry: '" << entry.text << "'.";
user_dict_->UpdateEntry(entry, -1); // mark as deleted in user dict
Expand Down
10 changes: 4 additions & 6 deletions src/rime/gear/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Context;
class Engine;
class Dictionary;
class UserDictionary;
class Language;
class Phrase;
class Memory;

Expand All @@ -31,9 +32,6 @@ struct CommitEntry : DictEntry {
bool Save() const;
};

class Language {
};

class Memory {
public:
Memory(const Ticket& ticket);
Expand All @@ -45,24 +43,24 @@ class Memory {
bool FinishSession();
bool DiscardSession();

Language* language() { return &language_; }

Dictionary* dict() const { return dict_.get(); }
UserDictionary* user_dict() const { return user_dict_.get(); }

const Language* language() const { return language_.get(); }

protected:
void OnCommit(Context* ctx);
void OnDeleteEntry(Context* ctx);
void OnUnhandledKey(Context* ctx, const KeyEvent& key);

the<Dictionary> dict_;
the<UserDictionary> user_dict_;
the<Language> language_;

private:
connection commit_connection_;
connection delete_connection_;
connection unhandled_key_connection_;
Language language_;
};

} // namespace rime
Expand Down
8 changes: 4 additions & 4 deletions src/rime/gear/poet.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ class Language;

class Poet {
public:
Poet(Language* language) : language_(language) {}
Poet(const Language* language) : language_(language) {}

an<Sentence> MakeSentence(const WordGraph& graph, size_t total_length);

an<Sentence> MakeSentence(const WordGraph& graph,
size_t total_length);
protected:
Language* language_;
const Language* language_;
};

} // namespace rime
Expand Down
17 changes: 3 additions & 14 deletions src/rime/gear/table_translator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,10 @@ static const char* kUnitySymbol = " \xe2\x98\xaf ";
// TableTranslation

TableTranslation::TableTranslation(TranslatorOptions* options,
Language* language,
const Language* language,
const string& input,
size_t start, size_t end,
const string& preedit)
: options_(options), language_(language),
input_(input), start_(start), end_(end), preedit_(preedit) {
if (options_)
options_->preedit_formatter().Apply(&preedit_);
set_exhausted(true);
}

TableTranslation::TableTranslation(TranslatorOptions* options,
Language* language,
const string& input,
size_t start, size_t end,
size_t start,
size_t end,
const string& preedit,
const DictEntryIterator& iter,
const UserDictEntryIterator& uter)
Expand Down
14 changes: 7 additions & 7 deletions src/rime/gear/table_translator.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ class TableTranslator : public Translator,
class TableTranslation : public Translation {
public:

TableTranslation(TranslatorOptions* options, Language* language,
const string& input, size_t start, size_t end,
const string& preedit);
TableTranslation(TranslatorOptions* options, Language* language,
const string& input, size_t start, size_t end,
TableTranslation(TranslatorOptions* options,
const Language* language,
const string& input,
size_t start,
size_t end,
const string& preedit,
const DictEntryIterator& iter,
const DictEntryIterator& iter = DictEntryIterator(),
const UserDictEntryIterator& uter = UserDictEntryIterator());

virtual bool Next();
Expand All @@ -74,7 +74,7 @@ class TableTranslation : public Translation {
}

TranslatorOptions* options_;
Language* language_;
const Language* language_;
string input_;
size_t start_;
size_t end_;
Expand Down
8 changes: 4 additions & 4 deletions src/rime/gear/translator_commons.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class Language;

class Phrase : public Candidate {
public:
Phrase(Language* language,
Phrase(const Language* language,
const string& type, size_t start, size_t end,
const an<DictEntry>& entry)
: Candidate(type, start, end),
Expand All @@ -93,14 +93,14 @@ class Phrase : public Candidate {
double weight() const { return entry_->weight; }
Code& code() const { return entry_->code; }
const DictEntry& entry() const { return *entry_; }
Language* language() const { return language_; }
const Language* language() const { return language_; }
Spans spans() {
return syllabifier_ ? syllabifier_->Syllabify(this)
: Spans();
}

protected:
Language* language_;
const Language* language_;
an<DictEntry> entry_;
an<PhraseSyllabifier> syllabifier_;
};
Expand All @@ -109,7 +109,7 @@ class Phrase : public Candidate {

class Sentence : public Phrase {
public:
Sentence(Language* language)
Sentence(const Language* language)
: Phrase(language, "sentence", 0, 0, New<DictEntry>()) {
entry_->weight = 1.0;
}
Expand Down
18 changes: 18 additions & 0 deletions src/rime/language.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Copyright RIME Developers
// Distributed under the BSD License
//
#include <rime/common.h>
#include <rime/language.h>

namespace rime {

// "luna_pinyin.extra" has language component "luna_pinyin".
string Language::get_language_component(const string& name) {
size_t dot = name.find('.');
if (dot != string::npos && dot != 0)
return name.substr(0, dot);
return name;
}

} // namespace rime
33 changes: 33 additions & 0 deletions src/rime/language.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Copyright RIME Developers
// Distributed under the BSD License
//
#ifndef RIME_LANGUAGE_H_
#define RIME_LANGUAGE_H_

#include <rime/common.h>

namespace rime {

class Language {
const string name_;

public:
Language(const string& name) : name_(name) {}
string name() const { return name_; }

bool operator== (const Language& other) const {
return name_ == other.name_;
}

template <class T, class U>
static bool intelligible(const T& t, const U& u) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有没有办法给 TU 类型增加一个必须有 language 方法的约束,类似 interface 或者 trait 机制?似乎直接使用 template 一旦 intelligible 方法使用出错编译器的报错就完全不能看了。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

講究。你當是寫 Rust?
雖然有,但我不想爲了類型檢查寫一堆模板庫函。滿足於代碼簡單可工作。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有道理

return t->language() && u->language() && *t->language() == *u->language();
}

static string get_language_component(const string& name);
};

} // namespace rime

#endif // RIME_LANGUAGE_H_