From a1922ff7881ff45a21133589d19d543eeef57dfc Mon Sep 17 00:00:00 2001
From: nathan
Date: Sat, 20 Jun 2015 01:53:32 +0200
Subject: [PATCH] Code polish and refactor to support multiple types of
publishing and subscribing
---
src/dorkbox/util/messagebus/MessageBus.java | 7 +-
.../Publisher.java | 2 +-
.../publication/PublisherAll_MultiArg.java | 1 -
...PublisherExactWithSuperTypes_FirstArg.java | 26 ++++--
...PublisherExactWithSuperTypes_MultiArg.java | 1 -
.../publication/PublisherExact_FirstArg.java | 38 +++++---
.../publication/PublisherExact_MultiArg.java | 1 -
.../subscription/FirstArgSubscriber.java | 91 ++++++-------------
.../subscription/MultiArgSubscriber.java | 6 +-
.../messagebus/subscription/Subscriber.java | 2 +-
.../subscription/SubscriptionManager.java | 4 +-
11 files changed, 86 insertions(+), 93 deletions(-)
rename src/dorkbox/util/messagebus/{subscription => publication}/Publisher.java (83%)
diff --git a/src/dorkbox/util/messagebus/MessageBus.java b/src/dorkbox/util/messagebus/MessageBus.java
index 439ca8d..361c2ce 100644
--- a/src/dorkbox/util/messagebus/MessageBus.java
+++ b/src/dorkbox/util/messagebus/MessageBus.java
@@ -9,7 +9,10 @@ import dorkbox.util.messagebus.error.DefaultErrorHandler;
import dorkbox.util.messagebus.error.ErrorHandlingSupport;
import dorkbox.util.messagebus.error.PublicationError;
import dorkbox.util.messagebus.publication.*;
-import dorkbox.util.messagebus.subscription.*;
+import dorkbox.util.messagebus.subscription.FirstArgSubscriber;
+import dorkbox.util.messagebus.subscription.MultiArgSubscriber;
+import dorkbox.util.messagebus.subscription.Subscriber;
+import dorkbox.util.messagebus.subscription.SubscriptionManager;
import dorkbox.util.messagebus.utils.ClassUtils;
import org.jctools.util.Pow2;
@@ -71,7 +74,7 @@ public class MessageBus implements IMessageBus {
subscriber = new MultiArgSubscriber(errorHandler, classUtils);
}
else {
- subscriber = new FirstArgSubscriber(errorHandler, classUtils);
+ subscriber = new FirstArgSubscriber(errorHandler);
}
switch (publishMode) {
diff --git a/src/dorkbox/util/messagebus/subscription/Publisher.java b/src/dorkbox/util/messagebus/publication/Publisher.java
similarity index 83%
rename from src/dorkbox/util/messagebus/subscription/Publisher.java
rename to src/dorkbox/util/messagebus/publication/Publisher.java
index 7953086..d63c720 100644
--- a/src/dorkbox/util/messagebus/subscription/Publisher.java
+++ b/src/dorkbox/util/messagebus/publication/Publisher.java
@@ -1,4 +1,4 @@
-package dorkbox.util.messagebus.subscription;
+package dorkbox.util.messagebus.publication;
public interface Publisher {
void publish(Object message1);
diff --git a/src/dorkbox/util/messagebus/publication/PublisherAll_MultiArg.java b/src/dorkbox/util/messagebus/publication/PublisherAll_MultiArg.java
index 24b2b1c..e19ee38 100644
--- a/src/dorkbox/util/messagebus/publication/PublisherAll_MultiArg.java
+++ b/src/dorkbox/util/messagebus/publication/PublisherAll_MultiArg.java
@@ -4,7 +4,6 @@ import dorkbox.util.messagebus.common.DeadMessage;
import dorkbox.util.messagebus.common.adapter.StampedLock;
import dorkbox.util.messagebus.error.ErrorHandlingSupport;
import dorkbox.util.messagebus.error.PublicationError;
-import dorkbox.util.messagebus.subscription.Publisher;
import dorkbox.util.messagebus.subscription.Subscriber;
import dorkbox.util.messagebus.subscription.Subscription;
import dorkbox.util.messagebus.utils.VarArgUtils;
diff --git a/src/dorkbox/util/messagebus/publication/PublisherExactWithSuperTypes_FirstArg.java b/src/dorkbox/util/messagebus/publication/PublisherExactWithSuperTypes_FirstArg.java
index e0dd54d..012c9ed 100644
--- a/src/dorkbox/util/messagebus/publication/PublisherExactWithSuperTypes_FirstArg.java
+++ b/src/dorkbox/util/messagebus/publication/PublisherExactWithSuperTypes_FirstArg.java
@@ -4,7 +4,6 @@ import dorkbox.util.messagebus.common.DeadMessage;
import dorkbox.util.messagebus.common.adapter.StampedLock;
import dorkbox.util.messagebus.error.ErrorHandlingSupport;
import dorkbox.util.messagebus.error.PublicationError;
-import dorkbox.util.messagebus.subscription.Publisher;
import dorkbox.util.messagebus.subscription.Subscriber;
import dorkbox.util.messagebus.subscription.Subscription;
@@ -79,13 +78,15 @@ public class PublisherExactWithSuperTypes_FirstArg implements Publisher {
// Run subscriptions
if (subscriptions != null) {
+ Class>[] handledMessages;
Subscription sub;
for (int i = 0; i < subscriptions.length; i++) {
sub = subscriptions[i];
- final Class>[] handledMessages = sub.getHandler().getHandledMessages();
-
- sub.publish(message1, message2);
+ handledMessages = sub.getHandler().getHandledMessages();
+ if (handledMessages.length == 2) {
+ sub.publish(message1, message2);
+ }
}
}
else {
@@ -122,10 +123,15 @@ public class PublisherExactWithSuperTypes_FirstArg implements Publisher {
// Run subscriptions
if (subscriptions != null) {
+ Class>[] handledMessages;
Subscription sub;
for (int i = 0; i < subscriptions.length; i++) {
sub = subscriptions[i];
- sub.publish(message1, message2, message3);
+
+ handledMessages = sub.getHandler().getHandledMessages();
+ if (handledMessages.length == 3) {
+ sub.publish(message1, message2, message3);
+ }
}
}
else {
@@ -155,7 +161,8 @@ public class PublisherExactWithSuperTypes_FirstArg implements Publisher {
try {
final Object message1 = messages[0];
final Class> messageClass = message1.getClass();
- final Object[] newMessages = Arrays.copyOfRange(messages, 1, messages.length);
+ final int length = messages.length;
+ final Object[] newMessages = Arrays.copyOfRange(messages, 1, length);
final StampedLock lock = this.lock;
long stamp = lock.readLock();
@@ -164,10 +171,15 @@ public class PublisherExactWithSuperTypes_FirstArg implements Publisher {
// Run subscriptions
if (subscriptions != null) {
+ Class>[] handledMessages;
Subscription sub;
for (int i = 0; i < subscriptions.length; i++) {
sub = subscriptions[i];
- sub.publish(message1, newMessages);
+
+ handledMessages = sub.getHandler().getHandledMessages();
+ if (handledMessages.length == length) {
+ sub.publish(message1, newMessages);
+ }
}
}
else {
diff --git a/src/dorkbox/util/messagebus/publication/PublisherExactWithSuperTypes_MultiArg.java b/src/dorkbox/util/messagebus/publication/PublisherExactWithSuperTypes_MultiArg.java
index 84267ac..8f519f7 100644
--- a/src/dorkbox/util/messagebus/publication/PublisherExactWithSuperTypes_MultiArg.java
+++ b/src/dorkbox/util/messagebus/publication/PublisherExactWithSuperTypes_MultiArg.java
@@ -4,7 +4,6 @@ import dorkbox.util.messagebus.common.DeadMessage;
import dorkbox.util.messagebus.common.adapter.StampedLock;
import dorkbox.util.messagebus.error.ErrorHandlingSupport;
import dorkbox.util.messagebus.error.PublicationError;
-import dorkbox.util.messagebus.subscription.Publisher;
import dorkbox.util.messagebus.subscription.Subscriber;
import dorkbox.util.messagebus.subscription.Subscription;
diff --git a/src/dorkbox/util/messagebus/publication/PublisherExact_FirstArg.java b/src/dorkbox/util/messagebus/publication/PublisherExact_FirstArg.java
index d2900fe..8853c84 100644
--- a/src/dorkbox/util/messagebus/publication/PublisherExact_FirstArg.java
+++ b/src/dorkbox/util/messagebus/publication/PublisherExact_FirstArg.java
@@ -4,12 +4,9 @@ import dorkbox.util.messagebus.common.DeadMessage;
import dorkbox.util.messagebus.common.adapter.StampedLock;
import dorkbox.util.messagebus.error.ErrorHandlingSupport;
import dorkbox.util.messagebus.error.PublicationError;
-import dorkbox.util.messagebus.subscription.Publisher;
import dorkbox.util.messagebus.subscription.Subscriber;
import dorkbox.util.messagebus.subscription.Subscription;
-import java.util.Arrays;
-
public class PublisherExact_FirstArg implements Publisher {
private final ErrorHandlingSupport errorHandler;
private final Subscriber subscriber;
@@ -33,10 +30,15 @@ public class PublisherExact_FirstArg implements Publisher {
// Run subscriptions
if (subscriptions != null) {
+ Class>[] handledMessages;
Subscription sub;
for (int i = 0; i < subscriptions.length; i++) {
sub = subscriptions[i];
- sub.publish(message1);
+
+ handledMessages = sub.getHandler().getHandledMessages();
+ if (handledMessages.length == 1) {
+ sub.publish(message1);
+ }
}
}
else {
@@ -73,10 +75,15 @@ public class PublisherExact_FirstArg implements Publisher {
// Run subscriptions
if (subscriptions != null) {
+ Class>[] handledMessages;
Subscription sub;
for (int i = 0; i < subscriptions.length; i++) {
sub = subscriptions[i];
- sub.publish(message1, message2);
+
+ handledMessages = sub.getHandler().getHandledMessages();
+ if (handledMessages.length == 2) {
+ sub.publish(message1, message2);
+ }
}
}
else {
@@ -113,10 +120,15 @@ public class PublisherExact_FirstArg implements Publisher {
// Run subscriptions
if (subscriptions != null) {
+ Class>[] handledMessages;
Subscription sub;
for (int i = 0; i < subscriptions.length; i++) {
sub = subscriptions[i];
- sub.publish(message1, message2, message3);
+
+ handledMessages = sub.getHandler().getHandledMessages();
+ if (handledMessages.length == 3) {
+ sub.publish(message1, message2, message3);
+ }
}
}
else {
@@ -144,9 +156,8 @@ public class PublisherExact_FirstArg implements Publisher {
@Override
public void publish(final Object[] messages) {
try {
- final Object message1 = messages[0];
- final Class> messageClass = message1.getClass();
- final Object[] newMessages = Arrays.copyOfRange(messages, 1, messages.length);
+ final Class> messageClass = messages[0].getClass();
+ final int length = messages.length;
final StampedLock lock = this.lock;
long stamp = lock.readLock();
@@ -155,10 +166,15 @@ public class PublisherExact_FirstArg implements Publisher {
// Run subscriptions
if (subscriptions != null) {
+ Class>[] handledMessages;
Subscription sub;
for (int i = 0; i < subscriptions.length; i++) {
sub = subscriptions[i];
- sub.publish(message1, newMessages);
+
+ handledMessages = sub.getHandler().getHandledMessages();
+ if (handledMessages.length == length) {
+ sub.publish(messages);
+ }
}
}
else {
@@ -168,7 +184,7 @@ public class PublisherExact_FirstArg implements Publisher {
lock.unlockRead(stamp);
if (deadSubscriptions != null) {
- final DeadMessage deadMessage = new DeadMessage(message1, newMessages);
+ final DeadMessage deadMessage = new DeadMessage(messages);
Subscription sub;
for (int i = 0; i < deadSubscriptions.length; i++) {
diff --git a/src/dorkbox/util/messagebus/publication/PublisherExact_MultiArg.java b/src/dorkbox/util/messagebus/publication/PublisherExact_MultiArg.java
index 5199ebd..0f9066c 100644
--- a/src/dorkbox/util/messagebus/publication/PublisherExact_MultiArg.java
+++ b/src/dorkbox/util/messagebus/publication/PublisherExact_MultiArg.java
@@ -4,7 +4,6 @@ import dorkbox.util.messagebus.common.DeadMessage;
import dorkbox.util.messagebus.common.adapter.StampedLock;
import dorkbox.util.messagebus.error.ErrorHandlingSupport;
import dorkbox.util.messagebus.error.PublicationError;
-import dorkbox.util.messagebus.subscription.Publisher;
import dorkbox.util.messagebus.subscription.Subscriber;
import dorkbox.util.messagebus.subscription.Subscription;
diff --git a/src/dorkbox/util/messagebus/subscription/FirstArgSubscriber.java b/src/dorkbox/util/messagebus/subscription/FirstArgSubscriber.java
index db1304d..c9e0537 100644
--- a/src/dorkbox/util/messagebus/subscription/FirstArgSubscriber.java
+++ b/src/dorkbox/util/messagebus/subscription/FirstArgSubscriber.java
@@ -3,7 +3,6 @@ package dorkbox.util.messagebus.subscription;
import dorkbox.util.messagebus.common.MessageHandler;
import dorkbox.util.messagebus.common.adapter.JavaVersionAdapter;
import dorkbox.util.messagebus.error.ErrorHandlingSupport;
-import dorkbox.util.messagebus.utils.ClassUtils;
import dorkbox.util.messagebus.utils.VarArgUtils;
import java.util.ArrayList;
@@ -14,6 +13,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
/**
* Permits subscriptions that only use the first parameters as the signature. The publisher MUST provide the correct additional parameters,
* and they must be of the correct type, otherwise it will throw an error.
+ *
+ * Parameter length checking during publication is performed, so that you can have multiple handlers with the same signature, but each
+ * with a different number of parameters
*/
public class FirstArgSubscriber implements Subscriber {
@@ -24,82 +26,47 @@ public class FirstArgSubscriber implements Subscriber {
// write access is synchronized and happens only when a listener of a specific class is registered the first time
// the following are used ONLY for FIRST ARG subscription/publication. (subscriptionsPerMessageMulti isn't used in this case)
- private final Map, ArrayList> subscriptionsPerMessageSingle_1;
- private final Map, ArrayList> subscriptionsPerMessageSingle_2;
- private final Map, ArrayList> subscriptionsPerMessageSingle_3;
+ private final Map, ArrayList> subscriptionsPerMessage;
- public FirstArgSubscriber(final ErrorHandlingSupport errorHandler, final ClassUtils classUtils) {
+ public FirstArgSubscriber(final ErrorHandlingSupport errorHandler) {
this.errorHandler = errorHandler;
// the following are used ONLY for FIRST ARG subscription/publication. (subscriptionsPerMessageMulti isn't used in this case)
- this.subscriptionsPerMessageSingle_1 = JavaVersionAdapter.get.concurrentMap(32, LOAD_FACTOR, 1);
- this.subscriptionsPerMessageSingle_2 = JavaVersionAdapter.get.concurrentMap(32, LOAD_FACTOR, 1);
- this.subscriptionsPerMessageSingle_3 = JavaVersionAdapter.get.concurrentMap(32, LOAD_FACTOR, 1);
+ this.subscriptionsPerMessage = JavaVersionAdapter.get.concurrentMap(32, LOAD_FACTOR, 1);
}
// inside a write lock
// add this subscription to each of the handled types
// to activate this sub for publication
private void registerFirst(final Subscription subscription, final Class> listenerClass,
- final Map, ArrayList> subs_1, final Map, ArrayList> subs_2,
- final Map, ArrayList> subs_3) {
+ final Map, ArrayList> subscriptions) {
final MessageHandler handler = subscription.getHandler();
final Class>[] messageHandlerTypes = handler.getHandledMessages();
final int size = messageHandlerTypes.length;
- Class> type0 = messageHandlerTypes[0];
-
- switch (size) {
- case 1: {
- ArrayList subs = subs_1.get(type0);
- if (subs == null) {
- subs = new ArrayList();
-
- subs_1.put(type0, subs);
- }
-
- subs.add(subscription);
- return;
- }
- case 2: {
- ArrayList subs = subs_2.get(type0);
- if (subs == null) {
- subs = new ArrayList();
-
- subs_2.put(type0, subs);
- }
-
- subs.add(subscription);
- return;
- }
- case 3: {
- ArrayList subs = subs_3.get(type0);
- if (subs == null) {
- subs = new ArrayList();
-
- subs_3.put(type0, subs);
- }
-
- subs.add(subscription);
- return;
- }
- case 0:
- default: {
- errorHandler.handleError("Error while trying to subscribe class", listenerClass);
- return;
- }
+ if (size == 0) {
+ errorHandler.handleError("Error while trying to subscribe class", listenerClass);
+ return;
}
+
+ final Class> type0 = messageHandlerTypes[0];
+
+ ArrayList subs = subscriptions.get(type0);
+ if (subs == null) {
+ subs = new ArrayList();
+
+ subscriptions.put(type0, subs);
+ }
+
+ subs.add(subscription);
}
@Override
public void register(final Class> listenerClass, final int handlersSize, final Subscription[] subsPerListener) {
- final Map, ArrayList> sub_1 = this.subscriptionsPerMessageSingle_1;
- final Map, ArrayList> sub_2 = this.subscriptionsPerMessageSingle_2;
- final Map, ArrayList> sub_3 = this.subscriptionsPerMessageSingle_3;
-
+ final Map, ArrayList> subscriptions = this.subscriptionsPerMessage;
Subscription subscription;
@@ -110,7 +77,7 @@ public class FirstArgSubscriber implements Subscriber {
// now add this subscription to each of the handled types
// only register based on the FIRST parameter
- registerFirst(subscription, listenerClass, sub_1, sub_2, sub_3);
+ registerFirst(subscription, listenerClass, subscriptions);
}
}
@@ -126,30 +93,28 @@ public class FirstArgSubscriber implements Subscriber {
@Override
public void shutdown() {
- this.subscriptionsPerMessageSingle_1.clear();
- this.subscriptionsPerMessageSingle_2.clear();
- this.subscriptionsPerMessageSingle_3.clear();
+ this.subscriptionsPerMessage.clear();
}
@Override
- public void clearConcurrentCollections() {
+ public void clear() {
}
@Override
public ArrayList getExactAsArray(final Class> messageClass) {
- return subscriptionsPerMessageSingle_1.get(messageClass);
+ return subscriptionsPerMessage.get(messageClass);
}
@Override
public ArrayList getExactAsArray(final Class> messageClass1, final Class> messageClass2) {
- return subscriptionsPerMessageSingle_2.get(messageClass1);
+ return subscriptionsPerMessage.get(messageClass1);
}
@Override
public ArrayList getExactAsArray(final Class> messageClass1, final Class> messageClass2,
final Class> messageClass3) {
- return subscriptionsPerMessageSingle_3.get(messageClass1);
+ return subscriptionsPerMessage.get(messageClass1);
}
@Override
diff --git a/src/dorkbox/util/messagebus/subscription/MultiArgSubscriber.java b/src/dorkbox/util/messagebus/subscription/MultiArgSubscriber.java
index b772310..373bf86 100644
--- a/src/dorkbox/util/messagebus/subscription/MultiArgSubscriber.java
+++ b/src/dorkbox/util/messagebus/subscription/MultiArgSubscriber.java
@@ -55,7 +55,7 @@ public class MultiArgSubscriber implements Subscriber {
}
@Override
- public void clearConcurrentCollections() {
+ public void clear() {
this.subUtils.clear();
this.varArgUtils.clear();
}
@@ -72,7 +72,7 @@ public class MultiArgSubscriber implements Subscriber {
final Class>[] messageHandlerTypes = handler.getHandledMessages();
final int size = messageHandlerTypes.length;
- Class> type0 = messageHandlerTypes[0];
+ final Class> type0 = messageHandlerTypes[0];
switch (size) {
case 0: {
@@ -153,7 +153,7 @@ public class MultiArgSubscriber implements Subscriber {
this.subscriptionsPerMessageSingle.clear();
this.subscriptionsPerMessageMulti.clear();
- clearConcurrentCollections();
+ clear();
}
@Override
diff --git a/src/dorkbox/util/messagebus/subscription/Subscriber.java b/src/dorkbox/util/messagebus/subscription/Subscriber.java
index c7d1e1d..f438986 100644
--- a/src/dorkbox/util/messagebus/subscription/Subscriber.java
+++ b/src/dorkbox/util/messagebus/subscription/Subscriber.java
@@ -16,7 +16,7 @@ public interface Subscriber {
void shutdown();
- void clearConcurrentCollections();
+ void clear();
ArrayList getExactAsArray(Class> superClass);
diff --git a/src/dorkbox/util/messagebus/subscription/SubscriptionManager.java b/src/dorkbox/util/messagebus/subscription/SubscriptionManager.java
index e088a66..586c874 100644
--- a/src/dorkbox/util/messagebus/subscription/SubscriptionManager.java
+++ b/src/dorkbox/util/messagebus/subscription/SubscriptionManager.java
@@ -64,7 +64,7 @@ public final class SubscriptionManager {
}
// these are concurrent collections
- subscriber.clearConcurrentCollections();
+ subscriber.clear();
Subscription[] subscriptions = getListenerSubs(listenerClass);
@@ -145,7 +145,7 @@ public final class SubscriptionManager {
}
// these are concurrent collections
- subscriber.clearConcurrentCollections();
+ subscriber.clear();
final Subscription[] subscriptions = getListenerSubs(listenerClass);
if (subscriptions != null) {