You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
3.9 KiB
159 lines
3.9 KiB
11 years ago
|
package mightypork.utils.control.bus;
|
||
11 years ago
|
|
||
11 years ago
|
|
||
11 years ago
|
import java.util.Collection;
|
||
11 years ago
|
import java.util.HashSet;
|
||
11 years ago
|
|
||
11 years ago
|
import mightypork.utils.control.bus.clients.DelegatingClient;
|
||
|
import mightypork.utils.control.bus.clients.ToggleableClient;
|
||
11 years ago
|
import mightypork.utils.logging.Log;
|
||
11 years ago
|
|
||
|
|
||
|
/**
|
||
11 years ago
|
* Message channel, module of {@link EventBus}
|
||
11 years ago
|
*
|
||
|
* @author MightyPork
|
||
11 years ago
|
* @param <EVENT> message type
|
||
11 years ago
|
* @param <CLIENT> client (subscriber) type
|
||
11 years ago
|
*/
|
||
11 years ago
|
final public class EventChannel<EVENT extends Handleable<CLIENT>, CLIENT> {
|
||
11 years ago
|
|
||
11 years ago
|
private Class<CLIENT> clientClass;
|
||
11 years ago
|
private Class<EVENT> messageClass;
|
||
11 years ago
|
|
||
|
|
||
11 years ago
|
public EventChannel(Class<EVENT> messageClass, Class<CLIENT> clientClass) {
|
||
11 years ago
|
|
||
11 years ago
|
if (messageClass == null || clientClass == null) throw new NullPointerException("Null Message or Client class.");
|
||
11 years ago
|
|
||
11 years ago
|
this.clientClass = clientClass;
|
||
|
this.messageClass = messageClass;
|
||
|
}
|
||
11 years ago
|
|
||
|
|
||
11 years ago
|
/**
|
||
|
* Try to broadcast a message.<br>
|
||
|
* If message is of wrong type, <code>false</code> is returned.
|
||
|
*
|
||
11 years ago
|
* @param message a message to be sent
|
||
|
* @param clients collection of clients
|
||
11 years ago
|
* @return true if message was accepted by this channel
|
||
11 years ago
|
*/
|
||
11 years ago
|
public boolean broadcast(Object message, Collection<Object> clients)
|
||
11 years ago
|
{
|
||
|
if (!canBroadcast(message)) return false;
|
||
11 years ago
|
|
||
11 years ago
|
EVENT evt = messageClass.cast(message);
|
||
11 years ago
|
|
||
11 years ago
|
doBroadcast(evt, clients, new HashSet<Object>());
|
||
11 years ago
|
|
||
11 years ago
|
return true;
|
||
|
}
|
||
11 years ago
|
|
||
|
|
||
11 years ago
|
private void doBroadcast(EVENT message, Collection<Object> clients, Collection<Object> processed)
|
||
11 years ago
|
{
|
||
|
for (Object client : clients) {
|
||
11 years ago
|
|
||
11 years ago
|
// circular reference check
|
||
|
if (processed.contains(client)) {
|
||
|
Log.w("Client already served (subscribing twice?)");
|
||
|
continue;
|
||
|
}
|
||
|
processed.add(client);
|
||
11 years ago
|
|
||
11 years ago
|
// opt-out
|
||
|
if (client instanceof ToggleableClient) {
|
||
11 years ago
|
if (!((ToggleableClient) client).isListening()) {
|
||
11 years ago
|
continue;
|
||
|
}
|
||
|
}
|
||
11 years ago
|
|
||
11 years ago
|
sendTo(client, message);
|
||
11 years ago
|
|
||
11 years ago
|
if (client instanceof DelegatingClient) {
|
||
|
if (((DelegatingClient) client).doesDelegate()) {
|
||
|
doBroadcast(message, ((DelegatingClient) client).getChildClients(), processed);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
11 years ago
|
|
||
|
|
||
11 years ago
|
/**
|
||
11 years ago
|
* Send a message to a client.
|
||
11 years ago
|
*
|
||
11 years ago
|
* @param client target client
|
||
|
* @param message message to send
|
||
11 years ago
|
*/
|
||
11 years ago
|
@SuppressWarnings("unchecked")
|
||
11 years ago
|
private void sendTo(Object client, EVENT message)
|
||
11 years ago
|
{
|
||
11 years ago
|
if (clientClass.isInstance(client)) {
|
||
|
((Handleable<CLIENT>) message).handleBy((CLIENT) client);
|
||
|
}
|
||
11 years ago
|
}
|
||
11 years ago
|
|
||
|
|
||
11 years ago
|
/**
|
||
|
* Check if the given message can be broadcasted by this
|
||
11 years ago
|
* {@link EventChannel}
|
||
11 years ago
|
*
|
||
11 years ago
|
* @param message event object
|
||
11 years ago
|
* @return can be broadcasted
|
||
|
*/
|
||
11 years ago
|
public boolean canBroadcast(Object message)
|
||
11 years ago
|
{
|
||
11 years ago
|
return message != null && messageClass.isInstance(message);
|
||
11 years ago
|
}
|
||
11 years ago
|
|
||
|
|
||
11 years ago
|
@Override
|
||
|
public int hashCode()
|
||
|
{
|
||
11 years ago
|
final int prime = 13;
|
||
11 years ago
|
int result = 1;
|
||
11 years ago
|
result = prime * result + ((clientClass == null) ? 0 : clientClass.hashCode());
|
||
|
result = prime * result + ((messageClass == null) ? 0 : messageClass.hashCode());
|
||
11 years ago
|
return result;
|
||
|
}
|
||
11 years ago
|
|
||
|
|
||
11 years ago
|
@Override
|
||
|
public boolean equals(Object obj)
|
||
|
{
|
||
|
if (this == obj) return true;
|
||
|
if (obj == null) return false;
|
||
11 years ago
|
if (!(obj instanceof EventChannel)) return false;
|
||
|
EventChannel<?, ?> other = (EventChannel<?, ?>) obj;
|
||
11 years ago
|
if (clientClass == null) {
|
||
|
if (other.clientClass != null) return false;
|
||
|
} else if (!clientClass.equals(other.clientClass)) return false;
|
||
|
if (messageClass == null) {
|
||
|
if (other.messageClass != null) return false;
|
||
|
} else if (!messageClass.equals(other.messageClass)) return false;
|
||
11 years ago
|
return true;
|
||
|
}
|
||
11 years ago
|
|
||
|
|
||
11 years ago
|
@Override
|
||
|
public String toString()
|
||
|
{
|
||
11 years ago
|
return "CHANNEL( " + messageClass.getSimpleName() + " -> " + clientClass.getSimpleName() + " )";
|
||
11 years ago
|
}
|
||
11 years ago
|
|
||
|
|
||
11 years ago
|
/**
|
||
|
* Create an instance for given types
|
||
|
*
|
||
11 years ago
|
* @param messageClass event class
|
||
|
* @param clientClass client class
|
||
11 years ago
|
* @return the broadcaster
|
||
|
*/
|
||
11 years ago
|
public static <F_EVENT extends Handleable<F_CLIENT>, F_CLIENT> EventChannel<F_EVENT, F_CLIENT> create(Class<F_EVENT> messageClass, Class<F_CLIENT> clientClass)
|
||
11 years ago
|
{
|
||
11 years ago
|
return new EventChannel<F_EVENT, F_CLIENT>(messageClass, clientClass);
|
||
11 years ago
|
}
|
||
11 years ago
|
|
||
11 years ago
|
}
|