You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@pivot.apache.org by Greg Brown <gk...@mac.com> on 2009/10/14 17:21:27 UTC

Re: svn commit: r825164

This change should address the issue of multiple images being asynchronously loaded for the same URL.

Noel, thanks for catching this.

G

On Wednesday, October 14, 2009, at 11:17AM, <gb...@apache.org> wrote:
>Author: gbrown
>Date: Wed Oct 14 15:17:48 2009
>New Revision: 825164
>
>URL: http://svn.apache.org/viewvc?rev=825164&view=rev
>Log:
>Ensure that only one image is loaded asynchronously for any given URL.
>
>Modified:
>    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/ImageView.java
>
>Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/ImageView.java
>URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/ImageView.java?rev=825164&r1=825163&r2=825164&view=diff
>==============================================================================
>--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/ImageView.java (original)
>+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/ImageView.java Wed Oct 14 15:17:48 2009
>@@ -18,7 +18,9 @@
> 
> import java.net.URL;
> 
>+import org.apache.pivot.collections.ArrayList;
> import org.apache.pivot.collections.Dictionary;
>+import org.apache.pivot.collections.HashMap;
> import org.apache.pivot.serialization.JSONSerializer;
> import org.apache.pivot.util.ListenerList;
> import org.apache.pivot.util.ThreadUtilities;
>@@ -62,6 +64,11 @@
> 
>     private ImageViewListenerList imageViewListeners = new ImageViewListenerList();
> 
>+    // Maintains a mapping of image URL to image views that should be notified when
>+    // an asynchronously loaded image is available
>+    private static HashMap<URL, ArrayList<ImageView>> loadMap =
>+        new HashMap<URL, ArrayList<ImageView>>();
>+
>     /**
>      * Creates an empty image view.
>      */
>@@ -125,20 +132,36 @@
> 
>         if (image == null) {
>             if (asynchronous) {
>-                Image.load(imageURL, new TaskAdapter<Image>(new TaskListener<Image>() {
>-                    @Override
>-                    public void taskExecuted(Task<Image> task) {
>-                        Image image = task.getResult();
>-
>-                        setImage(image);
>-                        ApplicationContext.getResourceCache().put(imageURL, image);
>-                    }
>-
>-                    @Override
>-                    public void executeFailed(Task<Image> task) {
>-                        // No-op
>-                    }
>-                }));
>+                if (loadMap.containsKey(imageURL)) {
>+                    // Add this to the list of image views that are interested in
>+                    // the image at this URL
>+                    loadMap.get(imageURL).add(this);
>+                } else {
>+                    Image.load(imageURL, new TaskAdapter<Image>(new TaskListener<Image>() {
>+                        @Override
>+                        public void taskExecuted(Task<Image> task) {
>+                            Image image = task.getResult();
>+
>+                            // Update the contents of all image views that requested this
>+                            // image
>+                            for (ImageView imageView : loadMap.get(imageURL)) {
>+                                imageView.setImage(image);
>+                            }
>+
>+                            loadMap.remove(imageURL);
>+
>+                            // Add the image to the cache
>+                            ApplicationContext.getResourceCache().put(imageURL, image);
>+                        }
>+
>+                        @Override
>+                        public void executeFailed(Task<Image> task) {
>+                            // No-op
>+                        }
>+                    }));
>+
>+                    loadMap.put(imageURL, new ArrayList<ImageView>(this));
>+                }
>             } else {
>                 try {
>                     image = Image.load(imageURL);
>
>
>
>

Re: svn commit: r825164

Posted by Noel Grandin <no...@gmail.com>.
Someday, if we have a Pivot convention, I'll tell you about the time I
spent 2 years chasing a single race-condition bug in a billing system
:-)

- Noel.

On Wed, Oct 14, 2009 at 17:21, Greg Brown <gk...@mac.com> wrote:
> This change should address the issue of multiple images being asynchronously loaded for the same URL.
>
> Noel, thanks for catching this.
>
> G
>
> On Wednesday, October 14, 2009, at 11:17AM, <gb...@apache.org> wrote:
>>Author: gbrown
>>Date: Wed Oct 14 15:17:48 2009
>>New Revision: 825164
>>
>>URL: http://svn.apache.org/viewvc?rev=825164&view=rev
>>Log:
>>Ensure that only one image is loaded asynchronously for any given URL.
>>
>>Modified:
>>    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/ImageView.java
>>
>>Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/ImageView.java
>>URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/ImageView.java?rev=825164&r1=825163&r2=825164&view=diff
>>==============================================================================
>>--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/ImageView.java (original)
>>+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/ImageView.java Wed Oct 14 15:17:48 2009
>>@@ -18,7 +18,9 @@
>>
>> import java.net.URL;
>>
>>+import org.apache.pivot.collections.ArrayList;
>> import org.apache.pivot.collections.Dictionary;
>>+import org.apache.pivot.collections.HashMap;
>> import org.apache.pivot.serialization.JSONSerializer;
>> import org.apache.pivot.util.ListenerList;
>> import org.apache.pivot.util.ThreadUtilities;
>>@@ -62,6 +64,11 @@
>>
>>     private ImageViewListenerList imageViewListeners = new ImageViewListenerList();
>>
>>+    // Maintains a mapping of image URL to image views that should be notified when
>>+    // an asynchronously loaded image is available
>>+    private static HashMap<URL, ArrayList<ImageView>> loadMap =
>>+        new HashMap<URL, ArrayList<ImageView>>();
>>+
>>     /**
>>      * Creates an empty image view.
>>      */
>>@@ -125,20 +132,36 @@
>>
>>         if (image == null) {
>>             if (asynchronous) {
>>-                Image.load(imageURL, new TaskAdapter<Image>(new TaskListener<Image>() {
>>-                    @Override
>>-                    public void taskExecuted(Task<Image> task) {
>>-                        Image image = task.getResult();
>>-
>>-                        setImage(image);
>>-                        ApplicationContext.getResourceCache().put(imageURL, image);
>>-                    }
>>-
>>-                    @Override
>>-                    public void executeFailed(Task<Image> task) {
>>-                        // No-op
>>-                    }
>>-                }));
>>+                if (loadMap.containsKey(imageURL)) {
>>+                    // Add this to the list of image views that are interested in
>>+                    // the image at this URL
>>+                    loadMap.get(imageURL).add(this);
>>+                } else {
>>+                    Image.load(imageURL, new TaskAdapter<Image>(new TaskListener<Image>() {
>>+                        @Override
>>+                        public void taskExecuted(Task<Image> task) {
>>+                            Image image = task.getResult();
>>+
>>+                            // Update the contents of all image views that requested this
>>+                            // image
>>+                            for (ImageView imageView : loadMap.get(imageURL)) {
>>+                                imageView.setImage(image);
>>+                            }
>>+
>>+                            loadMap.remove(imageURL);
>>+
>>+                            // Add the image to the cache
>>+                            ApplicationContext.getResourceCache().put(imageURL, image);
>>+                        }
>>+
>>+                        @Override
>>+                        public void executeFailed(Task<Image> task) {
>>+                            // No-op
>>+                        }
>>+                    }));
>>+
>>+                    loadMap.put(imageURL, new ArrayList<ImageView>(this));
>>+                }
>>             } else {
>>                 try {
>>                     image = Image.load(imageURL);
>>
>>
>>
>>
>