move component registry to its own crate. automatically register asset handles

This commit is contained in:
Carter Anderson 2020-05-25 14:51:38 -07:00
parent ab66d21d2a
commit f0f0e3c1a8
17 changed files with 119 additions and 84 deletions

View File

@ -6,9 +6,10 @@ edition = "2018"
[features] [features]
default = ["headless", "wgpu", "winit"] default = ["headless", "wgpu", "winit"]
headless = ["asset", "core", "derive", "diagnostic", "gltf", "input", "pbr", "property", "render", "scene", "text", "transform", "ui", "window"] headless = ["asset", "component_registry", "core", "derive", "diagnostic", "gltf", "input", "pbr", "property", "render", "scene", "text", "transform", "ui", "window"]
asset = ["bevy_asset"] asset = ["bevy_asset"]
core = ["bevy_core"] core = ["bevy_core"]
component_registry = ["bevy_component_registry"]
derive = ["bevy_derive"] derive = ["bevy_derive"]
diagnostic = ["bevy_diagnostic"] diagnostic = ["bevy_diagnostic"]
gltf = ["bevy_gltf"] gltf = ["bevy_gltf"]
@ -35,6 +36,7 @@ members = [
# bevy # bevy
bevy_app = { path = "crates/bevy_app" } bevy_app = { path = "crates/bevy_app" }
bevy_asset = { path = "crates/bevy_asset", optional = true } bevy_asset = { path = "crates/bevy_asset", optional = true }
bevy_component_registry = { path = "crates/bevy_component_registry", optional = true }
bevy_core = { path = "crates/bevy_core", optional = true } bevy_core = { path = "crates/bevy_core", optional = true }
bevy_derive = { path = "crates/bevy_derive", optional = true } bevy_derive = { path = "crates/bevy_derive", optional = true }
bevy_diagnostic = { path = "crates/bevy_diagnostic", optional = true } bevy_diagnostic = { path = "crates/bevy_diagnostic", optional = true }

View File

@ -11,6 +11,7 @@ filesystem_watcher = ["notify"]
[dependencies] [dependencies]
bevy_app = { path = "../bevy_app" } bevy_app = { path = "../bevy_app" }
bevy_core = { path = "../bevy_core" } bevy_core = { path = "../bevy_core" }
bevy_component_registry = { path = "../bevy_component_registry" }
bevy_property = { path = "../bevy_property" } bevy_property = { path = "../bevy_property" }
legion = { path = "../bevy_legion" } legion = { path = "../bevy_legion" }

View File

@ -3,6 +3,7 @@ use crate::{
Handle, HandleId, Handle, HandleId,
}; };
use bevy_app::{AppBuilder, Events, FromResources}; use bevy_app::{AppBuilder, Events, FromResources};
use bevy_component_registry::RegisterComponent;
use bevy_core::bytes::GetBytes; use bevy_core::bytes::GetBytes;
use legion::prelude::*; use legion::prelude::*;
use std::{ use std::{
@ -146,6 +147,7 @@ impl AddAsset for AppBuilder {
T: Send + Sync + 'static, T: Send + Sync + 'static,
{ {
self.init_resource::<Assets<T>>() self.init_resource::<Assets<T>>()
.register_component::<Handle<T>>()
.add_system_to_stage( .add_system_to_stage(
super::stage::ASSET_EVENTS, super::stage::ASSET_EVENTS,
Assets::<T>::asset_event_system.system(), Assets::<T>::asset_event_system.system(),
@ -175,7 +177,10 @@ impl AddAsset for AppBuilder {
.get_mut::<AssetServer>() .get_mut::<AssetServer>()
.expect("AssetServer does not exist. Consider adding it as a resource."); .expect("AssetServer does not exist. Consider adding it as a resource.");
asset_server.add_loader(TLoader::from_resources(self.resources())); asset_server.add_loader(TLoader::from_resources(self.resources()));
let handler = ChannelAssetHandler::new(TLoader::from_resources(self.resources()), asset_channel.sender.clone()); let handler = ChannelAssetHandler::new(
TLoader::from_resources(self.resources()),
asset_channel.sender.clone(),
);
asset_server.add_handler(handler); asset_server.add_handler(handler);
} }
self self

View File

@ -13,6 +13,7 @@ pub use load_request::*;
pub use loader::*; pub use loader::*;
use bevy_app::{AppBuilder, AppPlugin}; use bevy_app::{AppBuilder, AppPlugin};
use bevy_component_registry::RegisterComponent;
use legion::prelude::IntoSystem; use legion::prelude::IntoSystem;
pub mod stage { pub mod stage {
@ -27,7 +28,8 @@ impl AppPlugin for AssetPlugin {
fn build(&self, app: &mut AppBuilder) { fn build(&self, app: &mut AppBuilder) {
app.add_stage_before(bevy_app::stage::PRE_UPDATE, stage::LOAD_ASSETS) app.add_stage_before(bevy_app::stage::PRE_UPDATE, stage::LOAD_ASSETS)
.add_stage_after(bevy_app::stage::POST_UPDATE, stage::ASSET_EVENTS) .add_stage_after(bevy_app::stage::POST_UPDATE, stage::ASSET_EVENTS)
.init_resource::<AssetServer>(); .init_resource::<AssetServer>()
.register_property_type::<HandleId>();
#[cfg(feature = "filesystem_watcher")] #[cfg(feature = "filesystem_watcher")]
app.add_system_to_stage( app.add_system_to_stage(
stage::LOAD_ASSETS, stage::LOAD_ASSETS,

View File

@ -0,0 +1,13 @@
[package]
name = "bevy_component_registry"
version = "0.1.0"
authors = ["Carter Anderson <mcanders1@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bevy_app = { path = "../bevy_app" }
bevy_property = { path = "../bevy_property" }
legion = { path = "../bevy_legion" }
serde = { version = "1", features = ["derive"] }

View File

@ -1,10 +1,8 @@
use bevy_app::AppBuilder;
use bevy_property::{Properties, Property, PropertyTypeRegistry}; use bevy_property::{Properties, Property, PropertyTypeRegistry};
use legion::{ use legion::{
prelude::{Entity, World}, prelude::{Entity, World},
storage::{Component, ComponentResourceSet, ComponentTypeId}, storage::{Component, ComponentResourceSet, ComponentTypeId},
}; };
use serde::Deserialize;
use std::{ use std::{
collections::HashMap, collections::HashMap,
sync::{Arc, RwLock}, sync::{Arc, RwLock},
@ -84,42 +82,3 @@ impl ComponentRegistration {
} }
} }
} }
pub trait RegisterComponent {
fn register_component<T>(&mut self) -> &mut Self
where
T: Properties + Component + Default;
fn register_property_type<T>(&mut self) -> &mut Self
where
T: Property + for<'de> Deserialize<'de>;
}
impl RegisterComponent for AppBuilder {
fn register_component<T>(&mut self) -> &mut Self
where
T: Properties + Component + Default,
{
{
let registry_context = self
.resources()
.get_mut::<ComponentRegistryContext>()
.unwrap();
registry_context.value.write().unwrap().register::<T>();
}
self
}
fn register_property_type<T>(&mut self) -> &mut Self
where
T: Property + for<'de> Deserialize<'de>,
{
{
let registry_context = self
.resources()
.get_mut::<PropertyTypeRegistryContext>()
.unwrap();
registry_context.value.write().unwrap().register::<T>();
}
self
}
}

View File

@ -0,0 +1,17 @@
mod component_registry;
mod register_component;
pub use component_registry::*;
pub use register_component::*;
use bevy_app::{AppBuilder, AppPlugin};
#[derive(Default)]
pub struct ComponentRegistryPlugin;
impl AppPlugin for ComponentRegistryPlugin {
fn build(&self, app: &mut AppBuilder) {
app.init_resource::<ComponentRegistryContext>()
.init_resource::<PropertyTypeRegistryContext>();
}
}

View File

@ -0,0 +1,45 @@
use bevy_property::{Property, Properties};
use legion::storage::Component;
use serde::Deserialize;
use crate::{PropertyTypeRegistryContext, ComponentRegistryContext};
use bevy_app::AppBuilder;
pub trait RegisterComponent {
fn register_component<T>(&mut self) -> &mut Self
where
T: Properties + Component + Default;
fn register_property_type<T>(&mut self) -> &mut Self
where
T: Property + for<'de> Deserialize<'de>;
}
impl RegisterComponent for AppBuilder {
fn register_component<T>(&mut self) -> &mut Self
where
T: Properties + Component + Default,
{
{
let registry_context = self
.resources()
.get_mut::<ComponentRegistryContext>()
.unwrap();
registry_context.value.write().unwrap().register::<T>();
}
self
}
fn register_property_type<T>(&mut self) -> &mut Self
where
T: Property + for<'de> Deserialize<'de>,
{
{
let registry_context = self
.resources()
.get_mut::<PropertyTypeRegistryContext>()
.unwrap();
registry_context.value.write().unwrap().register::<T>();
}
self
}
}

View File

@ -7,6 +7,7 @@ edition = "2018"
[dependencies] [dependencies]
bevy_app = { path = "../bevy_app" } bevy_app = { path = "../bevy_app" }
bevy_asset = { path = "../bevy_asset" } bevy_asset = { path = "../bevy_asset" }
bevy_component_registry = { path = "../bevy_component_registry" }
bevy_property = { path = "../bevy_property" } bevy_property = { path = "../bevy_property" }
legion = { path = "../bevy_legion", features = ["serialize"] } legion = { path = "../bevy_legion", features = ["serialize"] }
serde = { version = "1.0", features = ["derive"]} serde = { version = "1.0", features = ["derive"]}

View File

@ -1,25 +1,13 @@
mod component_registry;
mod scene; mod scene;
mod scene_loader; mod scene_loader;
pub mod serde; pub mod serde;
pub use component_registry::*;
pub use scene::*; pub use scene::*;
pub use scene_loader::*; pub use scene_loader::*;
use bevy_app::{AppBuilder, AppPlugin}; use bevy_app::{AppBuilder, AppPlugin};
use bevy_asset::AddAsset; use bevy_asset::AddAsset;
#[derive(Default)]
pub struct ComponentRegistryPlugin;
impl AppPlugin for ComponentRegistryPlugin {
fn build(&self, app: &mut AppBuilder) {
app.init_resource::<ComponentRegistryContext>()
.init_resource::<PropertyTypeRegistryContext>();
}
}
#[derive(Default)] #[derive(Default)]
pub struct ScenePlugin; pub struct ScenePlugin;

View File

@ -1,5 +1,5 @@
use crate::ComponentRegistry;
use anyhow::Result; use anyhow::Result;
use bevy_component_registry::ComponentRegistry;
use bevy_property::DynamicProperties; use bevy_property::DynamicProperties;
use legion::prelude::World; use legion::prelude::World;
use serde::Serialize; use serde::Serialize;

View File

@ -1,7 +1,8 @@
use crate::{serde::SceneDeserializer, PropertyTypeRegistryContext, Scene}; use crate::{serde::SceneDeserializer, Scene};
use anyhow::Result; use anyhow::Result;
use bevy_app::FromResources; use bevy_app::FromResources;
use bevy_asset::AssetLoader; use bevy_asset::AssetLoader;
use bevy_component_registry::PropertyTypeRegistryContext;
use legion::prelude::Resources; use legion::prelude::Resources;
use serde::de::DeserializeSeed; use serde::de::DeserializeSeed;
use std::{cell::RefCell, path::Path, rc::Rc}; use std::{cell::RefCell, path::Path, rc::Rc};

View File

@ -1,7 +1,5 @@
use bevy::prelude::*; use bevy::{component_registry::ComponentRegistryContext, prelude::*};
use bevy_scene::ComponentRegistryContext;
use serde::Serialize; use serde::Serialize;
use bevy_asset::HandleId;
fn main() { fn main() {
App::build() App::build()
@ -11,8 +9,6 @@ fn main() {
// In the future registered components will also be usable from the Bevy editor. // In the future registered components will also be usable from the Bevy editor.
.register_component::<Test>() .register_component::<Test>()
.register_component::<Foo>() .register_component::<Foo>()
.register_component::<Handle<Mesh>>()
.register_property_type::<HandleId>()
.add_startup_system(load_scene) .add_startup_system(load_scene)
// .add_startup_system(serialize_scene) // .add_startup_system(serialize_scene)
.run(); .run();
@ -37,28 +33,25 @@ fn load_scene(world: &mut World, resources: &mut Resources) {
let scene_handle: Handle<Scene> = asset_server let scene_handle: Handle<Scene> = asset_server
.load_sync(&mut scenes, "assets/scene/load_scene_example.scn") .load_sync(&mut scenes, "assets/scene/load_scene_example.scn")
.unwrap(); .unwrap();
let scene= scenes.get(&scene_handle).unwrap(); let scene = scenes.get(&scene_handle).unwrap();
scene.add_to_world(world, &component_registry.value.read().unwrap()).unwrap(); scene
.add_to_world(world, &component_registry.value.read().unwrap())
.unwrap();
} }
#[allow(dead_code)] #[allow(dead_code)]
fn serialize_scene(world: &mut World, resources: &mut Resources) { fn serialize_scene(world: &mut World, resources: &mut Resources) {
let component_registry = resources.get::<ComponentRegistryContext>().unwrap(); let component_registry = resources.get::<ComponentRegistryContext>().unwrap();
world.build() world
.build()
.build_entity() .build_entity()
.add(Test { .add(Test { x: 1.0, y: 2.0 })
x: 1.0,
y: 2.0,
})
.add(Handle::<Mesh>::new()) .add(Handle::<Mesh>::new())
.add(Foo { .add(Foo {
value: "hello".to_string() value: "hello".to_string(),
}) })
.build_entity() .build_entity()
.add(Test { .add(Test { x: 3.0, y: 4.0 });
x: 3.0,
y: 4.0,
});
let scene = Scene::from_world(world, &component_registry.value.read().unwrap()); let scene = Scene::from_world(world, &component_registry.value.read().unwrap());
let pretty_config = ron::ser::PrettyConfig::default().with_decimal_floats(true); let pretty_config = ron::ser::PrettyConfig::default().with_decimal_floats(true);

View File

@ -1,6 +1,8 @@
use bevy::prelude::*; use bevy::{
use bevy_property::{AsProperties, ron::deserialize_dynamic_properties}; component_registry::PropertyTypeRegistryContext,
use bevy_scene::PropertyTypeRegistryContext; prelude::*,
property::{ron::deserialize_dynamic_properties, AsProperties},
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
fn main() { fn main() {

View File

@ -13,7 +13,7 @@ impl AddDefaultPlugins for AppBuilder {
self.add_plugin(bevy_diagnostic::DiagnosticsPlugin::default()); self.add_plugin(bevy_diagnostic::DiagnosticsPlugin::default());
#[cfg(feature = "scene")] #[cfg(feature = "scene")]
self.add_plugin(bevy_scene::ComponentRegistryPlugin::default()); self.add_plugin(bevy_component_registry::ComponentRegistryPlugin::default());
#[cfg(feature = "input")] #[cfg(feature = "input")]
self.add_plugin(bevy_input::InputPlugin::default()); self.add_plugin(bevy_input::InputPlugin::default());

View File

@ -49,6 +49,8 @@ pub use legion;
#[cfg(feature = "asset")] #[cfg(feature = "asset")]
pub use bevy_asset as asset; pub use bevy_asset as asset;
#[cfg(feature = "component_registry")]
pub use bevy_component_registry as component_registry;
#[cfg(feature = "core")] #[cfg(feature = "core")]
pub use bevy_core as core; pub use bevy_core as core;
#[cfg(feature = "derive")] #[cfg(feature = "derive")]

View File

@ -1,5 +1,7 @@
#[cfg(feature = "asset")] #[cfg(feature = "asset")]
pub use crate::asset::{AddAsset, AssetEvent, AssetServer, Assets, Handle}; pub use crate::asset::{AddAsset, AssetEvent, AssetServer, Assets, Handle};
#[cfg(feature = "component_registry")]
pub use crate::component_registry::RegisterComponent;
#[cfg(feature = "core")] #[cfg(feature = "core")]
pub use crate::core::{ pub use crate::core::{
time::Time, time::Time,
@ -12,7 +14,7 @@ pub use crate::diagnostic::DiagnosticsPlugin;
#[cfg(feature = "pbr")] #[cfg(feature = "pbr")]
pub use crate::pbr::{entity::*, light::Light, material::StandardMaterial}; pub use crate::pbr::{entity::*, light::Light, material::StandardMaterial};
#[cfg(feature = "property")] #[cfg(feature = "property")]
pub use crate::property::{Property, Properties, PropertyVal, PropertiesVal, DynamicProperties}; pub use crate::property::{DynamicProperties, Properties, PropertiesVal, Property, PropertyVal};
#[cfg(feature = "render")] #[cfg(feature = "render")]
pub use crate::render::{ pub use crate::render::{
draw_target, draw_target,
@ -32,13 +34,15 @@ pub use crate::render::{
ActiveCamera, ActiveCamera2d, Camera, CameraType, Color, ColorSource, Renderable, ActiveCamera, ActiveCamera2d, Camera, CameraType, Color, ColorSource, Renderable,
}; };
#[cfg(feature = "scene")] #[cfg(feature = "scene")]
pub use crate::scene::{Scene, RegisterComponent}; pub use crate::scene::Scene;
#[cfg(feature = "text")] #[cfg(feature = "text")]
pub use crate::text::Font; pub use crate::text::Font;
#[cfg(feature = "transform")] #[cfg(feature = "transform")]
pub use crate::transform::prelude::*; pub use crate::transform::prelude::*;
#[cfg(feature = "ui")] #[cfg(feature = "ui")]
pub use crate::ui::{entity::*, Anchors, ColorMaterial, Margins, Node, Rect, Sprite, widget::Label}; pub use crate::ui::{
entity::*, widget::Label, Anchors, ColorMaterial, Margins, Node, Rect, Sprite,
};
#[cfg(feature = "window")] #[cfg(feature = "window")]
pub use crate::window::{Window, WindowDescriptor, WindowPlugin, Windows}; pub use crate::window::{Window, WindowDescriptor, WindowPlugin, Windows};
pub use crate::{ pub use crate::{