use shipyard::{
advanced::atomic_refcell::SharedBorrow, advanced::tracking::TrackingTimestamp,
all_storages::AllStorages, Borrow, BorrowInfo, Component, EntitiesViewMut, IntoIter, Unique,
UniqueView, ViewMut, World,
};
use std::iter;
#[derive(Component)]
struct Parent;
#[derive(Component)]
struct Child;
#[derive(Borrow, BorrowInfo)]
struct Hierarchy<'v> {
entities: EntitiesViewMut<'v>,
parents: ViewMut<'v, Parent>,
children: ViewMut<'v, Child>,
}
struct RandomNumber(u64);
#[test]
#[rustfmt::skip]
#[allow(unused)]
fn view() {
#[derive(Component)]
struct Parent;
#[derive(Component)]
struct Child;
#[derive(Borrow, BorrowInfo, IntoIter)]
#[shipyard(item_name = "Node")]
struct Hierarchy<'v> {
#[shipyard(item_field_skip)]
entities: EntitiesViewMut<'v>,
#[shipyard(item_field_name = "parent")]
parents: ViewMut<'v, Parent>,
#[shipyard(item_field_name = "child")]
children: ViewMut<'v, Child>,
}
let world = World::new();
world.run(|mut hierarchy: Hierarchy| {
for Node { parent, child } in hierarchy.iter() {
}
});
}
mod wgpu {
use std::{error::Error, fmt::Display};
pub(crate) struct Surface;
impl Surface {
pub(crate) fn get_current_texture(&self) -> Result<SurfaceTexture, SurfaceError> {
unreachable!()
}
}
pub(crate) struct Device;
impl Device {
pub(crate) fn create_command_encoder(
&self,
_: &CommandEncoderDescriptor,
) -> CommandEncoder {
unreachable!()
}
}
pub(crate) struct Queue;
impl Queue {
pub(crate) fn submit(&self, iter: impl IntoIterator<Item = ()>) {
unreachable!()
}
}
pub(crate) struct SurfaceConfiguration;
#[derive(Debug)]
pub(crate) struct SurfaceError;
impl Display for SurfaceError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
unreachable!()
}
}
impl Error for SurfaceError {}
pub(crate) struct SurfaceTexture {
pub(crate) texture: Texture,
}
impl SurfaceTexture {
pub(crate) fn present(&self) {
unreachable!()
}
}
pub(crate) struct Texture;
impl Texture {
pub(crate) fn create_view(&self, desc: &TextureViewDescriptor) -> TextureView {
unreachable!()
}
}
#[derive(Default)]
pub(crate) struct TextureViewDescriptor;
pub(crate) struct TextureView;
pub(crate) struct CommandEncoderDescriptor {
pub(crate) label: Option<&'static str>,
}
pub(crate) struct CommandEncoder;
impl CommandEncoder {
pub(crate) fn begin_render_pass(&self, _: &RenderPassDescriptor) -> RenderPass {
unreachable!()
}
pub(crate) fn finish(self) {
unreachable!()
}
}
pub(crate) struct RenderPassDescriptor<'desc> {
pub(crate) label: Option<&'static str>,
pub(crate) color_attachments: &'desc [RenderPassColorAttachment<'desc>],
pub(crate) depth_stencil_attachment: Option<()>,
}
pub(crate) struct RenderPass;
pub(crate) struct RenderPassColorAttachment<'tex> {
pub(crate) view: &'tex TextureView,
pub(crate) resolve_target: Option<&'tex TextureView>,
pub(crate) ops: Operations<Color>,
}
pub(crate) struct Operations<T> {
pub(crate) load: LoadOp<T>,
pub(crate) store: bool,
}
pub(crate) enum LoadOp<T> {
Clear(T),
}
pub(crate) struct Color {
pub(crate) r: f32,
pub(crate) g: f32,
pub(crate) b: f32,
pub(crate) a: f32,
}
}
mod winit {
pub(crate) mod dpi {
pub(crate) struct PhysicalSize<T>(T);
}
}
#[derive(Unique)]
struct Graphics {
surface: wgpu::Surface,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
size: winit::dpi::PhysicalSize<u32>,
}
fn render(graphics: UniqueView<Graphics>) -> Result<(), wgpu::SurfaceError> {
let output = graphics.surface.get_current_texture()?;
let view = output
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
let mut encoder = graphics
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Render Encoder"),
});
{
let mut _render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Render Pass"),
color_attachments: &[wgpu::RenderPassColorAttachment {
view: &view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color {
r: 0.1,
g: 0.2,
b: 0.3,
a: 1.0,
}),
store: true,
},
}],
depth_stencil_attachment: None,
});
}
graphics.queue.submit(iter::once(encoder.finish()));
output.present();
Ok(())
}
#[rustfmt::skip]
mod render {
use super::wgpu;
use super::RenderGraphicsViewMut;
fn render(mut graphics: RenderGraphicsViewMut) {
let mut _render_pass = graphics
.encoder
.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Render Pass"),
color_attachments: &[wgpu::RenderPassColorAttachment {
view: &graphics.view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color {
r: 0.1,
g: 0.2,
b: 0.3,
a: 1.0,
}),
store: true,
},
}],
depth_stencil_attachment: None,
});
}
}
struct RenderGraphicsViewMut {
view: wgpu::TextureView,
encoder: wgpu::CommandEncoder,
}
impl shipyard::borrow::Borrow for RenderGraphicsViewMut {
type View<'v> = RenderGraphicsViewMut;
fn borrow<'a>(
all_storages: &'a AllStorages,
all_borrow: Option<SharedBorrow<'a>>,
last_run: Option<TrackingTimestamp>,
current: TrackingTimestamp,
) -> Result<Self::View<'a>, shipyard::error::GetStorage> {
let graphics =
UniqueView::<Graphics>::borrow(&all_storages, all_borrow, last_run, current)?;
let output = graphics
.surface
.get_current_texture()
.map_err(shipyard::error::GetStorage::from_custom)?;
let view = output
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
let encoder = graphics
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Render Encoder"),
});
Ok(RenderGraphicsViewMut { encoder, view })
}
}
#[rustfmt::skip]
mod view {
use super::{wgpu, UniqueView, Graphics, AllStorages, SharedBorrow, TrackingTimestamp};
use std::iter;
struct RenderGraphicsViewMut<'v> {
encoder: wgpu::CommandEncoder,
view: wgpu::TextureView,
output: Option<wgpu::SurfaceTexture>,
graphics: UniqueView<'v, Graphics>,
}
impl shipyard::borrow::Borrow for RenderGraphicsViewMut<'_> {
type View<'v> = RenderGraphicsViewMut<'v>;
fn borrow<'a>(
all_storages: &'a AllStorages,
all_borrow: Option<SharedBorrow<'a>>,
last_run: Option<TrackingTimestamp>,
current: TrackingTimestamp,
) -> Result<Self::View<'a>, shipyard::error::GetStorage> {
let graphics =
UniqueView::<Graphics>::borrow(&all_storages, all_borrow, last_run, current)?;
let output = graphics
.surface
.get_current_texture()
.map_err(shipyard::error::GetStorage::from_custom)?;
let view = output
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
let encoder = graphics
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Render Encoder"),
});
Ok(RenderGraphicsViewMut {
encoder,
view,
output: Some(output),
graphics,
})
}
}
impl Drop for RenderGraphicsViewMut<'_> {
fn drop(&mut self) {
let encoder = std::mem::replace(
&mut self.encoder,
self.graphics
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Render Encoder"),
}),
);
self.graphics.queue.submit(iter::once(encoder.finish()));
self.output.take().unwrap().present();
}
}
unsafe impl shipyard::borrow::BorrowInfo for RenderGraphicsViewMut<'_> {
fn borrow_info(info: &mut Vec<shipyard::scheduler::info::TypeInfo>) {
<UniqueView<Graphics>>::borrow_info(info);
}
fn enable_tracking(
enable_tracking_fn: &mut Vec<fn(&AllStorages) -> Result<(), shipyard::error::GetStorage>>,
) {
}
}
}