Skip to content

Commit

Permalink
Release 0.19 (#144)
Browse files Browse the repository at this point in the history
Changelist:
- Upgrade to Bevy 0.10 for related adapter crates
- Implemented Client-authoritative Entities
- Improved Bevy adapter API
  • Loading branch information
connorcarpenter authored Mar 10, 2023
1 parent 6f38660 commit 665b7ba
Show file tree
Hide file tree
Showing 163 changed files with 4,958 additions and 3,129 deletions.
4 changes: 2 additions & 2 deletions adapters/bevy/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ maintenance = { status = "actively-developed" }
[dependencies]
naia-client = { version = "0.18", path = "../../../client", features = ["bevy_support", "wbindgen"] }
naia-bevy-shared = { version = "0.18", path = "../shared" }
bevy_app = { version = "0.9", default-features=false }
bevy_ecs = { version = "0.9", default-features=false }
bevy_app = { version = "0.10", default-features=false }
bevy_ecs = { version = "0.10", default-features=false }
56 changes: 20 additions & 36 deletions adapters/bevy/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,24 @@ use std::net::SocketAddr;

use bevy_ecs::{
entity::Entity,
system::SystemParam,
world::{Mut, World},
system::{ResMut, SystemParam},
};

use naia_client::{Client as NaiaClient, EntityRef, NaiaClientError};
use naia_client::{Client as NaiaClient, NaiaClientError};

use naia_bevy_shared::{
Channel, EntityDoesNotExistError, EntityHandle, EntityHandleConverter, Message, Tick,
WorldProxy, WorldRef,
};

use super::state::State;

// Client

pub struct Client<'a> {
world: &'a World,
client: Mut<'a, NaiaClient<Entity>>,
#[derive(SystemParam)]
pub struct Client<'w> {
client: ResMut<'w, NaiaClient<Entity>>,
}

