Skip to content

Commit

Permalink
ability to get the DocumentHandle from TreeDrawer::new
Browse files Browse the repository at this point in the history
yes, literally spent my New Years Eve doing this. Outside there are now so many Fireworks....

Happy New Year I guess
  • Loading branch information
Sharktheone committed Dec 31, 2024
1 parent 8007476 commit 7171291
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 34 deletions.
2 changes: 1 addition & 1 deletion crates/gosub_instance/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl<C: ModuleConfiguration> EngineInstance<C> {
handles: Handles<C>,
) -> Result<Self> {
let fetcher = Arc::new(Fetcher::new(url.clone()));
let data = C::TreeDrawer::with_fetcher(url.clone(), fetcher.clone(), layouter, false).await?;
let (data, handle) = C::TreeDrawer::with_fetcher(url.clone(), fetcher.clone(), layouter, false).await?;

let (itx, irx) = tokio::sync::mpsc::channel(128);

Expand Down
25 changes: 16 additions & 9 deletions crates/gosub_interface/src/draw.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::config::HasDrawComponents;
use crate::config::{HasDocument, HasDrawComponents, HasHtmlParser};
use crate::eventloop::EventLoopHandle;
use crate::layout::LayoutTree;
use crate::render_backend::{ImgCache, NodeDesc, RenderBackend};
Expand All @@ -8,6 +8,8 @@ use std::future::Future;
use std::sync::mpsc::Sender;
use std::sync::Arc;
use url::Url;
use crate::document_handle::DocumentHandle;
use gosub_shared::types::Result;

pub trait TreeDrawer<C: HasDrawComponents> {
type ImgCache: ImgCache<C::RenderBackend>;
Expand All @@ -20,9 +22,10 @@ pub trait TreeDrawer<C: HasDrawComponents> {
url: Url,
layouter: C::Layouter,
debug: bool,
) -> impl Future<Output = gosub_shared::types::Result<Self>>
) -> impl Future<Output = gosub_shared::types::Result<(Self, DocumentHandle<C>)>>
where
Self: Sized;
Self: Sized,
C: HasDocument;

fn from_source(
// The initial url that the source was loaded from
Expand All @@ -33,9 +36,10 @@ pub trait TreeDrawer<C: HasDrawComponents> {
layouter: C::Layouter,
// Debug flag
debug: bool,
) -> gosub_shared::types::Result<Self>
) -> Result<(Self, DocumentHandle<C>)>
where
Self: Sized;
Self: Sized,
C: HasDocument;

fn with_fetcher(
// The initial url that the source was loaded from
Expand All @@ -46,9 +50,10 @@ pub trait TreeDrawer<C: HasDrawComponents> {
layouter: C::Layouter,
// Debug flag
debug: bool,
) -> impl Future<Output = gosub_shared::types::Result<Self>>
) -> impl Future<Output = Result<(Self, DocumentHandle<C>)>>
where
Self: Sized;
Self: Sized,
C: HasDocument;

fn clear_buffers(&mut self);
fn toggle_debug(&mut self);
Expand All @@ -67,9 +72,11 @@ pub trait TreeDrawer<C: HasDrawComponents> {

fn delete_scene(&mut self);

fn reload(&mut self, el: impl EventLoopHandle<C>) -> impl Future<Output = ()> + 'static;
fn reload(&mut self, el: impl EventLoopHandle<C>) -> impl Future<Output = Result<DocumentHandle<C>>> + 'static
where C: HasDocument;

fn navigate(&mut self, url: Url, el: impl EventLoopHandle<C>) -> impl Future<Output = ()> + 'static;
fn navigate(&mut self, url: Url, el: impl EventLoopHandle<C>) -> impl Future<Output = Result<DocumentHandle<C>>> + 'static
where C: HasDocument;

fn reload_from(&mut self, tree: C::RenderTree);
}
38 changes: 20 additions & 18 deletions crates/gosub_renderer/src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use std::future::Future;
use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex};
use url::Url;
use gosub_interface::document_handle::DocumentHandle;

mod img;
pub mod img_cache;
Expand Down Expand Up @@ -209,26 +210,23 @@ where
self.dirty = true;
}

