Skip to content

Commit

Permalink
fix: don't depend on bevy_tasks, but poll futures using futures-lite …
Browse files Browse the repository at this point in the history
…directly
  • Loading branch information
SebastianSpeitel committed Jan 26, 2024
1 parent 39e7c3e commit 53c89bf
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 41 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ twitch = ["thiserror"]
async-compat = "0.2"
bevy_app = "0.12"
bevy_ecs = "0.12"
bevy_tasks = "0.12"
futures-lite = "1.12"
irc = { version = "0.15", default-features = false, features = ["tls-rust"] }
log = "*"
Expand Down
68 changes: 28 additions & 40 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
//! # TODO: Add documentation
use std::ops::{Deref, DerefMut};
use std::sync::{Arc, Mutex};
use std::pin::Pin;
use std::sync::OnceLock;

use async_compat::Compat;
use bevy_ecs::prelude::*;
use bevy_tasks::{AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool};
use futures_lite::{future, StreamExt};
pub use irc;
use irc::client::prelude::*;
Expand Down Expand Up @@ -153,48 +153,51 @@ pub struct Capabilities(pub Vec<Capability>);
#[derive(Component)]
struct Stream(irc::client::ClientStream);

type ConnectingFut = Compat<
Pin<
Box<
dyn std::future::Future<Output = Result<irc::client::Client, irc::error::Error>>
+ Sync
+ Send,
>,
>,
>;

#[derive(Component)]
struct Connecting(Arc<Mutex<Option<Result<irc::client::Client, irc::error::Error>>>>);
struct Connecting(OnceLock<ConnectingFut>);

#[derive(Component)]
struct Identified;

fn connect(
mut commands: Commands,
chats: Query<(Entity, &Connection), Added<Connection>>,
pool: NonSend<TaskPool>,
) {
fn connect(mut commands: Commands, chats: Query<(Entity, &Connection), Added<Connection>>) {
for (chat, con) in &chats {
let cell = Arc::new(Mutex::new(None));
let config = Config {
server: Some(con.host.clone()),
port: Some(con.port),
ping_time: Some(u32::MAX),
..Default::default()
};
let task_cell = cell.clone();
pool.0
.spawn(async move {
let res = Compat::new(irc::client::Client::from_config(config)).await;
task_cell.lock().unwrap().replace(res);
})
.detach();
let fut = irc::client::Client::from_config(config);
let boxed_fut: Pin<Box<dyn std::future::Future<Output = _> + Send + Sync>> = Box::pin(fut);
let fut = Compat::new(boxed_fut);
let cell = OnceLock::new();
let _ = cell.set(fut);
commands.entity(chat).insert(Connecting(cell));
}
}

fn finish_connect(mut commands: Commands, chats: Query<(Entity, &mut Connecting)>) {
for (chat, connecting) in &chats {
let mut state = connecting.0.lock().unwrap();
let res = match state.take() {
None => continue,
Some(r) => r,
fn finish_connect(mut commands: Commands, mut chats: Query<(Entity, &mut Connecting)>) {
for (chat, mut connecting) in &mut chats {
let fut = connecting.0.get_mut().unwrap();

let Some(res) = future::block_on(future::poll_once(fut)) else {
continue;
};
drop(state);
commands.entity(chat).remove::<Connecting>();

let mut client = match res {
Err(e) => {
error!("Failed to connect: {}", e);
error!("Failed to connect: {e:?}");
continue;
}
Ok(c) => c,
Expand Down Expand Up @@ -318,14 +321,7 @@ pub struct IRCPlugin;

impl bevy_app::Plugin for IRCPlugin {
fn build(&self, app: &mut bevy_app::App) {
use bevy_app::{PreUpdate, Update};

ComputeTaskPool::get_or_init(Default::default);
AsyncComputeTaskPool::get_or_init(Default::default);
IoTaskPool::get_or_init(Default::default);

app.init_non_send_resource::<TaskPool>();
app.add_systems(PreUpdate, tick);
use bevy_app::Update;

app.add_event::<MessageEvent>();
app.add_systems(Update, connect);
Expand All @@ -337,11 +333,3 @@ impl bevy_app::Plugin for IRCPlugin {
}
}

#[derive(Resource, Default)]
struct TaskPool(bevy_tasks::TaskPool);

fn tick(pool: NonSend<TaskPool>) {
pool.0.with_local_executor(|executor| {
executor.try_tick();
});
}

0 comments on commit 53c89bf

Please sign in to comment.