thanks, committed patch here : http://gwt-code-reviews.appspot.com/1500804/
On 26 juil, 22:43, Gal Dolber <gal.dol...@gmail.com> 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(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) { > > ... > > plus de détails » -- 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.