/* * Copyright (c) 2004-2011 Marco Maccaferri and others. * All rights reserved. This program and the accompanying materials * are 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: * Marco Maccaferri - initial API and implementation */ package org.eclipsetrader.ui; import org.eclipse.core.databinding.observable.Realm; import org.eclipse.swt.widgets.Display; public class QueuedRealm extends Realm { static final int INITIAL_SIZE = 256; static final int GROW_SIZE = 32; static final int MESSAGE_LIMIT = 1024; static final Realm instance = new QueuedRealm(); private Display display; int messageCount; Runnable[] messages = new Runnable[INITIAL_SIZE]; private Object messageLock = new Object(); private Runnable delayedRunnable = new Runnable() { @Override public void run() { Runnable runnable; while ((runnable = removeFirst()) != null) { runnable.run(); } } }; public static Realm getInstance() { return instance; } private QueuedRealm() { this.display = Display.getDefault(); } /* (non-Javadoc) * @see org.eclipse.core.databinding.observable.Realm#isCurrent() */ @Override public boolean isCurrent() { return Display.getCurrent() == display; } /* (non-Javadoc) * @see org.eclipse.core.databinding.observable.Realm#exec(java.lang.Runnable) */ @Override public void exec(Runnable runnable) { addLast(runnable); } /* (non-Javadoc) * @see org.eclipse.core.databinding.observable.Realm#asyncExec(java.lang.Runnable) */ @Override public void asyncExec(Runnable runnable) { addLast(runnable); } /* (non-Javadoc) * @see org.eclipse.core.databinding.observable.Realm#syncExec(java.lang.Runnable) */ @Override protected void syncExec(Runnable runnable) { display.syncExec(runnable); } void addLast(Runnable runnable) { boolean wake = false; synchronized (messageLock) { if (messages == null) { messages = new Runnable[INITIAL_SIZE]; } if (messageCount == messages.length) { Runnable[] newMessages = new Runnable[messageCount + GROW_SIZE]; System.arraycopy(messages, 0, newMessages, 0, messageCount); messages = newMessages; System.out.println(messages.length); } messages[messageCount++] = runnable; wake = messageCount == 1; } if (wake) { display.asyncExec(delayedRunnable); } } Runnable removeFirst() { synchronized (messageLock) { if (messageCount == 0) { return null; } Runnable lock = messages[0]; System.arraycopy(messages, 1, messages, 0, --messageCount); messages[messageCount] = null; if (messageCount == 0) { if (messages.length > MESSAGE_LIMIT) { messages = null; } } return lock; } } }