Mercurial > projects > dwt-addons
diff dwtx/jface/resource/AbstractResourceManager.d @ 9:6c14e54dfc11
completed /jface/resource/
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 29 Mar 2008 02:25:12 +0100 |
parents | |
children | da5ad8eedf5d |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/resource/AbstractResourceManager.d Sat Mar 29 02:25:12 2008 +0100 @@ -0,0 +1,160 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 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.jface.resource.AbstractResourceManager; + +import dwtx.jface.resource.ResourceManager; +import dwtx.jface.resource.DeviceResourceDescriptor; + +import tango.util.collection.HashMap; +import tango.util.collection.model.Map; + +import dwt.dwthelper.utils; + +/** + * Abstract implementation of ResourceManager. Maintains reference counts for all previously + * allocated DWT resources. Delegates to the abstract method allocate(...) the first time a resource + * is referenced and delegates to the abstract method deallocate(...) the last time a reference is + * removed. + * + * @since 3.1 + */ +abstract class AbstractResourceManager : ResourceManager { + + /** + * Map of ResourceDescriptor onto RefCount. (null when empty) + */ + private HashMap!(DeviceResourceDescriptor,RefCount) map = null; + + /** + * Holds a reference count for a previously-allocated resource + */ + private static class RefCount { + Object resource; + int count = 1; + + this(Object resource) { + this.resource = resource; + } + } + + /** + * Called the first time a resource is requested. Should allocate and return a resource + * of the correct type. + * + * @since 3.1 + * + * @param descriptor identifier for the resource to allocate + * @return the newly allocated resource + * @throws DeviceResourceException Thrown when allocation of an DWT device resource fails + */ + protected abstract Object allocate(DeviceResourceDescriptor descriptor); + + /** + * Called the last time a resource is dereferenced. Should release any resources reserved by + * allocate(...). + * + * @since 3.1 + * + * @param resource resource being deallocated + * @param descriptor identifier for the resource + */ + protected abstract void deallocate(Object resource, DeviceResourceDescriptor descriptor); + + /* (non-Javadoc) + * @see ResourceManager#create(DeviceResourceDescriptor) + */ + public final Object create(DeviceResourceDescriptor descriptor){ + + // Lazily allocate the map + if (map is null) { + map = new HashMap!(DeviceResourceDescriptor,RefCount); + } + + // Get the current reference count + RefCount count = map.get(descriptor); + if (count !is null) { + // If this resource already exists, increment the reference count and return + // the existing resource. + count.count++; + return count.resource; + } + + // Allocate and return a new resource (with ref count = 1) + Object resource = allocate(descriptor); + + count = new RefCount(resource); + map.add(descriptor, count); + + return resource; + } + + /* (non-Javadoc) + * @see ResourceManager#destroy(DeviceResourceDescriptor) + */ + public final void destroy(DeviceResourceDescriptor descriptor) { + // If the map is empty (null) then there are no resources to dispose + if (map is null) { + return; + } + + // Find the existing resource + RefCount count = map.get(descriptor); + if (count !is null) { + // If the resource exists, decrement the reference count. + count.count--; + if (count.count is 0) { + // If this was the last reference, deallocate it. + deallocate(count.resource, descriptor); + map.removeKey(descriptor); + } + } + + // Null out the map when empty to save a small amount of memory + if (map.drained()) { + map = null; + } + } + + /** + * Deallocates any resources allocated by this registry that have not yet been + * deallocated. + * + * @since 3.1 + */ + public void dispose() { + super.dispose(); + + if (map is null) { + return; + } + + foreach( key, val; map ){ + deallocate(val.resource, key); + } + + map = null; + } + + /* (non-Javadoc) + * @see dwtx.jface.resource.ResourceManager#find(dwtx.jface.resource.DeviceResourceDescriptor) + */ + public Object find(DeviceResourceDescriptor descriptor) { + if (map is null) { + return null; + } + RefCount refCount = cast(RefCount)map.get(descriptor); + if (refCount is null) + return null; + return refCount.resource; + } +}