Skip to content

Commit

Permalink
feat(jni): add getRimeCandidates API
Browse files Browse the repository at this point in the history
  • Loading branch information
WhiredPlanck committed Aug 27, 2024
1 parent b95633a commit 74430fa
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
14 changes: 14 additions & 0 deletions app/src/main/java/com/osfans/trime/core/Rime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ class Rime : RimeApi, RimeLifecycleOwner {
getRimeOption(option)
}

override suspend fun getCandidates(
startIndex: Int,
limit: Int,
): Array<CandidateListItem> =
withRimeContext {
getRimeCandidates(startIndex, limit) ?: emptyArray()
}

private fun handleRimeNotification(notif: RimeNotification<*>) {
when (notif) {
is RimeNotification.SchemaNotification -> schemaItemCached = notif.value
Expand Down Expand Up @@ -454,6 +462,12 @@ class Rime : RimeApi, RimeLifecycleOwner {
state: Boolean,
): String?

@JvmStatic
external fun getRimeCandidates(
startIndex: Int,
limit: Int,
): Array<CandidateListItem>?

/** call from rime_jni */
@JvmStatic
fun handleRimeNotification(
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/com/osfans/trime/core/RimeApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,9 @@ interface RimeApi {
)

suspend fun getRuntimeOption(option: String): Boolean

suspend fun getCandidates(
startIndex: Int,
limit: Int,
): Array<CandidateListItem>
}
48 changes: 48 additions & 0 deletions app/src/main/jni/librime_jni/rime_jni.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <rime_api.h>

#include <string>
#include <vector>

#include "jni-utils.h"
#include "objconv.h"
Expand Down Expand Up @@ -117,6 +118,31 @@ class Rime {
return rime->get_state_label(session, optionName.c_str(), state);
}

using CandidateItem = std::pair<std::string, std::string>;
using CandidateList = std::vector<CandidateItem>;

CandidateList getCandidates(int startIndex, int limit) {
CandidateList result;
result.reserve(limit);
RimeCandidateListIterator iter{nullptr};
if (rime->candidate_list_from_index(session, &iter, startIndex)) {
int count = 0;
while (rime->candidate_list_next(&iter)) {
if (count >= limit) break;
std::string text(iter.candidate.text);
std::string comment;
if (iter.candidate.comment) {
comment = iter.candidate.comment;
}
auto item = std::make_pair(text, comment);
result.emplace_back(std::move(item));
++count;
}
rime->candidate_list_end(&iter);
}
return std::move(result);
}

void exit() {
rime->destroy_session(session);
session = 0;
Expand Down Expand Up @@ -480,3 +506,25 @@ Java_com_osfans_trime_core_Rime_getRimeStateLabel(JNIEnv *env,
return env->NewStringUTF(
Rime::Instance().stateLabel(CString(env, option_name), state).c_str());
}

extern "C" JNIEXPORT jobjectArray JNICALL
Java_com_osfans_trime_core_Rime_getRimeCandidates(JNIEnv *env, jclass clazz,
jint start_index,
jint limit) {
if (!is_rime_running()) {
return nullptr;
}
auto candidates = Rime::Instance().getCandidates(start_index, limit);
int size = static_cast<int>(candidates.size());
jobjectArray array =
env->NewObjectArray(size, GlobalRef->CandidateListItem, nullptr);
for (int i = 0; i < size; i++) {
auto &candidate = candidates[i];
auto item = JRef<>(env, env->NewObject(GlobalRef->CandidateListItem,
GlobalRef->CandidateListItemInit,
*JString(env, candidate.second),
*JString(env, candidate.first)));
env->SetObjectArrayElement(array, i, item);
}
return array;
}

0 comments on commit 74430fa

Please sign in to comment.