perform from check in relationship query

This commit is contained in:
Rowan 2024-11-25 09:24:20 -06:00
parent 6224cce8b7
commit a8d9f36b34
2 changed files with 27 additions and 41 deletions

View file

@ -34,10 +34,10 @@ const hasComponents = (world, types, entity) => (
types.every(type => hasComponent(world, type, entity)) types.every(type => hasComponent(world, type, entity))
) )
const matches = (world, types, set = new Set()) => entity => { const matches = (world, types, results, set = new Set()) => entity => {
if (set.has(entity)) { if (set.has(entity)) {
return true return true
} else if (hasComponents(world, types, entity)) { } else if (hasComponents(world, types, entity) && (results == null || results.includes(entity))) {
set.add(entity) set.add(entity)
return true return true
} else { } else {
@ -51,23 +51,15 @@ const queryRelationship = (query, world) => {
return node.relationship ? node.from : node return node.relationship ? node.from : node
}) })
const matchesFrom = matches(world, from.components.map(prop('type'))) const matchesFrom = matches(world, from.components.map(prop('type')), from.query(world))
const matchesTo = matches(world, to.components.map(prop('type'))) const matchesTo = matches(world, to.components.map(prop('type')))
const Edge = edge.components[0].type const Edge = edge.components[0].type
// FIXME: filter these to make sure the from components match the previous edge's to components
const edges = edge.query(world) const edges = edge.query(world)
console.log('59', edges)
const result = [] const result = []
for (let i = 0; i < edges.length; i++) { for (let i = 0; i < edges.length; i++) {
const eid = edges[i] const eid = edges[i]
if (matchesFrom(Edge.from[eid])) {
console.log('65', eid, from.components.map(({ name, label }) => ({ name, label })))
if (matchesTo(Edge.to[eid])) {
console.log('67', eid, to.components.map(({ name, label }) => ({ name, label })))
}
}
if (matchesFrom(Edge.from[eid]) && matchesTo(Edge.to[eid])) { if (matchesFrom(Edge.from[eid]) && matchesTo(Edge.to[eid])) {
result.push(eid) result.push(eid)
} }
@ -84,7 +76,6 @@ const executeQuery = curry((query, world) => {
} }
const edges = queryRelationship(query, world) const edges = queryRelationship(query, world)
console.log('80', query.from.components, edges)
if (query.to.relationship) { if (query.to.relationship) {
return edges.reduce((acc, eid) => { return edges.reduce((acc, eid) => {
@ -94,12 +85,10 @@ const executeQuery = curry((query, world) => {
query.to query.to
) )
const a = executeQuery(next, world) return executeQuery(next, world)
.map(child => [eid, ...child]) .map(child => [eid, ...child])
.map(([l, r]) => [{ entity: l, query }, r]) .map(([l, r]) => [{ entity: l, query }, r])
//.concat(acc) .concat(acc)
console.log(a)
return a.concat(acc)
}, []) }, [])
} else { } else {
return assembleQuery(query, edges) return assembleQuery(query, edges)
@ -162,11 +151,8 @@ export const query = curry((input, { world, component }) => {
return parseAll(q, input).map(({ use, ...rest }) => { return parseAll(q, input).map(({ use, ...rest }) => {
const useWorld = world[use?.value ?? 'default'] const useWorld = world[use?.value ?? 'default']
const preparedQuery = prepareQuery(rest, component) const preparedQuery = prepareQuery(rest, component)
//console.log('prepared', preparedQuery)
const results = executeQuery(preparedQuery, useWorld) const results = executeQuery(preparedQuery, useWorld)
//console.log('results', results)
const returns = resolveReturns(results) const returns = resolveReturns(results)
//console.log('returns', returns)
return returns return returns
}) })
}) })

View file

@ -53,18 +53,18 @@ describe('query', () => {
relate(world, b, Knows, a) // 9 relate(world, b, Knows, a) // 9
relate(world, c, Knows, player) // 10 relate(world, c, Knows, player) // 10
//assert.deepEqual( assert.deepEqual(
// query('MATCH (player:Player) RETURN player', engine).unwrap(), query('MATCH (player:Player) RETURN player', engine).unwrap(),
// [{ player: {} }] [{ player: {} }]
//) )
//assert.deepEqual( assert.deepEqual(
// query('MATCH (player:Player)-[e1:Knows]->(a:NPC) RETURN player, e1, a', engine).unwrap(), query('MATCH (player:Player)-[e1:Knows]->(a:NPC) RETURN player, e1, a', engine).unwrap(),
// [ [
// { player: {}, e1: { from: 0, to: 1 }, a: {} }, { player: {}, e1: { from: 0, to: 1 }, a: {} },
// { player: {}, e1: { from: 0, to: 3 }, a: {} } { player: {}, e1: { from: 0, to: 3 }, a: {} }
// ] ]
//) )
assert.deepEqual( assert.deepEqual(
query('MATCH (player:Player)-[e1:Knows]->(a:NPC)-[e2:Knows]->(b:NPC) RETURN player, e1, a, e2, b', engine).unwrap(), query('MATCH (player:Player)-[e1:Knows]->(a:NPC)-[e2:Knows]->(b:NPC) RETURN player, e1, a, e2, b', engine).unwrap(),
@ -75,17 +75,17 @@ describe('query', () => {
) )
}) })
//it('should match multiple components', () => { it('should match multiple components', () => {
// const world = engine.world.default const world = engine.world.default
// const { Player, Health } = engine.component const { Player, Health } = engine.component
// const player = create(world, Player, Health) const player = create(world, Player, Health)
// Health.max[player] = 50 Health.max[player] = 50
// Health.current[player] = 25 Health.current[player] = 25
// assert.deepEqual( assert.deepEqual(
// query('MATCH (e:Entity, h:Health) return e, h.max', engine).unwrap(), query('MATCH (e:Entity, h:Health) return e, h.max', engine).unwrap(),
// [{ e: 11, h: { current: 25, max: 50 } }] [{ e: 11, h: { current: 25, max: 50 } }]
// ) )
//}) })
}) })