Skip to content

Instantly share code, notes, and snippets.

@WebReflection
Last active December 21, 2015 11:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save WebReflection/6296790 to your computer and use it in GitHub Desktop.
Save WebReflection/6296790 to your computer and use it in GitHub Desktop.
JavaScript Structs and Typed Objects simplified "fakelyfill"
(function(){
var
// to include old IEs no 1-9 or 0-9 range as first char allowed
SIMPLE_PROPERTY_NAME = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/,
// the right global to pollute
G = typeof global === typeof G ? window : global,
// shortcut for Function composition
F = G.Function,
// shortcut for common Array stuff
A = G.Array.prototype,
// usual shortcut for objects keys
has = {}.hasOwnProperty,
// all possible usable types
types = [
// unsigned
'uint8',
'uint8Clamped',
'uint16',
'uint32',
// signed
'int8',
'int16',
'int32',
// float
'float32',
'float64',
// boolean
'boolean',
// opaque
'string',
// + miscs
'struct',
// 'array',
'pointer',
'object',
'any'
// 'Any'
]
;
while (types.length) {
if (!(types[0] in G)) {
G[types[0]] = {};
}
types.shift();
}
if (G.StructType) return;
// should do nothing with this code
function storage(o) {
return {
buffer: null,
byteOffset: undefined,
byteLength: undefined
};
}
G.StructType = function StructType(descriptor) {
var body = [], key, T;
for (key in descriptor) {
if (has.call(descriptor, key)) {
if (SIMPLE_PROPERTY_NAME.test(key)) {
body.push('this.' + key + '=o.' + key);
} else {
key = JSON.stringify(key);
body.push('this[' + key + ']=o[' + key + ']');
}
}
}
// create the (hopefully) fastest possible implementation
T = F('return function T(o){' + body.join(';') + '}')();
T.storage = storage;
return T;
};
if (G.ArrayType) return;
// fill all entries with a single value
function fill(withWhat) {
for(var i = this.length; i--;) {
this[i] = withWhat;
}
}
// pretending a new Array
function toArray() {
return A.slice.call(this);
}
// updates all entries with those
// found in respective argument indexes
function update(withWhat) {
for(var i = this.length; i--;) {
this[i] = withWhat[i];
}
}
G.ArrayType = function ArrayType(Type, len) {
function T(a) {
for(var
o = a || A,
i = 0,
length = len == null ? o.length : len;
i < length; this[i]=o[i++]
);
this.length = length;
}
var p = T.prototype;
p.fill = fill;
p.toArray = toArray;
p.update = update;
p.forEach = A.forEach;
p.map = A.map;
p.reduce = A.reduce;
return T;
};
}());
@WebReflection
Copy link
Author

example

var Point = new StructType({x: uint32, y: uint32});
var ArrayPoint = new ArrayType(Point);
new Point({x: 1, y: 2}) instanceof Point; // true
new ArrayPoint([
  new Point({x: 1, y: 1}),
  new Point({x: 2, y: 2}),
  new Point({x: 3, y: 3})
]) instanceof ArrayPoint; // true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment