From eecd2d519422216f1ba6facff7b3b07c072214f6 Mon Sep 17 00:00:00 2001 From: Janne Koschinski <janne@kuschku.de> Date: Mon, 12 Sep 2016 02:57:29 +0200 Subject: [PATCH] Improved RPC performance --- .../kuschku/libquassel/ProtocolHandler.java | 13 +- .../syncables/types/invokers/IClient.java | 75 ++++++++++++ .../types/invokers/InvokerRegistry.java | 2 +- .../java/de/kuschku/util/ReflectionUtils.java | 113 ------------------ app/src/main/res/layout/widget_nick.xml | 5 +- 5 files changed, 80 insertions(+), 128 deletions(-) create mode 100644 app/src/main/java/de/kuschku/libquassel/syncables/types/invokers/IClient.java delete mode 100644 app/src/main/java/de/kuschku/util/ReflectionUtils.java diff --git a/app/src/main/java/de/kuschku/libquassel/ProtocolHandler.java b/app/src/main/java/de/kuschku/libquassel/ProtocolHandler.java index 187185b91..eca9bc5c2 100644 --- a/app/src/main/java/de/kuschku/libquassel/ProtocolHandler.java +++ b/app/src/main/java/de/kuschku/libquassel/ProtocolHandler.java @@ -49,8 +49,8 @@ import de.kuschku.libquassel.objects.types.CoreSetupAck; import de.kuschku.libquassel.objects.types.SessionInit; import de.kuschku.libquassel.syncables.SyncableRegistry; import de.kuschku.libquassel.syncables.types.SyncableObject; +import de.kuschku.libquassel.syncables.types.invokers.IClient; import de.kuschku.libquassel.syncables.types.invokers.InvokerRegistry; -import de.kuschku.util.ReflectionUtils; import static de.kuschku.util.AndroidAssert.assertNotNull; @@ -86,13 +86,7 @@ public class ProtocolHandler implements IProtocolHandler { @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(@NonNull RpcCallFunction packedFunc) { try { - if (packedFunc.functionName.substring(0, 1).equals("2")) { - ReflectionUtils.invokeMethod(client, "_" + packedFunc.functionName.substring(1), packedFunc.params); - } else if (packedFunc.functionName.equals("__objectRenamed__")) { - ReflectionUtils.invokeMethod(client, "_" + packedFunc.functionName, packedFunc.params); - } else { - throw new IllegalArgumentException("Unknown type: " + packedFunc.functionName); - } + IClient.get().invoke(packedFunc, client); } catch (Exception e) { busProvider.sendEvent(new GeneralErrorEvent(e)); } @@ -111,14 +105,11 @@ public class ProtocolHandler implements IProtocolHandler { if (syncable instanceof SyncableObject && !((SyncableObject) syncable).initialized()) { client.initObject(packedFunc.className, packedFunc.objectName, (SyncableObject) syncable); } else { - //ReflectionUtils.invokeMethod(syncable, "_" + packedFunc.methodName, packedFunc.params); InvokerRegistry.invoke(packedFunc, syncable); } } } catch (Exception e) { busProvider.sendEvent(new GeneralErrorEvent(e, packedFunc.toString())); - } catch (Error e) { - e.printStackTrace(); } } diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/invokers/IClient.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/invokers/IClient.java new file mode 100644 index 000000000..7e7777385 --- /dev/null +++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/invokers/IClient.java @@ -0,0 +1,75 @@ +/* + * QuasselDroid - Quassel client for Android + * Copyright (C) 2016 Janne Koschinski + * Copyright (C) 2016 Ken Børge Viktil + * Copyright (C) 2016 Magnus Fjell + * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.syncables.types.invokers; + +import android.support.annotation.NonNull; + +import de.kuschku.libquassel.client.QClient; +import de.kuschku.libquassel.functions.types.RpcCallFunction; +import de.kuschku.libquassel.message.Message; +import de.kuschku.libquassel.primitives.types.BufferInfo; +import de.kuschku.libquassel.syncables.types.impl.Identity; + +public class IClient { + @NonNull + private static final IClient invoker = new IClient(); + + private IClient() { + } + + @NonNull + public static IClient get() { + return invoker; + } + + public void invoke(RpcCallFunction function, QClient obj) { + switch (function.functionName) { + case "2displayMsg": { + obj._displayMsg((Message) function.params.get(0)); + } break; + case "2bufferInfoUpdated": { + obj._bufferInfoUpdated((BufferInfo) function.params.get(0)); + } break; + case "2identityCreated": { + obj._identityCreated((Identity) function.params.get(0)); + } break; + case "2identityRemoved": { + obj._identityRemoved((int) function.params.get(0)); + } break; + case "2networkCreated": { + obj._networkCreated((int) function.params.get(0)); + } break; + case "2networkRemoved": { + obj._networkRemoved((int) function.params.get(0)); + } break; + case "2passwordChanged": { + obj._passwordChanged((long) function.params.get(0), (boolean) function.params.get(1)); + } break; + case "2displayStatusMsg": { + obj._displayStatusMsg((String) function.params.get(0), (String) function.params.get(1)); + } break; + case "__objectRenamed__": { + obj.___objectRenamed__((String) function.params.get(0), (String) function.params.get(1), (String) function.params.get(2)); + } break; + } + } +} diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/invokers/InvokerRegistry.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/invokers/InvokerRegistry.java index bd460558e..f13714dce 100644 --- a/app/src/main/java/de/kuschku/libquassel/syncables/types/invokers/InvokerRegistry.java +++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/invokers/InvokerRegistry.java @@ -52,7 +52,7 @@ public class InvokerRegistry { return (Invoker<T>) IIgnoreListManager.get(); case "IrcUser": return (Invoker<T>) IIrcUser.get(); - case "INetworkConfig": + case "NetworkConfig": return (Invoker<T>) INetworkConfig.get(); default: return null; diff --git a/app/src/main/java/de/kuschku/util/ReflectionUtils.java b/app/src/main/java/de/kuschku/util/ReflectionUtils.java deleted file mode 100644 index 6da3581a2..000000000 --- a/app/src/main/java/de/kuschku/util/ReflectionUtils.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * QuasselDroid - Quassel client for Android - * Copyright (C) 2016 Janne Koschinski - * Copyright (C) 2016 Ken Børge Viktil - * Copyright (C) 2016 Magnus Fjell - * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package de.kuschku.util; - -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import com.google.common.primitives.Primitives; - -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.List; - -import de.kuschku.libquassel.exceptions.SyncInvocationException; -import de.kuschku.libquassel.primitives.types.QVariant; -import de.kuschku.util.backports.Objects; - -import static de.kuschku.util.AndroidAssert.assertNotNull; - -public class ReflectionUtils { - private ReflectionUtils() { - - } - - private static void unboxList(@NonNull Object[] list) { - for (int i = 0; i < list.length; i++) { - if (list[i] instanceof QVariant) - list[i] = ((QVariant) list[i]).data; - } - } - - public static void invokeMethod(@NonNull Object o, @NonNull String name, @NonNull Object[] argv) throws SyncInvocationException { - name = stripName(name); - unboxList(argv); - - Class<?>[] classes = new Class<?>[argv.length]; - for (int i = 0; i < argv.length; i++) { - if (argv[i] == null) classes[i] = null; - else classes[i] = argv[i].getClass(); - } - Method m = getMethodFromSignature(name, o.getClass(), classes); - if (m == null) - throw new SyncInvocationException(String.format("No method %s::%s with argument types %s", o.getClass().getSimpleName(), name, Arrays.toString(classes))); - - try { - m.invoke(o, argv); - } catch (Exception e) { - throw new SyncInvocationException(e, String.format("Error invoking %s::%s with classes %s", o.getClass().getSimpleName(), name, Arrays.toString(classes))); - } - } - - @NonNull - private static String stripName(@NonNull String name) { - return (name.contains("(")) ? name.substring(0, name.indexOf("(")) : name; - } - - public static void invokeMethod(@NonNull Object o, @NonNull String name, @NonNull List argv) throws SyncInvocationException { - invokeMethod(o, name, argv.toArray(new Object[argv.size()])); - } - - @Nullable - private static <T> Method getMethodFromSignature(String methodName, @NonNull Class<T> cl, @NonNull Class<?>[] parameterTypes) { - Method[] methods = cl.getMethods(); - assertNotNull(methods); - - looper: - for (Method m : methods) { - assertNotNull(m); - assertNotNull(m.getParameterTypes()); - - if (Objects.equals(m.getName(), methodName) && m.getParameterTypes().length == parameterTypes.length) { - for (int i = 0; i < parameterTypes.length; i++) { - Class<?> mParam = m.getParameterTypes()[i]; - Class<?> vParam = parameterTypes[i]; - - // Can’t check type of null values, so we’ll assume it will work - if (vParam == null) continue; - - assertNotNull(vParam); - - if (mParam.isPrimitive() && Primitives.isWrapperType(vParam)) - vParam = Primitives.unwrap(vParam); - - if (mParam != vParam && !mParam.isAssignableFrom(vParam)) { - continue looper; - } - } - return m; - } - } - - return null; - } -} diff --git a/app/src/main/res/layout/widget_nick.xml b/app/src/main/res/layout/widget_nick.xml index 9b6d63799..8fd801f62 100644 --- a/app/src/main/res/layout/widget_nick.xml +++ b/app/src/main/res/layout/widget_nick.xml @@ -37,9 +37,8 @@ android:layout_gravity="center_vertical" android:background="@drawable/badge" android:gravity="center" - android:textColor="@color/colorFillDark" - tools:text="\@" - /> + android:textColor="?colorBackground" + tools:text="\@"/> <LinearLayout android:layout_width="0dp" -- GitLab