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 happy
http://code.google.com/webtoolkit/makinggwtbetter.html (also you 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, david.herv...@gmail.com <
david.herv...@gmail.com> wrote:

> No body concerned ?
>
> On 25 juil, 10:50, "david.herv...@gmail.com" <david.herv...@gmail.com>
> 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 puts.
> >       @SuppressWarnings("unchecked")
> >       List<H> handlers = (List<H>) sourceMap.get(source);
> >       if (handlers == null) {
> >         handlers = new ArrayList<H>();
> >         sourceMap.put(source, handlers);
> >       }
> >
> >       return handlers;
> >     }
> >
> >    /**
> >     * Return a copy of handlers to dispatch event to
> >     */
> >     private <H> List<H> getDispatchList(Event.Type<H> type, Object
> > source) {
> >       List<H> directHandlers = getHandlerList(type, source);
> >       if (source == null) {
> >         return new ArrayList<H>(directHandlers);
> >       }
> >
> >       List<H> globalHandlers = getHandlerList(type, null);
> >
> >       List<H> rtn = new ArrayList<H>(directHandlers);
> >       rtn.addAll(globalHandlers);
> >       return rtn;
> >     }
> >
> >     private <H> List<H> getHandlerList(Event.Type<H> type, Object
> > source) {
> >       Map<Object, List<?>> sourceMap = map.get(type);
> >       if (sourceMap == null) {
> >         return Collections.emptyList();
> >       }
> >
> >       // safe, we control the puts.
> >       @SuppressWarnings("unchecked")
> >       List<H> handlers = (List<H>) sourceMap.get(source);
> >       if (handlers == null) {
> >         return Collections.emptyList();
> >       }
> >
> >       return handlers;
> >     }
> >
> >     private void prune(Event.Type<?> type, Object source) {
> >       Map<Object, List<?>> sourceMap = map.get(type);
> >
> >       List<?> pruned = sourceMap.remove(source);
> >
> >       assert pruned != null : "Can't prune what wasn't there";
> >       assert pruned.isEmpty() : "Pruned unempty list!";
> >
> >       if (sourceMap.isEmpty()) {
> >         map.remove(type);
> >       }
> >     }
> >
> >   }
>
> --
> You received this message because you are subscribed to the Google Groups
> "Google Web Toolkit" group.
> To post to this group, send email to google-web-toolkit@googlegroups.com.
> To unsubscribe from this group, send email to
> google-web-toolkit+unsubscr...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/google-web-toolkit?hl=en.
>
>


-- 
Guit: Elegant, beautiful, modular and *production ready* gwt applications.

http://code.google.com/p/guit/

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to google-web-toolkit@googlegroups.com.
To unsubscribe from this group, send email to 
google-web-toolkit+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to