Introduce Program::run_with to control the initial state
This commit is contained in:
parent
92f8dddc2c
commit
943b6c9657
2 changed files with 60 additions and 37 deletions
|
|
@ -21,19 +21,13 @@ pub fn main() -> iced::Result {
|
||||||
.run()
|
.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Tour {
|
pub struct Tour {
|
||||||
steps: Steps,
|
steps: Steps,
|
||||||
debug: bool,
|
debug: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tour {
|
impl Tour {
|
||||||
fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
steps: Steps::new(),
|
|
||||||
debug: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn title(&self) -> String {
|
fn title(&self) -> String {
|
||||||
format!("{} - Iced", self.steps.title())
|
format!("{} - Iced", self.steps.title())
|
||||||
}
|
}
|
||||||
|
|
@ -90,12 +84,6 @@ impl Tour {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Tour {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
BackPressed,
|
BackPressed,
|
||||||
|
|
@ -177,6 +165,12 @@ impl Steps {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Steps {
|
||||||
|
fn default() -> Self {
|
||||||
|
Steps::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum Step {
|
enum Step {
|
||||||
Welcome,
|
Welcome,
|
||||||
Slider {
|
Slider {
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ pub fn program<State, Message, Theme>(
|
||||||
view: impl for<'a> self::View<'a, State, Message, Theme>,
|
view: impl for<'a> self::View<'a, State, Message, Theme>,
|
||||||
) -> Program<impl Definition<State = State, Message = Message, Theme = Theme>>
|
) -> Program<impl Definition<State = State, Message = Message, Theme = Theme>>
|
||||||
where
|
where
|
||||||
State: Default + 'static,
|
State: 'static,
|
||||||
Message: Send + std::fmt::Debug,
|
Message: Send + std::fmt::Debug,
|
||||||
Theme: Default + application::DefaultStyle,
|
Theme: Default + application::DefaultStyle,
|
||||||
{
|
{
|
||||||
|
|
@ -87,7 +87,6 @@ where
|
||||||
impl<State, Message, Theme, Update, View> Definition
|
impl<State, Message, Theme, Update, View> Definition
|
||||||
for Application<State, Message, Theme, Update, View>
|
for Application<State, Message, Theme, Update, View>
|
||||||
where
|
where
|
||||||
State: Default,
|
|
||||||
Message: Send + std::fmt::Debug,
|
Message: Send + std::fmt::Debug,
|
||||||
Theme: Default + application::DefaultStyle,
|
Theme: Default + application::DefaultStyle,
|
||||||
Update: self::Update<State, Message>,
|
Update: self::Update<State, Message>,
|
||||||
|
|
@ -98,8 +97,8 @@ where
|
||||||
type Theme = Theme;
|
type Theme = Theme;
|
||||||
type Executor = executor::Default;
|
type Executor = executor::Default;
|
||||||
|
|
||||||
fn build(&self) -> (Self::State, Command<Self::Message>) {
|
fn load(&self) -> Command<Self::Message> {
|
||||||
(Self::State::default(), Command::none())
|
Command::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(
|
fn update(
|
||||||
|
|
@ -151,25 +150,57 @@ pub struct Program<P: Definition> {
|
||||||
|
|
||||||
impl<P: Definition> Program<P> {
|
impl<P: Definition> Program<P> {
|
||||||
/// Runs the underlying [`Application`] of the [`Program`].
|
/// Runs the underlying [`Application`] of the [`Program`].
|
||||||
|
///
|
||||||
|
/// The state of the [`Program`] must implement [`Default`].
|
||||||
|
/// If your state does not implement [`Default`], use [`run_with`]
|
||||||
|
/// instead.
|
||||||
|
///
|
||||||
|
/// [`run_with`]: Self::run_with
|
||||||
pub fn run(self) -> Result
|
pub fn run(self) -> Result
|
||||||
where
|
where
|
||||||
Self: 'static,
|
Self: 'static,
|
||||||
|
P::State: Default,
|
||||||
{
|
{
|
||||||
struct Instance<P: Definition> {
|
self.run_with(P::State::default)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Runs the underlying [`Application`] of the [`Program`] with a
|
||||||
|
/// closure that creates the initial state.
|
||||||
|
pub fn run_with(
|
||||||
|
self,
|
||||||
|
initialize: impl Fn() -> P::State + Clone + 'static,
|
||||||
|
) -> Result
|
||||||
|
where
|
||||||
|
Self: 'static,
|
||||||
|
{
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
struct Instance<P: Definition, I> {
|
||||||
program: P,
|
program: P,
|
||||||
state: P::State,
|
state: P::State,
|
||||||
|
_initialize: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Definition> Application for Instance<P> {
|
impl<P: Definition, I: Fn() -> P::State> Application for Instance<P, I> {
|
||||||
type Message = P::Message;
|
type Message = P::Message;
|
||||||
type Theme = P::Theme;
|
type Theme = P::Theme;
|
||||||
type Flags = P;
|
type Flags = (P, I);
|
||||||
type Executor = P::Executor;
|
type Executor = P::Executor;
|
||||||
|
|
||||||
fn new(program: Self::Flags) -> (Self, Command<Self::Message>) {
|
fn new(
|
||||||
let (state, command) = P::build(&program);
|
(program, initialize): Self::Flags,
|
||||||
|
) -> (Self, Command<Self::Message>) {
|
||||||
|
let state = initialize();
|
||||||
|
let command = program.load();
|
||||||
|
|
||||||
(Self { program, state }, command)
|
(
|
||||||
|
Self {
|
||||||
|
program,
|
||||||
|
state,
|
||||||
|
_initialize: PhantomData,
|
||||||
|
},
|
||||||
|
command,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn title(&self) -> String {
|
fn title(&self) -> String {
|
||||||
|
|
@ -206,7 +237,7 @@ impl<P: Definition> Program<P> {
|
||||||
let Self { raw, settings } = self;
|
let Self { raw, settings } = self;
|
||||||
|
|
||||||
Instance::run(Settings {
|
Instance::run(Settings {
|
||||||
flags: raw,
|
flags: (raw, initialize),
|
||||||
id: settings.id,
|
id: settings.id,
|
||||||
window: settings.window,
|
window: settings.window,
|
||||||
fonts: settings.fonts,
|
fonts: settings.fonts,
|
||||||
|
|
@ -389,7 +420,7 @@ pub trait Definition: Sized {
|
||||||
/// The executor of the program.
|
/// The executor of the program.
|
||||||
type Executor: Executor;
|
type Executor: Executor;
|
||||||
|
|
||||||
fn build(&self) -> (Self::State, Command<Self::Message>);
|
fn load(&self) -> Command<Self::Message>;
|
||||||
|
|
||||||
fn update(
|
fn update(
|
||||||
&self,
|
&self,
|
||||||
|
|
@ -445,8 +476,8 @@ fn with_title<P: Definition>(
|
||||||
type Theme = P::Theme;
|
type Theme = P::Theme;
|
||||||
type Executor = P::Executor;
|
type Executor = P::Executor;
|
||||||
|
|
||||||
fn build(&self) -> (Self::State, Command<Self::Message>) {
|
fn load(&self) -> Command<Self::Message> {
|
||||||
self.program.build()
|
self.program.load()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn title(&self, state: &Self::State) -> String {
|
fn title(&self, state: &Self::State) -> String {
|
||||||
|
|
@ -509,10 +540,8 @@ fn with_load<P: Definition>(
|
||||||
type Theme = P::Theme;
|
type Theme = P::Theme;
|
||||||
type Executor = executor::Default;
|
type Executor = executor::Default;
|
||||||
|
|
||||||
fn build(&self) -> (Self::State, Command<Self::Message>) {
|
fn load(&self) -> Command<Self::Message> {
|
||||||
let (state, command) = self.program.build();
|
Command::batch([self.program.load(), (self.load)()])
|
||||||
|
|
||||||
(state, Command::batch([command, (self.load)()]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(
|
fn update(
|
||||||
|
|
@ -582,8 +611,8 @@ fn with_subscription<P: Definition>(
|
||||||
(self.subscription)(state)
|
(self.subscription)(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build(&self) -> (Self::State, Command<Self::Message>) {
|
fn load(&self) -> Command<Self::Message> {
|
||||||
self.program.build()
|
self.program.load()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(
|
fn update(
|
||||||
|
|
@ -646,8 +675,8 @@ fn with_theme<P: Definition>(
|
||||||
(self.theme)(state)
|
(self.theme)(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build(&self) -> (Self::State, Command<Self::Message>) {
|
fn load(&self) -> Command<Self::Message> {
|
||||||
self.program.build()
|
self.program.load()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn title(&self, state: &Self::State) -> String {
|
fn title(&self, state: &Self::State) -> String {
|
||||||
|
|
@ -714,8 +743,8 @@ fn with_style<P: Definition>(
|
||||||
(self.style)(state, theme)
|
(self.style)(state, theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build(&self) -> (Self::State, Command<Self::Message>) {
|
fn load(&self) -> Command<Self::Message> {
|
||||||
self.program.build()
|
self.program.load()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn title(&self, state: &Self::State) -> String {
|
fn title(&self, state: &Self::State) -> String {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue