Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: lib/typedObjects/utils.js

Issue 5728072976302080: Issue 151 - [Typed objects] Implement dynamically-sized array types (Closed)
Patch Set: Created July 11, 2014, 7:26 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/typedObjects/primitiveTypes.js ('k') | test/index.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2014 Eyeo GmbH 3 * Copyright (C) 2006-2014 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 if (index < 0) 80 if (index < 0)
81 { 81 {
82 index = (viewTypes.push(viewType) | 0) - 1; 82 index = (viewTypes.push(viewType) | 0) - 1;
83 views.push([]); 83 views.push([]);
84 } 84 }
85 result.push(views[index]); 85 result.push(views[index]);
86 } 86 }
87 return result; 87 return result;
88 }; 88 };
89 89
90 /**
91 * Creates a wrapper function for a setter that will call the watcher function
92 * with the new value of the property before executing the actual setter.
93 */
94 function watchSetter(/**Function*/ setter, /**Function*/ watcher) /**Function*/
95 {
96 return function(value)
97 {
98 setter.call(this, watcher.call(this, value));
99 }
100 }
101
102 /**
103 * Creates a parameter-less wrapper function around a getter that will get
104 * bufferIndex and byteOffset parameters from object properties.
105 */
106 function wrapGetter(/**Function*/ getter) /**Function*/
107 {
108 return function()
109 {
110 return getter.call(this, this.bufferIndex, this.byteOffset);
111 }
112 }
113
114 /**
115 * Creates a wrapper function around a setter with value as the only parameter,
116 * the bufferIndex and byteOffset parameters will be retrieved from object
117 * properties.
118 */
119 function wrapSetter(/**Function*/ setter) /**Function*/
120 {
121 return function(value)
122 {
123 return setter.call(this, this.bufferIndex, this.byteOffset, value);
124 }
125 }
126
90 /** 127 /**
91 * Defines properties with given name and type on an object. 128 * Defines properties with given name and type on an object.
92 * 129 *
93 * @param obj object to define properties on 130 * @param obj object to define properties on
94 * @param properties object mapping property names to their respective types 131 * @param properties object mapping property names to their respective types
95 * @param viewTypes see getViewsForType() 132 * @param viewTypes see getViewsForType()
96 * @param views see getViewsForType() 133 * @param views see getViewsForType()
97 * @param [offset] byte array offset at which the properties should start 134 * @param [offset] byte array offset at which the properties should start
98 * @param [cleanupValues] array of property/value combinations to be set when th e object is created or destroyed 135 * @param [watchers] map of watcher functions to be called when a particular pro perty is being set
136 * @param [initialValues] array of property/value combinations to be set when th e object is created or destroyed
99 * @return new start offset for additional properties 137 * @return new start offset for additional properties
100 */ 138 */
101 exports.defineProperties = function defineProperties(obj, properties, viewTypes, views, offset, cleanupValues) 139 exports.defineProperties = function defineProperties(obj, properties, viewTypes, views, offset, watchers, initialValues)
102 { 140 {
103 offset = offset | 0; 141 offset = offset | 0;
104 142
105 let propList = []; 143 let propList = [];
106 for (let name in properties) 144 for (let name in properties)
107 propList.push([name, properties[name]]); 145 propList.push([name, properties[name]]);
108 146
109 // Put larger properties first to make sure alignment requirements are met. 147 // Put larger properties first to make sure alignment requirements are met.
110 propList.sort(function(a, b) 148 propList.sort(function(a, b)
111 { 149 {
112 return b[1].referenceLength - a[1].referenceLength; 150 return b[1].referenceLength - a[1].referenceLength;
113 }); 151 });
114 152
115 // Generates getters and setters for each property. 153 // Generates getters and setters for each property.
116 let descriptors = {}; 154 let descriptors = {};
117 for (let i = 0, l = propList.length | 0; i < l; i++) 155 for (let i = 0, l = propList.length | 0; i < l; i++)
118 { 156 {
119 let [name, type] = propList[i]; 157 let [name, type] = propList[i];
120 158
121 let viewParams = getViewsForType(type, viewTypes, views); 159 let viewParams = getViewsForType(type, viewTypes, views);
122 descriptors[name] = { 160 descriptors[name] = {
123 get: type.createGetter.apply(type, [offset].concat(viewParams)), 161 get: wrapGetter(type.createGetter.apply(type, [offset].concat(viewParams)) ),
124 set: type.createSetter.apply(type, [offset].concat(viewParams)), 162 set: wrapSetter(type.createSetter.apply(type, [offset].concat(viewParams)) ),
125 configurable: false, 163 configurable: false,
126 enumerable: true 164 enumerable: true
127 }; 165 };
166
167 if (watchers && typeof watchers[name] == "function")
168 descriptors[name].set = watchSetter(descriptors[name].set, watchers[name]) ;
169
128 offset += type.referenceLength; 170 offset += type.referenceLength;
129 if (cleanupValues && typeof type.cleanupValue != "undefined") 171 if (initialValues && typeof type.initialValue != "undefined")
130 cleanupValues.push([name, type.cleanupValue]); 172 initialValues.push([name, type.initialValue]);
131 } 173 }
132 174
133 // Define properties 175 // Define properties
134 Object.defineProperties(obj, descriptors); 176 Object.defineProperties(obj, descriptors);
135 177
136 return offset; 178 return offset;
137 }; 179 };
180
181 /**
182 * Creates a new array buffer and adds the necessary views.
183 *
184 * @param {Integer} byteSize bytes to allocate for the buffer
185 * @param {Array} buffers existing buffers (will be modified)
186 * @param {Array} viewTypes view types for the buffers
187 * @param {Array} views existing buffer views (will be modified)
188 * @result {Integer} index of the buffer created
189 */
190 let addBuffer = exports.addBuffer = function(byteSize, buffers, viewTypes, views )
191 {
192 let buffer = new ArrayBuffer(byteSize | 0);
193 buffers.push(buffer);
194 for (let i = 0, l = viewTypes.length | 0; i < l; i++)
195 views[i].push(new viewTypes[i](buffer));
196 return (buffers.length | 0) - 1;
197 }
198
199 /**
200 * Releases an array buffer.
201 *
202 * @param {Integer} bufferIndex index of the buffer to be released.
203 * @param {Array} buffers existing buffers (will be modified)
204 * @param {Array} views existing buffer views (will be modified)
205 */
206 exports.removeBuffer = function(bufferIndex, buffers, views)
207 {
208 delete buffers[bufferIndex];
209 for (let i = 0, l = views.length | 0; i < l; i++)
210 delete views[i][bufferIndex];
211 }
212
213 /**
214 * Allocates a new fixed-size element. It will return the first available free
215 * block or create a new buffer if the existing ones have no space left.
216 *
217 * @param {TypedReference} firstFree head of the linked list pointing to unallo cated elements
218 * @param {Integer} byteLength size of an element
219 * @param {Integer} bufferSize number of elements in a buffer
220 * @param {Array} buffers existing buffers (might be modified in necessary)
221 * @param {Array} viewTypes view types for the buffers
222 * @param {Array} views existing buffer views (might be modified if necessary)
223 * @result {Array} [bufferIndex, byteOffset] parameters of the newly allocated b lock
224 */
225 exports.alloc = function(firstFree, byteLength, bufferSize, buffers, viewTypes, views)
226 {
227 let bufferIndex = firstFree.bufferIndex | 0;
228 let byteOffset = firstFree.byteOffset | 0;
229 if (bufferIndex >= 0)
230 {
231 // There is still a free spot, simply move on firstFree reference
232 [firstFree.bufferIndex, firstFree.byteOffset] =
233 [firstFree.targetBufferIndex, firstFree.targetByteOffset];
234 }
235 else
236 {
237 byteLength = byteLength | 0;
238 bufferSize = bufferSize | 0;
239
240 // Create new buffer and use the first element of it
241 bufferIndex = addBuffer(byteLength * bufferSize, buffers, viewTypes, views);
242 byteOffset = 0;
243
244 // Mark last element of the new buffer as the last free spot
245 firstFree.bufferIndex = bufferIndex;
246 firstFree.byteOffset = (bufferSize - 1) * byteLength;
247 firstFree.targetBufferIndex = -1;
248
249 // Make each remaining element of the new buffer point to the next one
250 for (let i = bufferSize - 2; i >= 1; i--)
251 {
252 let nextByteOffset = firstFree.byteOffset;
253 firstFree.byteOffset = nextByteOffset - byteLength;
254 firstFree.targetBufferIndex = bufferIndex;
255 firstFree.targetByteOffset = nextByteOffset;
256 }
257 }
258 return [bufferIndex, byteOffset];
259 };
260
261 /**
262 * Releases the block at given offset so that it can be allocated again.
263 *
264 * @param {TypedReference} firstFree head of the linked list pointing to unallo cated elements
265 * @param {Integer} bufferIndex buffer index of the block to be released
266 * @param {Integer} byteOffset byte offset o fthe block to be released
267 */
268 exports.dealloc = function(firstFree, bufferIndex, byteOffset)
269 {
270 let oldFreeBufferIndex = firstFree.bufferIndex | 0;
271 let oldFreeByteOffset = firstFree.byteOffset | 0;
272
273 firstFree.bufferIndex = bufferIndex | 0;
274 firstFree.byteOffset = byteOffset | 0;
275 firstFree.targetBufferIndex = oldFreeBufferIndex;
276 firstFree.targetByteOffset = oldFreeByteOffset;
277 }
OLDNEW
« no previous file with comments | « lib/typedObjects/primitiveTypes.js ('k') | test/index.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld