Project

General

Profile

1811o_20150811_1.txt

Sergey Ivanovskiy, 08/11/2015 06:17 PM

Download (9.11 KB)

 
1
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js'
2
--- src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js	2015-08-10 20:53:46 +0000
3
+++ src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js	2015-08-11 21:58:00 +0000
4
@@ -309,7 +309,13 @@
5
                   case 0x8B:
6
                      // destroy top-level or child window
7
                      var id = me.readInt32BinaryMessage(message, 1);
8
-                     p2j.screen.destroyWindow(id);
9
+                     var numberImages = me.readInt32BinaryMessage(message, 5);
10
+                     var images = [];
11
+                     for ( var i = 0; i < numberImages; i++)
12
+                     {
13
+                        images[i] = me.readInt32BinaryMessage(message, 9 + i << 2);
14
+                     }
15
+                     p2j.screen.destroyWindow(id, images);
16
                      break;
17
                   case 0x8C:
18
                      // change visibility for top-level or child window
19

    
20
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebDriver.java'
21
--- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebDriver.java	2015-08-10 20:53:46 +0000
22
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebDriver.java	2015-08-11 21:40:08 +0000
23
@@ -22,11 +22,11 @@
24
 
25
 // TODO: remove this, it is there to allow compilation
26
 import java.awt.Font;
27
+import java.util.HashMap;
28
 import java.util.HashSet;
29
 // don't import the entire logging package as it has naming conflicts with jetty
30
 import java.util.logging.Level;
31
 import java.util.logging.Logger;
32
-
33
 import java.util.*;
34
 
35
 import org.eclipse.jetty.util.resource.*;
36
@@ -80,8 +80,11 @@
37
    /** Virtual screen for drawing in a memory */
38
    private VirtualScreen virtualScreen;
39
    
40
-   /** Images loaded by a client. */
41
-   private final HashSet<Integer> loadedImages;
42
+   /** Image usages is a mapping of an image loaded by a client to its owner windows. */
43
+   private final Map<Integer, Set<Integer> > imageUsages;
44
+   
45
+   /** Owned images is a mapping of a window to its owned images. */
46
+   private final Map<Integer, Set<Integer> > ownedImages;
47
    
48
    /** A cache of font metrics objects, by their remote font ID. */
49
    private Map<Integer, FontMetricsHelper> fontMetricsCache = new HashMap<>();
50
@@ -107,7 +110,8 @@
51
       });
52
       
53
       this.config = config;
54
-      this.loadedImages = new HashSet<Integer>();
55
+      this.imageUsages = new HashMap<Integer, Set<Integer>>();
56
+      this.ownedImages = new HashMap<Integer, Set<Integer>>();
57
    }
58
    
59
    /**
60
@@ -196,16 +200,77 @@
61
    }
62
    
63
    /**
64
+    * Returns its virtual screen that represents the physical screen in a memory
65
+    * using a sRGB pixel model.
66
     * 
67
-    * @return
68
+    * @return The virtual screen to draw images in a memory.
69
     */
70
    public VirtualScreen getVirtualScreen()
71
    {
72
       return virtualScreen;
73
    }
74
    
75
-   public boolean addImage(int imageHash) {
76
-      return this.loadedImages.add(imageHash);
77
+   /**
78
+    * Register a usage of the given image by the given window.
79
+    * 
80
+    * @param    imageHash
81
+    *           The image hash id.
82
+    * @param    windowId
83
+    *           The window id.
84
+    * 
85
+    * @return   True iff it is the first usage of the given image.
86
+    */
87
+   public boolean addImageUsage(int imageHash, int windowId) {
88
+      boolean newLoadedImage = false;
89
+      
90
+      Set<Integer> usages = imageUsages.get(imageHash);
91
+      if (usages == null)
92
+      {
93
+         usages = new HashSet<Integer>();
94
+         imageUsages.put(imageHash, usages);
95
+         newLoadedImage = true;
96
+      }
97
+      usages.add(windowId);
98
+      
99
+      Set<Integer> images = ownedImages.get(windowId);
100
+      if (images == null)
101
+      {
102
+         images = new HashSet<Integer>();
103
+         ownedImages.put(windowId, images);
104
+      }
105
+      images.add(imageHash);
106
+      
107
+      return newLoadedImage;
108
+   }
109
+   
110
+   /**
111
+    * Returns all unused images. Removes the given window from all image usages.
112
+    * 
113
+    * @param    windowId
114
+    *           The window id.
115
+    * 
116
+    * @return The set of all unused images.
117
+    */
118
+   public Set<Integer> removeUnusedImages(int windowId) {
119
+      Set<Integer> imagesToRemove = new HashSet<Integer>();
120
+      Set<Integer> images = ownedImages.remove(windowId);
121
+      if (images != null && !images.isEmpty())
122
+      {
123
+         for (Integer imageHash : images)
124
+         {
125
+            Set<Integer> usages = imageUsages.get(imageHash);
126
+            if (usages.remove(windowId))
127
+            {
128
+               if (usages.isEmpty())
129
+               {
130
+                  imagesToRemove.add(imageHash);
131
+                  imageUsages.remove(imageHash);
132
+               }
133
+            }
134
+         }
135
+      }
136
+      
137
+      return imagesToRemove;
138
    }
139
    
140
    /**
141

    
142
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java'
143
--- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java	2015-08-10 22:08:54 +0000
144
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java	2015-08-11 21:40:08 +0000
145
@@ -21,6 +21,8 @@
146
 package com.goldencode.p2j.ui.client.gui.driver.web;
147
 
148
 import java.awt.image.BufferedImage;
149
+import java.util.Set;
150
+
151
 
152
 import com.goldencode.p2j.ui.client.*;
153
 import com.goldencode.p2j.ui.client.gui.driver.*;
154
@@ -87,7 +89,9 @@
155
    @Override
156
    public void quit()
157
    {
158
-      websock.destroyWindow(windowId);
159
+      Set<Integer> imagesToRemove = webdriver.removeUnusedImages(windowId);
160
+      
161
+      websock.destroyWindow(windowId, imagesToRemove.toArray(new Integer[imagesToRemove.size()]));
162
    }
163
 
164
    /**
165
@@ -397,7 +401,7 @@
166
             int imageHash = wrappedImage.getImage().hashCode();
167
             ImageEncoding encoding;
168
             byte[] encodedImage;
169
-            if (webdriver.addImage(imageHash))
170
+            if (webdriver.addImageUsage(imageHash, windowId))
171
             {
172
                encoding = ImageEncoding.RAW;
173
                virtualScreen.drawImage(wrappedImage, ps.x, ps.y);
174

    
175
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java'
176
--- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java	2015-08-10 20:53:46 +0000
177
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java	2015-08-11 21:51:53 +0000
178
@@ -132,10 +132,23 @@
179
     *
180
     * @param    id
181
     *           The window id to destroy.
182
+    * @param    cashedImages
183
+    *           The array of client cached images to remove.
184
     */
185
-   public void destroyWindow(int id)
186
+   public void destroyWindow(int id, Integer[] cachedImages)
187
    {
188
-      sendBinaryMessage(MSG_DESTROY_WINDOW, id);
189
+      byte[] message = new byte[9 + cachedImages.length << 2];
190
+      
191
+      message[0] = MSG_DESTROY_WINDOW;
192
+      writeMessageInt32(message, 1, id);
193
+      writeMessageInt32(message, 5, cachedImages.length);
194
+      int idx = 9;
195
+      for(Integer imageHash : cachedImages)
196
+      {
197
+         writeMessageInt32(message, idx, imageHash);
198
+         idx += 4;
199
+      }
200
+      sendBinaryMessage(message);
201
    }
202
    
203
    /**
204

    
205
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js'
206
--- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js	2015-08-10 22:08:54 +0000
207
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js	2015-08-11 22:03:51 +0000
208
@@ -517,10 +517,12 @@
209
                var pixelsInBytes = width * height * 4;
210
                var imgData;
211
                var imgDataOffset;
212
-               if(loadedImages.has(key)) {
213
+               if(loadedImages.has(key))
214
+               {
215
                   imgData = loadedImages.get(key);
216
                   imgDataOffset = 0;
217
-               } else {
218
+               } else
219
+               {
220
                   imgData = message;
221
                   imgDataOffset = idx + 22;
222
                   loadedImages.set(key, message.subarray(imgDataOffset, imgDataOffset + pixelsInBytes));
223
@@ -822,7 +824,20 @@
224
    }                         
225
    
226
    /**
227
+    * It draws an image on the canvas.
228
     * 
229
+    * @param    {Number} x
230
+    *           X coordinate of the top left corner.
231
+    * @param    {Number} y
232
+    *           Y coordinate of the top left corner.
233
+    * @param    {Number} width
234
+    *           Width of the image in pixels.
235
+    * @param    {Number} height
236
+    *           Height of the image in pixels.
237
+    * @param    {Array} imgData
238
+    *           The image data array contains the encoded image started from the given offset.
239
+    * @param    {Number} imgDataOffset
240
+    *           The offset of the encoded image data.
241
     */
242
    function drawImage(x, y, width, height, imgData, imgDataOffset)
243
    {
244
@@ -1256,8 +1271,10 @@
245
     *
246
     * @param    wid
247
     *           The window id by which this window can be uniquely identified.
248
+    * @param    images
249
+    *           The cached images to remove.
250
     */
251
-   me.destroyWindow = function(wid)
252
+   me.destroyWindow = function(wid, images)
253
    {
254
       if (!isValidWindowId(wid))
255
       {
256
@@ -1274,7 +1291,10 @@
257
       var win = getWindow(wid);
258
       
259
       win.cleanup();
260
-      
261
+      for (var image in images)
262
+      {
263
+         loadedImages.delete(image);
264
+      }
265
       // remove from our window list
266
       delete winlist[wid];
267
    }
268