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

Yet another stab at a general wrapper / container interface #916

Closed
rjrjr opened this issue Feb 2, 2023 · 0 comments · Fixed by #920
Closed

Yet another stab at a general wrapper / container interface #916

rjrjr opened this issue Feb 2, 2023 · 0 comments · Fixed by #920
Assignees
Labels
ui Related to UI integration

Comments

@rjrjr
Copy link
Contributor

rjrjr commented Feb 2, 2023

import com.squareup.workflow1.ui.Screen

/**
 * A model type comprised of a set of other models of the same base type.
 *
 * @param C the invariant base type of the contents of such a container,
 * usually [Screen] or [Overlay]. It is common for the [Container] itself to
 * implement [C], but that is not a requirement. E.g., an [Overlay] might be 
 * container of [Screen].
 * @param T the specific subtype of [C] collected by this [Container].
 */
interface Container<C, T : C> {
  fun asSequence(): Sequence<T>

  /**
   * Returns a [Container] with the [transform]ed contents of the receiver.
   * It is expected that an implementation will take advantage of covariance
   * to declare its own type as the return type, rather than plain old [Container].
   * This requirement is not enforced because recursive generics are a fussy nuisance.
   */
  fun <U : C> mapContent(transform: (T) -> U): Container<C, U>
}

/**
 * A singleton [Container].
 */
interface Wrapper<C, T : C> : Container<C, T> {
  val content: T

  override fun asSequence(): Sequence<T> = sequenceOf(content)

  override fun <U : C> mapContent(transform: (T) -> U): Wrapper<C, U>
}

class WrappyScreen<S : Screen>(
  override val content: S
) : Screen, Wrapper<Screen, S> {
  override fun <U : Screen> mapContent(transform: (S) -> U): WrappyScreen<U> {
    return WrappyScreen(transform(content))
  }
}

class BStack<T : Screen>(
  val top: T,
  val backstack: List<T> = emptyList()
) : Container<Screen, T> {
  override fun asSequence(): Sequence<T> {
    return backstack.asSequence() + top
  }

  override fun <U : Screen> mapContent(transform: (T) -> U): BStack<U> {
    return BStack(transform(top), backstack.map(transform))
  }
}
@rjrjr rjrjr self-assigned this Feb 2, 2023
@rjrjr rjrjr added the ui Related to UI integration label Feb 2, 2023
rjrjr added a commit that referenced this issue Feb 8, 2023
Introduces the `Container` and `Wrapper` types, giving Workflow UI its first
general notion of structure. Their integration with `Compatibile` reduces the
likelihood of making the most common mistake with wrapper types (namely,
forgetting to do that). And they standardize the `map()` function that
gets implemented by wrappers more often than not.

Also updates `forWrapper` and `toUnwrappingViewFactory` to be defined in terms
of `Wrapper`, allowing us to simplify their APIs by relying on
`Wrapper.content` in default lambda implementations.

And while we're in the neighborhood, adds long needed `prepEnvironment` and
`prepContext` function arguments that simplify transforming a
`ScreenViewFactory` to pre-process its `ViewEnvironment` and `Context`. We
use this new capability to simplify the default `ScreenViewFactory`
implementation for `EnvironmentScreen`.

Closes #916
@rjrjr rjrjr closed this as completed Feb 8, 2023
@rjrjr rjrjr reopened this Feb 8, 2023
rjrjr added a commit that referenced this issue Feb 8, 2023
Introduces the `Container` and `Wrapper` types, giving Workflow UI its first
general notion of structure. Their integration with `Compatibile` reduces the
likelihood of making the most common mistake with wrapper types (namely,
forgetting to do that). And they standardize the `map()` function that
gets implemented by wrappers more often than not.

Also updates `forWrapper` and `toUnwrappingViewFactory` to be defined in terms
of `Wrapper`, allowing us to simplify their APIs by relying on
`Wrapper.content` in default lambda implementations.

And while we're in the neighborhood, adds long needed `prepEnvironment` and
`prepContext` function arguments that simplify transforming a
`ScreenViewFactory` to pre-process its `ViewEnvironment` and `Context`. We
use this new capability to simplify the default `ScreenViewFactory`
implementation for `EnvironmentScreen`.

Closes #916
rjrjr added a commit that referenced this issue Feb 28, 2023
Introduces the `Container` and `Wrapper` types, giving Workflow UI its first
general notion of structure. Their integration with `Compatibile` reduces the
likelihood of making the most common mistake with wrapper types (namely,
forgetting to do that). And they standardize the `map()` function that
gets implemented by wrappers more often than not.

Also updates `forWrapper` and `toUnwrappingViewFactory` to be defined in terms
of `Wrapper`, allowing us to simplify their APIs by relying on
`Wrapper.content` in default lambda implementations.

And while we're in the neighborhood, adds long needed `prepEnvironment` and
`prepContext` function arguments that simplify transforming a
`ScreenViewFactory` to pre-process its `ViewEnvironment` and `Context`. We
use this new capability to simplify the default `ScreenViewFactory`
implementation for `EnvironmentScreen`.

Closes #916
rjrjr added a commit that referenced this issue Feb 28, 2023
Introduces the `Container` and `Wrapper` types, giving Workflow UI its first
general notion of structure. Their integration with `Compatibile` reduces the
likelihood of making the most common mistake with wrapper types (namely,
forgetting to do that). And they standardize the `map()` function that
gets implemented by wrappers more often than not.

Also updates `forWrapper` and `toUnwrappingViewFactory` to be defined in terms
of `Wrapper`, allowing us to simplify their APIs by relying on
`Wrapper.content` in default lambda implementations.

