i feel alike, all new registrations are delayed until the end of firing (depth=0) .. so nothing will happen if firing those new events before the end .. depth behaves like a lock for concurrency, but not really necessary for single-thread JavaScript ..
On Jul 27, 9:58 am, "[email protected]" <[email protected]> wrote: > thanks, committed patch here :http://gwt-code-reviews.appspot.com/1500804/ > > On 26 juil, 22:43, Gal Dolber <[email protected]> wrote: > > > > > > > > > I am, but your post is too long to read :) > > > For what I understood, I had a similar problem, and I solved it > > encapsulating the "create widgetC" in a DeferredCommand (for your example). > > > Its really hard for me to understand the modification you purpose, maybe > > someone from google could see it. > > But I think that if you found a better way of doing something you should > > send a patch and make us all > > happyhttp://code.google.com/webtoolkit/makinggwtbetter.html(alsoyou will get > > more help in gwt-code-reviews.appspot.com than here) > > > Regards! > > > // on the WidgetA.EventType reception is decided to create a widget C > > create widgetC > > > On Tue, Jul 26, 2011 at 5:11 PM, [email protected] < > > > [email protected]> wrote: > > > No body concerned ? > > > > On 25 juil, 10:50, "[email protected]" <[email protected]> > > > wrote: > > > > Hi, > > > > > I'm facing a problem when using the simple implementation of the > > > > EventBus. > > > > > // register widget B to be notified when WidgetA trigger an event > > > > register handler of WidgetB on WidgetA.EventType > > > > > // dispatch (firingDepth is incremented) > > > > WidgetA.fireEvent > > > > > // my widget is really called !!! that's good news > > > > WidgetB.onWidgetAEvent > > > > > // on the WidgetA.EventType reception is decided to create a widget C > > > > create widgetC > > > > > // this widget register himself to be notified on widgetB events -> > > > > here the widget is registered in the deferredDeltas map (enqueueing) > > > > register handler of widgetC on WidgetB.EventType > > > > > // widget B fired an event which is never trapped by the widget C > > > > because the handler of Widget C is in the deferredDeltas AND > > > > firingDepth is not 0 > > > > WidgetB.fireEvent > > > > > I'm doubtful because I was expected Widget C to receive event from > > > > Widget B. A work around is to encapsulate the WidgetB.fireEvent into a > > > > DeferredCommand but it's not really a solution. > > > > > An other solution is to reconsider the usage of firingDepth, I don't > > > > really know why it is used (actually I know, but avoid concurrency > > > > modification that way leads to the upper that strange behavior). > > > > In simple implementation (thread safe) will be to get rid of the usage > > > > of this firingDepth/deferredDeltas and that getHandlerList return a > > > > copy of the handlers to go through and that's it: > > > > We insert directly the handler when they request for registration and > > > > we fire on the current map of handlers > > > > > Below is a possible implementation of what I think is a better > > > > implementation (behaviorally speaking) : > > > > > package com.google.web.bindery.event.shared; > > > > > import java.util.ArrayList; > > > > import java.util.Collections; > > > > import java.util.HashMap; > > > > import java.util.HashSet; > > > > import java.util.List; > > > > import java.util.ListIterator; > > > > import java.util.Map; > > > > import java.util.Set; > > > > > import com.google.web.bindery.event.shared.Event.Type; > > > > > public class MySimpleEventBus extends EventBus { > > > > > private final boolean isReverseOrder; > > > > > /** > > > > * Map of event type to map of event source to list of their > > > > handlers. > > > > */ > > > > private final Map<Event.Type<?>, Map<Object, List<?>>> map = > > > > new HashMap<Event.Type<?>, Map<Object, List<?>>>(); > > > > > public MySimpleEventBus() { > > > > this(false); > > > > } > > > > > /** > > > > * Allows creation of an instance that fires its handlers in the > > > > reverse of > > > > * the order in which they were added, although filtered handlers > > > > all fire > > > > * before unfiltered handlers. > > > > * <p> > > > > * > > > > * @deprecated This is a legacy feature, required by GWT's old > > > > HandlerManager. > > > > * Reverse order is not honored for handlers tied to a > > > > specific > > > > * event source (via {@link #addHandlerToSource}. > > > > */ > > > > @Deprecated > > > > protected MySimpleEventBus(boolean fireInReverseOrder) { > > > > isReverseOrder = fireInReverseOrder; > > > > } > > > > > @Override > > > > public <H> HandlerRegistration addHandler(Type<H> type, H handler) > > > > { > > > > return doAdd(type, null, handler); > > > > } > > > > > @Override > > > > public <H> HandlerRegistration addHandlerToSource(final > > > > Event.Type<H> type, final Object source, > > > > final H handler) { > > > > if (source == null) { > > > > throw new NullPointerException("Cannot add a handler with a > > > > null source"); > > > > } > > > > > return doAdd(type, source, handler); > > > > } > > > > > @Override > > > > public void fireEvent(Event<?> event) { > > > > doFire(event, null); > > > > } > > > > > @Override > > > > public void fireEventFromSource(Event<?> event, Object source) { > > > > if (source == null) { > > > > throw new NullPointerException("Cannot fire from a null > > > > source"); > > > > } > > > > doFire(event, source); > > > > } > > > > > /** > > > > * @deprecated required by legacy features in GWT's old > > > > HandlerManager > > > > */ > > > > @Deprecated > > > > protected <H> void doRemove(Event.Type<H> type, Object source, H > > > > handler) { > > > > doRemoveNow(type, source, handler); > > > > } > > > > > /** > > > > * @deprecated required by legacy features in GWT's old > > > > HandlerManager > > > > */ > > > > @Deprecated > > > > protected <H> H getHandler(Event.Type<H> type, int index) { > > > > assert index < getHandlerCount(type) : "handlers for " + > > > > type.getClass() + " have size: " > > > > + getHandlerCount(type) + " so do not have a handler at > > > > index: " + index; > > > > > List<H> l = getHandlerList(type, null); > > > > return l.get(index); > > > > } > > > > > /** > > > > * @deprecated required by legacy features in GWT's old > > > > HandlerManager > > > > */ > > > > @Deprecated > > > > protected int getHandlerCount(Event.Type<?> eventKey) { > > > > return getHandlerList(eventKey, null).size(); > > > > } > > > > > /** > > > > * @deprecated required by legacy features in GWT's old > > > > HandlerManager > > > > */ > > > > @Deprecated > > > > protected boolean isEventHandled(Event.Type<?> eventKey) { > > > > return map.containsKey(eventKey); > > > > } > > > > > private <H> HandlerRegistration doAdd(final Event.Type<H> type, > > > > final Object source, > > > > final H handler) { > > > > if (type == null) { > > > > throw new NullPointerException("Cannot add a handler with a > > > > null type"); > > > > } > > > > if (handler == null) { > > > > throw new NullPointerException("Cannot add a null handler"); > > > > } > > > > > doAddNow(type, source, handler); > > > > > return new HandlerRegistration() { > > > > public void removeHandler() { > > > > doRemove(type, source, handler); > > > > } > > > > }; > > > > } > > > > > private <H> void doAddNow(Event.Type<H> type, Object source, H > > > > handler) { > > > > List<H> l = ensureHandlerList(type, source); > > > > l.add(handler); > > > > } > > > > > private <H> void doFire(Event<H> event, Object source) { > > > > if (event == null) { > > > > throw new NullPointerException("Cannot fire null event"); > > > > } > > > > try { > > > > > if (source != null) { > > > > event.setSource(source); > > > > } > > > > > List<H> handlers = getDispatchList(event.getAssociatedType(), > > > > source); > > > > Set<Throwable> causes = null; > > > > > ListIterator<H> it = > > > > isReverseOrder ? handlers.listIterator(handlers.size()) : > > > > handlers.listIterator(); > > > > while (isReverseOrder ? it.hasPrevious() : it.hasNext()) { > > > > H handler = isReverseOrder ? it.previous() : it.next(); > > > > > try { > > > > event.dispatch(handler); > > > > } catch (Throwable e) { > > > > if (causes == null) { > > > > causes = new HashSet<Throwable>(); > > > > } > > > > causes.add(e); > > > > } > > > > } > > > > > if (causes != null) { > > > > throw new UmbrellaException(causes); > > > > } > > > > } finally { > > > > // no more to do > > > > } > > > > } > > > > > private <H> void doRemoveNow(Event.Type<H> type, Object source, H > > > > handler) { > > > > List<H> l = getHandlerList(type, source); > > > > > boolean removed = l.remove(handler); > > > > assert removed : "redundant remove call"; > > > > if (removed && l.isEmpty()) { > > > > prune(type, source); > > > > } > > > > } > > > > > private <H> List<H> ensureHandlerList(Event.Type<H> type, Object > > > > source) { > > > > Map<Object, List<?>> sourceMap = map.get(type); > > > > if (sourceMap == null) { > > > > sourceMap = new HashMap<Object, List<?>>(); > > > > map.put(type, sourceMap); > > > > } > > > > > // safe, we control the > > ... > > read more » -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
