Use type_name as plugin name default

This commit is contained in:
Carter Anderson 2020-04-05 14:12:14 -07:00
parent 7bb889bada
commit 0202dcb009
25 changed files with 349 additions and 391 deletions

View file

@ -368,7 +368,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
})
}
#[proc_macro_derive(RegisterAppPlugin)]
#[proc_macro_derive(DynamicAppPlugin)]
pub fn derive_app_plugin(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let struct_name = &ast.ident;

View file

@ -1,48 +1,34 @@
use bevy::{prelude::*, plugin::AppPlugin};
use bevy::prelude::*;
#[derive(RegisterAppPlugin)]
#[derive(DynamicAppPlugin)]
pub struct ExamplePlugin;
impl AppPlugin for ExamplePlugin {
fn build(&self, app_builder: AppBuilder) -> AppBuilder {
app_builder.setup(setup)
}
fn name(&self) -> &str {
"example"
}
}
pub fn setup(world: &mut World, resources: &mut Resources) {
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
let mut material_storage = resources
.get_mut::<AssetStorage<StandardMaterial>>()
.unwrap();
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
let cube_material_handle = material_storage.add(StandardMaterial {
albedo: Color::rgb(0.5, 0.4, 0.3),
..Default::default()
});
world.build()
// plane
.add_entity(MeshEntity {
mesh: plane_handle,
material: StandardMaterial {
albedo: Color::rgb(0.1, 0.2, 0.1),
},
..Default::default()
})
// cube
.add_entity(MeshEntity {
mesh: cube_handle,
material: StandardMaterial {
albedo: Color::rgb(0.5, 0.4, 0.3),
},
translation: Translation::new(0.0, 0.0, 1.0),
material: cube_material_handle,
..Default::default()
})
// light
.add_entity(LightEntity {
light: Light {
color: Color::rgb(0.8, 0.8, 0.5),
fov: f32::to_radians(60.0),
depth: 0.1..50.0,
},
translation: Translation::new(4.0, -4.0, 5.0),
..Default::default()
})

View file

@ -5,7 +5,7 @@ fn main() {
.add_default_plugins()
.load_plugin(concat!(
env!("CARGO_MANIFEST_DIR"),
"/examples/plugin_loading/example_plugin/target/release/libexample_plugin.so"
"/examples/dynamic_plugin_loading/example_plugin/target/release/libexample_plugin.so"
))
.run();
}

View file

@ -27,6 +27,7 @@ impl App {
}
pub fn build() -> AppBuilder {
env_logger::init();
AppBuilder::new()
}

View file

@ -226,6 +226,7 @@ impl AppBuilder {
pub fn load_plugin(self, path: &str) -> Self {
let (_lib, plugin) = load_plugin(path);
log::debug!("loaded plugin: {}", plugin.name());
plugin.build(self)
}
@ -233,6 +234,7 @@ impl AppBuilder {
where
T: AppPlugin,
{
log::debug!("added plugin: {}", plugin.name());
plugin.build(self)
}
}

View file

@ -4,8 +4,9 @@ use std::any::Any;
pub trait AppPlugin: Any + Send + Sync {
fn build(&self, app: AppBuilder) -> AppBuilder;
// TODO: consider removing "name" in favor of calling type_name::<Plugin>() from the host app
fn name(&self) -> &str;
fn name(&self) -> &str {
type_name_of_val(self)
}
}
pub type CreateAppPlugin = unsafe fn() -> *mut dyn AppPlugin;
@ -19,3 +20,7 @@ pub fn load_plugin(path: &str) -> (Library, Box<dyn AppPlugin>) {
(lib, plugin)
}
}
fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
std::any::type_name::<T>()
}

View file

@ -36,7 +36,4 @@ impl AppPlugin for ScheduleRunnerPlugin {
},
})
}
fn name(&self) -> &str {
"ScheduleRun"
}
}

View file