And while we're in the neighborhood, adds long needed `prepEnvironment` and
`prepContext` function arguments that simplify transforming a
`ScreenViewFactory` to pre-process its `ViewEnvironment` and `Context`. We
use this new capability to simplify the default `ScreenViewFactory`
implementation for `EnvironmentScreen`.

Closes #916
rjrjr added a commit that referenced this issue Feb 28, 2023
Introduces the `Container` and `Wrapper` types, giving Workflow UI its first
general notion of structure. Their integration with `Compatibile` reduces the
likelihood of making the most common mistake with wrapper types (namely,
forgetting to do that). And they standardize the `map()` function that
gets implemented by wrappers more often than not.

Also updates `forWrapper` and `toUnwrappingViewFactory` to be defined in terms
of `Wrapper`, allowing us to simplify their APIs by relying on
`Wrapper.content` in default lambda implementations.

And while we're in the neighborhood, adds long needed `prepEnvironment` and
`prepContext` function arguments that simplify transforming a
`ScreenViewFactory` to pre-process its `ViewEnvironment` and `Context`. We
use this new capability to simplify the default `ScreenViewFactory`
implementation for `EnvironmentScreen`.

Closes #916
rjrjr added a commit that referenced this issue Feb 28, 2023
Introduces the `Container` and `Wrapper` types, giving Workflow UI its first
general notion of structure. Their integration with `Compatibile` reduces the
likelihood of making the most common mistake with wrapper types (namely,
forgetting to do that). And they standardize the `map()` function that
gets implemented by wrappers more often than not.

Also updates `forWrapper` and `toUnwrappingViewFactory` to be defined in terms
of `Wrapper`, allowing us to simplify their APIs by relying on
`Wrapper.content` in default lambda implementations.

And while we're in the neighborhood, adds long needed `prepEnvironment` and
`prepContext` function arguments that simplify transforming a
`ScreenViewFactory` to pre-process its `ViewEnvironment` and `Context`. We
use this new capability to simplify the default `ScreenViewFactory`
implementation for `EnvironmentScreen`.

Closes #916
rjrjr added a commit that referenced this issue Feb 28, 2023
Introduces the `Container` and `Wrapper` types, giving Workflow UI its first
general notion of structure. Their integration with `Compatibile` reduces the
likelihood of making the most common mistake with wrapper types (namely,
forgetting to do that). And they standardize the `map()` function that
gets implemented by wrappers more often than not.

Also updates `forWrapper` and `toUnwrappingViewFactory` to be defined in terms
of `Wrapper`, allowing us to simplify their APIs by relying on
`Wrapper.content` in default lambda implementations.

And while we're in the neighborhood, adds long needed `prepEnvironment` and
`prepContext` function arguments that simplify transforming a
`ScreenViewFactory` to pre-process its `ViewEnvironment` and `Context`. We
use this new capability to simplify the default `ScreenViewFactory`
implementation for `EnvironmentScreen`.

Closes #916
rjrjr added a commit that referenced this issue Mar 1, 2023
Introduces the `Container` and `Wrapper` types, giving Workflow UI its first
general notion of structure. Their integration with `Compatibile` reduces the
likelihood of making the most common mistake with wrapper types (namely,
forgetting to do that). And they standardize the `map()` function that
gets implemented by wrappers more often than not.

Also updates `forWrapper` and `toUnwrappingViewFactory` to be defined in terms
of `Wrapper`, allowing us to simplify their APIs by relying on
`Wrapper.content` in default lambda implementations.

And while we're in the neighborhood, adds long needed `prepEnvironment` and
`prepContext` function arguments that simplify transforming a
`ScreenViewFactory` to pre-process its `ViewEnvironment` and `Context`. We
use this new capability to simplify the default `ScreenViewFactory`
implementation for `EnvironmentScreen`.

Closes #916
rjrjr added a commit that referenced this issue Mar 1, 2023
Introduces the `Container` and `Wrapper` types, giving Workflow UI its first
general notion of structure. Their integration with `Compatibile` reduces the
likelihood of making the most common mistake with wrapper types (namely,
forgetting to do that). And they standardize the `map()` function that
gets implemented by wrappers more often than not.

Also updates `forWrapper` and `toUnwrappingViewFactory` to be defined in terms
of `Wrapper`, allowing us to simplify their APIs by relying on
`Wrapper.content` in default lambda implementations.

And while we're in the neighborhood, adds long needed `prepEnvironment` and
`prepContext` function arguments that simplify transforming a
`ScreenViewFactory` to pre-process its `ViewEnvironment` and `Context`. We
use this new capability to simplify the default `ScreenViewFactory`
implementation for `EnvironmentScreen`.

Closes #916
rjrjr added a commit that referenced this issue Mar 1, 2023
Introduces the `Container` and `Wrapper` types, giving Workflow UI its first
general notion of structure. Their integration with `Compatibile` reduces the
likelihood of making the most common mistake with wrapper types (namely,
forgetting to do that). And they standardize the `map()` function that
gets implemented by wrappers more often than not.

Also updates `forWrapper` and `toUnwrappingViewFactory` to be defined in terms
of `Wrapper`, allowing us to simplify their APIs by relying on
`Wrapper.content` in default lambda implementations.

And while we're in the neighborhood, adds long needed `prepEnvironment` and
`prepContext` function arguments that simplify transforming a
`ScreenViewFactory` to pre-process its `ViewEnvironment` and `Context`. We
use this new capability to simplify the default `ScreenViewFactory`
implementation for `EnvironmentScreen`.

Closes #916
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ui Related to UI integration
Projects
None yet
1 participant