engine: look dictionaries up synchronously
The dictionary thread ran in imthread's own proc, so a lookup could only start once the engine blocked, and it was a trie probe anyway; the emoji and Hanja searches already called dictlookup directly. The request/result channels, sequence numbers, staleness checks and the second draw per Japanese key are gone; dictqjp fills the candidates in place. Emit.dict and Lang.dictq only ever triggered lookups for Vietnamese, which has no dictionary. dictlookup(Lang*, key, out, max) returns the count. The Hanja lookup no longer pre-checks for a single syllable; a reading either has an entry or it does not.
This commit is contained in:
@@ -165,37 +165,6 @@ engine_candidate_shortcut_modifiers(struct ct *t)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
engine_dictionary_queue_latest_wins(struct ct *t)
|
||||
{
|
||||
Channel *saved;
|
||||
Dictreq old, got;
|
||||
Str key;
|
||||
|
||||
saved = dictreqc;
|
||||
dictreqc = chancreate(sizeof(Dictreq), 1);
|
||||
memset(&old, 0, sizeof old);
|
||||
old.key = mkstr("old-key");
|
||||
old.pre = mkstr("old-preedit");
|
||||
old.lang = LangJP;
|
||||
old.seq = 0;
|
||||
CT_CHECK(t, channbsend(dictreqc, &old) > 0);
|
||||
init();
|
||||
im.l = getlang(LangJP);
|
||||
im.pre = mkstr("new-preedit");
|
||||
key = mkstr("new-key");
|
||||
dictsend(&im, &key);
|
||||
if(CT_CHECK(t, channbrecv(dictreqc, &got) > 0)){
|
||||
checkstr(t, "newest dictionary key", "new-key", &got.key);
|
||||
checkstr(t, "newest dictionary preedit", "new-preedit", &got.pre);
|
||||
CT_EQ_INT(t, LangJP, got.lang);
|
||||
CT_EQ_UINT(t, dictseq, got.seq);
|
||||
}
|
||||
CT_CHECK(t, channbrecv(dictreqc, &got) <= 0);
|
||||
chanfree(dictreqc);
|
||||
dictreqc = saved;
|
||||
}
|
||||
|
||||
static Keyres
|
||||
ownerrequestatcap(void *owner, int cap, int op, Rune key, u32int mod,
|
||||
Caret *caret)
|
||||
@@ -306,66 +275,6 @@ engine_active_owner_reset(struct ct *t)
|
||||
checkstr(t, "same owner after reset", "ん", &res.preedit);
|
||||
}
|
||||
|
||||
void
|
||||
engine_rejects_stale_dictionary_results(struct ct *t)
|
||||
{
|
||||
Dictreq a, b;
|
||||
Dictres res;
|
||||
Trie *saved;
|
||||
Lang *jp;
|
||||
char one, two;
|
||||
int n;
|
||||
|
||||
jp = getlang(LangJP);
|
||||
saved = jp->dict;
|
||||
jp->dict = trienew();
|
||||
init();
|
||||
im.l = jp;
|
||||
while(channbrecv(dictreqc, &a) > 0)
|
||||
;
|
||||
ownerrequest(&one, Keypress, 'k', 0);
|
||||
ownerrequest(&one, Keypress, 'a', 0);
|
||||
n = 0;
|
||||
while(channbrecv(dictreqc, &a) > 0)
|
||||
n++;
|
||||
if(!CT_CHECK(t, n > 0))
|
||||
goto cleanup;
|
||||
ownerrequest(&one, Keyreset, 0, 0);
|
||||
ownerrequest(&two, Keypress, 'k', 0);
|
||||
ownerrequest(&two, Keypress, 'a', 0);
|
||||
n = 0;
|
||||
while(channbrecv(dictreqc, &b) > 0)
|
||||
n++;
|
||||
if(!CT_CHECK(t, n > 0))
|
||||
goto cleanup;
|
||||
CT_EQ_INT(t, 0, scmp(&a.key, &b.key));
|
||||
CT_EQ_INT(t, 0, scmp(&a.pre, &b.pre));
|
||||
CT_EQ_INT(t, a.lang, b.lang);
|
||||
CT_CHECK(t, a.seq != b.seq);
|
||||
|
||||
memset(&res, 0, sizeof res);
|
||||
res.key = a.pre;
|
||||
res.lang = a.lang;
|
||||
res.seq = a.seq;
|
||||
res.kouho[0] = mkstr("stale");
|
||||
res.nkouho = 1;
|
||||
dictresult(&res);
|
||||
CT_EQ_INT(t, 0, im.nkouho);
|
||||
|
||||
res.key = b.pre;
|
||||
res.lang = b.lang;
|
||||
res.seq = b.seq;
|
||||
res.kouho[0] = mkstr("current");
|
||||
dictresult(&res);
|
||||
if(CT_EQ_INT(t, 1, im.nkouho))
|
||||
checkstr(t, "current dictionary result", "current", &im.kouho[0]);
|
||||
cleanup:
|
||||
while(channbrecv(dictreqc, &a) > 0)
|
||||
;
|
||||
trieclose(jp->dict);
|
||||
jp->dict = saved;
|
||||
}
|
||||
|
||||
void
|
||||
engine_active_owner_caret(struct ct *t)
|
||||
{
|
||||
@@ -660,7 +569,6 @@ engine_direct_language_modes(struct ct *t)
|
||||
CT_EQ_PTR(t, nil, im.l->mapname);
|
||||
CT_EQ_PTR(t, nil, im.l->map);
|
||||
CT_EQ_PTR(t, nil, im.l->dictname);
|
||||
CT_EQ_PTR(t, nil, im.l->dictq);
|
||||
CT_CHECK(t, strcmp(getlang(LangHANJA)->dictname, "hanja") == 0);
|
||||
CT_CHECK(t, keystroke('r', 0, &com));
|
||||
checkstr(t, "Korean without map", "ㄱ", &im.pre);
|
||||
@@ -789,17 +697,16 @@ draindraw(Drawcmd *last)
|
||||
static void
|
||||
setcandidates(int n)
|
||||
{
|
||||
Dictres res;
|
||||
char name[8];
|
||||
int i;
|
||||
|
||||
memset(&res, 0, sizeof res);
|
||||
clearkouho();
|
||||
for(i = 0; i < n; i++){
|
||||
snprint(name, sizeof name, "c%d", i+1);
|
||||
res.kouho[i] = mkstr(name);
|
||||
im.kouho[i] = mkstr(name);
|
||||
}
|
||||
res.nkouho = n;
|
||||
setkouho(&res);
|
||||
im.nkouho = n;
|
||||
selectfirst();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -929,31 +836,20 @@ void
|
||||
engine_candidate_completion(struct ct *t)
|
||||
{
|
||||
static Rune keys[] = { Kret, Ktab };
|
||||
Dictres res;
|
||||
Str com;
|
||||
int arrived, i;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < nelem(keys); i++)
|
||||
for(arrived = 0; arrived < 2; arrived++){
|
||||
init();
|
||||
im.l = getlang(LangJP);
|
||||
im.pre = mkstr("reading");
|
||||
memset(&res, 0, sizeof res);
|
||||
res.key = im.pre;
|
||||
res.lang = LangJP;
|
||||
res.seq = dictseq;
|
||||
res.kouho[0] = mkstr("candidate");
|
||||
res.nkouho = 1;
|
||||
if(arrived)
|
||||
dictresult(&res);
|
||||
sclear(&com);
|
||||
CT_CHECK(t, keystroke(keys[i], 0, &com));
|
||||
if(!arrived)
|
||||
dictresult(&res);
|
||||
checkstr(t, "unselected candidate commits reading",
|
||||
"reading", &com);
|
||||
CT_EQ_INT(t, 0, im.nkouho);
|
||||
}
|
||||
for(i = 0; i < nelem(keys); i++){
|
||||
init();
|
||||
im.l = getlang(LangJP);
|
||||
im.pre = mkstr("reading");
|
||||
setcandidates(1);
|
||||
sclear(&com);
|
||||
CT_CHECK(t, keystroke(keys[i], 0, &com));
|
||||
checkstr(t, "unselected candidate commits reading",
|
||||
"reading", &com);
|
||||
CT_EQ_INT(t, 0, im.nkouho);
|
||||
}
|
||||
|
||||
candidatebegin(2);
|
||||
im.pre = mkstr("reading");
|
||||
@@ -1047,24 +943,22 @@ searchend(Searchfix *f)
|
||||
void
|
||||
engine_popup_preedit_capability(struct ct *t)
|
||||
{
|
||||
Dictres res;
|
||||
Drawcmd dc;
|
||||
Keyres kres;
|
||||
Lang *jp;
|
||||
Trie *saved;
|
||||
char client, inactive;
|
||||
|
||||
jp = getlang(LangJP);
|
||||
saved = jp->dict;
|
||||
jp->dict = trienew();
|
||||
setdict(jp->dict, "か", "家");
|
||||
init();
|
||||
im.l = getlang(LangJP);
|
||||
im.l = jp;
|
||||
draindraw(nil);
|
||||
ownerrequestcap(&client, Cclientpreedit, Keypress, 'k', 0);
|
||||
ownerrequestcap(&client, Cclientpreedit, Keypress, 'a', 0);
|
||||
memset(&res, 0, sizeof res);
|
||||
res.lang = LangJP;
|
||||
res.key = mkstr("か");
|
||||
res.seq = dictseq;
|
||||
res.kouho[0] = mkstr("家");
|
||||
res.nkouho = 1;
|
||||
dictresult(&res);
|
||||
im.sel = 0;
|
||||
CT_EQ_INT(t, 1, im.nkouho);
|
||||
redraw();
|
||||
if(CT_CHECK(t, draindraw(&dc) > 0)){
|
||||
CT_EQ_INT(t, 0, dc.pre.n);
|
||||
@@ -1115,6 +1009,8 @@ engine_popup_preedit_capability(struct ct *t)
|
||||
|
||||
ownerrequest(&client, Keyrelease, 0, 0);
|
||||
draindraw(nil);
|
||||
trieclose(jp->dict);
|
||||
jp->dict = saved;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1124,9 +1020,6 @@ hanjabegin(Searchfix *f, int lang)
|
||||
f->dictlang->dict = trienew();
|
||||
setdict(f->dictlang->dict, "한", "漢 韓");
|
||||
setdict(f->dictlang->dict, "가", "家");
|
||||
setdict(f->dictlang->dict, "ㄱ", "假");
|
||||
setdict(f->dictlang->dict, "한글", "文");
|
||||
setdict(f->dictlang->dict, "か", "仮");
|
||||
init();
|
||||
im.l = getlang(lang);
|
||||
}
|
||||
@@ -1182,22 +1075,9 @@ engine_japanese_readings(struct ct *t)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
newestrequest(Dictreq *req)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = 0;
|
||||
while(channbrecv(dictreqc, req) > 0)
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
engine_japanese_candidates(struct ct *t)
|
||||
{
|
||||
Dictreq req;
|
||||
Dictres res;
|
||||
Trie *saved;
|
||||
Lang *jp;
|
||||
Str com, shown;
|
||||
@@ -1213,12 +1093,6 @@ engine_japanese_candidates(struct ct *t)
|
||||
goto cleanup;
|
||||
shown = shownpre(&im);
|
||||
checkstr(t, "complete Japanese reading", "かんじ", &shown);
|
||||
if(!CT_CHECK(t, newestrequest(&req) > 0))
|
||||
goto cleanup;
|
||||
checkstr(t, "dictionary lookup key", "かんじ", &req.key);
|
||||
checkstr(t, "dictionary request identity", "かんじ", &req.pre);
|
||||
dictlookup(&req, &res);
|
||||
dictresult(&res);
|
||||
if(!CT_EQ_INT(t, 2, im.nkouho))
|
||||
goto cleanup;
|
||||
CT_EQ_INT(t, 0, im.sel);
|
||||
@@ -1228,8 +1102,17 @@ engine_japanese_candidates(struct ct *t)
|
||||
CT_EQ_INT(t, 1, im.sel);
|
||||
CT_CHECK(t, keystroke(Kret, 0, &com));
|
||||
checkstr(t, "selected Kanji", "幹事", &com);
|
||||
CT_EQ_INT(t, 0, im.nkouho);
|
||||
/* Backspace looks a complete shorter reading up again. */
|
||||
setdict(jp->dict, "かん", "缶");
|
||||
if(!typekeys(t, "kanji", &com))
|
||||
goto cleanup;
|
||||
CT_CHECK(t, keystroke(Kback, 0, &com));
|
||||
CT_EQ_INT(t, 0, im.nkouho);
|
||||
CT_CHECK(t, keystroke(Kback, 0, &com));
|
||||
if(CT_EQ_INT(t, 1, im.nkouho))
|
||||
checkstr(t, "shorter reading candidate", "缶", &im.kouho[0]);
|
||||
cleanup:
|
||||
newestrequest(&req);
|
||||
trieclose(jp->dict);
|
||||
jp->dict = saved;
|
||||
}
|
||||
@@ -1294,11 +1177,9 @@ engine_katakana_sequences(struct ct *t)
|
||||
{ "xu", "ゥ" },
|
||||
{ "vu", "ヴ" },
|
||||
};
|
||||
Dictreq req;
|
||||
Str com, shown;
|
||||
int i;
|
||||
|
||||
newestrequest(&req);
|
||||
for(i = 0; i < nelem(cases); i++){
|
||||
init();
|
||||
im.l = getlang(LangJPK);
|
||||
@@ -1308,10 +1189,10 @@ engine_katakana_sequences(struct ct *t)
|
||||
checkstr(t, cases[i].keys, "", &com);
|
||||
shown = shownpre(&im);
|
||||
checkstr(t, cases[i].keys, cases[i].want, &shown);
|
||||
CT_EQ_INT(t, 0, im.nkouho);
|
||||
CT_CHECK(t, keystroke(Kret, 0, &com));
|
||||
checkstr(t, "committed Katakana", cases[i].want, &com);
|
||||
}
|
||||
CT_EQ_INT(t, 0, newestrequest(&req));
|
||||
CT_EQ_PTR(t, nil, getlang(LangJPK)->dictname);
|
||||
}
|
||||
|
||||
@@ -1692,48 +1573,6 @@ engine_emoji_start_and_unknown(struct ct *t)
|
||||
searchend(&f);
|
||||
}
|
||||
|
||||
void
|
||||
engine_emoji_dictionary_identity(struct ct *t)
|
||||
{
|
||||
Dictres res;
|
||||
Searchfix f;
|
||||
|
||||
emojibegin(&f, 0);
|
||||
im.pre = mkstr("same");
|
||||
im.kouho[0] = mkstr("old");
|
||||
im.nkouho = 1;
|
||||
im.sel = 0;
|
||||
memset(&res, 0, sizeof res);
|
||||
res.key = im.pre;
|
||||
res.seq = dictseq;
|
||||
res.kouho[0] = mkstr("wrong");
|
||||
res.nkouho = 1;
|
||||
res.lang = LangJP;
|
||||
dictresult(&res);
|
||||
CT_EQ_INT(t, 1, im.nkouho);
|
||||
checkstr(t, "wrong language ignored", "old", &im.kouho[0]);
|
||||
|
||||
res.lang = LangKO;
|
||||
res.key = mkstr("other");
|
||||
dictresult(&res);
|
||||
CT_EQ_INT(t, 1, im.nkouho);
|
||||
checkstr(t, "wrong preedit ignored", "old", &im.kouho[0]);
|
||||
|
||||
res.key = im.pre;
|
||||
search.lang = LangEMOJI;
|
||||
dictresult(&res);
|
||||
CT_EQ_INT(t, 1, im.nkouho);
|
||||
checkstr(t, "search response ignored", "old", &im.kouho[0]);
|
||||
|
||||
search.lang = 0;
|
||||
res.kouho[0] = mkstr("right");
|
||||
dictresult(&res);
|
||||
CT_EQ_INT(t, 1, im.nkouho);
|
||||
CT_EQ_INT(t, 0, im.sel);
|
||||
checkstr(t, "matching response accepted", "right", &im.kouho[0]);
|
||||
searchend(&f);
|
||||
}
|
||||
|
||||
void
|
||||
engine_hanja_search(struct ct *t)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user