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