/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.util; import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; import org.eclipse.swt.widgets.Display; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.event.*; public class XModelTreeListenerSWTASync implements XModelTreeListener { private XModelTreeListener listener; Queue<XModelTreeEvent> queue = new ConcurrentLinkedQueue<XModelTreeEvent>(); private Set<XModelObject> nodes = new HashSet<XModelObject>(); Runnable runnable = null; private synchronized void add(XModelTreeEvent event) { if(event.kind() == XModelTreeEvent.NODE_CHANGED) { //If event has other kind than NODE_CHANGED, it should never be filtered out! if(nodes.contains(event.getModelObject())) { return; } //Add to filter nodes.add(event.getModelObject()); } //Add event to queue. queue.add(event); } private void run(XModelTreeEvent event) { add(event); synchronized(this) { if(runnable != null) return; runnable = new R(); } Display.getDefault().asyncExec(runnable); } public XModelTreeListenerSWTASync(XModelTreeListener listener){ this.listener = listener; } public void nodeChanged(final XModelTreeEvent event) { run(event); } public void structureChanged(final XModelTreeEvent event) { run(event); } public synchronized void dispose() { listener = null; queue.clear(); } public synchronized XModelTreeListener getListener() { return listener; } class R implements Runnable { public void run() { XModelTreeListener listener = getListener(); if (listener != null) { try { while (!queue.isEmpty()) { XModelTreeEvent event = queue.poll(); synchronized(XModelTreeListenerSWTASync.this) { nodes.remove(event.getModelObject()); } if (event.kind() == XModelTreeEvent.NODE_CHANGED) { listener.nodeChanged(event); } else { listener.structureChanged(event); } } } finally { runnable = null; } } } } }