Skip to content

Commit

Permalink
runtime: Handle widget operations in program::State helper
Browse files Browse the repository at this point in the history
  • Loading branch information
Drakulix committed Jun 13, 2023
1 parent 329fbc7 commit dd34591
Showing 1 changed file with 50 additions and 8 deletions.
58 changes: 50 additions & 8 deletions runtime/src/program/state.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::core::event::{self, Event};
use crate::core::mouse;
use crate::core::renderer;
use crate::core::widget::operation::Outcome;
use crate::core::{Clipboard, Size};
use crate::user_interface::{self, UserInterface};
use crate::{Command, Debug, Program};
use crate::{command::Action, Command, Debug, Program};

/// The execution state of a [`Program`]. It leverages caching, event
/// processing, and rendering primitive storage.
Expand Down Expand Up @@ -94,7 +95,7 @@ where
style: &renderer::Style,
clipboard: &mut dyn Clipboard,
debug: &mut Debug,
) -> (Vec<Event>, Option<Command<P::Message>>) {
) -> (Vec<Event>, Vec<Action<P::Message>>) {
let mut user_interface = build_user_interface(
&mut self.program,
self.cache.take().unwrap(),
Expand Down Expand Up @@ -128,21 +129,21 @@ where
messages.append(&mut self.queued_messages);
debug.event_processing_finished();

let command = if messages.is_empty() {
let actions = if messages.is_empty() {
debug.draw_started();
self.mouse_interaction =
user_interface.draw(renderer, theme, style, cursor);
debug.draw_finished();

self.cache = Some(user_interface.into_cache());

None
Vec::new()
} else {
// When there are messages, we are forced to rebuild twice
// for now :^)
let temp_cache = user_interface.into_cache();

let commands =
let (actions, widget_actions) =
Command::batch(messages.into_iter().map(|message| {
debug.log_message(&message);

Expand All @@ -151,7 +152,12 @@ where
debug.update_finished();

command
}));
}))
.actions()
.into_iter()
.partition::<Vec<_>, _>(|action| {
!matches!(action, Action::Widget(_))
});

let mut user_interface = build_user_interface(
&mut self.program,
Expand All @@ -161,17 +167,53 @@ where
debug,
);

let had_operations = !widget_actions.is_empty();
for operation in widget_actions
.into_iter()
.map(|action| match action {
Action::Widget(widget_action) => widget_action,
_ => unreachable!(),
})
{
let mut current_operation = Some(operation);
while let Some(mut operation) = current_operation.take() {
user_interface.operate(renderer, operation.as_mut());
match operation.finish() {
Outcome::None => {},
Outcome::Some(message) => self.queued_messages.push(message),
Outcome::Chain(op) => {
current_operation = Some(op);
}
};
}
}

let mut user_interface = if had_operations {
// When there were operations, we are forced to rebuild thrice ...
let temp_cache = user_interface.into_cache();

build_user_interface(
&mut self.program,
temp_cache,
renderer,
bounds,
debug,
)
} else {
user_interface
};

debug.draw_started();
self.mouse_interaction =
user_interface.draw(renderer, theme, style, cursor);
debug.draw_finished();

self.cache = Some(user_interface.into_cache());

Some(commands)
actions
};

(uncaptured_events, command)
(uncaptured_events, actions)
}
}

Expand Down

0 comments on commit dd34591

Please sign in to comment.