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 9257f3fad9
commit ab61d2dbfd
No known key found for this signature in database
GPG Key ID: 0A48559CA32CB48F
6 changed files with 46 additions and 46 deletions

View File

@ -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;

View File

@ -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

View File

@ -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.

View File

@ -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();
} }
} }

View File

@ -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);
} }
} }

View File

@ -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);
} }
} }