Simplify cache storage with a CacheMap class
This commit is contained in:
parent
4f654cc2a5
commit
9c19d544d6
46
src/main/java/envoy/client/data/CacheMap.java
Normal file
46
src/main/java/envoy/client/data/CacheMap.java
Normal file
@ -0,0 +1,46 @@
|
||||
package envoy.client.data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Stores a heterogeneous map of {@link Cache} objects with different type
|
||||
* parameters.
|
||||
* <p>
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
* File: <strong>CacheMap.java</strong><br>
|
||||
* Created: <strong>09.07.2020</strong><br>
|
||||
*
|
||||
* @author Kai S. K. Engelbart
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final class CacheMap {
|
||||
|
||||
private final Map<Class<?>, Cache<?>> map = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Adds a cache to the map.
|
||||
*
|
||||
* @param <T> the type accepted by the cache
|
||||
* @param key the class that maps to the cache
|
||||
* @param cache the cache to store
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public <T> void put(Class<T> key, Cache<T> cache) { map.put(key, cache); }
|
||||
|
||||
/**
|
||||
* Returns a cache mapped by a class.
|
||||
*
|
||||
* @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<T> get(Class<T> key) { return (Cache<T>) map.get(key); }
|
||||
|
||||
/**
|
||||
* @return the map in which the caches are stored
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public Map<Class<?>, Cache<?>> getMap() { return map; }
|
||||
}
|
@ -3,13 +3,11 @@ package envoy.client.net;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import envoy.client.data.Cache;
|
||||
import envoy.client.data.CacheMap;
|
||||
import envoy.client.data.ClientConfig;
|
||||
import envoy.client.data.LocalDB;
|
||||
import envoy.client.event.SendEvent;
|
||||
@ -40,8 +38,6 @@ public class Client implements Closeable {
|
||||
private Receiver receiver;
|
||||
private boolean online;
|
||||
|
||||
private Map<Class<?>, Cache<?>> cacheMap;
|
||||
|
||||
// Asynchronously initialized during handshake
|
||||
private volatile User sender;
|
||||
private volatile boolean rejected;
|
||||
@ -64,7 +60,8 @@ public class Client implements Closeable {
|
||||
* @throws InterruptedException if the current thread is interrupted while
|
||||
* waiting for the handshake response
|
||||
*/
|
||||
public void performHandshake(LoginCredentials credentials, Map<Class<?>, Cache<?>> cacheMap)
|
||||
public void performHandshake(LoginCredentials credentials,
|
||||
CacheMap cacheMap)
|
||||
throws TimeoutException, IOException, InterruptedException {
|
||||
if (online) throw new IllegalStateException("Handshake has already been performed successfully");
|
||||
|
||||
@ -78,7 +75,7 @@ public class Client implements Closeable {
|
||||
|
||||
// Register user creation processor, contact list processor and message cache
|
||||
receiver.registerProcessor(User.class, sender -> this.sender = sender);
|
||||
cacheMap.forEach((inputclass, cache) -> receiver.registerProcessor(inputclass, cache));
|
||||
receiver.registerProcessors(cacheMap.getMap());
|
||||
receiver.registerProcessor(HandshakeRejection.class, evt -> { rejected = true; eventBus.dispatch(evt); });
|
||||
|
||||
rejected = false;
|
||||
@ -124,7 +121,7 @@ public class Client implements Closeable {
|
||||
* requested from the server
|
||||
* @since Envoy Client v0.2-alpha
|
||||
*/
|
||||
public void initReceiver(LocalDB localDB, Map<Class<?>, Cache<?>> cacheMap) throws IOException {
|
||||
public void initReceiver(LocalDB localDB, CacheMap cacheMap) throws IOException {
|
||||
checkOnline();
|
||||
|
||||
// Process incoming messages
|
||||
@ -134,18 +131,17 @@ public class Client implements Closeable {
|
||||
final GroupMessageStatusChangeProcessor groupMessageStatusChangeProcessor = new GroupMessageStatusChangeProcessor();
|
||||
|
||||
receiver.registerProcessor(GroupMessage.class, receivedGroupMessageProcessor);
|
||||
|
||||
receiver.registerProcessor(Message.class, receivedMessageProcessor);
|
||||
|
||||
receiver.registerProcessor(MessageStatusChange.class, messageStatusChangeProcessor);
|
||||
|
||||
receiver.registerProcessor(GroupMessageStatusChange.class, groupMessageStatusChangeProcessor);
|
||||
|
||||
// Relay cached unread messages and unread groupMessages
|
||||
cacheMap.get(Message.class).setProcessor((Consumer<?>) receivedMessageProcessor);
|
||||
cacheMap.get(GroupMessage.class).setProcessor((Consumer<?>) receivedGroupMessageProcessor);
|
||||
// Process message status changes
|
||||
cacheMap.get(MessageStatusChange.class).setProcessor((Consumer<?>) messageStatusChangeProcessor);
|
||||
cacheMap.get(GroupMessageStatusChange.class).setProcessor((Consumer<?>) groupMessageStatusChangeProcessor);
|
||||
cacheMap.get(Message.class).setProcessor(receivedMessageProcessor);
|
||||
cacheMap.get(GroupMessage.class).setProcessor(receivedGroupMessageProcessor);
|
||||
|
||||
// Relay cached status changes
|
||||
cacheMap.get(MessageStatusChange.class).setProcessor(messageStatusChangeProcessor);
|
||||
cacheMap.get(GroupMessageStatusChange.class).setProcessor(groupMessageStatusChangeProcessor);
|
||||
|
||||
// Process user status changes
|
||||
receiver.registerProcessor(UserStatusChange.class, eventBus::dispatch);
|
||||
|
@ -79,9 +79,7 @@ public class Receiver extends Thread {
|
||||
@SuppressWarnings("rawtypes")
|
||||
final Consumer processor = processors.get(obj.getClass());
|
||||
if (processor == null)
|
||||
logger.log(Level.WARNING, String.format(
|
||||
"The received object has the %s for which no processor is defined.",
|
||||
obj.getClass()));
|
||||
logger.log(Level.WARNING, String.format("The received object has the %s for which no processor is defined.", obj.getClass()));
|
||||
else processor.accept(obj);
|
||||
}
|
||||
} catch (final SocketException e) {
|
||||
@ -103,6 +101,14 @@ public class Receiver extends Thread {
|
||||
*/
|
||||
public <T> void registerProcessor(Class<T> processorClass, Consumer<T> processor) { processors.put(processorClass, processor); }
|
||||
|
||||
/**
|
||||
* Adds a map of object processors to this {@link Receiver}.
|
||||
*
|
||||
* @param processors the processors to add the processors to add
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public void registerProcessors(Map<Class<?>, ? extends Consumer<?>> processors) { this.processors.putAll(processors); }
|
||||
|
||||
/**
|
||||
* Removes all object processors registered at this {@link Receiver}.
|
||||
*
|
||||
|
@ -2,7 +2,6 @@ package envoy.client.ui;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -100,7 +99,7 @@ public final class Startup extends Application {
|
||||
// Initialize client and unread message cache
|
||||
client = new Client();
|
||||
|
||||
final var cacheMap = new HashMap<Class<?>, Cache<?>>();
|
||||
final var cacheMap = new CacheMap();
|
||||
cacheMap.put(Message.class, new Cache<Message>());
|
||||
cacheMap.put(GroupMessage.class, new Cache<GroupMessage>());
|
||||
cacheMap.put(MessageStatusChange.class, new Cache<MessageStatusChange>());
|
||||
|
@ -2,7 +2,6 @@ package envoy.client.ui.controller;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -57,7 +56,7 @@ public final class LoginScene {
|
||||
|
||||
private Client client;
|
||||
private LocalDB localDB;
|
||||
private Map<Class<?>, Cache<?>> cacheMap;
|
||||
private CacheMap cacheMap;
|
||||
private SceneContext sceneContext;
|
||||
|
||||
private static final Logger logger = EnvoyLog.getLogger(LoginScene.class);
|
||||
@ -81,7 +80,7 @@ public final class LoginScene {
|
||||
* @param sceneContext the scene context used to initialize the chat scene
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public void initializeData(Client client, LocalDB localDB, Map<Class<?>, Cache<?>> cacheMap, SceneContext sceneContext) {
|
||||
public void initializeData(Client client, LocalDB localDB, CacheMap cacheMap, SceneContext sceneContext) {
|
||||
this.client = client;
|
||||
this.localDB = localDB;
|
||||
this.cacheMap = cacheMap;
|
||||
@ -198,6 +197,6 @@ public final class LoginScene {
|
||||
sceneContext.<ChatScene>getController().initializeData(sceneContext, localDB, client, writeProxy);
|
||||
|
||||
// Relay unread messages from cache
|
||||
if (client.isOnline()) cacheMap.values().forEach(cache -> { if (cache != null) cache.relay(); });
|
||||
if (client.isOnline()) cacheMap.getMap().values().forEach(cache -> { if (cache != null) cache.relay(); });
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user