Skip to content

Commit

Permalink
Add Weakmap – Weak from Map -> Obj, not Obj -> Map
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanpenner committed Aug 27, 2015
1 parent 43d6745 commit 6a1ea35
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
14 changes: 14 additions & 0 deletions packages/ember-metal/lib/meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import EmptyObject from 'ember-metal/empty_object';
*/
let members = {
cache: ownMap,
weak: ownMap,
watching: inheritedMap,
mixins: inheritedMap,
bindings: inheritedMap,
Expand All @@ -53,6 +54,7 @@ function Meta(obj, parentMeta) {
this._deps = undefined;
this._chainWatchers = undefined;
this._chains = undefined;
this._weak = undefined;
// used only internally
this.source = obj;

Expand Down Expand Up @@ -148,6 +150,18 @@ Meta.prototype._getInherited = function(key) {
}
};

Meta.prototype.getWeak = function(symbol) {
var weak = this.readableWeak();
if (weak) {
return weak[symbol];
}
};

Meta.prototype.setWeak = function(symbol, value) {
var weak = this.writableWeak();
return weak[symbol] = value;
};

Meta.prototype._findInherited = function(key, subkey) {
let pointer = this;
while (pointer !== undefined) {
Expand Down
39 changes: 39 additions & 0 deletions packages/ember-metal/lib/weak_map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { GUID_KEY } from 'ember-metal/utils';
import { meta } from 'ember-metal/meta';

var id = 0;

/*
* @private
* @class Ember.WeakMap
*
* Weak relationship from Map -> Key, but not Key to Map.
*
* Key must be a non null object
*/
export default function WeakMap() {
this._id = GUID_KEY + (id++);
}

/*
* @method get
* @param key {Object}
* @return {*} stored value
*/
WeakMap.prototype.get = function(obj) {
var map = meta(obj).readableWeak();
if (map) {
return map[this._id];
}
};

/*
* @method set
* @param key {Object}
* @param value {Any}
* @return {Any} stored value
*/
WeakMap.prototype.set = function(obj, value) {
meta(obj).writableWeak()[this._id] = value;
return this;
};
48 changes: 48 additions & 0 deletions packages/ember-metal/tests/weak_map_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import WeakMap from 'ember-metal/weak_map';

QUnit.module('Ember.WeakMap');

QUnit.test('has weakMap like qualities', function(assert) {
var map = new WeakMap();
var map2 = new WeakMap();

var a = {};
var b = {};
var c = {};

equal(map.get(a), undefined);
equal(map.get(b), undefined);
equal(map.get(c), undefined);

equal(map2.get(a), undefined);
equal(map2.get(b), undefined);
equal(map2.get(c), undefined);

equal(map.set(a, 1), map, 'map.set should return itself');
equal(map.get(a), 1);
equal(map.set(b, undefined), map);
equal(map.set(a, 2), map);
equal(map.get(a), 2);
equal(map.set(b, undefined), map);

equal(map2.get(a), undefined);
equal(map2.get(b), undefined);
equal(map2.get(c), undefined);

equal(map.set(c, 1), map);
equal(map.get(c), 1);
equal(map.get(a), 2);
equal(map.get(b), undefined);

equal(map2.set(a, 3), map2);
equal(map2.set(b, 4), map2);
equal(map2.set(c, 5), map2);

equal(map2.get(a), 3);
equal(map2.get(b), 4);
equal(map2.get(c), 5);

equal(map.get(c), 1);
equal(map.get(a), 2);
equal(map.get(b), undefined);
});

0 comments on commit 6a1ea35

Please sign in to comment.