@ -1,20 +0,0 @@
use super::Time;
use crate::app::{plugin::AppPlugin, AppBuilder};
use bevy_transform::transform_system_bundle;
#[derive(Default)]
pub struct CorePlugin;
impl AppPlugin for CorePlugin {
fn build(&self, mut app: AppBuilder) -> AppBuilder {
for transform_system in transform_system_bundle::build(&mut app.world).drain(..) {
app = app.add_system(transform_system);
}
app.add_resource(Time::new())
}
fn name(&self) -> &str {
"Core"
}
}

View file

@ -1,9 +1,23 @@
pub mod bytes;
mod core_plugin;
pub mod event;
mod time;
pub use bytes::*;
pub use core_plugin::*;
pub use event::*;
pub use time::*;
use crate::app::{plugin::AppPlugin, AppBuilder};
use bevy_transform::transform_system_bundle;
#[derive(Default)]
pub struct CorePlugin;
impl AppPlugin for CorePlugin {
fn build(&self, mut app: AppBuilder) -> AppBuilder {
for transform_system in transform_system_bundle::build(&mut app.world).drain(..) {
app = app.add_system(transform_system);
}
app.add_resource(Time::new())
}
}

View file

@ -0,0 +1,121 @@
use std::{
collections::{HashMap, VecDeque},
time::{Duration, SystemTime},
};
use uuid::Uuid;
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
pub struct DiagnosticId(pub Uuid);
#[derive(Debug)]
pub struct DiagnosticMeasurement {
pub time: SystemTime,
pub value: f64,
}
#[derive(Debug)]
pub struct Diagnostic {
pub id: DiagnosticId,
pub name: String,
history: VecDeque<DiagnosticMeasurement>,
sum: f64,
max_history_length: usize,
}
impl Diagnostic {
pub fn add_measurement(&mut self, value: f64) {
let time = SystemTime::now();
if self.history.len() == self.max_history_length {
if let Some(removed_diagnostic) = self.history.pop_back() {
self.sum -= removed_diagnostic.value;
}
}
self.sum += value;
self.history
.push_front(DiagnosticMeasurement { time, value });
}
pub fn new(id: DiagnosticId, name: &str, max_history_length: usize) -> Diagnostic {
Diagnostic {
id,
name: name.to_string(),
history: VecDeque::with_capacity(max_history_length),
max_history_length,
sum: 0.0,
}
}
pub fn value(&self) -> Option<f64> {
self.history.back().map(|measurement| measurement.value)
}
pub fn sum(&self) -> f64 {
self.sum
}
pub fn average(&self) -> Option<f64> {
if self.history.len() > 0 {
Some(self.sum / self.history.len() as f64)
} else {
None
}
}
pub fn history_len(&self) -> usize {
self.history.len()
}
pub fn duration(&self) -> Option<Duration> {
if self.history.len() < 2 {
return None;
}
if let Some(oldest) = self.history.back() {
if let Some(newest) = self.history.front() {
return newest.time.duration_since(oldest.time).ok();
}
}
return None;
}
pub fn get_max_history_length(&self) -> usize {
self.max_history_length
}
}
#[derive(Default)]
pub struct Diagnostics {
diagnostics: HashMap<DiagnosticId, Diagnostic>,
}
impl Diagnostics {
pub fn add(&mut self, diagnostic: Diagnostic) {
self.diagnostics.insert(diagnostic.id, diagnostic);
}
pub fn get(&self, id: DiagnosticId) -> Option<&Diagnostic> {
self.diagnostics.get(&id)
}
pub fn get_mut(&mut self, id: DiagnosticId) -> Option<&mut Diagnostic> {
self.diagnostics.get_mut(&id)
}
pub fn get_measurement(&self, id: DiagnosticId) -> Option<&DiagnosticMeasurement> {
self.diagnostics
.get(&id)
.and_then(|diagnostic| diagnostic.history.front())
}
pub fn add_measurement(&mut self, id: DiagnosticId, value: f64) {
if let Some(diagnostic) = self.diagnostics.get_mut(&id) {
diagnostic.add_measurement(value);
}
}
pub fn iter(&self) -> impl Iterator<Item = &Diagnostic> {
self.diagnostics.values()
}
}

