Added tools (for allowing endpoints to directly talk to eachother outside of messages)

This commit is contained in:
nathan 2014-09-29 23:42:32 +02:00
parent 687482309e
commit 913dae7933
3 changed files with 68 additions and 4 deletions

View File

@ -304,7 +304,9 @@ public abstract class EndPoint {
} }
/** /**
* Closes all connections ONLY (keeps the server/client running) * Closes all connections ONLY (keeps the server/client running).
* <p>
* This is used, for example, when reconnecting to a server. The server should ALWAYS use STOP.
*/ */
public void close() { public void close() {
// give a chance to other threads. // give a chance to other threads.
@ -328,7 +330,7 @@ public abstract class EndPoint {
/** /**
* Safely closes all associated resources/threads/connections * Safely closes all associated resources/threads/connections
*/ */
public final void stop() { public void stop() {
// check to make sure we are in our OWN thread, otherwise, this thread will never exit -- because it will wait indefinitely // check to make sure we are in our OWN thread, otherwise, this thread will never exit -- because it will wait indefinitely
// for itself to finish (since it blocks itself). // for itself to finish (since it blocks itself).
// This occurs when calling stop from within a listener callback. // This occurs when calling stop from within a listener callback.
@ -442,7 +444,7 @@ public abstract class EndPoint {
/** /**
* Extra actions to perform when stopping this endpoint. * Extra actions to perform when stopping this endpoint.
*/ */
protected void stopExtraActions() { void stopExtraActions() {
} }
public String getName() { public String getName() {

View File

@ -5,6 +5,7 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters;
@ -23,6 +24,7 @@ import dorkbox.network.connection.wrapper.ChannelWrapper;
import dorkbox.network.pipeline.KryoEncoder; import dorkbox.network.pipeline.KryoEncoder;
import dorkbox.network.pipeline.KryoEncoderCrypto; import dorkbox.network.pipeline.KryoEncoderCrypto;
import dorkbox.network.rmi.RmiBridge; import dorkbox.network.rmi.RmiBridge;
import dorkbox.network.util.EndpointTool;
import dorkbox.network.util.KryoSerializationManager; import dorkbox.network.util.KryoSerializationManager;
import dorkbox.network.util.SerializationManager; import dorkbox.network.util.SerializationManager;
import dorkbox.network.util.exceptions.InitializationException; import dorkbox.network.util.exceptions.InitializationException;
@ -228,6 +230,8 @@ public abstract class EndPointWithSerialization extends EndPoint {
/** /**
* Closes all connections ONLY (keeps the server/client running) * Closes all connections ONLY (keeps the server/client running)
* <p>
* This is used, for example, when reconnecting to a server. The server should ALWAYS use STOP.
*/ */
@Override @Override
public void close() { public void close() {
@ -241,7 +245,60 @@ public abstract class EndPointWithSerialization extends EndPoint {
* Extra actions to perform when stopping this endpoint. * Extra actions to perform when stopping this endpoint.
*/ */
@Override @Override
protected void stopExtraActions() { final void stopExtraActions() {
this.connectionManager.stop(); this.connectionManager.stop();
} }
ConcurrentHashMap<Class<?>, EndpointTool> toolMap = new ConcurrentHashMap<Class<?>, EndpointTool>();
/**
* Registers a tool with the server, to be used by other services.
*/
public void registerTool(EndpointTool toolClass) {
if (toolClass == null) {
throw new IllegalArgumentException("Tool must not be null! Unable to add tool");
}
Class<?>[] interfaces = toolClass.getClass().getInterfaces();
int length = interfaces.length;
int index = -1;
if (length > 1) {
Class<?> clazz2;
Class<EndpointTool> cls = EndpointTool.class;
for (int i=0;i<length;i++) {
clazz2 = interfaces[i];
if (cls.isAssignableFrom(clazz2)) {
index = i;
break;
}
}
if (index == -1) {
throw new IllegalArgumentException("Unable to discover tool interface! WHOOPS!");
}
} else {
index = 0;
}
Class<?> clazz = interfaces[index];
EndpointTool put = this.toolMap.put(clazz, toolClass);
if (put != null) {
throw new IllegalArgumentException("Tool must be unique! Unable to add tool");
}
}
/**
* Only get the tools in the ModuleStart (ie: load) methods. If done in the constructor, the tool might not be available yet
*/
public <T extends EndpointTool> T getTool(Class<?> toolClass) {
if (toolClass == null) {
throw new IllegalArgumentException("Tool must not be null! Unable to add tool");
}
@SuppressWarnings("unchecked")
T tool = (T) this.toolMap.get(toolClass);
return tool;
}
} }

View File

@ -0,0 +1,5 @@
package dorkbox.network.util;
public interface EndpointTool {
}