WIP mutations: Enough for an extremely basic example

This commit is contained in:
JMS55 2023-12-10 12:35:19 -08:00
parent 3d71d27e7d
commit cad620fe11
7 changed files with 399 additions and 79 deletions

290
Cargo.lock generated
View file

@ -281,6 +281,17 @@ version = "4.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1"
[[package]]
name = "async-trait"
version = "0.1.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "atomic-waker"
version = "1.1.2"
@ -495,7 +506,8 @@ name = "bevy_dioxus"
version = "0.1.0"
dependencies = [
"bevy",
"dioxus-core",
"dioxus",
"smallvec",
]
[[package]]
@ -1284,6 +1296,12 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2"
[[package]]
name = "constcat"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd7e35aee659887cbfb97aaf227ac12cad1a9d7c71e55ff3376839ed4e282d08"
[[package]]
name = "constgebra"
version = "0.1.3"
@ -1417,6 +1435,40 @@ dependencies = [
"winapi",
]
[[package]]
name = "darling"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "darling_macro"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [
"darling_core",
"quote",
"syn 2.0.39",
]
[[package]]
name = "dasp_sample"
version = "0.11.0"
@ -1429,6 +1481,20 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
[[package]]
name = "dioxus"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d9e3b0725e520250bf23213f996d241cca29cea4360a9bf08a44e0033f8e569"
dependencies = [
"dioxus-core",
"dioxus-core-macro",
"dioxus-hooks",
"dioxus-hot-reload",
"dioxus-html",
"dioxus-rsx",
]
[[package]]
name = "dioxus-core"
version = "0.4.3"
@ -1440,11 +1506,92 @@ dependencies = [
"futures-util",
"longest-increasing-subsequence",
"rustc-hash",
"serde",
"slab",
"smallbox",
"tracing",
]
[[package]]
name = "dioxus-core-macro"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21afaccb28587aed0ba98856335912f5ce7052c0aafa74b213829a3b8bfd2345"
dependencies = [
"constcat",
"dioxus-core",
"dioxus-rsx",
"prettyplease",
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "dioxus-debug-cell"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ea539174bb236e0e7dc9c12b19b88eae3cb574dedbd0252a2d43ea7e6de13e2"
[[package]]
name = "dioxus-hooks"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bb23ce82df4fb13e9ddaa01d1469f1f32d683dd4636204bd0a0eaf434b65946"
dependencies = [
"dioxus-core",
"dioxus-debug-cell",
"futures-channel",
"slab",
"thiserror",
"tracing",
]
[[package]]
name = "dioxus-hot-reload"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7d8c9e89e866a6b84b8ad696f0ff2f6f6563d2235eb99acc6952f19e516cc09"
dependencies = [
"dioxus-core",
"dioxus-html",
"dioxus-rsx",
"interprocess-docfix",
"serde",
"serde_json",
]
[[package]]
name = "dioxus-html"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "828a42a2d70688a2412a8538c8b5a5eceadf68f682f899dc4455a0169db39dfd"
dependencies = [
"async-channel 1.9.0",
"async-trait",
"dioxus-core",
"enumset",
"euclid",
"keyboard-types",
"serde",
"serde-value",
"serde_json",
"serde_repr",
"web-sys",
]
[[package]]
name = "dioxus-rsx"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c974133c7c95497a486d587e40449927711430b308134b9cd374b8d35eceafb3"
dependencies = [
"dioxus-core",
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "dispatch"
version = "0.2.0"
@ -1489,6 +1636,27 @@ dependencies = [
"syn 2.0.39",
]
[[package]]
name = "enumset"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d"
dependencies = [
"enumset_derive",
]
[[package]]
name = "enumset_derive"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "equivalent"
version = "1.0.1"
@ -1511,6 +1679,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f253bc5c813ca05792837a0ff4b3a580336b224512d48f7eda1d7dd9210787"
dependencies = [
"num-traits",
"serde",
]
[[package]]
@ -1914,6 +2083,12 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "image"
version = "0.24.7"
@ -1986,6 +2161,32 @@ dependencies = [
"web-sys",
]
[[package]]
name = "interprocess-docfix"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b84ee245c606aeb0841649a9288e3eae8c61b853a8cd5c0e14450e96d53d28f"
dependencies = [
"blocking",
"cfg-if",
"futures-core",
"futures-io",
"intmap",
"libc",
"once_cell",
"rustc_version",
"spinning",
"thiserror",
"to_method",
"winapi",
]
[[package]]
name = "intmap"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae52f28f45ac2bc96edb7714de995cffc174a395fb0abf5bff453587c980d7b9"
[[package]]
name = "io-kit-sys"
version = "0.4.0"
@ -2054,6 +2255,17 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "keyboard-types"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a"
dependencies = [
"bitflags 2.4.1",
"serde",
"unicode-segmentation",
]
[[package]]
name = "khronos-egl"
version = "4.1.0"
@ -2553,6 +2765,15 @@ dependencies = [
"libredox",
]
[[package]]
name = "ordered-float"
version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
dependencies = [
"num-traits",
]
[[package]]
name = "overload"
version = "0.1.1"
@ -2676,6 +2897,16 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "prettyplease"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d"
dependencies = [
"proc-macro2",
"syn 2.0.39",
]
[[package]]
name = "proc-macro-crate"
version = "1.3.1"
@ -2842,6 +3073,15 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "ruzstd"
version = "0.4.0"
@ -2874,6 +3114,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]]
name = "serde"
version = "1.0.193"
@ -2883,6 +3129,16 @@ dependencies = [
"serde_derive",
]
[[package]]
name = "serde-value"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
dependencies = [
"ordered-float",
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.193"
@ -2905,6 +3161,17 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_repr"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
@ -2968,6 +3235,15 @@ dependencies = [
"serde",
]
[[package]]
name = "spinning"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d4f0e86297cad2658d92a707320d87bf4e6ae1050287f51d19b67ef3f153a7b"
dependencies = [
"lock_api",
]
[[package]]
name = "spirv"
version = "0.2.0+1.5.4"
@ -3112,6 +3388,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "to_method"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8"
[[package]]
name = "toml_datetime"
version = "0.6.5"
@ -3245,6 +3527,12 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-segmentation"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "unicode-width"
version = "0.1.11"

View file

@ -5,4 +5,8 @@ edition = "2021"
[dependencies]
bevy = { git = "https://github.com/JMS55/bevy", branch = "query_new" }
dioxus-core = "0.4"
dioxus = "0.4"
smallvec = "1.0"
[[example]]
name = "basic"

25
examples/basic.rs Normal file
View file

@ -0,0 +1,25 @@
use bevy::{
app::{App, Startup},
core_pipeline::core_2d::Camera2dBundle,
ecs::system::Commands,
ui::node_bundles::NodeBundle,
DefaultPlugins,
};
use bevy_dioxus::{dioxus::prelude::*, DioxusUiBundle, DioxusUiPlugin, DioxusUiRoot};
fn main() {
App::new()
.add_plugins((DefaultPlugins, DioxusUiPlugin))
.add_systems(Startup, |mut commands: Commands| {
commands.spawn(DioxusUiBundle {
dioxus_ui_root: DioxusUiRoot::new(ui_root),
node_bundle: NodeBundle::default(),
});
commands.spawn(Camera2dBundle::default());
})
.run();
}
fn ui_root(cx: Scope) -> Element {
render!("Hello")
}

View file

@ -1,27 +1,26 @@
use bevy::{
ecs::{
entity::Entity,
reflect::{AppTypeRegistry, ReflectComponent},
system::{Command, Commands},
world::Mut,
},
hierarchy::{BuildChildren, DespawnRecursiveExt},
prelude::World,
reflect::Reflect,
ecs::{entity::Entity, system::Commands},
hierarchy::BuildChildren,
prelude::default,
text::{Text, TextStyle},
ui::node_bundles::TextBundle,
utils::HashMap,
};
use dioxus_core::{BorrowedAttributeValue, ElementId, Mutation, Mutations};
use std::sync::Arc;
use dioxus::core::{ElementId, Mutation, Mutations, Template, TemplateNode};
use smallvec::SmallVec;
pub fn apply_mutations(
mutations: Mutations,
element_id_to_bevy_ui_entity: &mut HashMap<ElementId, Entity>,
templates: &mut HashMap<String, ()>,
templates: &mut HashMap<String, BevyTemplate>,
root_entity: Entity,
commands: &mut Commands,
) {
for new_template in mutations.templates {
templates.insert(new_template.name.to_owned(), todo!());
templates.insert(
new_template.name.to_owned(),
BevyTemplate::from_dioxus(&new_template),
);
}
let map = element_id_to_bevy_ui_entity;
@ -37,16 +36,14 @@ pub fn apply_mutations(
}
}
Mutation::AssignId { path, id } => todo!(),
Mutation::CreatePlaceholder { id } => {
map.insert(id, commands.spawn(()).id());
Mutation::CreatePlaceholder { id } => todo!(),
Mutation::CreateTextNode { value, id } => todo!(),
Mutation::HydrateText { path, value, id } => todo!(),
Mutation::LoadTemplate { name, index, id } => {
let entity = templates[name].roots[index].spawn(commands);
map.insert(id, entity);
stack.push(entity);
}
Mutation::CreateTextNode { .. } => {
unreachable!("Should not be used by bevy_dioxus elements");
}
Mutation::HydrateText { .. } => {
unreachable!("Should not be used by bevy_dioxus elements");
}
Mutation::LoadTemplate { name, index, id } => todo!(),
Mutation::ReplaceWith { id, m } => todo!(),
Mutation::ReplacePlaceholder { path, m } => todo!(),
Mutation::InsertAfter { id, m } => todo!(),
@ -55,63 +52,61 @@ pub fn apply_mutations(
name,
value,
id,
ns: _,
} => commands.add(SetReflectedComponent {
entity: map[&id],
component_type_path: name.to_owned(),
component_value: match value {
BorrowedAttributeValue::Any(value) => Some(Arc::clone(
value
.as_any()
.downcast_ref::<Arc<dyn Reflect>>()
.expect(&format!(
"Encountered an attribute with name {name} that did not impl Reflect"
)),
)),
BorrowedAttributeValue::None => None,
_ => unreachable!("Should not be used by bevy_dioxus elements"),
},
}),
Mutation::SetText { .. } => unreachable!("Should not be used by bevy_dioxus elements"),
ns,
} => todo!(),
Mutation::SetText { value, id } => todo!(),
Mutation::NewEventListener { name, id } => todo!(),
Mutation::RemoveEventListener { name, id } => todo!(),
Mutation::Remove { id } => {
commands
.entity(map.remove(&id).unwrap())
.despawn_recursive();
}
Mutation::PushRoot { id } => stack.push(map[&id]),
Mutation::Remove { id } => todo!(),
Mutation::PushRoot { id } => todo!(),
}
}
}
struct SetReflectedComponent {
entity: Entity,
component_type_path: String,
component_value: Option<Arc<dyn Reflect>>,
pub struct BevyTemplate {
roots: SmallVec<[BevyTemplateNode; 4]>,
}
impl Command for SetReflectedComponent {
fn apply(self, world: &mut World) {
world.resource_scope(|world: &mut World, type_registry: Mut<AppTypeRegistry>| {
let type_registry = type_registry.read();
let reflected_component = type_registry
.get_with_type_path(&self.component_type_path)
.expect(&format!(
"Encountered an attribute with name {} that was not registered for reflection",
self.component_type_path
))
.data::<ReflectComponent>()
.expect(&format!(
"Encountered an attribute with name {} that did not reflect Component",
self.component_type_path
));
enum BevyTemplateNode {
Text(Text),
}
let entity_mut = &mut world.entity_mut(self.entity);
match self.component_value {
Some(value) => reflected_component.insert(entity_mut, &*value),
None => reflected_component.remove(entity_mut),
}
});
impl BevyTemplate {
fn from_dioxus(template: &Template) -> Self {
Self {
roots: template
.roots
.iter()
.map(BevyTemplateNode::from_dioxus)
.collect(),
}
}
}
impl BevyTemplateNode {
fn from_dioxus(node: &TemplateNode) -> Self {
match node {
TemplateNode::Element {
tag,
namespace,
attrs,
children,
} => todo!(),
TemplateNode::Text { text } => {
Self::Text(Text::from_section(*text, TextStyle::default()))
}
TemplateNode::Dynamic { id } => todo!(),
TemplateNode::DynamicText { id } => todo!(),
}
}
fn spawn(&self, commands: &mut Commands) -> Entity {
match self {
Self::Text(text) => commands.spawn(TextBundle {
text: text.clone(),
..default()
}),
}
.id()
}
}

View file

@ -7,7 +7,7 @@ use bevy::ecs::{
system::{IntoSystem, Query, Resource},
world::{unsafe_world_cell::UnsafeWorldCell, World},
};
use dioxus_core::ScopeState;
use dioxus::core::ScopeState;
pub trait DioxusUiHooks {
fn use_world<'a>(&'a self) -> &'a World;

View file

@ -4,21 +4,23 @@ mod hooks;
mod tick;
use self::{
apply_mutations::BevyTemplate,
deferred_system::DeferredSystemRegistry,
tick::{tick_dioxus_ui, VirtualDomUnsafe},
};
use bevy::{
app::{App, Plugin, Update},
ecs::{component::Component, entity::Entity},
ecs::{bundle::Bundle, component::Component, entity::Entity},
ui::node_bundles::NodeBundle,
utils::HashMap,
};
use dioxus_core::ElementId;
use dioxus::core::{Element, ElementId, Scope};
pub use self::{
deferred_system::DeferredSystem,
hooks::{DioxusUiHooks, DioxusUiQuery},
};
pub use dioxus_core::{Element, Scope};
pub use dioxus;
pub struct DioxusUiPlugin;
@ -29,11 +31,17 @@ impl Plugin for DioxusUiPlugin {
}
}
#[derive(Bundle)]
pub struct DioxusUiBundle {
pub dioxus_ui_root: DioxusUiRoot,
pub node_bundle: NodeBundle,
}
#[derive(Component)]
pub struct DioxusUiRoot {
virtual_dom: VirtualDomUnsafe,
element_id_to_bevy_ui_entity: HashMap<ElementId, Entity>,
templates: HashMap<String, ()>,
templates: HashMap<String, BevyTemplate>,
needs_rebuild: bool,
}

View file

@ -10,7 +10,7 @@ use bevy::{
prelude::{Deref, DerefMut},
utils::synccell::SyncCell,
};
use dioxus_core::{Element, Scope, ScopeState, VirtualDom};
use dioxus::core::{Element, Scope, ScopeState, VirtualDom};
use std::{mem, sync::Arc};
pub fn tick_dioxus_ui(world: &mut World) {