Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/framework/handlers/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ class TemplateHandler extends ResourceHandler {
this.decoder ??= new TextDecoder('utf-8');
return new Template(this._app, JSON.parse(this.decoder.decode(data)));
}

patch(asset, registry) {
// only process if this looks like valid template data
if (!asset || !asset.resource || !asset.data || !asset.data.entities) {
return;
}

const template = asset.resource;

// the `data` setter will handle cache invalidation
template.data = asset.data;
}
}

export { TemplateHandler };
10 changes: 10 additions & 0 deletions src/framework/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ class Template {

this._templateRoot = parser.parse(this._data);
}

set data(value) {
this._data = value;
// cache invalidation: the next instantiate() will parse and use the new _data
this._templateRoot = null;
}

get data() {
return this._data;
}
}

export { Template };
67 changes: 67 additions & 0 deletions test/framework/handlers/template-handler.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { expect } from 'chai';

import { Asset } from '../../../src/framework/asset/asset.js';
import { createApp } from '../../app.mjs';
import { jsdomSetup, jsdomTeardown } from '../../jsdom.mjs';

// Example template data in the database
function createFakeTemplateData(name) {
const rootId = 'root-guid';
return {
entities: {
[rootId]: {
name,
resource_id: rootId,
parent: null,
children: [],
position: [0, 0, 0],
rotation: [0, 0, 0],
scale: [1, 1, 1],
components: {}
}
}
};
}

describe('TemplateHandler', function () {
let app;

beforeEach(function () {
jsdomSetup();
app = createApp();
});

afterEach(function () {
app?.destroy();
app = null;
jsdomTeardown();
});


it('should reparse the new template data', function (done) {
// For this test case we pretend the data is already loaded
const file = null;

const data1 = createFakeTemplateData('root1');
const data2 = createFakeTemplateData('root2');

const templateAsset = new Asset('Template B', 'template', file, data1);

app.assets.add(templateAsset);
app.assets.load(templateAsset);

templateAsset.ready(function (asset) {
const first = asset.resource.instantiate();
expect(first.name).to.equal('root1');

// change asset data: should trigger handler.patch and resource invalidation
asset.data = data2;

expect(asset.resource.data).to.equal(asset.data);

const second = asset.resource.instantiate();
expect(second.name).to.equal('root2');
done();
});
});
});