use crate::protocol::{BatchEncoder, HostEvent, Mutation, ProtocolError};
use crate::schema::{AssetKind, MessageDuration, Selection, Theme, Window};
use std::task::{Context, Poll};
pub struct Batch {
encoder: BatchEncoder,
error: Option<ProtocolError>,
}
impl Default for Batch {
fn default() -> Self {
Self::new()
}
}
impl Batch {
pub fn new() -> Self {
Self {
encoder: BatchEncoder::with_capacity(16 * 1024, 4 * 1024, 256),
error: None,
}
}
pub fn arena(&self) -> (*const u8, usize) {
self.encoder.arena()
}
pub fn begin(&mut self) {
self.encoder.clear();
self.error = None;
}
pub fn finish(&mut self) -> Result<&[u8], ProtocolError> {
if let Some(error) = self.error.take() {
return Err(error);
}
self.encoder.finish()
}
pub fn write(&mut self, mutation: Mutation<'_>) {
if self.error.is_none() {
if let Err(error) = self.encoder.encode(&mutation) {
self.error = Some(error);
}
}
}
pub fn fail(&mut self, error: ProtocolError) {
self.error = Some(error);
}
pub fn set_theme(&mut self, theme: Theme) {
self.write(Mutation::SetTheme(theme));
}
pub fn set_window(&mut self, window: Window) {
self.write(Mutation::SetWindow(window));
}
pub fn set_text_node(&mut self, node_id: u32, text: &str, selection: Option<Selection>) {
self.write(Mutation::SetText {
node_id,
text,
selection,
});
}
pub fn register_asset(&mut self, asset_id: u32, kind: AssetKind, bytes: &[u8]) {
self.write(Mutation::RegisterAsset {
asset_id,
kind,
bytes,
});
}
pub fn release_asset(&mut self, asset_id: u32) {
self.write(Mutation::ReleaseAsset { asset_id });
}
pub fn show_message(
&mut self,
handler_id: u64,
text: &str,
action: &str,
duration: MessageDuration,
) {
self.write(Mutation::ShowMessage {
handler_id,
text,
action,
duration,
});
}
pub(crate) fn notification(&mut self, command: &crate::notification::NotificationCommand) {
use crate::notification::NotificationCommand;
match command {
NotificationCommand::Post(notification) => {
self.write(Mutation::PostNotification {
key: ¬ification.key,
title: ¬ification.title,
body: ¬ification.body,
channel: ¬ification.channel,
action_1: ¬ification.actions[0],
action_2: ¬ification.actions[1],
importance: notification.importance,
presentation: notification.presentation,
});
}
NotificationCommand::Withdraw(key) => {
self.write(Mutation::WithdrawNotification { key });
}
NotificationCommand::RequestPermission => {
self.write(Mutation::RequestNotificationPermission);
}
}
}
pub fn append_text_node(&mut self, node_id: u32, text: &str) {
self.write(Mutation::AppendText { node_id, text });
}
}
pub trait Runtime {
fn batch(&self) -> &Batch;
fn batch_mut(&mut self) -> &mut Batch;
fn rebuild(&mut self);
fn render(&mut self);
fn handle_event(&mut self, event: &HostEvent<'_>) -> Result<i64, ProtocolError>;
fn size_token(&self, node_id: u32) -> Option<u32> {
let _ = node_id;
None
}
fn poll_work(&mut self, context: &mut Context<'_>) -> Poll<()> {
let _ = context;
Poll::Pending
}
fn run_in_context(&mut self, action: &mut dyn FnMut()) {
action();
}
}