use super::{MockWindowImpl, TestServices, UnitTestApplication, UnitTestApplicationScope};
use crate::presentation_source::IRendererFactory;
use ferroui_base::media::MediaContext;
use ferroui_base::platform::IPlatformRenderInterface;
use ferroui_base::rendering::composition::Compositor;
use ferroui_base::rendering::testing::{DrawingLog, ManualRenderLoop, MockPlatformRenderInterface};
use ferroui_base::threading::Dispatcher;
use ferroui_base::FerroLocator;
use std::rc::Rc;
use std::sync::Arc;
pub struct CompositorTestServices {
compositor: Rc<Compositor>,
render_loop: Arc<ManualRenderLoop>,
app: UnitTestApplicationScope,
}
impl CompositorTestServices {
pub fn start(mut services: TestServices) -> CompositorTestServices {
if services.render_interface.is_none() {
let render_interface: Rc<dyn IPlatformRenderInterface> =
MockPlatformRenderInterface::new(DrawingLog::new());
services.render_interface = Some(render_interface);
}
let app = UnitTestApplication::start(services);
FerroLocator::current_mutable().bind::<dyn IRendererFactory>().to_func(|| None);
let render_loop = ManualRenderLoop::new();
let compositor = Self::create_dummy_compositor(Some(render_loop.clone()));
CompositorTestServices { compositor, render_loop, app }
}
pub fn create_dummy_compositor(render_loop: Option<Arc<ManualRenderLoop>>) -> Rc<Compositor> {
Compositor::with_scheduler(
render_loop.unwrap_or_else(ManualRenderLoop::new),
None,
true,
&MediaContext::instance().scheduler(),
Dispatcher::ui_thread(),
None,
None,
)
}
pub fn compositor(&self) -> &Rc<Compositor> {
&self.compositor
}
pub fn render_loop(&self) -> &Arc<ManualRenderLoop> {
&self.render_loop
}
pub fn setup(&self, platform_impl: &MockWindowImpl) {
platform_impl.setup_compositor(Some(self.compositor.clone()));
}
pub fn run_jobs(&self) {
Dispatcher::ui_thread().run_jobs(None);
self.render_loop.tick();
Dispatcher::ui_thread().run_jobs(None);
}
pub fn dispose(&self) {
self.app.dispose();
}
}