async fn from_url(url: Url, layouter: C::Layouter, debug: bool) -> Result<Self> {
let (rt, fetcher) = load_html_rendertree::<C>(url.clone(), None).await?;
async fn from_url(url: Url, layouter: C::Layouter, debug: bool) -> Result<(Self, DocumentHandle<C>)> {
let (rt, handle, fetcher) = load_html_rendertree::<C>(url.clone(), None).await?;

Ok(Self::new(rt, layouter, Arc::new(fetcher), debug))
Ok((Self::new(rt, layouter, Arc::new(fetcher), debug), handle))
}

fn from_source(url: Url, source_html: &str, layouter: C::Layouter, debug: bool) -> Result<Self> {
fn from_source(url: Url, source_html: &str, layouter: C::Layouter, debug: bool) -> Result<(Self, DocumentHandle<C>)> {
let fetcher = Fetcher::new(url.clone());
let rt = load_html_rendertree_source::<C>(url, source_html)?;
let (rt, handle)= load_html_rendertree_source::<C>(url, source_html)?;

Ok(Self::new(rt, layouter, Arc::new(fetcher), debug))
Ok((Self::new(rt, layouter, Arc::new(fetcher), debug), handle))
}

async fn with_fetcher(url: Url, fetcher: Arc<Fetcher>, layouter: C::Layouter, debug: bool) -> Result<Self>
where
Self: Sized,
{
let rt = load_html_rendertree_fetcher::<C>(url.clone(), &fetcher).await?;
async fn with_fetcher(url: Url, fetcher: Arc<Fetcher>, layouter: C::Layouter, debug: bool) -> Result<(Self, DocumentHandle<C>)> {
let (rt, handle) = load_html_rendertree_fetcher::<C>(url.clone(), &fetcher).await?;

Ok(Self::new(rt, layouter, fetcher, debug))
Ok((Self::new(rt, layouter, fetcher, debug), handle))
}

fn clear_buffers(&mut self) {
Expand Down Expand Up @@ -291,39 +289,43 @@ where
self.debugger_scene = None;
}

fn reload(&mut self, el: impl EventLoopHandle<C>) -> impl Future<Output = ()> + 'static {
fn reload(&mut self, el: impl EventLoopHandle<C>) -> impl Future<Output = Result<DocumentHandle<C>>> + 'static {
let fetcher = self.fetcher.clone();

async move {
info!("Reloading tab");

let rt = match load_html_rendertree_fetcher::<C>(fetcher.base().clone(), &fetcher).await {
let (rt, handle) = match load_html_rendertree_fetcher::<C>(fetcher.base().clone(), &fetcher).await {
Ok(rt) => rt,
Err(e) => {
error!("Failed to reload tab: {e}");
return;
return Err(e);
}
};

el.reload_from(rt);

Ok(handle)
}
}

fn navigate(&mut self, url: Url, el: impl EventLoopHandle<C>) -> impl Future<Output = ()> + 'static {
fn navigate(&mut self, url: Url, el: impl EventLoopHandle<C>) -> impl Future<Output = Result<DocumentHandle<C>>> + 'static {
let fetcher = self.fetcher.clone();

async move {
info!("Navigating to {url}");

let rt = match load_html_rendertree_fetcher::<C>(url.clone(), &fetcher).await {
let (rt, handle) = match load_html_rendertree_fetcher::<C>(url.clone(), &fetcher).await {
Ok(rt) => rt,
Err(e) => {
error!("Failed to navigate to {url}: {e}");
return;
return Err(e);
}
};

el.reload_from(rt);

Ok(handle)
}
}

Expand Down
12 changes: 6 additions & 6 deletions crates/gosub_renderer/src/render_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@ use url::Url;
pub async fn load_html_rendertree<C: HasRenderTree + HasHtmlParser>(
url: Url,
source: Option<&str>,
) -> gosub_shared::types::Result<(C::RenderTree, Fetcher)> {
) -> gosub_shared::types::Result<(C::RenderTree, DocumentHandle<C>, Fetcher)> {
let fetcher = Fetcher::new(url.clone());

let rt = match source {
let (rt, handle) = match source {
Some(source) => load_html_rendertree_source::<C>(url, source)?,
None => load_html_rendertree_fetcher::<C>(url, &fetcher).await?,
};

Ok((rt, fetcher))
Ok((rt, handle, fetcher))
}

// Generate a render tree from the given source HTML. THe URL is needed to resolve relative URLs
// and also to set the base URL for the document.
pub fn load_html_rendertree_source<C: HasRenderTree + HasHtmlParser>(
url: Url,
source_html: &str,
) -> gosub_shared::types::Result<C::RenderTree> {
) -> gosub_shared::types::Result<(C::RenderTree, DocumentHandle<C>)> {
let mut stream = ByteStream::new(Encoding::UTF8, None);
stream.read_from_str(source_html, Some(Encoding::UTF8));
stream.close();
Expand All @@ -48,14 +48,14 @@ pub fn load_html_rendertree_source<C: HasRenderTree + HasHtmlParser>(

drop(doc);

generate_render_tree(DocumentHandle::clone(&doc_handle))
Ok((generate_render_tree(DocumentHandle::clone(&doc_handle))?, doc_handle))
}

/// Generates a render tree from the given URL. The complete HTML source is fetched from the URL async.
pub async fn load_html_rendertree_fetcher<C: HasRenderTree + HasHtmlParser>(
url: Url,
fetcher: &Fetcher,
) -> gosub_shared::types::Result<C::RenderTree> {
) -> gosub_shared::types::Result<(C::RenderTree, DocumentHandle<C>)> {
let html = if url.scheme() == "http" || url.scheme() == "https" {
// Fetch the html from the url
let response = fetcher.get(url.as_ref()).await?;
Expand Down

0 comments on commit 7171291

Please sign in to comment.