From 243adea3e64edfd3a6ccadf3b01cf410f04a9cdc Mon Sep 17 00:00:00 2001 From: cha0s Date: Tue, 23 Jun 2020 19:44:31 -0500 Subject: [PATCH] flow: typing --- packages/behavior/compile.js | 14 ++++++++ packages/behavior/context.js | 12 +++++++ packages/behavior/index.js | 3 ++ packages/behavior/type.js | 39 +++++++++++++++++------ packages/behavior/types.hooks.js | 15 +++++---- packages/entity/traits/alive.trait.js | 2 +- packages/physics/traits/collider.trait.js | 4 +-- 7 files changed, 71 insertions(+), 18 deletions(-) diff --git a/packages/behavior/compile.js b/packages/behavior/compile.js index 71bd78f..91218ba 100644 --- a/packages/behavior/compile.js +++ b/packages/behavior/compile.js @@ -17,6 +17,20 @@ export default function compile(variant) { return compiler(variant); } +export function isCompilable(variant) { + if ('object' !== typeof variant || null === variant) { + return false; + } + if (!variant.type) { + return false; + } + return !!compilers()[variant.type]; +} + +export function makeCompilable(variant) { + return isCompilable(variant) ? variant : {type: 'literal', value: variant}; +} + registerHooks({ autoreg$accept: (type, M) => { if ('hooks' === type && 'behaviorCompilers' in M) { diff --git a/packages/behavior/context.js b/packages/behavior/context.js index ed3c8fe..70ff9af 100644 --- a/packages/behavior/context.js +++ b/packages/behavior/context.js @@ -43,6 +43,18 @@ export default class Context { this.addObjectMap(globals()); } + description() { + const children = Object.entries(this.all()) + .reduce((r, [key, [, type]]) => ({ + ...r, + [key]: {type}, + }), {}); + return { + children, + type: 'context', + }; + } + destroy() { this.map.clear(); } diff --git a/packages/behavior/index.js b/packages/behavior/index.js index 071d3b8..aee7960 100644 --- a/packages/behavior/index.js +++ b/packages/behavior/index.js @@ -12,6 +12,8 @@ export { export { default as compile, compilers, + isCompilable, + makeCompilable, } from './compile'; export { @@ -24,6 +26,7 @@ export { description, digraph, fitsInto, + fromLiteral, invertedDigraph, types, } from './type'; diff --git a/packages/behavior/type.js b/packages/behavior/type.js index 30f83d7..8bd52e0 100644 --- a/packages/behavior/type.js +++ b/packages/behavior/type.js @@ -16,9 +16,8 @@ function typeDigraph(type, marked = {}) { marked[type] = true; return []; } - const description = description(type, undefined); const subtypes = Object.keys( - Object.values(description.children) + Object.values(description(type, undefined).children) .reduce((r, {type: childType}) => ({ ...r, [childType]: true, @@ -29,7 +28,7 @@ function typeDigraph(type, marked = {}) { } export const digraph = memoize(() => { - return Object.keys(allTypes()) + return Object.keys(types()) .reduce((r, type) => ({ ...r, [type]: typeDigraph(type), @@ -37,12 +36,12 @@ export const digraph = memoize(() => { }); export const invertedDigraph = memoize(() => { - const digraph = digraph(); + const dig = digraph(); let inverted = {}; - const fromTypes = Object.keys(digraph); + const fromTypes = Object.keys(dig); for (let i = 0; i < fromTypes.length; i++) { const fromType = fromTypes[i]; - const toTypes = digraph[fromType]; + const toTypes = dig[fromType]; for (let j = 0; j < toTypes.length; j++) { const toType = toTypes[j]; inverted[toType] = (inverted[toType] || {}); @@ -65,7 +64,7 @@ export const candidates = (description, type) => { : Object.entries(children) .reduce((r, [key, {type}]) => ( r.concat( - types.some((candidate) => typeFits(candidate, type)) + types.some((candidate) => fitsInto(candidate, type)) ? [key] : [] ) @@ -86,7 +85,7 @@ export function description(type, instance) { } return { ...defaults, - ...('function' === typeof allTypes[type] ? allTypes[type](variable) : allTypes[type]) + ...('function' === typeof allTypes[type] ? allTypes[type](instance) : allTypes[type]) }; } @@ -97,10 +96,32 @@ export function fitsInto(candidate, reference) { return -1 !== reference.split('|').map((type) => type.trim()).indexOf(candidate); } +export function fromLiteral(value) { + if ('undefined' === typeof value) { + return 'undefined'; + } + if (null === value) { + return 'null'; + } + if ('number' === typeof value) { + return 'number'; + } + if ('string' === typeof value) { + return 'string'; + } + if ('boolean' === typeof value) { + return 'bool'; + } + if (value.length && 2 === value.length && value instanceof Array) { + return 'vector'; + } + return 'object'; +} + registerHooks({ autoreg$accept: (type, M) => { if ('hooks' === type && 'behaviorTypes' in M) { - allTypes.cache.clear(); + types.cache.clear(); digraph.cache.clear(); invertedDigraph.cache.clear(); } diff --git a/packages/behavior/types.hooks.js b/packages/behavior/types.hooks.js index 696d3f2..af5b61a 100644 --- a/packages/behavior/types.hooks.js +++ b/packages/behavior/types.hooks.js @@ -40,8 +40,8 @@ export function behaviorTypes() { ['condition', { type: 'condition', }], - ['actions', { - type: 'actions', + ['expressions', { + type: 'expressions', }], ], }, @@ -49,8 +49,8 @@ export function behaviorTypes() { type: 'void', label: 'Run $1 in parallel.', args: [ - ['actions', { - type: 'actions', + ['expressions', { + type: 'expressions', }], ], }, @@ -58,8 +58,8 @@ export function behaviorTypes() { type: 'void', label: 'Run $1 serially.', args: [ - ['actions', { - type: 'actions', + ['expressions', { + type: 'expressions', }], ], }, @@ -68,6 +68,9 @@ export function behaviorTypes() { number: { defaultLiteral: 0, }, + object: { + defaultLiteral: {}, + }, stream: {}, string: { defaultLiteral: '', diff --git a/packages/entity/traits/alive.trait.js b/packages/entity/traits/alive.trait.js index e1f2c72..1c58171 100644 --- a/packages/entity/traits/alive.trait.js +++ b/packages/entity/traits/alive.trait.js @@ -83,7 +83,7 @@ export default class Alive extends decorate(Trait) { label: 'Death sound', }, deathActions: { - type: 'actions', + type: 'expressions', label: 'Death actions', }, deathCondition: { diff --git a/packages/physics/traits/collider.trait.js b/packages/physics/traits/collider.trait.js index 7f1a55e..4d548d9 100644 --- a/packages/physics/traits/collider.trait.js +++ b/packages/physics/traits/collider.trait.js @@ -92,11 +92,11 @@ export default class Collider extends decorate(Trait) { label: 'Collides with groups', }, collisionEndActions: { - type: 'actions', + type: 'expressions', label: 'Collision ending actions', }, collisionStartActions: { - type: 'actions', + type: 'expressions', label: 'Collision starting actions', }, collisionGroup: {