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:
157
strans.c
157
strans.c
@@ -6,10 +6,7 @@ static int visible = 0;
|
||||
static void *activeowner;
|
||||
static int activecap;
|
||||
static Caret caret;
|
||||
static u32int dictseq;
|
||||
static int candidatechosen;
|
||||
static void dictqmap(Im*);
|
||||
static void dictqjp(Im*);
|
||||
static void backjp(Im*);
|
||||
static int maplookup(Trie*, Str*, Str*);
|
||||
|
||||
@@ -23,20 +20,19 @@ struct Search
|
||||
static Search search;
|
||||
|
||||
Lang langs[] = {
|
||||
{LangEN, nil, nil, nil, nil, nil, nil, nil},
|
||||
{LangJP, "hira", "kanji", transmap, backjp, dictqjp, nil, nil},
|
||||
{LangJPK, "kata", nil, transmap, backjp, dictqjp, nil, nil},
|
||||
{LangKO, nil, nil, transko, backko, nil, nil, nil},
|
||||
{LangHANJA, nil, "hanja", nil, nil, nil, nil, nil},
|
||||
{LangEMOJI, nil, "emoji", nil, nil, nil, nil, nil},
|
||||
{LangVI, "telex", nil, transvi, backvi, dictqmap, nil, nil},
|
||||
{LangEN, nil, nil, nil, nil, nil, nil},
|
||||
{LangJP, "hira", "kanji", transmap, backjp, nil, nil},
|
||||
{LangJPK, "kata", nil, transmap, backjp, nil, nil},
|
||||
{LangKO, nil, nil, transko, backko, nil, nil},
|
||||
{LangHANJA, nil, "hanja", nil, nil, nil, nil},
|
||||
{LangEMOJI, nil, "emoji", nil, nil, nil, nil},
|
||||
{LangVI, "telex", nil, transvi, backvi, nil, nil},
|
||||
};
|
||||
int nlang = nelem(langs);
|
||||
|
||||
static void
|
||||
clearkouho(void)
|
||||
{
|
||||
dictseq++;
|
||||
im.nkouho = 0;
|
||||
im.sel = -1;
|
||||
candidatechosen = 0;
|
||||
@@ -144,19 +140,6 @@ impre(Str *s)
|
||||
*s = im.pre;
|
||||
}
|
||||
|
||||
static void
|
||||
setkouho(Dictres *res)
|
||||
{
|
||||
int i;
|
||||
|
||||
clearkouho();
|
||||
for(i = 0; i < res->nkouho; i++){
|
||||
im.kouho[i] = res->kouho[i];
|
||||
im.nkouho++;
|
||||
}
|
||||
selectfirst();
|
||||
}
|
||||
|
||||
static void
|
||||
snapshot(Drawcmd *dc)
|
||||
{
|
||||
@@ -210,43 +193,17 @@ reset(void)
|
||||
clearkouho();
|
||||
}
|
||||
|
||||
/* Kanji candidates for a complete reading. */
|
||||
static void
|
||||
dictsend(Im *im, Str *key)
|
||||
{
|
||||
Dictreq old, req;
|
||||
|
||||
req.key = *key;
|
||||
req.lang = im->l->lang;
|
||||
req.seq = dictseq;
|
||||
impre(&req.pre);
|
||||
/* imthread is the sole producer; discard every obsolete queued lookup. */
|
||||
while(channbrecv(dictreqc, &old) > 0)
|
||||
;
|
||||
channbsend(dictreqc, &req);
|
||||
}
|
||||
|
||||
static void
|
||||
dictqmap(Im *im)
|
||||
{
|
||||
Str dict;
|
||||
|
||||
clearkouho();
|
||||
if(im->l->map == nil)
|
||||
return;
|
||||
if(!mapget(im->l->map, &im->pre, &dict))
|
||||
return;
|
||||
dictsend(im, &dict);
|
||||
}
|
||||
|
||||
static void
|
||||
dictqjp(Im *im)
|
||||
dictqjp(void)
|
||||
{
|
||||
Str reading;
|
||||
|
||||
clearkouho();
|
||||
if(im->l->dict == nil || !jpreading(im, &reading) || reading.n == 0)
|
||||
if(!jpreading(&im, &reading) || reading.n == 0)
|
||||
return;
|
||||
dictsend(im, &reading);
|
||||
im.nkouho = dictlookup(im.l, &reading, im.kouho, Maxkouho);
|
||||
selectfirst();
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -355,7 +312,7 @@ dotrans(Rune c, Str *com)
|
||||
if(isjp(&im)){
|
||||
e.eat = transjp(&im, c, com);
|
||||
if(e.eat)
|
||||
dictqjp(&im);
|
||||
dictqjp();
|
||||
else
|
||||
clearkouho();
|
||||
return e.eat;
|
||||
@@ -380,9 +337,6 @@ dotrans(Rune c, Str *com)
|
||||
sappend(com, &e.s);
|
||||
sclear(&im.pre);
|
||||
sappend(&im.pre, &e.next);
|
||||
if(e.eat && e.dict.n > 0){
|
||||
dictsend(&im, &e.dict);
|
||||
}
|
||||
return e.eat;
|
||||
}
|
||||
|
||||
@@ -418,13 +372,13 @@ Emit
|
||||
transmap(Im *im, Rune c)
|
||||
{
|
||||
Emit e = {0};
|
||||
Str key;
|
||||
Str key, mapped;
|
||||
Trie *t;
|
||||
|
||||
t = im->l->map;
|
||||
key = im->pre;
|
||||
sputr(&key, c);
|
||||
if(maplookup(t, &key, &e.dict)){
|
||||
if(maplookup(t, &key, &mapped)){
|
||||
e.eat = 1;
|
||||
e.next = key;
|
||||
return e;
|
||||
@@ -433,7 +387,7 @@ transmap(Im *im, Rune c)
|
||||
e.s = im->pre;
|
||||
sclear(&key);
|
||||
sputr(&key, c);
|
||||
if(!maplookup(t, &key, &e.dict))
|
||||
if(!maplookup(t, &key, &mapped))
|
||||
return e;
|
||||
e.eat = 1;
|
||||
sputr(&e.next, c);
|
||||
@@ -526,40 +480,28 @@ addkouho(Str *s)
|
||||
im.kouho[im.nkouho++] = *s;
|
||||
}
|
||||
|
||||
static void
|
||||
searchlookup(int lang, Str *key, Dictres *res)
|
||||
{
|
||||
Dictreq req;
|
||||
|
||||
req.key = *key;
|
||||
req.pre = req.key;
|
||||
req.lang = lang;
|
||||
req.seq = 0;
|
||||
dictlookup(&req, res);
|
||||
}
|
||||
|
||||
/* The typed keys and their transliteration are both emoji queries. */
|
||||
static void
|
||||
emojiquery(void)
|
||||
{
|
||||
static Dictres res;
|
||||
Str raw, local;
|
||||
int i, rawhit, localhit;
|
||||
Str kouho[Maxkouho], raw, local;
|
||||
int i, n, rawhit, localhit;
|
||||
|
||||
raw = search.raw;
|
||||
foldascii(&raw);
|
||||
transstr(im.l, &search.raw, &local);
|
||||
foldascii(&local);
|
||||
clearkouho();
|
||||
searchlookup(LangEMOJI, &raw, &res);
|
||||
rawhit = res.nkouho != 0;
|
||||
for(i = 0; i < res.nkouho; i++)
|
||||
addkouho(&res.kouho[i]);
|
||||
n = dictlookup(getlang(LangEMOJI), &raw, kouho, Maxkouho);
|
||||
rawhit = n != 0;
|
||||
for(i = 0; i < n; i++)
|
||||
addkouho(&kouho[i]);
|
||||
localhit = 0;
|
||||
if(scmp(&raw, &local) != 0){
|
||||
searchlookup(LangEMOJI, &local, &res);
|
||||
localhit = res.nkouho != 0;
|
||||
for(i = 0; i < res.nkouho; i++)
|
||||
addkouho(&res.kouho[i]);
|
||||
n = dictlookup(getlang(LangEMOJI), &local, kouho, Maxkouho);
|
||||
localhit = n != 0;
|
||||
for(i = 0; i < n; i++)
|
||||
addkouho(&kouho[i]);
|
||||
}
|
||||
search.text = rawhit || !localhit ? raw : local;
|
||||
selectfirst();
|
||||
@@ -568,16 +510,13 @@ emojiquery(void)
|
||||
static void
|
||||
hanjaquery(void)
|
||||
{
|
||||
static Dictres res;
|
||||
Str key;
|
||||
|
||||
transstr(im.l, &search.raw, &key);
|
||||
search.text = key;
|
||||
if(key.n == 1 && key.r[0] >= 0xac00 && key.r[0] <= 0xd7a3){
|
||||
searchlookup(LangHANJA, &key, &res);
|
||||
setkouho(&res);
|
||||
}else
|
||||
clearkouho();
|
||||
clearkouho();
|
||||
im.nkouho = dictlookup(getlang(LangHANJA), &key, im.kouho, Maxkouho);
|
||||
selectfirst();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -766,8 +705,10 @@ transition(u32int ks, u32int mod, Str *com)
|
||||
reset();
|
||||
return 1;
|
||||
}
|
||||
if(im.l->dictq != nil)
|
||||
im.l->dictq(&im);
|
||||
if(isjp(&im))
|
||||
dictqjp();
|
||||
else
|
||||
clearkouho();
|
||||
return 1;
|
||||
}
|
||||
if(ks == Kesc){
|
||||
@@ -896,7 +837,6 @@ init(void)
|
||||
memset(&caret, 0, sizeof caret);
|
||||
activeowner = nil;
|
||||
activecap = 0;
|
||||
dictseq = 0;
|
||||
candidatechosen = 0;
|
||||
visible = 0;
|
||||
}
|
||||
@@ -1004,41 +944,16 @@ imhandlekey(Keyreq *kr)
|
||||
chansend(kr->reply, &res);
|
||||
}
|
||||
|
||||
static void
|
||||
dictresult(Dictres *res)
|
||||
{
|
||||
Str pre;
|
||||
|
||||
impre(&pre);
|
||||
if(search.lang || res->seq != dictseq || res->lang != im.l->lang ||
|
||||
scmp(&res->key, &pre) != 0)
|
||||
return;
|
||||
setkouho(res);
|
||||
redraw();
|
||||
}
|
||||
|
||||
void
|
||||
imthread(void*)
|
||||
{
|
||||
static Dictres res;
|
||||
Keyreq kr;
|
||||
Alt alts[] = {
|
||||
{keyc, &kr, CHANRCV, nil},
|
||||
{dictresc, &res, CHANRCV, nil},
|
||||
{nil, nil, CHANEND, nil},
|
||||
};
|
||||
|
||||
threadsetname("im");
|
||||
init();
|
||||
for(;;){
|
||||
switch(alt(alts)){
|
||||
case 0:
|
||||
imhandlekey(&kr);
|
||||
break;
|
||||
case 1:
|
||||
dictresult(&res);
|
||||
break;
|
||||
}
|
||||
chanrecv(keyc, &kr);
|
||||
imhandlekey(&kr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user