1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
use crate::{ component::{ CompositeRenderDepth, CompositeRenderable, CompositeRenderableStroke, CompositeTransform, }, composite_renderer::{Command, CompositeRenderer, Rectangle, Renderable, Transformation}, }; use core::{ assets::database::AssetsDatabase, ecs::{Entities, Join, Read, ReadStorage, System, Write}, }; use std::marker::PhantomData; pub struct CompositeRendererSystem<CR> where CR: CompositeRenderer, { _phantom: PhantomData<CR>, } impl<CR> Default for CompositeRendererSystem<CR> where CR: CompositeRenderer, { fn default() -> Self { Self { _phantom: PhantomData, } } } impl<'s, CR> System<'s> for CompositeRendererSystem<CR> where CR: CompositeRenderer + Send + Sync + 'static, { type SystemData = ( Option<Write<'s, CR>>, Entities<'s>, Option<Read<'s, AssetsDatabase>>, ReadStorage<'s, CompositeRenderable>, ReadStorage<'s, CompositeTransform>, ReadStorage<'s, CompositeRenderDepth>, ReadStorage<'s, CompositeRenderableStroke>, ); fn run( &mut self, (renderer, entities, assets, renderables, transforms, depths, strokes): Self::SystemData, ) { if renderer.is_none() { return; } let renderer: &mut CR = &mut renderer.unwrap(); if let Some(assets) = &assets { renderer.update_cache(assets); } renderer.update_state(); let viewport = renderer.viewport(); let mut sorted = (&entities, &renderables, &transforms) .join() .map(|(entity, renderable, transform)| { let depth = if let Some(depth) = depths.get(entity) { depth.0 } else { 0.0 }; (depth, renderable, transform, entity) }) .collect::<Vec<_>>(); sorted.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap()); let commands = std::iter::once(if let Some(color) = renderer.state().clear_color { Command::Draw(Renderable::Rectangle(Rectangle { color, rect: viewport, })) } else { Command::None }) .chain( sorted .iter() .flat_map(|(_, renderable, transform, entity)| { let renderable = if let Some(stroke) = strokes.get(*entity) { Command::Stroke(stroke.0, renderable.0.clone()) } else { Command::Draw(renderable.0.clone()) }; vec![ Command::Store, Command::Transform(Transformation::Translate(transform.translation)), Command::Transform(Transformation::Rotate(transform.rotation)), Command::Transform(Transformation::Scale(transform.scale)), renderable, Command::Restore, ] }), ); drop(renderer.execute(commands)); } }