Skip to content

Commit

Permalink
scenes: deserialization and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
cart committed May 22, 2020
1 parent 553b754 commit d920100
Show file tree
Hide file tree
Showing 30 changed files with 822 additions and 247 deletions.
3 changes: 2 additions & 1 deletion CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

## Adapted Code

* legion
* legion_transform
* wgpu-rs examples

## Insipration
## Inspiration

* amethyst
* coffee
16 changes: 9 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ edition = "2018"

[features]
default = ["headless", "wgpu", "winit"]
headless = ["asset", "core", "derive", "diagnostic", "gltf", "input", "pbr", "render", "serialization", "text", "transform", "ui", "window"]
headless = ["asset", "core", "derive", "diagnostic", "gltf", "input", "pbr", "props", "render", "scene", "text", "transform", "ui", "window"]
asset = ["bevy_asset"]
core = ["bevy_core"]
derive = ["bevy_derive"]
diagnostic = ["bevy_diagnostic"]
gltf = ["bevy_gltf"]
input = ["bevy_input"]
pbr = ["bevy_pbr"]
props = ["bevy_props"]
render = ["bevy_render"]
serialization = ["bevy_serialization"]
scene = ["bevy_scene"]
text = ["bevy_text"]
transform = ["bevy_transform"]
ui = ["bevy_ui"]
Expand All @@ -40,8 +41,9 @@ bevy_diagnostic = { path = "crates/bevy_diagnostic", optional = true }
bevy_gltf = { path = "crates/bevy_gltf", optional = true }
bevy_input = { path = "crates/bevy_input", optional = true }
bevy_pbr = { path = "crates/bevy_pbr", optional = true }
bevy_props = { path = "crates/bevy_props", optional = true }
bevy_render = { path = "crates/bevy_render", optional = true }
bevy_serialization = { path = "crates/bevy_serialization", optional = true }
bevy_scene = { path = "crates/bevy_scene", optional = true }
bevy_transform = { path = "crates/bevy_transform", optional = true }
bevy_text = { path = "crates/bevy_text", optional = true }
bevy_ui = { path = "crates/bevy_ui", optional = true }
Expand Down Expand Up @@ -80,8 +82,8 @@ name = "parenting"
path = "examples/3d/parenting.rs"

[[example]]
name = "scene"
path = "examples/3d/scene.rs"
name = "3d_scene"
path = "examples/3d/3d_scene.rs"

[[example]]
name = "spawner"
Expand Down Expand Up @@ -148,8 +150,8 @@ name = "input_keyboard"
path = "examples/input/input_keyboard.rs"

[[example]]
name = "serializing"
path = "examples/serializing/serializing.rs"
name = "load_scene"
path = "examples/scene/load_scene.rs"

[[example]]
name = "shader_custom_material"
Expand Down
32 changes: 32 additions & 0 deletions assets/scene/load_scene_example.scn
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
(
id: 2309003120,
components: [
(
type: "Test",
data: (
x: 3,
y: 4,
),
),
(
type: "Foo",
data: (
value: "hi",
),
),
],
),
(
id: 4238063392,
components: [
(
type: "Test",
data: (
x: 3,
y: 4,
),
),
],
),
]
4 changes: 3 additions & 1 deletion crates/bevy_app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ edition = "2018"
[dependencies]
legion = { path = "../bevy_legion", features = ["serialize"] }
libloading = "0.5.2"
log = { version = "0.4", features = ["release_max_level_info"] }
log = { version = "0.4", features = ["release_max_level_info"] }
serde = { version = "1.0", features = ["derive"]}
erased-serde = "0.3"
2 changes: 1 addition & 1 deletion crates/bevy_app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ mod entity_archetype;
mod event;
mod plugin;
mod resources;
mod system;
pub mod schedule_plan;
pub mod schedule_runner;
pub mod stage;
mod system;

