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) {