-
Notifications
You must be signed in to change notification settings - Fork 556
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to properly compose functionality in systems? #1126
Comments
What I've done in a few places was essentially just add functionality to systems as a mixin. That's how event callback methods get added, and also how common methods for the graphics layer types get handled. You could formalize this as some sort of "components-for-systems" concept but it's not clear to me that this would be worth the overhead. Keep in mind that component init/remove methods don't necessarily care about the order they're run in, whereas I think most of the examples for systems do care. I do think there's another approach you could use for most of this block of code. The individual systems could just declare those methods as part of their events block -- all this common init code is doing is binding the events to specific named functions which are overridden. Those default-no-op method blocks for resize/render/setpixelart shouldn't really be necessary in an event driven system, where events can just be ignored if the system doesn't care about them. Another technique would be to use additional events instead of the explicit merging of init/remove; that is, instead of calling the two init methods in order, you could have the main init event trigger a Overall:
|
Would you kindly elaborate on that, maybe with some example code? Is that what's being done in the example I posted above? The other suggestions make sense for this particular case, thanks. Will make a PR that:
|
There is a problem with this approach: event callbacks, defined in the |
Btw, initialization order can be enforced with "required" components. |
If you want to get fancy, you can use higher-order functions. As an example, say you wanted to add a more sophisticated logging that includes the entity's name in the message. You could do this. function withLogging(c) {
return Object.assign({
logWithName: function(message) {
Crafty.log(this.getName() + ": " + message);
}
}, c);
}
Crafty.c("MyComponent", withLogging({
events: {
FrameStart: function() {
this.logWithName("Got frame start event"); // prints "EntityName: Got frame start event"
}
},
});
Crafty.e("MyComponent", { name: "EntityName" }); |
Recently I've been reinventing the wheel with systems. Crafty could do that for me, if I'd use an entity composed of multiple components:
What is the preferred way of handling this? I would like to decouple code and avoid writing everything into one large system template.
Would it make sense to allow systems to be composed of components? (As they are, as far as I understand, named, lazy initialized entities. See also discussion in #878).
The text was updated successfully, but these errors were encountered: