Skip to content

Commit

Permalink
runtime: Handle widget operations in program::State helper (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
Drakulix committed Jun 13, 2023
1 parent f2647b9 commit 978e9fe
Showing 1 changed file with 57 additions and 8 deletions.
65 changes: 57 additions & 8 deletions runtime/src/program/state.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use crate::core::event::{self, Event};
use crate::core::mouse;
use crate::core::renderer;
use crate::core::widget::operation::{
Operation, OperationOutputWrapper, OperationWrapper, Outcome,
};
use crate::core::{Clipboard, Point, 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 @@ -97,7 +100,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(
id,
&mut self.program,
Expand Down Expand Up @@ -132,21 +135,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_position);
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 @@ -155,7 +158,12 @@ where
debug.update_finished();

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

let mut user_interface = build_user_interface(
id,
Expand All @@ -166,17 +174,58 @@ 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!(),
})
.map(OperationWrapper::Message)
{
let mut current_operation = Some(operation);
while let Some(mut operation) = current_operation.take() {
user_interface.operate(renderer, &mut operation);
match operation.finish() {
Outcome::Some(OperationOutputWrapper::Message(
message,
)) => self.queued_messages.push(message),
Outcome::Chain(op) => {
current_operation =
Some(OperationWrapper::Wrapper(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(
id,
&mut self.program,
temp_cache,
renderer,
bounds,
debug,
)
} else {
user_interface
};

debug.draw_started();
self.mouse_interaction =
user_interface.draw(renderer, theme, style, cursor_position);
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 978e9fe

Please sign in to comment.