kult icon indicating copy to clipboard operation
kult copied to clipboard

How to make a component detect change?

Open WarlockD opened this issue 8 years ago • 4 comments

Lets say I have three components, position, scale, rotation that updates a matrix component to trasforms a sprite. Is there a way I can detect that position/scale/rotation component has changed in the system?

The idea being that I only have to update the transform component if its changed. then if the transform component has changed, update the verticies then.

The only way I can figure out is to wrap my vector class in a struct that flips a flag when the value is changed and then reset when it goes though the system.

Any ideas?

PS - Humm. You know, when I think of it, I think I am looking for a message system. Is there any examples of that?

WarlockD avatar Aug 14 '16 12:08 WarlockD

I think your approach would need 5 components { position, rotation, scale, matrix, dirty }. And then,

  • Everytime position, rotation or scale gets updated, they set the dirty flag.
  • Everytime you update the matrix components, check the dirty flags. Transform the pos/rot/sca components into the matrix, and clear the bit.

About messages, in the same spirit of ECS messages, are not implemented at the moment. I have yet to figure out if they're handy or just cumbersome in the end (ie, message-hell).

You can still create blank dynamic entities with a message-component and feed them to a hypothetical message-system btw.

r-lyeh-archived avatar Aug 14 '16 13:08 r-lyeh-archived

btw, found this. relevant and simpler approach!

https://www.reddit.com/r/gamedev/comments/1qtvug/entitycomponentsystems_and_dataoriented_design/cdgib2p

r-lyeh-archived avatar Aug 15 '16 01:08 r-lyeh-archived

Humm, this is a good point. would it be better that, instead of a dirty flag, to just add a "dirty" component? This way the join operation only joins all the entity's that are dirty or does that break some programming convention?

Maybe instead of messages call backs? Its wracking my brain now, I rewrote this paragraph six times already. You could just copy the component system to be an array of std::function<set? this way you could have something like call<Collide>(player,badguy) in a system.

I feel like you can even remove using the set entirely and program all the callbacks in some kind of template programming. I am still learning about template programming, its just hard to get your head around it sometimes.

WarlockD avatar Aug 16 '16 12:08 WarlockD

From my point of view/experience, messages can be very nasty to debug, specially when you have hundred or thousands per frame.

I rather like to examine and inspect the structs and datas in memory as they're when debugged.

You have two approaches from this point:

  • Everytime you touch a node, a moveable message is sent, then all listeners (including matrix component) will rebuild their stuff because of it. This scheme is what I would avoid for now (plus you would need to implement the messaging yourself at the moment; Kult has no messages for now).
  • Make a single transform component that holds the whole { vec3 pos, rot, sca; matrix4 mt; bool dirty } set. Setters for pos, sca and rot set the dirty flag. Update system would retrieve matrix mt if dirty flag is clean, else, would construct matrix from pos,rot,sca and clear the dirty flag for next update. This is the direct/simpler approach I'd like to use if I were you. Keep it simple (and debuggable :)

Hope it helps

r-lyeh-archived avatar Aug 16 '16 12:08 r-lyeh-archived