Skip to content
Snippets Groups Projects
Commit eecd2d51 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Improved RPC performance

parent b7c46e67
No related branches found
No related tags found
No related merge requests found
......@@ -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();
}
}
......
/*
* 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;
}
}
}
......@@ -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;
......
/*
* 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;
}
}
......@@ -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"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment