Add some way for dashbook context properties to not trigger a rebuild
Problem to solve
Currently, examples rely on context.*property (i.e. context.numberProperty) for controls. Setting these values triggers a rebuild, a bit like how Flutter does it. While this is fine for most cases, it cannot capture cases where an existing instance in an example is modified. It also doesn't reflect how the components within flame are actually changed.
For example, currently, TextBoxComponent doesn't reflow its text when TextBoxConfig.maxWidth is set. The text is only properly laid out when constructed, and in other cases where updateBounds is called by its superclass.
While this can be done by controls within the example itself, this is not idiomatic. This feature request would help bring this issue to light using the prescribed method to control the examples, i.e. context.numberProperty and its siblings.
This feature would also make the examples feel snappier in general.
Proposal
I propose the creation of a set of add*Property methods DashbookContext that is similar to context.*property with the addition of a newValue callback.
I'd imagine the API to look something like this:
..add(
'TextBoxComponent',
(context) {
final exampleGame = TextBoxExample();
context.addNumberProperty((value) {
final textBoxConfig = exampleGame.textBoxComponent.boxConfig;
exampleGame.textBoxComponent.boxConfig = textBoxConfig.copyWith(maxWidth: value);
});
return GameWidget(
game: exampleGame,
);
},
codeLink: baseLink('rendering/text_box_example.dart'),
info: TextBoxExample.description,
);
- DashbookContext gets a new API for imperatively adding typed properties. In this example,
context.addNumberProperty. - The developer would have to maintain a reference to the example game.
-
addNumberPropertytakes a method whose first argument is the new value, and so the body of the callback can therefore simply imperatively set any value in the game based on the new value. - Everything else is the same.
Based on an initial reading of the source code, my thoughts on implementation:
- The property widgets would need an additional argument. Since
onChangedalready exists,onValueChangedwould suffice. This would have the signature(newValue){} - In the controls of the said widgets, the onChanged callbacks should be changed such that
onValueChanged(value)would be inserted just before the call toonChanged(). - For existing
context.*propertymethods, theonValueChangedcallback will be a no-op. - The other API would then be able to expose
onValueChanged
Other
- [x] Are you interested in working on a PR for this?
Sounds good, I'll assign you to the issue!