Add subclass consumption for Cache with CacheMap#getApplicable
This commit is contained in:
parent
9c19d544d6
commit
76536ed279
@ -20,7 +20,7 @@ import envoy.util.EnvoyLog;
|
|||||||
* @author Kai S. K. Engelbart
|
* @author Kai S. K. Engelbart
|
||||||
* @since Envoy Client v0.3-alpha
|
* @since Envoy Client v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public class Cache<T> implements Consumer<T>, Serializable {
|
public final class Cache<T> implements Consumer<T>, Serializable {
|
||||||
|
|
||||||
private final Queue<T> elements = new LinkedList<>();
|
private final Queue<T> elements = new LinkedList<>();
|
||||||
private transient Consumer<T> processor;
|
private transient Consumer<T> processor;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package envoy.client.data;
|
package envoy.client.data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -14,10 +15,12 @@ import java.util.Map;
|
|||||||
* @author Kai S. K. Engelbart
|
* @author Kai S. K. Engelbart
|
||||||
* @since Envoy Client v0.1-beta
|
* @since Envoy Client v0.1-beta
|
||||||
*/
|
*/
|
||||||
public final class CacheMap {
|
public final class CacheMap implements Serializable {
|
||||||
|
|
||||||
private final Map<Class<?>, Cache<?>> map = new HashMap<>();
|
private final Map<Class<?>, Cache<?>> map = new HashMap<>();
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a cache to the map.
|
* Adds a cache to the map.
|
||||||
*
|
*
|
||||||
@ -38,6 +41,23 @@ public final class CacheMap {
|
|||||||
*/
|
*/
|
||||||
public <T> Cache<T> get(Class<T> key) { return (Cache<T>) map.get(key); }
|
public <T> Cache<T> get(Class<T> key) { return (Cache<T>) map.get(key); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a cache mapped by a class or any of its subclasses.
|
||||||
|
*
|
||||||
|
* @param <T> the type accepted by the cache
|
||||||
|
* @param key the class that maps to the cache
|
||||||
|
* @return the cache
|
||||||
|
* @since Envoy Client v0.1-beta
|
||||||
|
*/
|
||||||
|
public <T> Cache<? super T> getApplicable(Class<T> key) {
|
||||||
|
Cache<? super T> cache = get(key);
|
||||||
|
if (cache == null)
|
||||||
|
for (var e : map.entrySet())
|
||||||
|
if (e.getKey().isAssignableFrom(key))
|
||||||
|
cache = (Cache<? super T>) e.getValue();
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the map in which the caches are stored
|
* @return the map in which the caches are stored
|
||||||
* @since Envoy Client v0.1-beta
|
* @since Envoy Client v0.1-beta
|
||||||
|
@ -20,12 +20,16 @@ import envoy.event.NameChange;
|
|||||||
*/
|
*/
|
||||||
public abstract class LocalDB {
|
public abstract class LocalDB {
|
||||||
|
|
||||||
protected User user;
|
protected User user;
|
||||||
protected Map<String, Contact> users = new HashMap<>();
|
protected Map<String, Contact> users = new HashMap<>();
|
||||||
protected List<Chat> chats = new ArrayList<>();
|
protected List<Chat> chats = new ArrayList<>();
|
||||||
protected IDGenerator idGenerator;
|
protected IDGenerator idGenerator;
|
||||||
protected Cache<Message> messageCache = new Cache<>();
|
protected CacheMap cacheMap = new CacheMap();
|
||||||
protected Cache<MessageStatusChange> statusCache = new Cache<>();
|
|
||||||
|
{
|
||||||
|
cacheMap.put(Message.class, new Cache<>());
|
||||||
|
cacheMap.put(MessageStatusChange.class, new Cache<>());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a storage space for a user-specific list of chats.
|
* Initializes a storage space for a user-specific list of chats.
|
||||||
@ -139,28 +143,10 @@ public abstract class LocalDB {
|
|||||||
public boolean hasIDGenerator() { return idGenerator != null; }
|
public boolean hasIDGenerator() { return idGenerator != null; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the offline message cache
|
* @return the cache map for messages and message status changes
|
||||||
* @since Envoy Client v0.3-alpha
|
* @since Envoy Client v0.1-beta
|
||||||
*/
|
*/
|
||||||
public Cache<Message> getMessageCache() { return messageCache; }
|
public CacheMap getCacheMap() { return cacheMap; }
|
||||||
|
|
||||||
/**
|
|
||||||
* @param messageCache the offline message cache to set
|
|
||||||
* @since Envoy Client v0.3-alpha
|
|
||||||
*/
|
|
||||||
public void setMessageCache(Cache<Message> messageCache) { this.messageCache = messageCache; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the offline status cache
|
|
||||||
* @since Envoy Client v0.3-alpha
|
|
||||||
*/
|
|
||||||
public Cache<MessageStatusChange> getStatusCache() { return statusCache; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param statusCache the offline status cache to set
|
|
||||||
* @since Envoy Client v0.3-alpha
|
|
||||||
*/
|
|
||||||
public void setStatusCache(Cache<MessageStatusChange> statusCache) { this.statusCache = statusCache; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches for a message by ID.
|
* Searches for a message by ID.
|
||||||
|
@ -5,8 +5,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import envoy.data.IDGenerator;
|
import envoy.data.IDGenerator;
|
||||||
import envoy.data.Message;
|
|
||||||
import envoy.event.MessageStatusChange;
|
|
||||||
import envoy.util.SerializationUtils;
|
import envoy.util.SerializationUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,7 +62,7 @@ public final class PersistentLocalDB extends LocalDB {
|
|||||||
SerializationUtils.write(usersFile, users);
|
SerializationUtils.write(usersFile, users);
|
||||||
|
|
||||||
// Save user data
|
// Save user data
|
||||||
if (user != null) SerializationUtils.write(userFile, chats, messageCache, statusCache);
|
if (user != null) SerializationUtils.write(userFile, chats, cacheMap);
|
||||||
|
|
||||||
// Save id generator
|
// Save id generator
|
||||||
if (hasIDGenerator()) SerializationUtils.write(idGeneratorFile, idGenerator);
|
if (hasIDGenerator()) SerializationUtils.write(idGeneratorFile, idGenerator);
|
||||||
@ -76,9 +74,8 @@ public final class PersistentLocalDB extends LocalDB {
|
|||||||
@Override
|
@Override
|
||||||
public void loadUserData() throws ClassNotFoundException, IOException {
|
public void loadUserData() throws ClassNotFoundException, IOException {
|
||||||
try (var in = new ObjectInputStream(new FileInputStream(userFile))) {
|
try (var in = new ObjectInputStream(new FileInputStream(userFile))) {
|
||||||
chats = (ArrayList<Chat>) in.readObject();
|
chats = (ArrayList<Chat>) in.readObject();
|
||||||
messageCache = (Cache<Message>) in.readObject();
|
cacheMap = (CacheMap) in.readObject();
|
||||||
statusCache = (Cache<MessageStatusChange>) in.readObject();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import java.io.IOException;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import envoy.client.data.Cache;
|
||||||
import envoy.client.data.LocalDB;
|
import envoy.client.data.LocalDB;
|
||||||
import envoy.data.Message;
|
import envoy.data.Message;
|
||||||
import envoy.event.MessageStatusChange;
|
import envoy.event.MessageStatusChange;
|
||||||
@ -43,7 +44,7 @@ public class WriteProxy {
|
|||||||
this.localDB = localDB;
|
this.localDB = localDB;
|
||||||
|
|
||||||
// Initialize cache processors for messages and message status change events
|
// Initialize cache processors for messages and message status change events
|
||||||
localDB.getMessageCache().setProcessor(msg -> {
|
localDB.getCacheMap().get(Message.class).setProcessor(msg -> {
|
||||||
try {
|
try {
|
||||||
logger.log(Level.FINER, "Sending cached " + msg);
|
logger.log(Level.FINER, "Sending cached " + msg);
|
||||||
client.sendMessage(msg);
|
client.sendMessage(msg);
|
||||||
@ -51,7 +52,7 @@ public class WriteProxy {
|
|||||||
logger.log(Level.SEVERE, "Could not send cached message: ", e);
|
logger.log(Level.SEVERE, "Could not send cached message: ", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
localDB.getStatusCache().setProcessor(evt -> {
|
localDB.getCacheMap().get(MessageStatusChange.class).setProcessor(evt -> {
|
||||||
logger.log(Level.FINER, "Sending cached " + evt);
|
logger.log(Level.FINER, "Sending cached " + evt);
|
||||||
try {
|
try {
|
||||||
client.sendEvent(evt);
|
client.sendEvent(evt);
|
||||||
@ -68,11 +69,7 @@ public class WriteProxy {
|
|||||||
* @since Envoy Client v0.3-alpha
|
* @since Envoy Client v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public void flushCache() {
|
public void flushCache() {
|
||||||
// Send messages
|
localDB.getCacheMap().getMap().values().forEach(Cache::relay);
|
||||||
localDB.getMessageCache().relay();
|
|
||||||
|
|
||||||
// Send message status change events
|
|
||||||
localDB.getStatusCache().relay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,7 +82,7 @@ public class WriteProxy {
|
|||||||
*/
|
*/
|
||||||
public void writeMessage(Message message) throws IOException {
|
public void writeMessage(Message message) throws IOException {
|
||||||
if (client.isOnline()) client.sendMessage(message);
|
if (client.isOnline()) client.sendMessage(message);
|
||||||
else localDB.getMessageCache().accept(message);
|
else localDB.getCacheMap().getApplicable(Message.class).accept(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,6 +95,6 @@ public class WriteProxy {
|
|||||||
*/
|
*/
|
||||||
public void writeMessageStatusChange(MessageStatusChange evt) throws IOException {
|
public void writeMessageStatusChange(MessageStatusChange evt) throws IOException {
|
||||||
if (client.isOnline()) client.sendEvent(evt);
|
if (client.isOnline()) client.sendEvent(evt);
|
||||||
else localDB.getStatusCache().accept(evt);
|
else localDB.getCacheMap().getApplicable(MessageStatusChange.class).accept(evt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ public final class LoginScene {
|
|||||||
sceneContext.load(SceneContext.SceneInfo.CHAT_SCENE);
|
sceneContext.load(SceneContext.SceneInfo.CHAT_SCENE);
|
||||||
sceneContext.<ChatScene>getController().initializeData(sceneContext, localDB, client, writeProxy);
|
sceneContext.<ChatScene>getController().initializeData(sceneContext, localDB, client, writeProxy);
|
||||||
|
|
||||||
// Relay unread messages from cache
|
// Relay the caches if online
|
||||||
if (client.isOnline()) cacheMap.getMap().values().forEach(cache -> { if (cache != null) cache.relay(); });
|
if (client.isOnline()) cacheMap.getMap().values().forEach(Cache::relay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user