View file

@ -1,42 +0,0 @@
use super::{
diagnostics::{frame_time_diagnostic_system, print_diagnostics_system},
Diagnostics,
};
use crate::app::{plugin::AppPlugin, AppBuilder};
use std::time::Duration;
pub struct DiagnosticsPlugin {
pub print_wait_duration: Duration,
pub print_diagnostics: bool,
pub add_defaults: bool,
}
impl Default for DiagnosticsPlugin {
fn default() -> Self {
DiagnosticsPlugin {
print_wait_duration: Duration::from_secs_f64(1.0),
print_diagnostics: false,
add_defaults: true,
}
}
}
impl AppPlugin for DiagnosticsPlugin {
fn build(&self, mut app: AppBuilder) -> AppBuilder {
app = app.add_resource(Diagnostics::default());
if self.add_defaults {
let frame_time_diagnostic_system =
{ frame_time_diagnostic_system(&mut app.resources, 10) };
app = app.add_system(frame_time_diagnostic_system)
}
if self.print_diagnostics {
app = app.add_system(print_diagnostics_system(self.print_wait_duration));
}
app
}
fn name(&self) -> &str {
"Diagnostics"
}
}

View file

@ -1,125 +1,40 @@
mod diagnostic_plugin;
mod diagnostic;
pub mod diagnostics;
pub use diagnostic_plugin::*;
pub use diagnostic::*;
use std::{
collections::{HashMap, VecDeque},
time::{Duration, SystemTime},
};
use uuid::Uuid;
use crate::app::{plugin::AppPlugin, AppBuilder};
use std::time::Duration;
use diagnostics::{print_diagnostics_system, frame_time_diagnostic_system};
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
pub struct DiagnosticId(Uuid);
#[derive(Debug)]
pub struct DiagnosticMeasurement {
pub time: SystemTime,
pub value: f64,
pub struct DiagnosticsPlugin {
pub print_wait_duration: Duration,
pub print_diagnostics: bool,
pub add_defaults: bool,
}
#[derive(Debug)]
pub struct Diagnostic {
pub id: DiagnosticId,
pub name: String,
history: VecDeque<DiagnosticMeasurement>,
sum: f64,
max_history_length: usize,
}
impl Diagnostic {
pub fn add_measurement(&mut self, value: f64) {
let time = SystemTime::now();
if self.history.len() == self.max_history_length {
if let Some(removed_diagnostic) = self.history.pop_back() {
self.sum -= removed_diagnostic.value;
}
impl Default for DiagnosticsPlugin {
fn default() -> Self {
DiagnosticsPlugin {
print_wait_duration: Duration::from_secs_f64(1.0),
print_diagnostics: false,
add_defaults: true,
}
self.sum += value;
self.history
.push_front(DiagnosticMeasurement { time, value });
}
pub fn new(id: DiagnosticId, name: &str, max_history_length: usize) -> Diagnostic {
Diagnostic {
id,
name: name.to_string(),
history: VecDeque::with_capacity(max_history_length),
max_history_length,
sum: 0.0,
}
}
pub fn value(&self) -> Option<f64> {
self.history.back().map(|measurement| measurement.value)
}
pub fn sum(&self) -> f64 {
self.sum
}
pub fn average(&self) -> Option<f64> {
if self.history.len() > 0 {
Some(self.sum / self.history.len() as f64)
} else {
None
}
}
pub fn history_len(&self) -> usize {
self.history.len()
}
pub fn duration(&self) -> Option<Duration> {
if self.history.len() < 2 {
return None;
}
if let Some(oldest) = self.history.back() {
if let Some(newest) = self.history.front() {
return newest.time.duration_since(oldest.time).ok();
}
}
return None;
}
pub fn get_max_history_length(&self) -> usize {
self.max_history_length
}
}
#[derive(Default)]
pub struct Diagnostics {
diagnostics: HashMap<DiagnosticId, Diagnostic>,
}
impl Diagnostics {
pub fn add(&mut self, diagnostic: Diagnostic) {
self.diagnostics.insert(diagnostic.id, diagnostic);
}
pub fn get(&self, id: DiagnosticId) -> Option<&Diagnostic> {
self.diagnostics.get(&id)
}
pub fn get_mut(&mut self, id: DiagnosticId) -> Option<&mut Diagnostic> {
self.diagnostics.get_mut(&id)
}
pub fn get_measurement(&self, id: DiagnosticId) -> Option<&DiagnosticMeasurement> {
self.diagnostics
.get(&id)
.and_then(|diagnostic| diagnostic.history.front())
}
pub fn add_measurement(&mut self, id: DiagnosticId, value: f64) {
if let Some(diagnostic) = self.diagnostics.get_mut(&id) {
diagnostic.add_measurement(value);
impl AppPlugin for DiagnosticsPlugin {
fn build(&self, mut app: AppBuilder) -> AppBuilder {
app = app.add_resource(Diagnostics::default());
if self.add_defaults {
let frame_time_diagnostic_system =
{ frame_time_diagnostic_system(&mut app.resources, 10) };
app = app.add_system(frame_time_diagnostic_system)
}
}
pub fn iter(&self) -> impl Iterator<Item = &Diagnostic> {
self.diagnostics.values()
if self.print_diagnostics {
app = app.add_system(print_diagnostics_system(self.print_wait_duration));
}
app
}
}

View file

@ -14,8 +14,4 @@ impl AppPlugin for InputPlugin {
.add_event::<MouseButtonInput>()
.add_event::<MouseMotion>()
}
fn name(&self) -> &str {
"Input"
}
}

View file

@ -21,14 +21,14 @@ impl DrawTarget for AssignedBatchesDrawTarget {
render_pass: &mut dyn RenderPass,
pipeline_handle: Handle<PipelineDescriptor>,
) {
log::debug!("drawing batches for pipeline {:?}", pipeline_handle);
log::trace!("drawing batches for pipeline {:?}", pipeline_handle);
let asset_batches = resources.get::<AssetBatchers>().unwrap();
let global_render_resource_assignments =
resources.get::<RenderResourceAssignments>().unwrap();
render_pass.set_render_resources(&global_render_resource_assignments);
for batch in asset_batches.get_batches() {
let indices = render_pass.set_render_resources(&batch.render_resource_assignments);
log::debug!("drawing batch {:?}", batch.render_resource_assignments.id);
log::trace!("drawing batch {:?}", batch.render_resource_assignments.id);
log::trace!("{:#?}", batch);
for batched_entity in batch.entities.iter() {
let renderable = world.get_component::<Renderable>(*batched_entity).unwrap();
@ -75,7 +75,7 @@ impl DrawTarget for AssignedBatchesDrawTarget {
let mut global_render_resource_assignments =
resources.get_mut::<RenderResourceAssignments>().unwrap();
log::debug!(
log::trace!(
"setting up batch bind groups for pipeline: {:?} {:?}",
pipeline_handle,
pipeline_descriptor.name,
@ -84,7 +84,7 @@ impl DrawTarget for AssignedBatchesDrawTarget {
renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor);
for batch in asset_batches.get_batches_mut() {
log::debug!(
log::trace!(
"setting up batch bind groups: {:?}",
batch.render_resource_assignments.id
);

View file

@ -1,7 +1,6 @@
mod camera;
pub mod mesh;
pub mod render_graph;
mod render_plugin;
pub mod shader;
mod color;
@ -11,7 +10,6 @@ mod vertex;
pub use camera::*;
pub use color::*;
pub use light::*;
pub use render_plugin::*;
pub use renderable::*;
pub use vertex::Vertex;
@ -23,3 +21,81 @@ pub mod render_resource;
mod renderable;
pub mod renderer;
pub mod texture;
use self::{
draw_target::draw_targets::{
AssignedBatchesDrawTarget, AssignedMeshesDrawTarget, MeshesDrawTarget, UiDrawTarget,
},
pass::passes::ForwardPassBuilder,
pipeline::{
pipelines::ForwardPipelineBuilder, PipelineCompiler, ShaderPipelineAssignments,
VertexBufferDescriptors,
},
render_graph::RenderGraph,
render_resource::{
build_entity_render_resource_assignments_system,
resource_providers::{
Camera2dResourceProvider, CameraResourceProvider, LightResourceProvider,
MeshResourceProvider, UiResourceProvider,
},
AssetBatchers, EntityRenderResourceAssignments, RenderResourceAssignments,
},
};
use crate::{prelude::*, window::WindowResized};
#[derive(Default)]
pub struct RenderPlugin;
impl RenderPlugin {
pub fn setup_render_graph_defaults(app: &mut AppBuilder) {
let mut pipelines = app
.resources
.get_mut::<AssetStorage<PipelineDescriptor>>()
.unwrap();
let mut shaders = app.resources.get_mut::<AssetStorage<Shader>>().unwrap();
let mut render_graph = app.resources.get_mut::<RenderGraph>().unwrap();
render_graph
.build(&mut pipelines, &mut shaders)
.add_draw_target(MeshesDrawTarget::default())
.add_draw_target(AssignedBatchesDrawTarget::default())
.add_draw_target(AssignedMeshesDrawTarget::default())
.add_draw_target(UiDrawTarget::default())
.add_resource_provider(CameraResourceProvider::new(
app.resources.get_event_reader::<WindowResized>(),
))
.add_resource_provider(Camera2dResourceProvider::new(
app.resources.get_event_reader::<WindowResized>(),
))
.add_resource_provider(LightResourceProvider::new(10))
.add_resource_provider(UiResourceProvider::new())
.add_resource_provider(MeshResourceProvider::new())
.add_resource_provider(UniformResourceProvider::<StandardMaterial>::new(true))
.add_resource_provider(UniformResourceProvider::<LocalToWorld>::new(true))
.add_forward_pass()
.add_forward_pipeline();
}
}
impl AppPlugin for RenderPlugin {
fn build(&self, mut app: AppBuilder) -> AppBuilder {
let mut asset_batchers = AssetBatchers::default();
asset_batchers.batch_types2::<Mesh, StandardMaterial>();
app = app
.add_system(build_entity_render_resource_assignments_system())
.add_resource(RenderGraph::default())
.add_resource(AssetStorage::<Mesh>::new())
.add_resource(AssetStorage::<Texture>::new())
.add_resource(AssetStorage::<Shader>::new())
.add_resource(AssetStorage::<StandardMaterial>::new())
.add_resource(AssetStorage::<PipelineDescriptor>::new())
.add_resource(ShaderPipelineAssignments::new())
.add_resource(VertexBufferDescriptors::default())
.add_resource(PipelineCompiler::new())
.add_resource(RenderResourceAssignments::default())
.add_resource(EntityRenderResourceAssignments::default())
.add_resource(asset_batchers);
RenderPlugin::setup_render_graph_defaults(&mut app);
app
}
}

View file

@ -1,77 +0,0 @@
use super::{
draw_target::draw_targets::{
AssignedBatchesDrawTarget, AssignedMeshesDrawTarget, MeshesDrawTarget, UiDrawTarget,
},
pass::passes::ForwardPassBuilder,
pipeline::{pipelines::ForwardPipelineBuilder, PipelineCompiler, ShaderPipelineAssignments, VertexBufferDescriptors},
render_graph::RenderGraph,
render_resource::{
build_entity_render_resource_assignments_system,
resource_providers::{
Camera2dResourceProvider, CameraResourceProvider, LightResourceProvider,
MeshResourceProvider, UiResourceProvider,
},
AssetBatchers, EntityRenderResourceAssignments, RenderResourceAssignments,
},
};
use crate::{prelude::*, window::WindowResized};
#[derive(Default)]
pub struct RenderPlugin;
impl RenderPlugin {
pub fn setup_render_graph_defaults(app: &mut AppBuilder) {
let mut pipelines = app
.resources
.get_mut::<AssetStorage<PipelineDescriptor>>()
.unwrap();
let mut shaders = app.resources.get_mut::<AssetStorage<Shader>>().unwrap();
let mut render_graph = app.resources.get_mut::<RenderGraph>().unwrap();
render_graph
.build(&mut pipelines, &mut shaders)
.add_draw_target(MeshesDrawTarget::default())
.add_draw_target(AssignedBatchesDrawTarget::default())
.add_draw_target(AssignedMeshesDrawTarget::default())
.add_draw_target(UiDrawTarget::default())
.add_resource_provider(CameraResourceProvider::new(
app.resources.get_event_reader::<WindowResized>(),
))
.add_resource_provider(Camera2dResourceProvider::new(
app.resources.get_event_reader::<WindowResized>(),
))
.add_resource_provider(LightResourceProvider::new(10))
.add_resource_provider(UiResourceProvider::new())
.add_resource_provider(MeshResourceProvider::new())
.add_resource_provider(UniformResourceProvider::<StandardMaterial>::new(true))
.add_resource_provider(UniformResourceProvider::<LocalToWorld>::new(true))
.add_forward_pass()
.add_forward_pipeline();
}
}
impl AppPlugin for RenderPlugin {
fn build(&self, mut app: AppBuilder) -> AppBuilder {
let mut asset_batchers = AssetBatchers::default();
asset_batchers.batch_types2::<Mesh, StandardMaterial>();
app = app
.add_system(build_entity_render_resource_assignments_system())
.add_resource(RenderGraph::default())
.add_resource(AssetStorage::<Mesh>::new())
.add_resource(AssetStorage::<Texture>::new())
.add_resource(AssetStorage::<Shader>::new())
.add_resource(AssetStorage::<StandardMaterial>::new())
.add_resource(AssetStorage::<PipelineDescriptor>::new())
.add_resource(ShaderPipelineAssignments::new())
.add_resource(VertexBufferDescriptors::default())
.add_resource(PipelineCompiler::new())
.add_resource(RenderResourceAssignments::default())
.add_resource(EntityRenderResourceAssignments::default())
.add_resource(asset_batchers);
RenderPlugin::setup_render_graph_defaults(&mut app);
app
}
fn name(&self) -> &str {
"Render"
}
}

View file

@ -24,9 +24,6 @@ impl AppPlugin for WgpuRendererPlugin {
let render_system = wgpu_render_system(&app.resources);
app.add_thread_local_to_stage(system_stage::RENDER, render_system)
}
fn name(&self) -> &str {
"WgpuRenderer"
}
}
pub fn wgpu_render_system(resources: &Resources) -> impl FnMut(&mut World, &mut Resources) {

View file

@ -60,7 +60,7 @@ impl WgpuResources {
if let Some((render_resource_set_id, _indices)) =
render_resource_assignments.get_render_resource_set_id(bind_group_descriptor.id)
{
log::debug!(
log::trace!(
"start creating bind group for RenderResourceSet {:?}",
render_resource_set_id
);
@ -132,7 +132,7 @@ impl WgpuResources {
.bind_groups
.insert(*render_resource_set_id, bind_group);
log::debug!(
log::trace!(
"created bind group for RenderResourceSet {:?}",
render_resource_set_id
);

View file

@ -17,7 +17,4 @@ impl AppPlugin for UiPlugin {
fn build(&self, app: AppBuilder) -> AppBuilder {
app.add_system(ui_update_system())
}
fn name(&self) -> &str {
"UI"
}
}

View file

@ -1,59 +1,45 @@
mod events;
mod window_plugin;
mod window;
mod windows;
#[cfg(feature = "winit")]
pub mod winit;
pub use events::*;
pub use window_plugin::*;
pub use window::*;
pub use windows::*;
use uuid::Uuid;
use crate::{
app::{plugin::AppPlugin, AppBuilder},
core::Events,
};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct WindowId(Uuid);
impl WindowId {
pub fn to_string(&self) -> String {
self.0.to_simple().to_string()
}
pub struct WindowPlugin {
pub primary_window: Option<WindowDescriptor>,
}
pub struct Window {
pub id: WindowId,
pub width: u32,
pub height: u32,
pub title: String,
pub vsync: bool,
}
impl Window {
pub fn new(window_descriptor: &WindowDescriptor) -> Self {
Window {
id: WindowId(Uuid::new_v4()),
height: window_descriptor.height,
width: window_descriptor.width,
title: window_descriptor.title.clone(),
vsync: window_descriptor.vsync,
}
}
}
#[derive(Debug, Clone)]
pub struct WindowDescriptor {
pub width: u32,
pub height: u32,
pub title: String,
pub vsync: bool,
}
impl Default for WindowDescriptor {
impl Default for WindowPlugin {
fn default() -> Self {
WindowDescriptor {
title: "bevy".to_string(),
width: 1280,
height: 720,
vsync: true,
WindowPlugin {
primary_window: Some(WindowDescriptor::default()),
}
}
}
impl AppPlugin for WindowPlugin {
fn build(&self, mut app: AppBuilder) -> AppBuilder {
app = app
.add_event::<WindowResized>()
.add_event::<CreateWindow>()
.add_event::<WindowCreated>()
.add_resource(Windows::default());
if let Some(ref primary_window_descriptor) = self.primary_window {
let mut create_window_event = app.resources.get_mut::<Events<CreateWindow>>().unwrap();
create_window_event.send(CreateWindow {
descriptor: primary_window_descriptor.clone(),
});
}
app
}
}

49
src/window/window.rs Normal file
View file

@ -0,0 +1,49 @@
use uuid::Uuid;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct WindowId(Uuid);
impl WindowId {
pub fn to_string(&self) -> String {
self.0.to_simple().to_string()
}
}
pub struct Window {
pub id: WindowId,
pub width: u32,
pub height: u32,
pub title: String,
pub vsync: bool,
}
impl Window {
pub fn new(window_descriptor: &WindowDescriptor) -> Self {
Window {
id: WindowId(Uuid::new_v4()),
height: window_descriptor.height,
width: window_descriptor.width,
title: window_descriptor.title.clone(),
vsync: window_descriptor.vsync,
}
}
}
#[derive(Debug, Clone)]
pub struct WindowDescriptor {
pub width: u32,
pub height: u32,
pub title: String,
pub vsync: bool,
}
impl Default for WindowDescriptor {
fn default() -> Self {
WindowDescriptor {
title: "bevy".to_string(),
width: 1280,
height: 720,
vsync: true,
}
}
}

View file

@ -1,40 +0,0 @@
use super::{CreateWindow, WindowCreated, WindowDescriptor, WindowResized, Windows};
use crate::{
app::{plugin::AppPlugin, AppBuilder},
core::Events,
};
pub struct WindowPlugin {
pub primary_window: Option<WindowDescriptor>,
}
impl Default for WindowPlugin {
fn default() -> Self {
WindowPlugin {
primary_window: Some(WindowDescriptor::default()),
}
}
}
impl AppPlugin for WindowPlugin {
fn build(&self, mut app: AppBuilder) -> AppBuilder {
app = app
.add_event::<WindowResized>()
.add_event::<CreateWindow>()
.add_event::<WindowCreated>()
.add_resource(Windows::default());
if let Some(ref primary_window_descriptor) = self.primary_window {
let mut create_window_event = app.resources.get_mut::<Events<CreateWindow>>().unwrap();
create_window_event.send(CreateWindow {
descriptor: primary_window_descriptor.clone(),
});
}
app
}
fn name(&self) -> &str {
"Window"
}
}

View file

@ -29,14 +29,9 @@ impl AppPlugin for WinitPlugin {
.add_resource(WinitWindows::default())
.set_runner(winit_runner)
}
fn name(&self) -> &str {
"Winit"
}
}
pub fn winit_runner(mut app: App) {
env_logger::init();
let event_loop = EventLoop::new();
let mut create_window_event_reader = app.resources.get_event_reader::<CreateWindow>();