Skip to content

Commit 74430fa

Browse files
committed
feat(jni): add getRimeCandidates API
1 parent b95633a commit 74430fa

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

app/src/main/java/com/osfans/trime/core/Rime.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ class Rime : RimeApi, RimeLifecycleOwner {
109109
getRimeOption(option)
110110
}
111111

112+
override suspend fun getCandidates(
113+
startIndex: Int,
114+
limit: Int,
115+
): Array<CandidateListItem> =
116+
withRimeContext {
117+
getRimeCandidates(startIndex, limit) ?: emptyArray()
118+
}
119+
112120
private fun handleRimeNotification(notif: RimeNotification<*>) {
113121
when (notif) {
114122
is RimeNotification.SchemaNotification -> schemaItemCached = notif.value
@@ -454,6 +462,12 @@ class Rime : RimeApi, RimeLifecycleOwner {
454462
state: Boolean,
455463
): String?
456464

465+
@JvmStatic
466+
external fun getRimeCandidates(
467+
startIndex: Int,
468+
limit: Int,
469+
): Array<CandidateListItem>?
470+
457471
/** call from rime_jni */
458472
@JvmStatic
459473
fun handleRimeNotification(

app/src/main/java/com/osfans/trime/core/RimeApi.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,9 @@ interface RimeApi {
4141
)
4242

4343
suspend fun getRuntimeOption(option: String): Boolean
44+
45+
suspend fun getCandidates(
46+
startIndex: Int,
47+
limit: Int,
48+
): Array<CandidateListItem>
4449
}

app/src/main/jni/librime_jni/rime_jni.cc

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <rime_api.h>
66

77
#include <string>
8+
#include <vector>
89

910
#include "jni-utils.h"
1011
#include "objconv.h"
@@ -117,6 +118,31 @@ class Rime {
117118
return rime->get_state_label(session, optionName.c_str(), state);
118119
}
119120

121+
using CandidateItem = std::pair<std::string, std::string>;
122+
using CandidateList = std::vector<CandidateItem>;
123+
124+
CandidateList getCandidates(int startIndex, int limit) {
125+
CandidateList result;
126+
result.reserve(limit);
127+
RimeCandidateListIterator iter{nullptr};
128+
if (rime->candidate_list_from_index(session, &iter, startIndex)) {
129+
int count = 0;
130+
while (rime->candidate_list_next(&iter)) {
131+
if (count >= limit) break;
132+
std::string text(iter.candidate.text);
133+
std::string comment;
134+
if (iter.candidate.comment) {
135+
comment = iter.candidate.comment;
136+
}
137+
auto item = std::make_pair(text, comment);
138+
result.emplace_back(std::move(item));
139+
++count;
140+
}
141+
rime->candidate_list_end(&iter);
142+
}
143+
return std::move(result);
144+
}
145+
120146
void exit() {
121147
rime->destroy_session(session);
122148
session = 0;
@@ -480,3 +506,25 @@ Java_com_osfans_trime_core_Rime_getRimeStateLabel(JNIEnv *env,
480506
return env->NewStringUTF(
481507
Rime::Instance().stateLabel(CString(env, option_name), state).c_str());
482508
}
509+
510+
extern "C" JNIEXPORT jobjectArray JNICALL
511+
Java_com_osfans_trime_core_Rime_getRimeCandidates(JNIEnv *env, jclass clazz,
512+
jint start_index,
513+
jint limit) {
514+
if (!is_rime_running()) {
515+
return nullptr;
516+
}
517+
auto candidates = Rime::Instance().getCandidates(start_index, limit);
518+
int size = static_cast<int>(candidates.size());
519+
jobjectArray array =
520+
env->NewObjectArray(size, GlobalRef->CandidateListItem, nullptr);
521+
for (int i = 0; i < size; i++) {
522+
auto &candidate = candidates[i];
523+
auto item = JRef<>(env, env->NewObject(GlobalRef->CandidateListItem,
524+
GlobalRef->CandidateListItemInit,
525+
*JString(env, candidate.second),
526+
*JString(env, candidate.first)));
527+
env->SetObjectArrayElement(array, i, item);
528+
}
529+
return array;
530+
}

0 commit comments

Comments
 (0)