Skip to content

Instantly share code, notes, and snippets.

@justjanne
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justjanne/93494e9b1abf1303996a to your computer and use it in GitHub Desktop.
Save justjanne/93494e9b1abf1303996a to your computer and use it in GitHub Desktop.
} else if (className.equals("IrcUser")) {
switch (function) {
case "partChannel":
Log.d(TAG, "Sync: IrcUser -> partChannel");
String[] tmp = objectName.split("/", 2);
int networkId = Integer.parseInt(tmp[0]);
String userName = tmp[1];
Bundle bundle = new Bundle();
bundle.putString("nick", userName);
bundle.putString("buffer", (String) packedFunc.remove(0).getData());
handler.obtainMessage(R.id.USER_PARTED, networkId, 0, bundle).sendToTarget();
break;
case "quit":
Log.d(TAG, "Sync: IrcUser -> quit");
tmp = objectName.split("/", 2);
networkId = Integer.parseInt(tmp[0]);
userName = tmp[1];
handler.obtainMessage(R.id.USER_QUIT, networkId, 0, userName).sendToTarget();
break;
case "setNick":
case "setServer":
case "setAway":
case "setAwayMessage":
case "setRealName":
Log.d(TAG, "Sync: "+className+" -> "+function);
try {
SyncMethodMessage p = new SyncMethodMessage();
p.from(className, objectName, function, packedFunc);
Message msg = handler.obtainMessage(R.id.DIRECT_MESSAGE);
msg.obj = p;
msg.sendToTarget();
} catch (ArrayIndexOutOfBoundsException e) {
final String networkIdString = objectName.split("/")[0];
Log.e(TAG, "Tried to execute "+function+"() on nonexisting object "+objectName);
Log.e(TAG, "Existing objects in Net: "+Client.getInstance().getNetworks().getNetworkById(Integer.valueOf(objectName.split("/")[0])).getUserList());
Log.e(TAG, "Existing objects in Client: "+Collections2.filter(Client.getInstance().getObjects(objectName).keySet(), new Predicate<String>() {
@Override
public boolean apply(String input) {
return input.startsWith(networkIdString);
}
}));
}
break;
}
}
/**
* Handler of incoming messages from CoreConnection, since it's in another
* read thread.
*/
class IncomingHandler extends Handler {
public boolean disabled = false;
@Override
public void handleMessage(android.os.Message msg) {
if (msg == null || coreConn == null || disabled) {
return;
}
Buffer buffer;
IrcMessage message;
List<IrcMessage> messageList;
Bundle bundle;
IrcUser user;
String bufferName;
switch (msg.what) {
case R.id.DIRECT_MESSAGE:
Message p = (Message) msg.obj;
p.apply();
}
}
/*
QuasselDroid - Quassel client for Android
Copyright (C) 2011 Ken Børge Viktil
Copyright (C) 2011 Magnus Fjell
Copyright (C) 2011 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, or under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either version 2.1 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 and the
GNU Lesser General Public License along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
package com.iskrembilen.quasseldroid.protocol.state;
import android.support.annotation.NonNull;
import android.util.Log;
import com.iskrembilen.quasseldroid.R;
import com.iskrembilen.quasseldroid.protocol.qtcomm.EmptyQVariantException;
import com.iskrembilen.quasseldroid.protocol.qtcomm.QVariant;
import com.iskrembilen.quasseldroid.protocol.qtcomm.QVariantType;
import com.iskrembilen.quasseldroid.protocol.state.serializers.Syncable;
import com.iskrembilen.quasseldroid.protocol.state.serializers.SyncableObject;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;
public class IrcUser extends SyncableObject implements Comparable<IrcUser> {
@Syncable(type=QVariantType.String)
public String name;
@Syncable(type=QVariantType.Bool)
public boolean away;
@Syncable(type=QVariantType.String)
public String awayMessage;
@Syncable(type=QVariantType.String)
public String ircOperator;
@Syncable(type=QVariantType.String)
public String nick;
@Syncable(type=QVariantType.StringList)
public List<String> channels = new ArrayList<String>();
@Syncable(type=QVariantType.String)
public String server;
@Syncable(type=QVariantType.String)
public String realName;
@Syncable(type=QVariantType.String)
public String host;
@Syncable(type=QVariantType.String)
public String user;
// public Date loginTime;
// public Date idleTime;
@Syncable(type=QVariantType.Bool)
public boolean encrypted;
@Syncable(type=QVariantType.Int)
public int lastAwayMessage;
public int networkId;
public String toString() {
return nick + " away: " + away + " Num chans: " + channels.size();
}
public void changeNick(String newNick) {
nick = newNick;
this.setChanged();
notifyObservers(R.id.USER_CHANGEDNICK);
}
public void notify(int id) {
this.setChanged();
notifyObservers(id);
}
@Override
public int compareTo(@NonNull IrcUser another) {
return this.nick.compareToIgnoreCase(another.nick);
}
public void setServer(String server) {
this.server = server;
}
public void setNick(String nick) {
this.nick = nick;
}
public String getObjectName() {
return networkId+"/"+nick;
}
public void setAway(boolean away) {
this.away = away;
}
public void setAwayMessage(String awayMessage) {
this.awayMessage = awayMessage;
}
public void setRealName(String realName) {
this.realName = realName;
}
}
package com.iskrembilen.quasseldroid.protocol.state.serializers;
import com.iskrembilen.quasseldroid.protocol.qtcomm.EmptyQVariantException;
import com.iskrembilen.quasseldroid.protocol.qtcomm.QVariant;
import com.iskrembilen.quasseldroid.protocol.qtcomm.QVariantType;
import com.iskrembilen.quasseldroid.protocol.state.Client;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Observable;
public abstract class SyncableObject extends Observable {
public void register() {
register(getObjectName());
}
public void register(String name) {
Client.getInstance().putObject(getClassName(),name,this);
}
public void unregister() {
unregister(getObjectName());
}
public void unregister(String name) {
Client.getInstance().removeObject(getClassName(),name);
}
public String getClassName() {
return getClass().getSimpleName();
}
public String getObjectName() {
return String.valueOf(this.hashCode());
}
/** Stores the object's state into a QVariantMap.
* The default implementation takes dynamic properties as well as getters that have
* names starting with "init" and stores them in a QVariantMap. Override this method in
* derived classes in order to store the object state in a custom form.
* DO NOT OVERRIDE THIS unless you know exactly what you do!
*
* @return The object's state in a QVariantMap
*/
public QVariant<Map<String,QVariant<?>>> toVariantMap() {
Map<String,QVariant<?>> map = new HashMap<>();
// Iterate through all attributes of the class
for (Field field : this.getClass().getDeclaredFields()) {
try {
Syncable annotation = field.getAnnotation(Syncable.class);
if (annotation!=null) {
// If the attribute is annotated as Syncable
String name;
// If no custom name is specified, use the name of the annotation
if (annotation.name().isEmpty())
name = field.getName();
else
name = annotation.name();
// Set the field accessible for us
field.setAccessible(true);
// If the type is usertype, use the usertype instead
if (annotation.type()== QVariantType.UserType)
map.put(name, new QVariant<>(field.get(this), annotation.userType()));
else
map.put(name, new QVariant<>(field.get(this), annotation.type()));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return new QVariant<>(map,QVariantType.Map);
}
public void fromVariantMap(QVariant<Map<String,QVariant<?>>> packedMap) throws EmptyQVariantException {
fromVariantMap(packedMap.getData());
}
/** Initialize the object's state from a given QVariantMap.
* see toVariantMap for important information concerning this method.
*/
public void fromVariantMap(Map<String,QVariant<?>> map) throws EmptyQVariantException {
// Iterate through all attributes of the class
for (Field field : this.getClass().getDeclaredFields()) {
try {
Syncable annotation = field.getAnnotation(Syncable.class);
// If the attribute is syncable
if (annotation != null) {
// Set the attribute accessible
field.setAccessible(true);
// Use field name if no custom name is set
String name;
if (annotation.name().isEmpty()) {
name = field.getName();
} else {
name = annotation.name();
}
// Set the value from the QVariantMap
if (map.containsKey(name)) {
field.set(this, map.get(name).getData());
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
public void fromOther(SyncableObject other) {
if (this.getClass() != other.getClass())
throw new IllegalArgumentException("Can’t initialize "+this.getClass().getSimpleName()+" with values from object of type "+other.getClass().getSimpleName());
// Iterate through all fields in the object
for (Field field : this.getClass().getDeclaredFields()) {
try {
Syncable annotation = field.getAnnotation(Syncable.class);
// If the field is syncable
if (annotation!=null) {
// Set the attribute accessible for us
field.setAccessible(true);
// Set the value of the attribute from the other object’s attribute
field.set(this,field.get(other));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
public void execute(String function, QVariant<?>... rawArgs) throws EmptyQVariantException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Object[] args = new Object[rawArgs.length];
Class[] argTypes = new Class[rawArgs.length];
for (int i = 0; i< rawArgs.length; i++) {
args[i] = rawArgs[i].getData();
argTypes[i] = rawArgs[i].getType().getJavaType();
}
Method method = this.getClass().getMethod(function, argTypes);
method.setAccessible(true);
method.invoke(this, args);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment