dashbook icon indicating copy to clipboard operation
dashbook copied to clipboard

Add some way for dashbook context properties to not trigger a rebuild

Open livtanong opened this issue 2 months ago • 1 comments

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.
  • addNumberProperty takes 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:

  1. The property widgets would need an additional argument. Since onChanged already exists, onValueChanged would suffice. This would have the signature (newValue){}
  2. In the controls of the said widgets, the onChanged callbacks should be changed such that onValueChanged(value) would be inserted just before the call to onChanged().
  3. For existing context.*property methods, the onValueChanged callback will be a no-op.
  4. The other API would then be able to expose onValueChanged

Other

  • [x] Are you interested in working on a PR for this?

livtanong avatar Nov 19 '25 05:11 livtanong

Sounds good, I'll assign you to the issue!

spydon avatar Nov 19 '25 07:11 spydon