From 73cc626693d5325b3ee0fa515be72d86f7958f0c Mon Sep 17 00:00:00 2001 From: WhiredPlanck Date: Wed, 3 Jun 2026 21:25:58 +0800 Subject: [PATCH] refactor: unify CandidateProto object for paged and bulk candidates --- .../main/java/com/osfans/trime/core/Rime.kt | 4 +-- .../java/com/osfans/trime/core/RimeApi.kt | 2 +- .../java/com/osfans/trime/core/RimeMessage.kt | 4 +-- .../java/com/osfans/trime/core/RimeProto.kt | 2 +- .../trime/core/{Structs.kt => SchemaItem.kt} | 5 --- .../trime/ime/candidates/CandidateItemUi.kt | 4 +-- .../compact/CompactCandidateViewAdapter.kt | 8 ++--- .../popup/LabeledCandidateItemUi.kt | 2 +- .../unrolled/CandidatesPagingSource.kt | 8 ++--- .../unrolled/PagingCandidateViewAdapter.kt | 14 ++++---- app/src/main/jni/librime_jni/helper-types.h | 18 +++------- app/src/main/jni/librime_jni/jni-utils.h | 8 ----- app/src/main/jni/librime_jni/objconv.h | 33 ++++++++----------- app/src/main/jni/librime_jni/rime_jni.cc | 9 +++-- 14 files changed, 46 insertions(+), 75 deletions(-) rename app/src/main/java/com/osfans/trime/core/{Structs.kt => SchemaItem.kt} (71%) diff --git a/app/src/main/java/com/osfans/trime/core/Rime.kt b/app/src/main/java/com/osfans/trime/core/Rime.kt index e9313d1713..b5b876782a 100644 --- a/app/src/main/java/com/osfans/trime/core/Rime.kt +++ b/app/src/main/java/com/osfans/trime/core/Rime.kt @@ -190,7 +190,7 @@ class Rime : override suspend fun getCandidates( startIndex: Int, limit: Int, - ): Array = withRimeContext { + ): Array = withRimeContext { getRimeCandidates(startIndex, limit) } @@ -490,7 +490,7 @@ class Rime : external fun getRimeCandidates( startIndex: Int, limit: Int, - ): Array + ): Array @JvmStatic external fun getRimeBulkCandidates(): Array diff --git a/app/src/main/java/com/osfans/trime/core/RimeApi.kt b/app/src/main/java/com/osfans/trime/core/RimeApi.kt index 91914dad92..750858e3af 100644 --- a/app/src/main/java/com/osfans/trime/core/RimeApi.kt +++ b/app/src/main/java/com/osfans/trime/core/RimeApi.kt @@ -84,5 +84,5 @@ interface RimeApi { suspend fun getCandidates( startIndex: Int, limit: Int, - ): Array + ): Array } diff --git a/app/src/main/java/com/osfans/trime/core/RimeMessage.kt b/app/src/main/java/com/osfans/trime/core/RimeMessage.kt index 377ea91e19..7dc56b39c1 100644 --- a/app/src/main/java/com/osfans/trime/core/RimeMessage.kt +++ b/app/src/main/java/com/osfans/trime/core/RimeMessage.kt @@ -106,7 +106,7 @@ sealed class RimeMessage( data class Data( val total: Int = -1, val highlighted: Int = 0, - val candidates: Array = arrayOf(), + val candidates: Array = arrayOf(), ) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -196,7 +196,7 @@ sealed class RimeMessage( CandidateListMessage.Data( params[0] as Int, params[1] as Int, - params[2] as Array, + params[2] as Array, ), ) MessageType.Key -> diff --git a/app/src/main/java/com/osfans/trime/core/RimeProto.kt b/app/src/main/java/com/osfans/trime/core/RimeProto.kt index 0d80811d3e..a69240382a 100644 --- a/app/src/main/java/com/osfans/trime/core/RimeProto.kt +++ b/app/src/main/java/com/osfans/trime/core/RimeProto.kt @@ -11,7 +11,7 @@ data class CommitProto( data class CandidateProto( val text: String, - val comment: String?, + val comment: String, val label: String, ) diff --git a/app/src/main/java/com/osfans/trime/core/Structs.kt b/app/src/main/java/com/osfans/trime/core/SchemaItem.kt similarity index 71% rename from app/src/main/java/com/osfans/trime/core/Structs.kt rename to app/src/main/java/com/osfans/trime/core/SchemaItem.kt index f7560baf43..a650daa288 100644 --- a/app/src/main/java/com/osfans/trime/core/Structs.kt +++ b/app/src/main/java/com/osfans/trime/core/SchemaItem.kt @@ -8,8 +8,3 @@ data class SchemaItem( val id: String, val name: String = "", ) - -data class CandidateItem( - val text: String, - val comment: String = "", -) diff --git a/app/src/main/java/com/osfans/trime/ime/candidates/CandidateItemUi.kt b/app/src/main/java/com/osfans/trime/ime/candidates/CandidateItemUi.kt index b8eba3589c..5a0c2f9bce 100644 --- a/app/src/main/java/com/osfans/trime/ime/candidates/CandidateItemUi.kt +++ b/app/src/main/java/com/osfans/trime/ime/candidates/CandidateItemUi.kt @@ -11,7 +11,7 @@ import android.graphics.Color import android.view.View import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.isVisible -import com.osfans.trime.core.CandidateItem +import com.osfans.trime.core.CandidateProto import com.osfans.trime.data.theme.ColorManager import com.osfans.trime.data.theme.FontManager import com.osfans.trime.data.theme.Theme @@ -160,7 +160,7 @@ class CandidateItemUi( @SuppressLint("UseKtx") fun update( - item: CandidateItem, + item: CandidateProto, highlighted: Boolean, ) { val tColor = if (highlighted) hlTextColor else textColor diff --git a/app/src/main/java/com/osfans/trime/ime/candidates/compact/CompactCandidateViewAdapter.kt b/app/src/main/java/com/osfans/trime/ime/candidates/compact/CompactCandidateViewAdapter.kt index 0ad7dc3194..0515a8a750 100644 --- a/app/src/main/java/com/osfans/trime/ime/candidates/compact/CompactCandidateViewAdapter.kt +++ b/app/src/main/java/com/osfans/trime/ime/candidates/compact/CompactCandidateViewAdapter.kt @@ -10,7 +10,7 @@ import android.view.ViewGroup import androidx.core.view.updateLayoutParams import com.chad.library.adapter4.BaseQuickAdapter import com.google.android.flexbox.FlexboxLayoutManager -import com.osfans.trime.core.CandidateItem +import com.osfans.trime.core.CandidateProto import com.osfans.trime.data.theme.Theme import com.osfans.trime.ime.candidates.CandidateItemUi import com.osfans.trime.ime.candidates.CandidateViewHolder @@ -20,7 +20,7 @@ import splitties.views.dsl.core.wrapContent open class CompactCandidateViewAdapter( val theme: Theme, -) : BaseQuickAdapter() { +) : BaseQuickAdapter() { init { setHasStableIds(true) } @@ -45,7 +45,7 @@ open class CompactCandidateViewAdapter( } fun updateCandidates( - data: Array, + data: Array, total: Int, highlightedIndex: Int, ) { @@ -70,7 +70,7 @@ open class CompactCandidateViewAdapter( override fun onBindViewHolder( holder: CandidateViewHolder, position: Int, - item: CandidateItem?, + item: CandidateProto?, ) { item ?: return val isHighlighted = position == highlightedIdx diff --git a/app/src/main/java/com/osfans/trime/ime/candidates/popup/LabeledCandidateItemUi.kt b/app/src/main/java/com/osfans/trime/ime/candidates/popup/LabeledCandidateItemUi.kt index 87800e9c7d..1be9c5fc6b 100644 --- a/app/src/main/java/com/osfans/trime/ime/candidates/popup/LabeledCandidateItemUi.kt +++ b/app/src/main/java/com/osfans/trime/ime/candidates/popup/LabeledCandidateItemUi.kt @@ -66,7 +66,7 @@ class LabeledCandidateItemUi( inSpanWith(labelFg, ctx.sp(labelSize), labelFont) { append(candidate.label) } append(" ") inSpanWith(textFg, ctx.sp(textSize), textFont) { append(candidate.text) } - if (!candidate.comment.isNullOrBlank()) { + if (candidate.comment.isNotBlank()) { append(" ") inSpanWith(commentFg, ctx.sp(commentSize), commentFont) { append(candidate.comment) } } diff --git a/app/src/main/java/com/osfans/trime/ime/candidates/unrolled/CandidatesPagingSource.kt b/app/src/main/java/com/osfans/trime/ime/candidates/unrolled/CandidatesPagingSource.kt index f2f5072e0d..c0781b5bd1 100644 --- a/app/src/main/java/com/osfans/trime/ime/candidates/unrolled/CandidatesPagingSource.kt +++ b/app/src/main/java/com/osfans/trime/ime/candidates/unrolled/CandidatesPagingSource.kt @@ -7,7 +7,7 @@ package com.osfans.trime.ime.candidates.unrolled import androidx.paging.PagingSource import androidx.paging.PagingState -import com.osfans.trime.core.CandidateItem +import com.osfans.trime.core.CandidateProto import com.osfans.trime.daemon.RimeSession import timber.log.Timber @@ -15,8 +15,8 @@ class CandidatesPagingSource( val rime: RimeSession, val total: Int, val offset: Int, -) : PagingSource() { - override suspend fun load(params: LoadParams): LoadResult { +) : PagingSource() { + override suspend fun load(params: LoadParams): LoadResult { // use candidate index for key, null means load from beginning (including offset) val startIndex = params.key ?: offset val pageSize = params.loadSize @@ -35,5 +35,5 @@ class CandidatesPagingSource( } // always reload from beginning - override fun getRefreshKey(state: PagingState) = null + override fun getRefreshKey(state: PagingState) = null } diff --git a/app/src/main/java/com/osfans/trime/ime/candidates/unrolled/PagingCandidateViewAdapter.kt b/app/src/main/java/com/osfans/trime/ime/candidates/unrolled/PagingCandidateViewAdapter.kt index 1e7dd3cdc3..cebde6e197 100644 --- a/app/src/main/java/com/osfans/trime/ime/candidates/unrolled/PagingCandidateViewAdapter.kt +++ b/app/src/main/java/com/osfans/trime/ime/candidates/unrolled/PagingCandidateViewAdapter.kt @@ -8,25 +8,25 @@ package com.osfans.trime.ime.candidates.unrolled import android.view.ViewGroup import androidx.paging.PagingDataAdapter import androidx.recyclerview.widget.DiffUtil -import com.osfans.trime.core.CandidateItem +import com.osfans.trime.core.CandidateProto import com.osfans.trime.data.theme.Theme import com.osfans.trime.ime.candidates.CandidateItemUi import com.osfans.trime.ime.candidates.CandidateViewHolder open class PagingCandidateViewAdapter( val theme: Theme, -) : PagingDataAdapter(diffCallback) { +) : PagingDataAdapter(diffCallback) { companion object { private val diffCallback = - object : DiffUtil.ItemCallback() { + object : DiffUtil.ItemCallback() { override fun areItemsTheSame( - oldItem: CandidateItem, - newItem: CandidateItem, + oldItem: CandidateProto, + newItem: CandidateProto, ): Boolean = oldItem === newItem override fun areContentsTheSame( - oldItem: CandidateItem, - newItem: CandidateItem, + oldItem: CandidateProto, + newItem: CandidateProto, ): Boolean = oldItem == newItem } } diff --git a/app/src/main/jni/librime_jni/helper-types.h b/app/src/main/jni/librime_jni/helper-types.h index b42e59c4b1..0e94b7710d 100644 --- a/app/src/main/jni/librime_jni/helper-types.h +++ b/app/src/main/jni/librime_jni/helper-types.h @@ -28,18 +28,6 @@ class SchemaItem { } }; -class CandidateItem { - public: - std::string text; - std::string comment; - - explicit CandidateItem(const RimeCandidate& candidate) - : text(candidate.text), - comment(candidate.comment ? candidate.comment : "") {} -}; - -using CandidateList = std::vector; - class CommitProto { public: std::optional text; @@ -52,8 +40,12 @@ class CommitProto { class CandidateProto { public: std::string text; - std::optional comment; + std::string comment; std::string label; + + CandidateProto() = default; + explicit CandidateProto(const RimeCandidate& c) + : text(c.text), comment(c.comment ? c.comment : "") {} }; class CompositionProto { diff --git a/app/src/main/jni/librime_jni/jni-utils.h b/app/src/main/jni/librime_jni/jni-utils.h index 9e8ed5bcb2..aed9e46cd4 100644 --- a/app/src/main/jni/librime_jni/jni-utils.h +++ b/app/src/main/jni/librime_jni/jni-utils.h @@ -103,9 +103,6 @@ class GlobalRefSingleton { jclass Rime; jmethodID HandleRimeMessage; - jclass CandidateItem; - jmethodID CandidateItemInit; - jclass CandidateProto; jmethodID CandidateProtoInit; @@ -153,11 +150,6 @@ class GlobalRefSingleton { HandleRimeMessage = env->GetStaticMethodID(Rime, "handleRimeMessage", "(I[Ljava/lang/Object;)V"); - CandidateItem = reinterpret_cast(env->NewGlobalRef( - env->FindClass("com/osfans/trime/core/CandidateItem"))); - CandidateItemInit = env->GetMethodID( - CandidateItem, "", "(Ljava/lang/String;Ljava/lang/String;)V"); - CandidateProto = reinterpret_cast(env->NewGlobalRef( env->FindClass("com/osfans/trime/core/CandidateProto"))); CandidateProtoInit = env->GetMethodID( diff --git a/app/src/main/jni/librime_jni/objconv.h b/app/src/main/jni/librime_jni/objconv.h index bd2fc06045..ecd9bd8305 100644 --- a/app/src/main/jni/librime_jni/objconv.h +++ b/app/src/main/jni/librime_jni/objconv.h @@ -41,24 +41,6 @@ inline std::vector stringArrayToStringVector(JNIEnv* env, return std::move(result); } -inline jobject rimeCandidateItemToJObject(JNIEnv* env, - const CandidateItem& item) { - return env->NewObject(GlobalRef->CandidateItem, GlobalRef->CandidateItemInit, - *JString(env, item.text), *JString(env, item.comment)); -} - -inline jobjectArray rimeCandidateListToJObjectArray( - JNIEnv* env, const std::vector& list) { - jobjectArray array = env->NewObjectArray(static_cast(list.size()), - GlobalRef->CandidateItem, nullptr); - int i = 0; - for (const auto& item : list) { - auto jItem = JRef(env, rimeCandidateItemToJObject(env, item)); - env->SetObjectArrayElement(array, i++, jItem); - } - return array; -} - inline jobjectArray stringVectorToJStringArray( JNIEnv* env, const std::vector& strings) { jobjectArray array = env->NewObjectArray(static_cast(strings.size()), @@ -79,11 +61,22 @@ inline jobject rimeCandidateToJObject(JNIEnv* env, const CandidateProto& candidate) { return env->NewObject( GlobalRef->CandidateProto, GlobalRef->CandidateProtoInit, - *JString(env, candidate.text), - candidate.comment ? *JString(env, *candidate.comment) : nullptr, + *JString(env, candidate.text), *JString(env, candidate.comment), *JString(env, candidate.label)); } +inline jobjectArray rimeCandidateListToJObjectArray( + JNIEnv* env, const std::vector& list) { + jobjectArray array = env->NewObjectArray(static_cast(list.size()), + GlobalRef->CandidateProto, nullptr); + int i = 0; + for (const auto& candidate : list) { + auto obj = JRef(env, rimeCandidateToJObject(env, candidate)); + env->SetObjectArrayElement(array, i++, obj); + } + return array; +} + inline jobject rimeCompositionToJObject(JNIEnv* env, const CompositionProto& composition) { return env->NewObject( diff --git a/app/src/main/jni/librime_jni/rime_jni.cc b/app/src/main/jni/librime_jni/rime_jni.cc index 7f3e0884d6..459988ab92 100644 --- a/app/src/main/jni/librime_jni/rime_jni.cc +++ b/app/src/main/jni/librime_jni/rime_jni.cc @@ -172,16 +172,15 @@ class Rime { return rime->change_page(session(), backward); } - CandidateList getCandidates(int startIndex, int limit) { - CandidateList result; + std::vector getCandidates(int startIndex, int limit) { + std::vector result; result.reserve(limit); RimeCandidateListIterator iter{}; if (rime->candidate_list_from_index(session(), &iter, startIndex)) { int count = 0; while (rime->candidate_list_next(&iter)) { if (count >= limit) break; - const CandidateItem item(iter.candidate); - result.emplace_back(item); + result.emplace_back(iter.candidate); ++count; } rime->candidate_list_end(&iter); @@ -189,7 +188,7 @@ class Rime { return std::move(result); } - std::tuple getBulkCandidates() { + std::tuple> getBulkCandidates() { constexpr int limit = 16; auto list = getCandidates(0, limit); // use -1 to indicate it's not sure how many candidates now