Description
Right now, the function passed to bindCompose
takes two parameters: rendering and ViewEnvironment
. A lot of view factories don't actually need the ViewEnvironment
though, so end up looking like bindCompose<Foo> { rendering, _ ->
. Always needing to specify that extra underscore is an unfortunate inconvenience.
There are three ways to solve this:
- Add an overload that takes a function with a single rendering parameter. Eg
bindCompose<Foo> { rendering ->
- Move both parameters into a new
WorkflowRenderingScope
type. Eg
class WorkflowRenderingScope<R>(
val rendering: R,
val viewEnvironment: ViewEnvironment
)
bindCompose<Foo> { /* this: WorkflowRenderingScope<Foo> */
- Mix of 1 and 2: only 1 function, but always put the view env in the scope. Leave the rendering as a parameter.
1 is more consistent with the best practice adopted by the core workflow library of avoiding passing data arguments (ie not types there solely to hang methods off of) as lambda receivers because they're not discoverable enough. 2 also mostly aligns with this, since the view env is kind of a secondary/auxiliary argument - not the main object of the function and often ignored. However, 3 is more consistent with Compose APIs, namely CanvasScope, DrawScope, ContentDrawScope. Some of these APIs used to be more like 2, but recently were refactored to be entirely receiver-based.
As this library sits right in between Workflow and Compose, which style of API should we be consistent with?
This question also applies to ComposeWorkflow.render
and Workflow.Companion.composed
. In the core workflow library, the abstract methods use option 1 (explicit params, no receiver) and the convenience builders are more like 2 (one param is in the receiver position, but no separate scope type).