aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/js/models/ReferenceCountedModel.js
blob: c188e9f505f329e2b69e854eac7875492c50166f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
var ReferenceCountedModel = Backbone.Model.extend({
	take: function() {
		if (!this._referenceCount) {
			this._referenceCount = 1;
			ReferenceCountedModel._ids[this.id] = this;
		} else
			++this._referenceCount;
	},
	put: function() {
		if (!this._referenceCount)
			throw "Double free in ReferenceCountedModel";
		if (!--this._referenceCount)
			delete ReferenceCountedModel._ids[this.id];
	}
});

ReferenceCountedModel._ids = {};

var ReferenceCountingCollection = Backbone.Collection.extend({
	_prepareModel: function(attrs, options) {
		if (attrs instanceof Backbone.Model) {
			if (!attrs.collection)
				attrs.collection = this;
			attrs.take();
			return attrs;
		}
		options || (options = {});
		options.collection = this;
		var model = new this.model(attrs, options);
		if (model.id in ReferenceCountedModel._ids)
			model = ReferenceCountedModel._ids[model.id];
		model.take();
		if (!model._validate(attrs, options))
			return false;
		return model;
	},
	_removeReference: function(model) {
		if (this === model.collection)
			delete model.collection;
		model.off('all', this._onModelEvent, this);
		model.put();
	}
});