Add subclass consumption for Cache with CacheMap#getApplicable

This commit is contained in:
Kai S. K. Engelbart 2020-07-09 10:53:27 +02:00
parent 9c19d544d6
commit 76536ed279
6 changed files with 46 additions and 46 deletions

View File

@ -20,7 +20,7 @@ import envoy.util.EnvoyLog;
* @author Kai S. K. Engelbart
* @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 transient Consumer<T> processor;

View File

@ -1,5 +1,6 @@
package envoy.client.data;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
@ -14,10 +15,12 @@ import java.util.Map;
* @author Kai S. K. Engelbart
* @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 static final long serialVersionUID = 1L;
/**
* 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); }
/**
* 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
* @since Envoy Client v0.1-beta

View File

@ -24,8 +24,12 @@ public abstract class LocalDB {
protected Map<String, Contact> users = new HashMap<>();
protected List<Chat> chats = new ArrayList<>();
protected IDGenerator idGenerator;
protected Cache<Message> messageCache = new Cache<>();
protected Cache<MessageStatusChange> statusCache = new Cache<>();
protected CacheMap cacheMap = new CacheMap();
{
cacheMap.put(Message.class, new Cache<>());
cacheMap.put(MessageStatusChange.class, new Cache<>());
}
/**
* 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; }
/**
* @return the offline message cache
* @since Envoy Client v0.3-alpha
* @return the cache map for messages and message status changes
* @since Envoy Client v0.1-beta
*/
public Cache<Message> getMessageCache() { return messageCache; }
/**
* @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; }
public CacheMap getCacheMap() { return cacheMap; }
/**
* Searches for a message by ID.

View File

@ -5,8 +5,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import envoy.data.IDGenerator;
import envoy.data.Message;
import envoy.event.MessageStatusChange;
import envoy.util.SerializationUtils;
/**
@ -64,7 +62,7 @@ public final class PersistentLocalDB extends LocalDB {
SerializationUtils.write(usersFile, users);
// Save user data
if (user != null) SerializationUtils.write(userFile, chats, messageCache, statusCache);
if (user != null) SerializationUtils.write(userFile, chats, cacheMap);
// Save id generator
if (hasIDGenerator()) SerializationUtils.write(idGeneratorFile, idGenerator);
@ -77,8 +75,7 @@ public final class PersistentLocalDB extends LocalDB {
public void loadUserData() throws ClassNotFoundException, IOException {
try (var in = new ObjectInputStream(new FileInputStream(userFile))) {
chats = (ArrayList<Chat>) in.readObject();
messageCache = (Cache<Message>) in.readObject();
statusCache = (Cache<MessageStatusChange>) in.readObject();
cacheMap = (CacheMap) in.readObject();
}
}

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import envoy.client.data.Cache;
import envoy.client.data.LocalDB;
import envoy.data.Message;
import envoy.event.MessageStatusChange;
@ -43,7 +44,7 @@ public class WriteProxy {
this.localDB = localDB;
// Initialize cache processors for messages and message status change events
localDB.getMessageCache().setProcessor(msg -> {
localDB.getCacheMap().get(Message.class).setProcessor(msg -> {
try {
logger.log(Level.FINER, "Sending cached " + msg);
client.sendMessage(msg);
@ -51,7 +52,7 @@ public class WriteProxy {
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);
try {
client.sendEvent(evt);
@ -68,11 +69,7 @@ public class WriteProxy {
* @since Envoy Client v0.3-alpha
*/
public void flushCache() {
// Send messages
localDB.getMessageCache().relay();
// Send message status change events
localDB.getStatusCache().relay();
localDB.getCacheMap().getMap().values().forEach(Cache::relay);
}
/**
@ -85,7 +82,7 @@ public class WriteProxy {
*/
public void writeMessage(Message message) throws IOException {
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 {
if (client.isOnline()) client.sendEvent(evt);
else localDB.getStatusCache().accept(evt);
else localDB.getCacheMap().getApplicable(MessageStatusChange.class).accept(evt);
}
}

View File

@ -196,7 +196,7 @@ public final class LoginScene {
sceneContext.load(SceneContext.SceneInfo.CHAT_SCENE);
sceneContext.<ChatScene>getController().initializeData(sceneContext, localDB, client, writeProxy);
// Relay unread messages from cache
if (client.isOnline()) cacheMap.getMap().values().forEach(cache -> { if (cache != null) cache.relay(); });
// Relay the caches if online
if (client.isOnline()) cacheMap.getMap().values().forEach(Cache::relay);
}
}