Skip to content

Commit

Permalink
feat,refactor(core,ui,jni): reimplement setting integer in custom config
Browse files Browse the repository at this point in the history
This can replace the huge, less robust schema overwriting in Rime.java
  • Loading branch information
WhiredPlanck committed Jan 10, 2023
1 parent acf3c77 commit 11b59b8
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 86 deletions.
71 changes: 4 additions & 67 deletions app/src/main/java/com/osfans/trime/core/Rime.java
Expand Up @@ -24,14 +24,8 @@
import com.osfans.trime.data.DataManager;
import com.osfans.trime.data.opencc.OpenCCDictManager;
import com.osfans.trime.data.schema.SchemaManager;
import java.io.BufferedReader;
import java.io.CharArrayWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import kotlin.Pair;
import kotlinx.coroutines.channels.BufferOverflow;
import kotlinx.coroutines.flow.FlowKt;
import kotlinx.coroutines.flow.MutableSharedFlow;
Expand Down Expand Up @@ -354,71 +348,11 @@ public static String getSchemaName() {

public static boolean selectSchema(String schemaId) {
Timber.d("Selecting schemaId=%s", schemaId);
overWriteSchema(schemaId);
boolean b = selectRimeSchema(schemaId);
getContexts();
return b;
}

// 刷新当前输入方案
public static void applySchemaChange() {
String schema_id = getCurrentRimeSchema();
// 实测直接select_schema(schema_id)方案没有重新载入,切换到不存在的方案,再切回去(会产生1秒的额外耗时).需要找到更好的方法
// 不发生覆盖则不生效
if (overWriteSchema(schema_id)) {
selectRimeSchema("nill");
selectRimeSchema(schema_id);
}
getContexts();
}
// 临时修改scheme文件参数
// 临时修改build后的scheme可以避免build过程的耗时
// 另外实际上jni读入yaml、修改、导出的效率并不高
private static boolean overWriteSchema(String schema_id) {
Map<String, String> map = new HashMap<>();
String page_size = AppPrefs.defaultInstance().getKeyboard().getCandidatePageSize();
Timber.d("overWriteSchema() page_size=" + page_size);
if (!page_size.equals("0")) {
map.put("page_size", page_size);
}
if (map.isEmpty()) return false;
return overWriteSchema(schema_id, map);
}

private static boolean overWriteSchema(String schema_id, Map<String, String> map) {
if (schema_id == null) schema_id = getCurrentRimeSchema();
File file =
new File(Rime.getRimeUserDataDir() + File.separator + "build", schema_id + ".schema.yaml");
try {
FileReader in = new FileReader(file);
BufferedReader bufIn = new BufferedReader(in);
CharArrayWriter tempStream = new CharArrayWriter();
String line = null;
read:
while ((line = bufIn.readLine()) != null) {
for (String k : map.keySet()) {
String key = k + ": ";
if (line.contains(key)) {
String value = ": " + map.get(k) + System.getProperty("line.separator");
tempStream.write(line.replaceFirst(":.+", value));
map.remove(k);
continue read;
}
}
tempStream.write(line);
tempStream.append(System.getProperty("line.separator"));
}
bufIn.close();
FileWriter out = new FileWriter(file);
tempStream.writeTo(out);
out.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return map.isEmpty();
}

public static Rime get(boolean full_check) {
if (self == null) {
if (full_check) {
Expand Down Expand Up @@ -491,6 +425,9 @@ public static native boolean deployRimeConfigFile(
public static native Map<String, Object> getRimeConfigMap(
@NonNull String configId, @NonNull String key);

public static native void setRimeCustomConfigInt(
@NonNull String configId, @NonNull Pair<String, Integer>[] keyValuePairs);

// testing
public static native boolean simulateKeySequence(@NonNull String keySequence);

Expand Down
Expand Up @@ -7,11 +7,15 @@ import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference
import com.osfans.trime.R
import com.osfans.trime.core.Rime
import com.osfans.trime.data.AppPrefs
import com.osfans.trime.data.DataManager
import com.osfans.trime.ime.core.Trime
import com.osfans.trime.ui.components.PaddingPreferenceFragment
import com.osfans.trime.ui.main.MainViewModel
import com.osfans.trime.ui.main.soundPicker
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class KeyboardFragment :
PaddingPreferenceFragment(),
Expand Down Expand Up @@ -41,7 +45,17 @@ class KeyboardFragment :
trime?.loadConfig()
}
"keyboard__candidate_page_size" -> {
Rime.applySchemaChange()
val pageSize = AppPrefs.defaultInstance().keyboard.candidatePageSize.toInt()
if (pageSize <= 0) return
lifecycleScope.launch {
withContext(Dispatchers.IO) {
Rime.setRimeCustomConfigInt(
"default",
arrayOf("menu/page_size" to pageSize)
)
Rime.deployRimeConfigFile("${DataManager.userDataDir}/default.yaml", "")
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/jni/librime_jni/jni-common.h
Expand Up @@ -3,7 +3,7 @@

#include "jni-utils.h"

static GlobalRefSingleton *GlobalRef;
extern GlobalRefSingleton *GlobalRef;

#define TAG "rime.jni"
#ifdef ANDROID
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/jni/librime_jni/jni-utils.h
Expand Up @@ -120,6 +120,10 @@ class GlobalRefSingleton {
jmethodID ArrayListInit;
jmethodID ArrayListAdd;

jclass Pair;
jmethodID PairFirst;
jmethodID PairSecond;

jclass Rime;
jmethodID HandleRimeNotification;

Expand Down Expand Up @@ -186,6 +190,10 @@ class GlobalRefSingleton {
ArrayListInit = env->GetMethodID(ArrayList, "<init>", "(I)V");
ArrayListAdd = env->GetMethodID(ArrayList, "add", "(ILjava/lang/Object;)V");

Pair = reinterpret_cast<jclass>(env->NewGlobalRef(env->FindClass("kotlin/Pair")));
PairFirst = env->GetMethodID(Pair, "getFirst", "()Ljava/lang/Object;");
PairSecond = env->GetMethodID(Pair, "getSecond", "()Ljava/lang/Object;");

Rime = reinterpret_cast<jclass>(env->NewGlobalRef(env->FindClass("com/osfans/trime/core/Rime")));
HandleRimeNotification = env->GetStaticMethodID(Rime, "handleRimeNotification", "(Ljava/lang/String;Ljava/lang/String;)V");

Expand Down
18 changes: 18 additions & 0 deletions app/src/main/jni/librime_jni/levers.cc
Expand Up @@ -56,3 +56,21 @@ Java_com_osfans_trime_core_Rime_selectRimeSchemas(JNIEnv *env, jclass /* thiz */
}
return true;
}

extern "C"
JNIEXPORT void JNICALL
Java_com_osfans_trime_core_Rime_setRimeCustomConfigInt(JNIEnv *env, jclass clazz, jstring config_id,
jobjectArray key_value_pairs) {
auto levers = get_levers();
auto custom = levers->custom_settings_init(CString(env, config_id), "rime.trime");
levers->load_settings(custom);
int arrayLength = env->GetArrayLength(key_value_pairs);
for (int i = 0; i < arrayLength; i++) {
auto pair = JRef<>(env, env->GetObjectArrayElement(key_value_pairs, i));
auto key = CString(env, (jstring) env->CallObjectMethod(pair, GlobalRef->PairFirst));
auto value = (jint) (size_t) env->CallObjectMethod(pair, GlobalRef->PairSecond);
levers->customize_int(custom, key, value);
levers->save_settings(custom);
}
levers->custom_settings_destroy(custom);
}
19 changes: 2 additions & 17 deletions app/src/main/jni/librime_jni/rime_jni.cc
Expand Up @@ -144,6 +144,8 @@ class Rime {
#define RETURN_IF_NOT_RUNNING DO_IF_NOT_RUNNING(return)
#define RETURN_VALUE_IF_NOT_RUNNING(v) DO_IF_NOT_RUNNING(return (v))

GlobalRefSingleton *GlobalRef;

JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM* jvm, void* reserved)
{
Expand Down Expand Up @@ -485,23 +487,6 @@ static jobject rimeConfigListToJObject(JNIEnv *env, RimeConfig* config, const st
return obj;
}

extern "C"
JNIEXPORT jobject JNICALL
Java_com_osfans_trime_core_Rime_config_1get_1list(JNIEnv *env, jclass /* thiz */, jstring name, jstring key) {
const char* s = env->GetStringUTFChars(name, nullptr);
RimeConfig config = {nullptr};
Bool b = RimeConfigOpen(s, &config);
env->ReleaseStringUTFChars(name, s);
jobject value = nullptr;
if (b) {
s = env->GetStringUTFChars(key, nullptr);
value = rimeConfigListToJObject(env, &config, s);
env->ReleaseStringUTFChars(key, s);
}
RimeConfigClose(&config);
return value;
}

static jobject rimeConfigMapToJObject(JNIEnv *env, RimeConfig *config, const std::string &key) {
auto rime = rime_get_api();
RimeConfigIterator iter = {nullptr};
Expand Down

0 comments on commit 11b59b8

Please sign in to comment.