Skip to content
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

Enhancing the DpmService API #26

Open
rneswold opened this issue Apr 18, 2023 · 2 comments
Open

Enhancing the DpmService API #26

rneswold opened this issue Apr 18, 2023 · 2 comments
Assignees
Labels
enhancement New feature or request

Comments

@rneswold
Copy link
Contributor

Some thoughts on the DpmService widget.

As data is returned, we want to update as few widgets as possible. Ideally, we only want to update the Text() widget that’s displaying the actual data. In the param page, we have a Entry widget which displays an entire row of the param page. For devices, it displays the name, description, reading, setting, status, (timestamp?). So to redraw all that data for each point would be “expensive”. Plus, the row would be getting updates for more than one property, so we really don’t want to re-render multiple times per data point.

As of today, a device ParameterEntry widget calls dpm.monitorDevices([widget.drf]) which returns a stream of Readings. The stream is passed to a StreamBuilder which rebuilds the dependent widgets each time a new value arrives (slightly cleaned-up):

StreamBuilder(
  stream: _stream,
  builder: (context, snapshot) {
    final bool hasData = snapshot.connectionState == ConnectionState.active;

    return _buildParam(
      hasData ? snapshot.data!.value : null,
      units,
      key: Key("${widget.drf}")
    );
  }
})

I propose keeping this API in case someone is writing Dart code. A Dart service wouldn’t use the StreamBuilder but would do computations as the stream returns data. This seems a little too much boilerplate code for Flutter developers, though, so I’d like to add to the API. What if we add an AcquisitionWidget?

AcquisitionWidget(
  drf: "M:OUTTMP@p,60000",
  builder: (BuildingContext context, Reading reading) {
    return Text("${reading.data}");
  }
)

What’s the difference?

  • The first example didn’t show the call to dpm.monitorDevices() and saving the stream in the class’s fields.
  • The first example didn’t show the code that had to pass the _stream down through the functions calls.
  • The first example opened its own websocket.
  • The proposed API would make the call to .monitorDevices() and keep track of the stream (subscribing and unsubscribing, as necessary.)
  • The proposed API would merge all requests over one websocket and deliver the results to the correct AcquisitionWidget's builder function.
  • The proposed API searches for the DpmService widget, so you can simply wrap the widget that needs updating (the first example doesn't show that _buildParam() actually creates a Row widget containing Text widgets and a SizedBox widget because focusing on the one Text field requires passing the stream down further.)

Of course, I stink at naming things so, if this sounds like a good plan, please help me name the classes appropriately.

@rneswold rneswold added the enhancement New feature or request label Apr 18, 2023
@rneswold rneswold self-assigned this Apr 18, 2023
@cnlklink
Copy link
Contributor

Let me make sure I follow...

So essentially, AcquisitionWidget will stand in for the reading/setting Text and manages the stream of data to that specific Text as displayed on the screen?

And then, the ParameterWidget could be composed of two AcquisitionWidgets - one for displaying the setting property and another for the reading property (or possibly a third for the control property)?

@rneswold
Copy link
Contributor Author

That's right, @cnlklink. A row has to start multiple requests for readings, settings, and status anyways. Why not let this widget do that and target the exact widget that needs to change when there's an update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants