|
1 | | ---[[ |
2 | | - Signals let you subscribe to component add, change, and remove events with |
3 | | - multiple listeners per component. Unlike hooks (see 110_hooks.luau), which |
4 | | - allow only one OnAdd, OnChange, and OnRemove per component, signals support |
5 | | - any number of subscribers and each subscription returns an unsubscribe |
6 | | - function so you can clean up when you no longer need to listen. |
7 | | -
|
8 | | - Use signals when you need several independent systems to react to the same |
9 | | - component lifecycle events, or when you want to subscribe and unsubscribe |
10 | | - dynamically (e.g. a UI that only cares while it's mounted). |
11 | | -]] |
12 | | - |
13 | | -local jecs = require("@jecs") |
14 | | -local world = jecs.world() |
15 | | - |
16 | | -local Position = world:component() :: jecs.Id<{ x: number, y: number }> |
17 | | - |
18 | | ---[[ |
19 | | - world:added(component, fn) |
20 | | -
|
21 | | - Subscribe to "component added" events. Your callback is invoked with: |
22 | | - (entity, id, value, oldarchetype) whenever the component is added to an entity. |
23 | | -
|
24 | | - Returns a function; call it to unsubscribe. |
25 | | -]] |
26 | | - |
27 | | -local unsub_added = world:added(Position, function(entity, id, value, oldarchetype) |
28 | | - print(`Position added to entity {entity}: ({value.x}, {value.y})`) |
29 | | -end) |
30 | | - |
31 | | ---[[ |
32 | | - world:changed(component, fn) |
33 | | -
|
34 | | - Subscribe to "component changed" events. Your callback is invoked with: |
35 | | - (entity, id, value, oldarchetype) whenever the component's value is updated |
36 | | - on an entity (e.g. via world:set). |
37 | | -
|
38 | | - Returns a function; call it to unsubscribe. |
39 | | -]] |
40 | | - |
41 | | -local unsub_changed = world:changed(Position, function(entity, id, value, oldarchetype) |
42 | | - print(`Position changed on entity {entity}: ({value.x}, {value.y})`) |
43 | | -end) |
44 | | - |
45 | | ---[[ |
46 | | - world:removed(component, fn) |
47 | | -
|
48 | | - Subscribe to "component removed" events. Your callback is invoked with: |
49 | | - (entity, id, delete?) when the component is removed. The third argument |
50 | | - `delete` is true when the entity is being deleted, false or nil when |
51 | | - only the component was removed (same semantics as OnRemove in 110_hooks). |
52 | | -
|
53 | | - Returns a function; call it to unsubscribe. |
54 | | -]] |
55 | | - |
56 | | -local unsub_removed = world:removed(Position, function(entity, id, delete) |
57 | | - if delete then |
58 | | - print(`Entity {entity} deleted (had Position)`) |
59 | | - else |
60 | | - print(`Position removed from entity {entity}`) |
61 | | - end |
62 | | -end) |
63 | | - |
64 | | -local e = world:entity() |
65 | | -world:set(e, Position, { x = 10, y = 20 }) -- added |
66 | | -world:set(e, Position, { x = 30, y = 40 }) -- changed |
67 | | -world:remove(e, Position) -- removed |
68 | | - |
69 | | -world:added(Position, function(entity) |
70 | | - print("Second listener: Position added") |
71 | | -end) |
72 | | - |
73 | | -world:set(e, Position, { x = 0, y = 0 }) -- Multiple listeners are all invoked |
74 | | - |
75 | | --- Unsubscribe when you no longer need to listen |
76 | | -unsub_added() |
77 | | -unsub_changed() |
78 | | -unsub_removed() |
79 | | - |
80 | | -world:set(e, Position, { x = 1, y = 1 }) |
81 | | -world:remove(e, Position) |
| 1 | +--[[ |
| 2 | + Signals let you subscribe to component add, change, and remove events with |
| 3 | + multiple listeners per component. Unlike hooks (see 110_hooks.luau), which |
| 4 | + allow only one OnAdd, OnChange, and OnRemove per component, signals support |
| 5 | + any number of subscribers and each subscription returns an unsubscribe |
| 6 | + function so you can clean up when you no longer need to listen. |
| 7 | +
|
| 8 | + Use signals when you need several independent systems to react to the same |
| 9 | + component lifecycle events, or when you want to subscribe and unsubscribe |
| 10 | + dynamically (e.g. a UI that only cares while it's mounted). |
| 11 | +]] |
| 12 | + |
| 13 | +local jecs = require("@jecs") |
| 14 | +local world = jecs.world() |
| 15 | + |
| 16 | +local Position = world:component() :: jecs.Id<{ x: number, y: number }> |
| 17 | + |
| 18 | +--[[ |
| 19 | + world:added(component, fn) |
| 20 | +
|
| 21 | + Subscribe to "component added" events. Your callback is invoked with: |
| 22 | + (entity, id, value, oldarchetype) whenever the component is added to an entity. |
| 23 | +
|
| 24 | + Returns a function; call it to unsubscribe. |
| 25 | +]] |
| 26 | + |
| 27 | +local unsub_added = world:added(Position, function(entity, id, value, oldarchetype) |
| 28 | + print(`Position added to entity {entity}: ({value.x}, {value.y})`) |
| 29 | +end) |
| 30 | + |
| 31 | +--[[ |
| 32 | + world:changed(component, fn) |
| 33 | +
|
| 34 | + Subscribe to "component changed" events. Your callback is invoked with: |
| 35 | + (entity, id, value, oldarchetype) whenever the component's value is updated |
| 36 | + on an entity (e.g. via world:set). |
| 37 | +
|
| 38 | + Returns a function; call it to unsubscribe. |
| 39 | +]] |
| 40 | + |
| 41 | +local unsub_changed = world:changed(Position, function(entity, id, value, oldarchetype) |
| 42 | + print(`Position changed on entity {entity}: ({value.x}, {value.y})`) |
| 43 | +end) |
| 44 | + |
| 45 | +--[[ |
| 46 | + world:removed(component, fn) |
| 47 | +
|
| 48 | + Subscribe to "component removed" events. Your callback is invoked with: |
| 49 | + (entity, id, delete?) when the component is removed. The third argument |
| 50 | + `delete` is true when the entity is being deleted, false or nil when |
| 51 | + only the component was removed (same semantics as OnRemove in 110_hooks). |
| 52 | +
|
| 53 | + Returns a function; call it to unsubscribe. |
| 54 | +]] |
| 55 | + |
| 56 | +local unsub_removed = world:removed(Position, function(entity, id, delete) |
| 57 | + if delete then |
| 58 | + print(`Entity {entity} deleted (had Position)`) |
| 59 | + else |
| 60 | + print(`Position removed from entity {entity}`) |
| 61 | + end |
| 62 | +end) |
| 63 | + |
| 64 | +local e = world:entity() |
| 65 | +world:set(e, Position, { x = 10, y = 20 }) -- added |
| 66 | +world:set(e, Position, { x = 30, y = 40 }) -- changed |
| 67 | +world:remove(e, Position) -- removed |
| 68 | + |
| 69 | +world:added(Position, function(entity) |
| 70 | + print("Second listener: Position added") |
| 71 | +end) |
| 72 | + |
| 73 | +world:set(e, Position, { x = 0, y = 0 }) -- Multiple listeners are all invoked |
| 74 | + |
| 75 | +-- Unsubscribe when you no longer need to listen |
| 76 | +unsub_added() |
| 77 | +unsub_changed() |
| 78 | +unsub_removed() |
| 79 | + |
| 80 | +world:set(e, Position, { x = 1, y = 1 }) |
| 81 | +world:remove(e, Position) |
0 commit comments