Skip to content

Commit

Permalink
Add Entity.findScript[s] functions (#5851)
Browse files Browse the repository at this point in the history
* Add Entity.findScript[s] functions

* Update types-fixup.mjs

* Use optional chaining syntax
  • Loading branch information
NewboO committed Nov 28, 2023
1 parent d3844d6 commit 811de63
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/framework/entity.js
Expand Up @@ -379,6 +379,36 @@ class Entity extends GraphNode {
});
}

/**
* Search the entity and all of its descendants for the first script instance of specified type.
*
* @param {string|Class<import('./script/script-type.js').ScriptType>} nameOrType - The name or type of {@link ScriptType}.
* @returns {import('./script/script-type.js').ScriptType|undefined} A script instance of specified type, if the entity or any of its descendants
* has one. Returns undefined otherwise.
* @example
* // Get the first found "playerController" instance in the hierarchy tree that starts with this entity
* var controller = entity.findScript("playerController");
*/
findScript(nameOrType) {
const entity = this.findOne(node => node.c?.script?.has(nameOrType));
return entity?.c.script.get(nameOrType);
}

/**
* Search the entity and all of its descendants for all script instances of specified type.
*
* @param {string|Class<import('./script/script-type.js').ScriptType>} nameOrType - The name or type of {@link ScriptType}.
* @returns {import('./script/script-type.js').ScriptType[]} All script instances of specified type in the entity or any of its
* descendants. Returns empty array if none found.
* @example
* // Get all "playerController" instances in the hierarchy tree that starts with this entity
* var controllers = entity.findScripts("playerController");
*/
findScripts(nameOrType) {
const entities = this.find(node => node.c?.script?.has(nameOrType));
return entities.map(entity => entity.c.script.get(nameOrType));
}

/**
* Get the GUID value for this Entity.
*
Expand Down
145 changes: 145 additions & 0 deletions test/framework/entity.test.mjs
Expand Up @@ -675,6 +675,151 @@ describe('Entity', function () {

});

describe('#findScript', function () {

it('finds script on single entity', function () {
const MyScript = createScript('myScript');
const e = new Entity();
e.addComponent('script');
e.script.create('myScript');
const script = e.findScript('myScript');
expect(script).to.be.an.instanceof(MyScript);
});

it('returns undefined when script is not found', function () {
const root = new Entity();
const child = new Entity();
root.addChild(child);
child.addComponent('script');
const script = root.findScript('myScript');
expect(script).to.be.undefined;
});

it('returns undefined when script component is not found', function () {
const root = new Entity();
const child = new Entity();
root.addChild(child);
const script = root.findScript('myScript');
expect(script).to.be.undefined;
});

it('finds script on child entity', function () {
const MyScript = createScript('myScript');
const root = new Entity();
const child = new Entity();
root.addChild(child);
child.addComponent('script');
child.script.create('myScript');
const script = root.findScript('myScript');
expect(script).to.be.an.instanceof(MyScript);
});

it('finds script on grandchild entity', function () {
const MyScript = createScript('myScript');
const root = new Entity();
const child = new Entity();
const grandchild = new Entity();
root.addChild(child);
child.addChild(grandchild);
grandchild.addComponent('script');
grandchild.script.create('myScript');
const script = root.findScript('myScript');
expect(script).to.be.an.instanceof(MyScript);
});

it('does not find script on parent entity', function () {
createScript('myScript');
const root = new Entity();
const child = new Entity();
root.addChild(child);
root.addComponent('script');
root.script.create('myScript');
const script = child.findScript('myScript');
expect(script).to.be.undefined;
});

});

describe('#findScripts', function () {

it('finds scripts on single entity', function () {
const MyScript = createScript('myScript');
const e = new Entity();
e.addComponent('script');
e.script.create('myScript');
const scripts = e.findScripts('myScript');
expect(scripts).to.be.an('array');
expect(scripts.length).to.equal(1);
expect(scripts[0]).to.be.an.instanceof(MyScript);
});

it('returns empty array when no scripts are found', function () {
const root = new Entity();
const child = new Entity();
root.addChild(child);
child.addComponent('script');
const scripts = root.findScripts('myScript');
expect(scripts).to.be.an('array');
expect(scripts.length).to.equal(0);
});

it('returns empty array when no script component are found', function () {
const root = new Entity();
const child = new Entity();
root.addChild(child);
const scripts = root.findScripts('myScript');
expect(scripts).to.be.an('array');
expect(scripts.length).to.equal(0);
});

it('finds scripts on child entity', function () {
const MyScript = createScript('myScript');
const root = new Entity();
const child = new Entity();
root.addChild(child);
child.addComponent('script');
child.script.create('myScript');
const scripts = root.findScripts('myScript');
expect(scripts).to.be.an('array');
expect(scripts.length).to.equal(1);
expect(scripts[0]).to.be.an.instanceof(MyScript);
});

it('finds scripts on 3 entity hierarchy', function () {
const MyScript = createScript('myScript');
const root = new Entity();
const child = new Entity();
const grandchild = new Entity();
root.addChild(child);
child.addChild(grandchild);
root.addComponent('script');
root.script.create('myScript');
child.addComponent('script');
child.script.create('myScript');
grandchild.addComponent('script');
grandchild.script.create('myScript');
const scripts = root.findScripts('myScript');
expect(scripts).to.be.an('array');
expect(scripts.length).to.equal(3);
expect(scripts[0]).to.be.an.instanceof(MyScript);
expect(scripts[1]).to.be.an.instanceof(MyScript);
expect(scripts[2]).to.be.an.instanceof(MyScript);
});

it('does not find scripts on parent entity', function () {
createScript('myScript');
const root = new Entity();
const child = new Entity();
root.addChild(child);
root.addComponent('script');
root.script.create('myScript');
const scripts = child.findScripts('myScript');
expect(scripts).to.be.an('array');
expect(scripts.length).to.equal(0);
});

});

describe('#removeComponent', function () {

it('removes a component from the entity', function () {
Expand Down
5 changes: 5 additions & 0 deletions utils/types-fixup.mjs
Expand Up @@ -4,6 +4,7 @@ import fs from 'fs';
const regex = /Class<(.*?)>/g;
const paths = [
'./types/framework/components/script/component.d.ts',
'./types/framework/entity.d.ts',
'./types/framework/script/script-attributes.d.ts',
'./types/framework/script/script-registry.d.ts',
'./types/framework/script/script.d.ts'
Expand All @@ -16,6 +17,10 @@ paths.forEach((path, index) => {
if (index === 0) {
dts += `
import { ScriptType } from '../../script/script-type.js';
`;
} else if (index === 1) {
dts += `
import { ScriptType } from './script/script-type.js';
`;
} else {
dts += `
Expand Down

0 comments on commit 811de63

Please sign in to comment.