This commit is contained in:
JMS55 2023-12-05 21:24:51 -08:00
commit 0fb498787b
5 changed files with 4004 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

3891
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

8
Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "bevy_dioxus"
version = "0.1.0"
edition = "2021"
[dependencies]
bevy = "0.12"
dioxus-core = "0.4"

72
src/implementation.rs Normal file
View File

@ -0,0 +1,72 @@
use super::DioxusUiRoot;
use bevy::{
ecs::{
entity::Entity,
system::{CommandQueue, Commands},
world::World,
},
prelude::{Deref, DerefMut},
utils::synccell::SyncCell,
};
use dioxus_core::{Mutations, VirtualDom};
use std::{cell::RefCell, rc::Rc};
pub fn tick_dioxus_ui(world: &mut World) {
unsafe {
let world_cell = world.as_unsafe_world_cell();
let apply_mutations = |mutations: Mutations, bevy_ui_root: Entity| {
todo!("Modify bevy_ui entities based on mutations");
};
let mut command_queue = CommandQueue::default();
for mut dioxus_ui_root in world_cell
.world_mut()
.query::<&mut DioxusUiRoot>()
.iter_mut(world_cell.world_mut())
{
dioxus_ui_root
.virtual_dom
.get()
.base_scope()
.provide_context(EcsContext {
world_read_only: std::mem::transmute(world_cell.world()),
commands: Rc::new(RefCell::new(Commands::new(
std::mem::transmute(&mut command_queue),
std::mem::transmute(world_cell.world()),
))),
});
let bevy_ui_root = dioxus_ui_root.root_entity.unwrap_or_else(|| {
// TODO: Spawn bevy_ui_root as a child of dioxus_ui_root
let bevy_ui_root = world_cell.world_mut().spawn(()).id();
apply_mutations(dioxus_ui_root.virtual_dom.get().rebuild(), bevy_ui_root);
bevy_ui_root
});
// TODO: Handle events from winit
// dioxus_ui_root
// .virtual_dom
// .get()
// .handle_event(todo!(), todo!(), todo!(), todo!());
apply_mutations(
dioxus_ui_root.virtual_dom.get().render_immediate(),
bevy_ui_root,
);
}
command_queue.apply(world);
}
}
#[derive(Clone)]
struct EcsContext {
world_read_only: &'static World,
commands: Rc<RefCell<Commands<'static, 'static>>>,
}
#[derive(Deref, DerefMut)]
pub struct VirtualDomUnsafe(pub SyncCell<VirtualDom>);
unsafe impl Send for VirtualDomUnsafe {}

32
src/lib.rs Normal file
View File

@ -0,0 +1,32 @@
mod implementation;
use self::implementation::{tick_dioxus_ui, VirtualDomUnsafe};
use bevy::{
app::{App, Plugin, Update},
ecs::{component::Component, entity::Entity},
utils::synccell::SyncCell,
};
use dioxus_core::{Element, Scope, VirtualDom};
pub struct DioxusUiPlugin;
impl Plugin for DioxusUiPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, tick_dioxus_ui);
}
}
#[derive(Component)]
pub struct DioxusUiRoot {
virtual_dom: VirtualDomUnsafe,
root_entity: Option<Entity>,
}
impl DioxusUiRoot {
pub fn new(root_component: fn(Scope) -> Element) -> Self {
Self {
virtual_dom: VirtualDomUnsafe(SyncCell::new(VirtualDom::new(root_component))),
root_entity: None,
}
}
}