pub use app::*;
pub use app_builder::*;
Expand Down
14 changes: 7 additions & 7 deletions crates/bevy_asset/src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
update_asset_storage_system, AssetChannel, AssetLoader, AssetServer, ChannelAssetHandler,
Handle, HandleId,
};
use bevy_app::{AppBuilder, Events};
use bevy_app::{AppBuilder, Events, FromResources};
use bevy_core::bytes::GetBytes;
use legion::prelude::*;
use std::{
Expand Down Expand Up @@ -134,9 +134,9 @@ pub trait AddAsset {
fn add_asset<T>(&mut self) -> &mut Self
where
T: Send + Sync + 'static;
fn add_asset_loader<TLoader, TAsset>(&mut self, loader: TLoader) -> &mut Self
fn add_asset_loader<TAsset, TLoader>(&mut self) -> &mut Self
where
TLoader: AssetLoader<TAsset> + Clone,
TLoader: AssetLoader<TAsset> + FromResources,
TAsset: Send + Sync + 'static;
}

Expand All @@ -153,9 +153,9 @@ impl AddAsset for AppBuilder {
.add_event::<AssetEvent<T>>()
}

fn add_asset_loader<TLoader, TAsset>(&mut self, loader: TLoader) -> &mut Self
fn add_asset_loader<TAsset, TLoader>(&mut self) -> &mut Self
where
TLoader: AssetLoader<TAsset> + Clone,
TLoader: AssetLoader<TAsset> + FromResources,
TAsset: Send + Sync + 'static,
{
{
Expand All @@ -174,8 +174,8 @@ impl AddAsset for AppBuilder {
.resources()
.get_mut::<AssetServer>()
.expect("AssetServer does not exist. Consider adding it as a resource.");
asset_server.add_loader(loader.clone());
let handler = ChannelAssetHandler::new(loader, asset_channel.sender.clone());
asset_server.add_loader(TLoader::from_resources(self.resources()));
let handler = ChannelAssetHandler::new(TLoader::from_resources(self.resources()), asset_channel.sender.clone());
asset_server.add_handler(handler);
}
self
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_gltf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ pub use loader::*;

use bevy_app::{AppBuilder, AppPlugin};
use bevy_asset::AddAsset;
use bevy_render::mesh::Mesh;

#[derive(Default)]
pub struct GltfPlugin;

impl AppPlugin for GltfPlugin {
fn build(&self, app: &mut AppBuilder) {
app.add_asset_loader(GltfLoader);
app.add_asset_loader::<Mesh, GltfLoader>();
}
}
2 changes: 1 addition & 1 deletion crates/bevy_gltf/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use gltf::{buffer::Source, iter, mesh::Mode};
use std::{fs, io, path::Path};
use thiserror::Error;

#[derive(Clone)]
#[derive(Default)]
pub struct GltfLoader;

impl AssetLoader<Mesh> for GltfLoader {
Expand Down
9 changes: 5 additions & 4 deletions crates/bevy_legion/legion_core/src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,12 @@ impl GuidEntityAllocator {

/// Allocates a new unused `Entity` ID.
pub fn create_entity(&self) -> Entity {
if !self.next_ids.read().is_empty() {
return self.next_ids.write().pop().unwrap();
}
let entity = if !self.next_ids.read().is_empty() {
self.next_ids.write().pop().unwrap()
} else {
Entity::new(rand::random::<u32>(), Wrapping(1))
};

let entity = Entity::new(rand::random::<u32>(), Wrapping(1));
self.entities.write().insert(entity);
entity
}
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_legion/legion_core/src/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl WorldId {
pub struct World {
id: WorldId,
storage: UnsafeCell<Storage>,
pub(crate) entity_allocator: Arc<GuidEntityAllocator>,
pub entity_allocator: Arc<GuidEntityAllocator>,
entity_locations: Locations,
defrag_progress: usize,
command_buffer_size: usize,
Expand Down
11 changes: 11 additions & 0 deletions crates/bevy_props/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "bevy_props"
version = "0.1.0"
authors = ["Carter Anderson <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = "1"
erased-serde = "0.3"
143 changes: 143 additions & 0 deletions crates/bevy_props/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
use serde::{ser::SerializeMap, Deserialize, Serialize};
use std::{any::Any, collections::HashMap};

pub struct Test {
a: usize,
b: String,
}

impl Props for Test {
fn prop(&self, name: &str) -> Option<&dyn Prop> {
match name {
"a" => Some(&self.a),
"b" => Some(&self.b),
_ => None,
}
}
fn prop_mut(&mut self, name: &str) -> Option<&mut dyn Prop> {
match name {
"a" => Some(&mut self.a),
"b" => Some(&mut self.b),
_ => None,
}
}
fn prop_names(&self) -> Vec<&str> {
static NAMES: &[&str] = &["a", "b"];
NAMES.to_vec()
}
}

#[derive(Default)]
pub struct DynamicProps {
pub props: HashMap<String, Box<dyn Prop>>,
}

impl DynamicProps {
pub fn set<T: Prop>(&mut self, name: &str, prop: T) {
self.props.insert(name.to_string(), Box::new(prop));
}
}

impl Props for DynamicProps {
fn prop(&self, name: &str) -> Option<&dyn Prop> {
self.props.get(name).map(|p| &**p)
}
fn prop_mut(&mut self, name: &str) -> Option<&mut dyn Prop> {
self.props.get_mut(name).map(|p| &mut **p)
}
fn prop_names(&self) -> Vec<&str> {
self.props.keys().map(|k| k.as_str()).collect::<Vec<&str>>()
}
}

impl Serialize for DynamicProps {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut state = serializer.serialize_map(Some(self.props.len()))?;
for prop_name in self.prop_names() {
let prop = self.prop(prop_name).unwrap();
state.serialize_entry(prop_name, prop)?;
}
state.end()
// let mut state = serializer.serialize_struct("dyn", self.props.len())?;
// {
// for prop_name in self.prop_names() {
// let prop = self.prop(prop_name).unwrap();
// state.serialize_field(strrr, prop)?;
// }
// }
// state.end()
}
}

pub trait Props {
fn prop(&self, name: &str) -> Option<&dyn Prop>;
fn prop_mut(&mut self, name: &str) -> Option<&mut dyn Prop>;
fn prop_names(&self) -> Vec<&str>;
fn apply(&mut self, props: &dyn Props) {
for prop_name in props.prop_names() {
self.prop_mut(prop_name)
.unwrap()
.set_prop_val(props.prop(prop_name).unwrap().clone());
}
}
}

pub trait Prop: erased_serde::Serialize + Send + Sync + Any + 'static {
fn any(&self) -> &dyn Any;
fn any_mut(&mut self) -> &mut dyn Any;
fn clone(&self) -> Box<dyn Any>;
fn type_name(&self) -> &str {
std::any::type_name::<Self>()
}
}

erased_serde::serialize_trait_object!(Prop);

pub trait PropVal {
fn prop_val<T: 'static>(&self) -> Option<&T>;
fn set_prop_val<T: 'static>(&mut self, value: T);
fn set_prop_val_boxed<T: 'static>(&mut self, value: Box<dyn Any>);
}

impl PropVal for dyn Prop {
fn prop_val<T: 'static>(&self) -> Option<&T> {
self.any().downcast_ref::<T>()
}
fn set_prop_val<T: 'static>(&mut self, value: T) {
if let Some(prop) = self.any_mut().downcast_mut::<T>() {
*prop = value;
}
}
fn set_prop_val_boxed<T: 'static>(&mut self, value: Box<dyn Any>) {
if let Some(prop) = self.any_mut().downcast_mut::<T>() {
*prop = *value.downcast::<T>().unwrap();
}
}
}

impl<'a> Deserialize<'a> for DynamicProps {
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'a>,
{
Ok(DynamicProps::default())
}
}

impl<T> Prop for T
where
T: Clone + Serialize + Send + Sync + Any + 'static,
{
fn any(&self) -> &dyn Any {
self
}
fn any_mut(&mut self) -> &mut dyn Any {
self
}
fn clone(&self) -> Box<dyn Any> {
Box::new(self.clone())
}
}
2 changes: 1 addition & 1 deletion crates/bevy_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl AppPlugin for RenderPlugin {
.add_asset::<Texture>()
.add_asset::<Shader>()
.add_asset::<PipelineDescriptor>()
.add_asset_loader(PngTextureLoader::default())
.add_asset_loader::<Texture, PngTextureLoader>()
.init_resource::<RenderGraph>()
.init_resource::<PipelineAssignments>()
.init_resource::<PipelineCompiler>()
Expand Down
Loading

0 comments on commit d920100

Please sign in to comment.