Skip to content

Commit

Permalink
fix: Fixes live query, using comp change events (#547)
Browse files Browse the repository at this point in the history
  • Loading branch information
mflerackers authored Nov 30, 2024
1 parent ac2d90f commit f605105
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 10 deletions.
35 changes: 35 additions & 0 deletions examples/livequery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
kaplay();

loadSprite("ghosty", "/sprites/ghosty.png");

const q = get("color", { liveUpdate: true });

loop(5, () => {
if (q.length < 10) {
const x = rand(0, width());
const y = rand(0, height());

const ghost = add([
sprite("ghosty"),
pos(x, y),
area(),
timer(),
color(RED),
"ghost"
]);
ghost.wait(5, () => {
ghost.unuse("color");
ghost.wait(5, () => {
ghost.use(color(RED));
})
})
}
});

onClick("ghost", (ghost) => {
ghost.destroy();
});

loop(1, () => {
debug.log(`There are ${q.length} touchable ghosts`);
});
4 changes: 2 additions & 2 deletions src/game/events/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,13 @@ export const onDestroy = overload2((action: (obj: GameObj) => void) => {

export const onUse = overload2((action: (obj: GameObj, id: string) => void) => {
return _k.game.events.on("use", action);
}, (tag: Tag, action: (obj: GameObj, id: string) => void) => {
}, (tag: Tag, action: (obj: GameObj) => void) => {
return on("use", tag, action);
});

export const onUnuse = overload2((action: (obj: GameObj, id: string) => void) => {
return _k.game.events.on("unuse", action);
}, (tag: Tag, action: (obj: GameObj, id: string) => void) => {
}, (tag: Tag, action: (obj: GameObj) => void) => {
return on("unuse", tag, action);
});

Expand Down
17 changes: 16 additions & 1 deletion src/game/make.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,15 +384,30 @@ export function make<T>(comps: CompList<T> = []): GameObj<T> {

const events: KEventController[] = [];

// TODO: handle when object add / remove tags
// TODO: clean up when obj destroyed
events.push(_k.k.onAdd((obj) => {
if (isChild(obj) && checkTagsOrComps(obj, t)) {
list.push(obj);
}
}));
events.push(_k.k.onDestroy((obj) => {
if (checkTagsOrComps(obj, t)) {
const idx = list.findIndex((o) => o.id === obj.id);
if (idx !== -1) {
list.splice(idx, 1);
}
}
}));
events.push(_k.k.onUse((obj) => {
if (isChild(obj) && checkTagsOrComps(obj, t)) {
const idx = list.findIndex((o) => o.id === obj.id);
if (idx == -1) {
list.push(obj);
}
}
}));
events.push(_k.k.onUnuse((obj, id) => {
if (isChild(obj) && !checkTagsOrComps(obj, t)) {
const idx = list.findIndex((o) => o.id === obj.id);
if (idx !== -1) {
list.splice(idx, 1);
Expand Down
13 changes: 8 additions & 5 deletions src/kaplay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ import {
onCollideEnd,
onCollideUpdate,
onDestroy,
onUse,
onUnuse,
onDraw,
onError,
onFixedUpdate,
Expand Down Expand Up @@ -349,8 +351,7 @@ const kaplay = <
>(
gopt: KAPLAYOpt<TPlugins, TButtons> = {},
): TPlugins extends [undefined] ? KAPLAYCtx<TButtons, TButtonsName>
: KAPLAYCtx<TButtons, TButtonsName> & MergePlugins<TPlugins> =>
{
: KAPLAYCtx<TButtons, TButtonsName> & MergePlugins<TPlugins> => {
if (_k.k) {
console.warn(
"KAPLAY already initialized, you are calling kaplay() multiple times, it may lead bugs!",
Expand Down Expand Up @@ -972,7 +973,7 @@ const kaplay = <

// TODO: this should only run once
app.run(
() => {},
() => { },
() => {
frameStart();

Expand Down Expand Up @@ -1035,7 +1036,7 @@ const kaplay = <
// clear canvas
gl.clear(
gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT
| gl.STENCIL_BUFFER_BIT,
| gl.STENCIL_BUFFER_BIT,
);

// unbind everything
Expand Down Expand Up @@ -1266,6 +1267,8 @@ const kaplay = <
onDraw,
onAdd,
onDestroy,
onUse,
onUnuse,
onClick,
onCollide,
onCollideUpdate,
Expand Down Expand Up @@ -1481,7 +1484,7 @@ const kaplay = <
// export everything to window if global is set
if (gopt.global !== false) {
for (const key in ctx) {
(<any> window[<any> key]) = ctx[key as keyof KAPLAYCtx];
(<any>window[<any>key]) = ctx[key as keyof KAPLAYCtx];
}
}

Expand Down
41 changes: 39 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,10 @@ export interface KAPLAYCtx<
* // Recursively get all children and descendents
* const allObjs = get("*", { recursive: true });
* ```
*
* // Get a live query which updates in real-time
* const allObjs = get("*", { liveUpdate: true });
* ```
*
* @returns A list of game objects that have the tag.
* @since v2000.0
Expand Down Expand Up @@ -338,6 +342,18 @@ export interface KAPLAYCtx<
* include: "friend",
* exclude: "bean",
* }); // will return [bag]
*
* // get all visible friends
* query({
* include: "friend",
* visible: true,
* });
*
* // get all friends less than 150 pixels from bean
* bean.query({
* include: "friend",
* distance: 150,
* });
*
* ```
*
Expand Down Expand Up @@ -1597,6 +1613,7 @@ export interface KAPLAYCtx<
/**
* Register an event that runs when an object is added
*
* @param tag - The tag to match, only called for objects with a matching tag.
* @param action - The function that runs when an object is added.
*
* @example
Expand All @@ -1619,7 +1636,6 @@ export interface KAPLAYCtx<
/**
* Register an event that runs when an object with the provided tag is destroyed.
*
* @param tag - The tag to listen for.
* @param action - The function that runs when an object is destroyed.
*
* @example
Expand All @@ -1646,6 +1662,7 @@ export interface KAPLAYCtx<
/**
* Register an event that runs when an object is destroyed.
*
* @param tag - The tag to match, only called for objects with a matching tag.
* @param action - The function that runs when an object is destroyed.
*
* @example
Expand All @@ -1667,6 +1684,26 @@ export interface KAPLAYCtx<
* @group Events
*/
onDestroy(action: (obj: GameObj) => void): KEventController;
/**
* Register an event that runs when an object starts using a component.
*
* @param action - The function that runs when an object starts using component.
*
* @returns The event controller.
* @since v3001.1
* @group Events
*/
onUse(action: (obj: GameObj, id: string) => void): KEventController;
/**
* Register an event that runs when an object stops using a component.
*
* @param action - The function that runs when an object stops using a component.
*
* @returns The event controller.
* @since v3001.1
* @group Events
*/
onUnuse(action: (obj: GameObj, id: string) => void): KEventController;
/**
* Register an event that runs when all assets finished loading.
*
Expand Down Expand Up @@ -2246,7 +2283,7 @@ export interface KAPLAYCtx<
* @returns The event controller.
* @since v3001.0
* @group Input
*/
*/
onMousePress(
btn: MouseButton | MouseButton[],
action: (m: MouseButton) => void,
Expand Down

0 comments on commit f605105

Please sign in to comment.