Skip to content

Commit

Permalink
Merge pull request #4708 from runspired/feat/es6-manager
Browse files Browse the repository at this point in the history
es6 RecordArrayManager
  • Loading branch information
bmac authored Jan 13, 2017
2 parents 37f2b50 + d2b04f4 commit ae4aa84
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 47 deletions.
10 changes: 9 additions & 1 deletion addon/-private/system/model/internal-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Relationships from "ember-data/-private/system/relationships/state/create
import Snapshot from "ember-data/-private/system/snapshot";
import EmptyObject from "ember-data/-private/system/empty-object";
import isEnabled from 'ember-data/-private/features';
import OrderedSet from "ember-data/-private/system/ordered-set";

import {
getOwner
Expand Down Expand Up @@ -114,7 +115,6 @@ export default class InternalModel {
this.modelName = modelName;
this.dataHasInitialized = false;
this._loadingPromise = null;
this._recordArrays = undefined;
this._record = null;
this.currentState = RootState.empty;
this.isReloading = false;
Expand All @@ -126,6 +126,7 @@ export default class InternalModel {
// caches for lazy getters
this._modelClass = null;
this.__deferredTriggers = null;
this.__recordArrays = null;
this._references = null;
this._recordReference = null;
this.__inFlightAttributes = null;
Expand All @@ -149,6 +150,13 @@ export default class InternalModel {
return this._recordReference;
}

get _recordArrays() {
if (this.__recordArrays === null) {
this.__recordArrays = OrderedSet.create();
}
return this.__recordArrays;
}

get references() {
if (this._references === null) {
this._references = new EmptyObject();
Expand Down
63 changes: 34 additions & 29 deletions addon/-private/system/record-array-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
FilteredRecordArray,
AdapterPopulatedRecordArray
} from "ember-data/-private/system/record-arrays";
import OrderedSet from "ember-data/-private/system/ordered-set";
import { assert } from 'ember-data/-private/debug';

const {
Expand Down Expand Up @@ -65,11 +64,13 @@ const {
@class RecordArrayManager
@namespace DS
@private
@extends Ember.Object
*/
export default Ember.Object.extend({
init() {
export default class RecordArrayManager {
constructor(options) {
heimdall.increment(create);
this.store = options.store;
this.isDestroying = false;
this.isDestroyed = false;
this.filteredRecordArrays = MapWithDefault.create({
defaultValue() { return []; }
});
Expand All @@ -84,20 +85,20 @@ export default Ember.Object.extend({
this.changedRecords = [];
this.loadedRecords = [];
this._adapterPopulatedRecordArrays = [];
},
}

recordDidChange(internalModel) {
heimdall.increment(recordDidChange);
if (this.changedRecords.push(internalModel) !== 1) { return; }

emberRun.schedule('actions', this, this.updateRecordArrays);
},
}

recordArraysForRecord(internalModel) {
heimdall.increment(recordArraysForRecord);
internalModel._recordArrays = internalModel._recordArrays || OrderedSet.create();

return internalModel._recordArrays;
},
}

/**
This method is invoked whenever data is loaded into the store by the
Expand Down Expand Up @@ -127,18 +128,18 @@ export default Ember.Object.extend({
}

updated.length = 0;
},
}

_recordWasDeleted(internalModel) {
heimdall.increment(_recordWasDeleted);
let recordArrays = internalModel._recordArrays;
let recordArrays = internalModel.__recordArrays;

if (!recordArrays) { return; }

recordArrays.forEach(array => array._removeInternalModels([internalModel]));

internalModel._recordArrays = null;
},
internalModel.__recordArrays = null;
}

_recordWasChanged(internalModel) {
heimdall.increment(_recordWasChanged);
Expand All @@ -149,15 +150,15 @@ export default Ember.Object.extend({
filter = get(array, 'filterFunction');
this.updateFilterRecordArray(array, filter, modelName, internalModel);
});
},
}

//Need to update live arrays on loading
recordWasLoaded(internalModel) {
heimdall.increment(recordWasLoaded);
if (this.loadedRecords.push(internalModel) !== 1) { return; }

emberRun.schedule('actions', this, this._flushLoadedRecords);
},
}

_flushLoadedRecords() {
heimdall.increment(_flushLoadedRecords);
Expand All @@ -183,7 +184,7 @@ export default Ember.Object.extend({
}

this.loadedRecords.length = 0;
},
}

/**
Update an individual filter.
Expand All @@ -204,7 +205,7 @@ export default Ember.Object.extend({
recordArrays.delete(array);
array._removeInternalModels([internalModel]);
}
},
}

_addInternalModelToRecordArray(array, internalModel) {
heimdall.increment(_addRecordToRecordArray);
Expand All @@ -213,7 +214,7 @@ export default Ember.Object.extend({
array._pushInternalModels([internalModel]);
recordArrays.add(array);
}
},
}

syncLiveRecordArray(array, modelName) {
assert(`recordArrayManger.syncLiveRecordArray expects modelName not modelClass as the second param`, typeof modelName === 'string');
Expand All @@ -232,7 +233,7 @@ export default Ember.Object.extend({
}

this.populateLiveRecordArray(array, modelName);
},
}

populateLiveRecordArray(array, modelName) {
assert(`recordArrayManger.populateLiveRecordArray expects modelName not modelClass as the second param`, typeof modelName === 'string');
Expand All @@ -248,7 +249,7 @@ export default Ember.Object.extend({
this._addInternalModelToRecordArray(array, record);
}
}
},
}

/**
This method is invoked if the `filterFunction` property is
Expand Down Expand Up @@ -276,7 +277,7 @@ export default Ember.Object.extend({
this.updateFilterRecordArray(array, filter, modelName, record);
}
}
},
}

/**
Get the `DS.RecordArray` for a modelName, which contains all loaded records of
Expand All @@ -291,7 +292,7 @@ export default Ember.Object.extend({

heimdall.increment(liveRecordArrayFor);
return this.liveRecordArrays.get(modelName);
},
}

/**
Create a `DS.RecordArray` for a modelName.
Expand All @@ -310,7 +311,7 @@ export default Ember.Object.extend({
isLoaded: true,
manager: this
});
},
}

/**
Create a `DS.FilteredRecordArray` for a modelName and register it for updates.
Expand All @@ -337,7 +338,7 @@ export default Ember.Object.extend({
this.registerFilteredRecordArray(array, modelName, filter);

return array;
},
}

/**
Create a `DS.AdapterPopulatedRecordArray` for a modelName with given query.
Expand All @@ -362,7 +363,7 @@ export default Ember.Object.extend({
this._adapterPopulatedRecordArrays.push(array);

return array;
},
}

/**
Register a RecordArray for a given modelName to be backed by
Expand All @@ -383,7 +384,7 @@ export default Ember.Object.extend({
recordArrays.push(array);

this.updateFilter(array, modelName, filter);
},
}

/**
Unregister a RecordArray.
Expand Down Expand Up @@ -414,16 +415,20 @@ export default Ember.Object.extend({
}
}
}
},
}

willDestroy() {
this._super(...arguments);

this.filteredRecordArrays.forEach(value => flatten(value).forEach(destroy));
this.liveRecordArrays.forEach(destroy);
this._adapterPopulatedRecordArrays.forEach(destroy);
this.isDestroyed = true;
}
});

destroy() {
this.isDestroying = true;
Ember.run.schedule('actions', this, this.willDestroy);
}
}

function destroy(entry) {
entry.destroy();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ export default RecordArray.extend({
links: cloneNull(payload.links)
});

internalModels.forEach(internalModel => this.manager.recordArraysForRecord(internalModel).add(this));
for (let i = 0, l = internalModels.length; i < l; i++) {
let internalModel = internalModels[i];
this.manager.recordArraysForRecord(internalModel).add(this)
}

// TODO: should triggering didLoad event be the last action of the runLoop?
Ember.run.once(this, 'trigger', 'didLoad');
Expand Down
4 changes: 2 additions & 2 deletions addon/-private/system/record-arrays/record-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ export default Ember.ArrayProxy.extend(Ember.Evented, {

_dissociateFromOwnRecords() {
this.get('content').forEach(internalModel => {
let recordArrays = internalModel._recordArrays;
let recordArrays = internalModel.__recordArrays;

if (recordArrays) {
recordArrays.delete(this);
Expand All @@ -215,7 +215,7 @@ export default Ember.ArrayProxy.extend(Ember.Evented, {
@private
*/
_unregisterFromManager() {
get(this, 'manager').unregisterRecordArray(this);
this.manager.unregisterRecordArray(this);
},

willDestroy() {
Expand Down
4 changes: 1 addition & 3 deletions addon/-private/system/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,7 @@ Store = Service.extend({
this._super(...arguments);
this._backburner = new Backburner(['normalizeRelationships', 'syncRelationships', 'finished']);
// internal bookkeeping; not observable
this.recordArrayManager = RecordArrayManager.create({
store: this
});
this.recordArrayManager = new RecordArrayManager({ store: this });
this._identityMap = new IdentityMap();
this._pendingSave = [];
this._instanceCache = new ContainerInstanceCache(getOwner(this), this);
Expand Down
2 changes: 0 additions & 2 deletions tests/dummy/app/routes/query/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ export default Route.extend({
let modelName = params.modelName;
delete params.modelName;

heimdall.enableTimelineFeatures();

let token = heimdall.start('ember-data');
return this.get('store').query(modelName, params)
.then((records) => {
Expand Down
29 changes: 20 additions & 9 deletions tests/unit/record-arrays/record-array-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,25 @@ test('#_removeInternalModels', function(assert) {
assert.deepEqual(content, [], 'now contains no models');
});

class FakeInternalModel {
constructor(record) {
this._record = record;
this.__recordArrays = null;
}

get _recordArrays() {
return this.__recordArrays;
}

getRecord() { return this._record; }

createSnapshot() {
return this._record;
}
}

function internalModelFor(record) {
return {
_recordArrays: undefined,
getRecord() { return record; },
createSnapshot() {
return record;
}
};
return new FakeInternalModel(record);
}

test('#save', function(assert) {
Expand Down Expand Up @@ -237,7 +248,7 @@ test('#destroy', function(assert) {
let internalModel1 = internalModelFor(model1);

// TODO: this will be removed once we fix ownership related memory leaks.
internalModel1._recordArrays = {
internalModel1.__recordArrays = {
delete(array) {
didDissociatieFromOwnRecords++;
assert.equal(array, recordArray);
Expand Down Expand Up @@ -308,7 +319,7 @@ test('#destroy', function(assert) {
let internalModel1 = internalModelFor(model1);

// TODO: this will be removed once we fix ownership related memory leaks.
internalModel1._recordArrays = {
internalModel1.__recordArrays = {
delete(array) {
didDissociatieFromOwnRecords++;
assert.equal(array, recordArray);
Expand Down

0 comments on commit ae4aa84

Please sign in to comment.