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))
)
const matches = (world, types, set = new Set()) => entity => {
const matches = (world, types, results, set = new Set()) => entity => {
if (set.has(entity)) {
return true
} else if (hasComponents(world, types, entity)) {
} else if (hasComponents(world, types, entity) && (results == null || results.includes(entity))) {
set.add(entity)
return true
} else {
@ -51,23 +51,15 @@ const queryRelationship = (query, world) => {
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 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)
console.log('59', edges)
const result = []
for (let i = 0; i < edges.length; 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])) {
result.push(eid)
}
@ -84,7 +76,6 @@ const executeQuery = curry((query, world) => {
}
const edges = queryRelationship(query, world)
console.log('80', query.from.components, edges)
if (query.to.relationship) {
return edges.reduce((acc, eid) => {
@ -94,12 +85,10 @@ const executeQuery = curry((query, world) => {
query.to
)
const a = executeQuery(next, world)
return executeQuery(next, world)
.map(child => [eid, ...child])
.map(([l, r]) => [{ entity: l, query }, r])
//.concat(acc)
console.log(a)
return a.concat(acc)
.concat(acc)
}, [])
} else {
return assembleQuery(query, edges)
@ -162,11 +151,8 @@ export const query = curry((input, { world, component }) => {
return parseAll(q, input).map(({ use, ...rest }) => {
const useWorld = world[use?.value ?? 'default']
const preparedQuery = prepareQuery(rest, component)
//console.log('prepared', preparedQuery)
const results = executeQuery(preparedQuery, useWorld)
//console.log('results', results)
const returns = resolveReturns(results)
//console.log('returns', returns)
return returns
})
})

View file

@ -53,18 +53,18 @@ describe('query', () => {
relate(world, b, Knows, a) // 9
relate(world, c, Knows, player) // 10
//assert.deepEqual(
// query('MATCH (player:Player) RETURN player', engine).unwrap(),
// [{ player: {} }]
//)
assert.deepEqual(
query('MATCH (player:Player) RETURN player', engine).unwrap(),
[{ player: {} }]
)
//assert.deepEqual(
// 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: 3 }, a: {} }
// ]
//)
assert.deepEqual(
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: 3 }, a: {} }
]
)
assert.deepEqual(
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', () => {
// const world = engine.world.default
// const { Player, Health } = engine.component
// const player = create(world, Player, Health)
it('should match multiple components', () => {
const world = engine.world.default
const { Player, Health } = engine.component
const player = create(world, Player, Health)
// Health.max[player] = 50
// Health.current[player] = 25
// assert.deepEqual(
// query('MATCH (e:Entity, h:Health) return e, h.max', engine).unwrap(),
// [{ e: 11, h: { current: 25, max: 50 } }]
// )
//})
Health.max[player] = 50
Health.current[player] = 25
assert.deepEqual(
query('MATCH (e:Entity, h:Health) return e, h.max', engine).unwrap(),
[{ e: 11, h: { current: 25, max: 50 } }]
)
})
})