Mercurial > projects > dwt-addons
view dwtx/core/commands/contexts/ContextManager.d @ 104:04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
These new wrappers now use the tango.util.containers instead of the tango.util.collections.
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 07 Aug 2008 15:01:33 +0200 |
parents | 6518c18a01f7 |
children |
line wrap: on
line source
/******************************************************************************* * Copyright (c) 2000, 2007 IBM Corporation 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: * IBM Corporation - initial API and implementation * Port to the D programming language: * Frank Benoit <benoit@tionex.de> *******************************************************************************/ module dwtx.core.commands.contexts.ContextManager; import dwtx.core.commands.contexts.IContextListener; import dwtx.core.commands.contexts.IContextManagerListener; import dwtx.core.commands.contexts.ContextEvent; import dwtx.core.commands.contexts.ContextManagerEvent; import dwtx.core.commands.contexts.Context; import dwtx.core.commands.common.HandleObjectManager; import dwtx.core.commands.util.Tracing; import dwtx.core.internal.commands.util.Util; import dwt.dwthelper.utils; import dwtx.dwtxhelper.Collection; /** * <p> * A context manager tracks the sets of defined and enabled contexts within the * application. The manager sends notification events to listeners when these * sets change. It is also possible to retrieve any given context with its * identifier. * </p> * <p> * This class is not intended to be extended by clients. * </p> * * @since 3.1 */ public final class ContextManager : HandleObjectManager, IContextListener { private static const String DEFER_EVENTS = "dwtx.ui.internal.contexts.deferEvents"; //$NON-NLS-1$ private static const String SEND_EVENTS = "dwtx.ui.internal.contexts.sendEvents"; //$NON-NLS-1$ /** * This flag can be set to <code>true</code> if the context manager should * print information to <code>System.out</code> when certain boundary * conditions occur. */ public static bool DEBUG = false; /** * The set of active context identifiers. This value may be empty, but it is * never <code>null</code>. */ private Set activeContextIds; private static Set EMPTY_SET; // allow the ContextManager to send one event for a larger delta private bool caching = false; private int cachingRef = 0; private bool activeContextsChange = false; private Set oldIds = null; public this(){ activeContextIds = new HashSet(); if( EMPTY_SET is null ){ EMPTY_SET = new HashSet(); } } /** * Activates a context in this context manager. * * @param contextId * The identifier of the context to activate; must not be * <code>null</code>. */ public final void addActiveContext(String contextId) { if (DEFER_EVENTS.equals(contextId)) { cachingRef++; if (cachingRef is 1 ) { setEventCaching(true); } return; } else if (SEND_EVENTS.equals(contextId)) { cachingRef--; if (cachingRef is 0) { setEventCaching(false); } return; } if (activeContextIds.contains(contextId)) { return; } activeContextsChange = true; if (caching) { activeContextIds.add(contextId); } else { Set previouslyActiveContextIds = new HashSet(activeContextIds); activeContextIds.add(contextId); fireContextManagerChanged(new ContextManagerEvent(this, null, false, true, previouslyActiveContextIds)); } if (DEBUG) { Tracing.printTrace("CONTEXTS", activeContextIds.toString()); //$NON-NLS-1$ } } /** * Adds a listener to this context manager. The listener will be notified * when the set of defined contexts changes. This can be used to track the * global appearance and disappearance of contexts. * * @param listener * The listener to attach; must not be <code>null</code>. */ public final void addContextManagerListener( IContextManagerListener listener) { addListenerObject(cast(Object)listener); } public final void contextChanged(ContextEvent contextEvent) { if (contextEvent.isDefinedChanged()) { Context context = contextEvent.getContext(); String contextId = context.getId(); bool contextIdAdded = context.isDefined(); if (contextIdAdded) { definedHandleObjects.add(context); } else { definedHandleObjects.remove(context); } if (isListenerAttached()) { fireContextManagerChanged(new ContextManagerEvent(this, contextId, contextIdAdded, false, null)); } } } /** * Notifies all of the listeners to this manager that the set of defined * context identifiers has changed. * * @param event * The event to send to all of the listeners; must not be * <code>null</code>. */ private final void fireContextManagerChanged(ContextManagerEvent event) { if (event is null) { throw new NullPointerException(); } Object[] listeners = getListeners(); for (int i = 0; i < listeners.length; i++) { IContextManagerListener listener = cast(IContextManagerListener) listeners[i]; listener.contextManagerChanged(event); } } /** * Returns the set of active context identifiers. * * @return The set of active context identifiers; this value may be * <code>null</code> if no active contexts have been set yet. If * the set is not <code>null</code>, then it contains only * instances of <code>String</code>. */ public final Set getActiveContextIds() { return Collections.unmodifiableSet(activeContextIds); } /** * Gets the context with the given identifier. If no such context currently * exists, then the context will be created (but be undefined). * * @param contextId * The identifier to find; must not be <code>null</code>. * @return The context with the given identifier; this value will never be * <code>null</code>, but it might be undefined. * @see Context */ public final Context getContext(String contextId) { checkId(contextId); Context context = cast(Context) handleObjectsById.get(contextId); if (context is null) { context = new Context(contextId); handleObjectsById.put(contextId, context); context.addContextListener(this); } return context; } /** * Returns the set of identifiers for those contexts that are defined. * * @return The set of defined context identifiers; this value may be empty, * but it is never <code>null</code>. */ public final Set getDefinedContextIds() { return getDefinedHandleObjectIds(); } /** * Returns the those contexts that are defined. * * @return The defined contexts; this value may be empty, but it is never * <code>null</code>. * @since 3.2 */ public final Context[] getDefinedContexts() { return arraycast!(Context)( definedHandleObjects .toArray(/+new Context[definedHandleObjects.size()]+/)); } /** * Deactivates a context in this context manager. * * @param contextId * The identifier of the context to deactivate; must not be * <code>null</code>. */ public final void removeActiveContext(String contextId) { if (!activeContextIds.contains(contextId)) { return; } activeContextsChange = true; if (caching) { activeContextIds.remove(contextId); } else { Set previouslyActiveContextIds = new HashSet(activeContextIds); activeContextIds.remove(contextId); fireContextManagerChanged(new ContextManagerEvent(this, null, false, true, previouslyActiveContextIds)); } if (DEBUG) { Tracing.printTrace("CONTEXTS", activeContextIds.toString()); //$NON-NLS-1$ } } /** * Removes a listener from this context manager. * * @param listener * The listener to be removed; must not be <code>null</code>. */ public final void removeContextManagerListener( IContextManagerListener listener) { removeListenerObject(cast(Object)listener); } /** * Changes the set of active contexts for this context manager. The whole * set is required so that internal consistency can be maintained and so * that excessive recomputations do nothing occur. * * @param activeContextIds * The new set of active context identifiers; may be * <code>null</code>. */ public final void setActiveContextIds(Set activeContextIds) { if (Util.equals(cast(Object)this.activeContextIds, cast(Object)activeContextIds)) { return; } activeContextsChange = true; Set previouslyActiveContextIds = this.activeContextIds; if (activeContextIds !is null) { this.activeContextIds = new HashSet(); this.activeContextIds.addAll(activeContextIds); } else { this.activeContextIds = null; } if (DEBUG) { Tracing.printTrace("CONTEXTS", (activeContextIds is null) ? "none" //$NON-NLS-1$ //$NON-NLS-2$ : activeContextIds.toString()); } if (!caching) { fireContextManagerChanged(new ContextManagerEvent(this, null, false, true, previouslyActiveContextIds)); } } /** * Set the manager to cache context id changes. * * @param cache * <code>true</code> to turn caching on, <code>false</code> * to turn caching off and send an event if necessary. * @since 3.3 */ private void setEventCaching(bool cache) { if (caching is cache) { return; } caching = cache; bool fireChange = activeContextsChange; Set holdOldIds = (oldIds is null?Collections.EMPTY_SET:oldIds); if (caching) { oldIds = new HashSet(activeContextIds); } else { oldIds = null; } activeContextsChange = false; if (!caching && fireChange) { fireContextManagerChanged(new ContextManagerEvent(this, null, false, true, holdOldIds)); } } }