impl<'a> Client<'a> {
impl<'w> Client<'w> {
// Public Methods //

pub fn new(world: &'a World) -> Self {
unsafe {
let client = world
.get_resource_unchecked_mut::<NaiaClient<Entity>>()
.expect("Naia Client has not been correctly initialized!");

Self { world, client }
}
}

//// Connections ////

pub fn auth<M: Message>(&mut self, auth: M) {
Expand Down Expand Up @@ -78,16 +63,6 @@ impl<'a> Client<'a> {
self.client.send_tick_buffer_message::<C, M>(tick, message);
}

//// Entities ////

pub fn entity(&self, entity: &Entity) -> EntityRef<Entity, WorldRef> {
return self.client.entity(self.world.proxy(), entity);
}

pub fn entities(&self) -> Vec<Entity> {
return self.client.entities(&self.world.proxy());
}

//// Ticks ////

pub fn client_tick(&self) -> Option<Tick> {
Expand All @@ -107,14 +82,23 @@ impl<'a> Client<'a> {
pub fn server_interpolation(&self) -> Option<f32> {
self.client.server_interpolation()
}
}

impl<'a> SystemParam for Client<'a> {
type Fetch = State;
// Entity Registration

pub fn enable_replication(&mut self, entity: &Entity) {
self.client.enable_replication(entity);
}

pub fn disable_replication(&mut self, entity: &Entity) {
self.client.disable_replication(entity);
}
}

impl<'a> EntityHandleConverter<Entity> for Client<'a> {
fn handle_to_entity(&self, entity_handle: &EntityHandle) -> Entity {
impl<'w> EntityHandleConverter<Entity> for Client<'w> {
fn handle_to_entity(
&self,
entity_handle: &EntityHandle,
) -> Result<Entity, EntityDoesNotExistError> {
self.client.handle_to_entity(entity_handle)
}

Expand Down
72 changes: 32 additions & 40 deletions adapters/bevy/client/src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
use bevy_ecs::{
entity::Entity,
system::{Command, Commands, EntityCommands},
system::{Command as BevyCommand, EntityCommands},
world::World,
};

use naia_bevy_shared::{WorldMutType, WorldProxyMut};
use naia_bevy_shared::{HostOwned, WorldMutType, WorldProxyMut};

pub trait CommandsExt<'w, 's> {
fn duplicate_entity<'a>(&'a mut self, entity: Entity) -> EntityCommands<'w, 's, 'a>;
fn mirror_entities(&mut self, mutable_entity: Entity, immutable_entity: Entity);
use crate::Client;

// Bevy Commands Extension
pub trait CommandsExt<'w, 's, 'a> {
fn enable_replication(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a>;
fn disable_replication(&'a mut self, client: &mut Client)
-> &'a mut EntityCommands<'w, 's, 'a>;
fn duplicate(&'a mut self) -> EntityCommands<'w, 's, 'a>;
}

impl<'w, 's> CommandsExt<'w, 's> for Commands<'w, 's> {
fn duplicate_entity<'a>(&'a mut self, entity: Entity) -> EntityCommands<'w, 's, 'a> {
let new_entity = self.spawn_empty().id();
let command = DuplicateComponents::new(new_entity, entity);
self.add(command);
self.entity(new_entity)
impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> {
fn enable_replication(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a> {
client.enable_replication(&self.id());
self.insert(HostOwned);
return self;
}

fn disable_replication(
&'a mut self,
client: &mut Client,
) -> &'a mut EntityCommands<'w, 's, 'a> {
client.disable_replication(&self.id());
self.remove::<HostOwned>();
return self;
}

fn mirror_entities(&mut self, mutable_entity: Entity, immutable_entity: Entity) {
self.add(MirrorEntities::new(mutable_entity, immutable_entity));
fn duplicate(&'a mut self) -> EntityCommands<'w, 's, 'a> {
let old_entity = self.id();
let commands = self.commands();
let new_entity = commands.spawn_empty().id();
let command = DuplicateComponents::new(new_entity, old_entity);
commands.add(command);
commands.entity(new_entity)
}
}

Expand All @@ -40,7 +58,7 @@ impl DuplicateComponents {
}
}

impl Command for DuplicateComponents {
impl BevyCommand for DuplicateComponents {
fn write(self, world: &mut World) {
WorldMutType::<Entity>::duplicate_components(
&mut world.proxy_mut(),
Expand All @@ -49,29 +67,3 @@ impl Command for DuplicateComponents {
);
}
}

//// MirrorEntities Command ////

pub(crate) struct MirrorEntities {
mutable_entity: Entity,
immutable_entity: Entity,
}

impl MirrorEntities {
pub fn new(new_entity: Entity, old_entity: Entity) -> Self {
Self {
mutable_entity: new_entity,
immutable_entity: old_entity,
}
}
}

impl Command for MirrorEntities {
fn write(self, world: &mut World) {
WorldMutType::<Entity>::mirror_entities(
&mut world.proxy_mut(),
&self.mutable_entity,
&self.immutable_entity,
);
}
}
8 changes: 8 additions & 0 deletions adapters/bevy/client/src/components.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use bevy_ecs::component::Component;

use naia_bevy_shared::HostOwned;

pub type ClientOwned = HostOwned;

#[derive(Component)]
pub struct ServerOwned;
31 changes: 9 additions & 22 deletions adapters/bevy/client/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,10 @@ pub struct InsertComponentEvents {
inner: HashMap<ComponentKind, Vec<Entity>>,
}

impl From<&mut Events<Entity>> for InsertComponentEvents {
fn from(events: &mut Events<Entity>) -> Self {
Self {
inner: events.take_inserts(),
}
}
}

impl InsertComponentEvents {
pub fn new(inner: HashMap<ComponentKind, Vec<Entity>>) -> Self {
Self { inner }
}
pub fn read<C: Replicate>(&self) -> Vec<Entity> {
let component_kind = ComponentKind::of::<C>();
if let Some(components) = self.inner.get(&component_kind) {
Expand All @@ -97,15 +92,11 @@ pub struct UpdateComponentEvents {
inner: HashMap<ComponentKind, Vec<(Tick, Entity)>>,
}

impl From<&mut Events<Entity>> for UpdateComponentEvents {
fn from(events: &mut Events<Entity>) -> Self {
Self {
inner: events.take_updates(),
}
impl UpdateComponentEvents {
pub fn new(inner: HashMap<ComponentKind, Vec<(Tick, Entity)>>) -> Self {
Self { inner }
}
}

impl UpdateComponentEvents {
pub fn read<C: Replicate>(&self) -> Vec<(Tick, Entity)> {
let component_kind = ComponentKind::of::<C>();
if let Some(components) = self.inner.get(&component_kind) {
Expand All @@ -121,15 +112,11 @@ pub struct RemoveComponentEvents {
inner: HashMap<ComponentKind, Vec<(Entity, Box<dyn Replicate>)>>,
}

impl From<&mut Events<Entity>> for RemoveComponentEvents {
fn from(events: &mut Events<Entity>) -> Self {
Self {
inner: events.take_removes(),
}
impl RemoveComponentEvents {
pub fn new(inner: HashMap<ComponentKind, Vec<(Entity, Box<dyn Replicate>)>>) -> Self {
Self { inner }
}
}

impl RemoveComponentEvents {
pub fn read<C: Replicate>(&self) -> Vec<(Entity, C)> {
let mut output = Vec::new();

Expand Down
7 changes: 3 additions & 4 deletions adapters/bevy/client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
pub use naia_bevy_shared::{sequence_greater_than, Tick};
pub use naia_bevy_shared::{sequence_greater_than, Random, ReceiveEvents, Tick};
pub use naia_client::{ClientConfig, CommandHistory};

pub mod events;

mod client;
mod commands;
mod components;
mod plugin;
mod stage;
mod state;
mod systems;

pub use client::Client;
pub use commands::CommandsExt;
pub use components::{ClientOwned, ServerOwned};
pub use plugin::Plugin;
pub use stage::Stage;
29 changes: 9 additions & 20 deletions adapters/bevy/client/src/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
use std::{ops::DerefMut, sync::Mutex};

use bevy_app::{App, CoreStage, Plugin as PluginType};
use bevy_ecs::{entity::Entity, schedule::SystemStage};
use bevy_app::{App, Plugin as PluginType};
use bevy_ecs::{entity::Entity, schedule::IntoSystemConfig};

use naia_bevy_shared::{BeforeReceiveEvents, Protocol, SharedPlugin};
use naia_client::{Client, ClientConfig};

use naia_bevy_shared::Protocol;

use super::{
events::{
ClientTickEvent, ConnectEvent, DespawnEntityEvent, DisconnectEvent, ErrorEvent,
InsertComponentEvents, MessageEvents, RejectEvent, RemoveComponentEvents, ServerTickEvent,
SpawnEntityEvent, UpdateComponentEvents,
},
stage::{PrivateStage, Stage},
systems::{before_receive_events, should_receive},
systems::before_receive_events,
};

struct PluginConfig {
Expand Down Expand Up @@ -48,12 +46,15 @@ impl PluginType for Plugin {
fn build(&self, app: &mut App) {
let mut config = self.config.lock().unwrap().deref_mut().take().unwrap();

let world_data = config.protocol.world_data();
let world_data = config.protocol.take_world_data();
world_data.add_systems(app);
app.insert_resource(world_data);

let client = Client::<Entity>::new(config.client_config, config.protocol.into());

app
// SHARED PLUGIN //
.add_plugin(SharedPlugin)
// RESOURCES //
.insert_resource(client)
// EVENTS //
Expand All @@ -69,19 +70,7 @@ impl PluginType for Plugin {
.add_event::<InsertComponentEvents>()
.add_event::<UpdateComponentEvents>()
.add_event::<RemoveComponentEvents>()
// STAGES //
// events //
.add_stage_before(
CoreStage::PreUpdate,
PrivateStage::BeforeReceiveEvents,
SystemStage::single_threaded().with_run_criteria(should_receive),
)
.add_stage_after(
PrivateStage::BeforeReceiveEvents,
Stage::ReceiveEvents,
SystemStage::single_threaded().with_run_criteria(should_receive),
)
// SYSTEMS //
.add_system_to_stage(PrivateStage::BeforeReceiveEvents, before_receive_events);
.add_system(before_receive_events.in_set(BeforeReceiveEvents));
}
}
11 changes: 0 additions & 11 deletions adapters/bevy/client/src/stage.rs

This file was deleted.

31 changes: 0 additions & 31 deletions adapters/bevy/client/src/state.rs

This file was deleted.

Loading

0 comments on commit 665b7ba

Please sign in to comment.