mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
remove futures_executor from renderer and rather pass tokio runtime to it properly. therefore the runtime is now created with Voxygen rather than with the Connect attempt
This commit is contained in:
parent
92684b31fa
commit
32e58c4b17
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -6161,7 +6161,6 @@ dependencies = [
|
||||
"egui_winit_platform",
|
||||
"enum-iterator",
|
||||
"euc",
|
||||
"futures-executor",
|
||||
"gilrs",
|
||||
"glyph_brush",
|
||||
"guillotiere",
|
||||
|
@ -98,7 +98,6 @@ crossbeam-channel = "0.5"
|
||||
directories-next = "2.0"
|
||||
dot_vox = "4.0"
|
||||
enum-iterator = "0.6"
|
||||
futures-executor = "0.3"
|
||||
guillotiere = "0.6"
|
||||
hashbrown = {version = "0.11", features = ["rayon", "serde", "nightly"]}
|
||||
image = {version = "0.23.12", default-features = false, features = ["ico", "png"]}
|
||||
|
@ -51,6 +51,9 @@ use common_base::span;
|
||||
use i18n::LocalizationHandle;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use std::sync::Arc;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
/// A type used to store state that is shared between all play states.
|
||||
pub struct GlobalState {
|
||||
pub userdata_dir: PathBuf,
|
||||
@ -58,6 +61,7 @@ pub struct GlobalState {
|
||||
pub settings: Settings,
|
||||
pub profile: Profile,
|
||||
pub window: Window,
|
||||
pub tokio_runtime: Arc<Runtime>,
|
||||
#[cfg(feature = "egui-ui")]
|
||||
pub egui_state: EguiState,
|
||||
pub lazy_init: scene::terrain::SpriteRenderContextLazy,
|
||||
|
@ -165,6 +165,28 @@ fn main() {
|
||||
default_hook(panic_info);
|
||||
}));
|
||||
|
||||
//Setup tokio runtime
|
||||
use common::consts::MIN_RECOMMENDED_TOKIO_THREADS;
|
||||
use std::sync::{
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
Arc,
|
||||
};
|
||||
use tokio::runtime::Builder;
|
||||
|
||||
let cores = num_cpus::get();
|
||||
let tokio_runtime = Arc::new(
|
||||
Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.worker_threads((cores / 4).max(MIN_RECOMMENDED_TOKIO_THREADS))
|
||||
.thread_name_fn(|| {
|
||||
static ATOMIC_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
let id = ATOMIC_ID.fetch_add(1, Ordering::SeqCst);
|
||||
format!("tokio-voxygen-{}", id)
|
||||
})
|
||||
.build()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
#[cfg(feature = "hot-reloading")]
|
||||
assets::start_hot_reloading();
|
||||
|
||||
@ -210,7 +232,7 @@ fn main() {
|
||||
|
||||
// Create window
|
||||
use veloren_voxygen::{error::Error, render::RenderError};
|
||||
let (mut window, event_loop) = match Window::new(&settings) {
|
||||
let (mut window, event_loop) = match tokio_runtime.block_on(Window::new(&settings)) {
|
||||
Ok(ok) => ok,
|
||||
// Custom panic message when a graphics backend could not be found
|
||||
Err(Error::RenderError(RenderError::CouldNotFindAdapter)) => {
|
||||
@ -247,6 +269,7 @@ fn main() {
|
||||
audio,
|
||||
profile,
|
||||
window,
|
||||
tokio_runtime,
|
||||
#[cfg(feature = "egui-ui")]
|
||||
egui_state,
|
||||
lazy_init,
|
||||
|
@ -3,11 +3,10 @@ use client::{
|
||||
error::{Error as ClientError, NetworkConnectError, NetworkError},
|
||||
Client, ServerInfo,
|
||||
};
|
||||
use common::consts::MIN_RECOMMENDED_TOKIO_THREADS;
|
||||
use crossbeam_channel::{unbounded, Receiver, Sender, TryRecvError};
|
||||
use std::{
|
||||
sync::{
|
||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
},
|
||||
time::Duration,
|
||||
@ -47,29 +46,13 @@ impl ClientInit {
|
||||
connection_args: ConnectionArgs,
|
||||
username: String,
|
||||
password: String,
|
||||
runtime: Option<Arc<runtime::Runtime>>,
|
||||
runtime: Arc<runtime::Runtime>,
|
||||
) -> Self {
|
||||
let (tx, rx) = unbounded();
|
||||
let (trust_tx, trust_rx) = unbounded();
|
||||
let cancel = Arc::new(AtomicBool::new(false));
|
||||
let cancel2 = Arc::clone(&cancel);
|
||||
|
||||
let runtime = runtime.unwrap_or_else(|| {
|
||||
// TODO: evaluate std::thread::available_concurrency as a num_cpus replacement
|
||||
let cores = num_cpus::get();
|
||||
Arc::new(
|
||||
runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.worker_threads((cores / 4).max(MIN_RECOMMENDED_TOKIO_THREADS))
|
||||
.thread_name_fn(|| {
|
||||
static ATOMIC_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
let id = ATOMIC_ID.fetch_add(1, Ordering::SeqCst);
|
||||
format!("tokio-voxygen-{}", id)
|
||||
})
|
||||
.build()
|
||||
.unwrap(),
|
||||
)
|
||||
});
|
||||
let runtime2 = Arc::clone(&runtime);
|
||||
|
||||
runtime.spawn(async move {
|
||||
|
@ -93,7 +93,7 @@ impl PlayState for MainMenuState {
|
||||
{
|
||||
if let Some(singleplayer) = &global_state.singleplayer {
|
||||
match singleplayer.receiver.try_recv() {
|
||||
Ok(Ok(runtime)) => {
|
||||
Ok(Ok(())) => {
|
||||
// Attempt login after the server is finished initializing
|
||||
attempt_login(
|
||||
&mut global_state.info_message,
|
||||
@ -101,7 +101,7 @@ impl PlayState for MainMenuState {
|
||||
"".to_owned(),
|
||||
ConnectionArgs::Mpsc(14004),
|
||||
&mut self.init,
|
||||
Some(runtime),
|
||||
&global_state.tokio_runtime,
|
||||
);
|
||||
},
|
||||
Ok(Err(e)) => {
|
||||
@ -261,7 +261,7 @@ impl PlayState for MainMenuState {
|
||||
password,
|
||||
connection_args,
|
||||
&mut self.init,
|
||||
None,
|
||||
&global_state.tokio_runtime,
|
||||
);
|
||||
},
|
||||
MainMenuEvent::CancelLoginAttempt => {
|
||||
@ -290,7 +290,7 @@ impl PlayState for MainMenuState {
|
||||
},
|
||||
#[cfg(feature = "singleplayer")]
|
||||
MainMenuEvent::StartSingleplayer => {
|
||||
let singleplayer = Singleplayer::new();
|
||||
let singleplayer = Singleplayer::new(&global_state.tokio_runtime);
|
||||
|
||||
global_state.singleplayer = Some(singleplayer);
|
||||
},
|
||||
@ -450,7 +450,7 @@ fn attempt_login(
|
||||
password: String,
|
||||
connection_args: ConnectionArgs,
|
||||
init: &mut InitState,
|
||||
runtime: Option<Arc<runtime::Runtime>>,
|
||||
runtime: &Arc<runtime::Runtime>,
|
||||
) {
|
||||
if let Err(err) = comp::Player::alias_validate(&username) {
|
||||
*info_message = Some(err.to_string());
|
||||
@ -463,7 +463,7 @@ fn attempt_login(
|
||||
connection_args,
|
||||
username,
|
||||
password,
|
||||
runtime,
|
||||
Arc::clone(runtime),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -183,7 +183,10 @@ pub struct Renderer {
|
||||
impl Renderer {
|
||||
/// Create a new `Renderer` from a variety of backend-specific components
|
||||
/// and the window targets.
|
||||
pub fn new(window: &winit::window::Window, mode: RenderMode) -> Result<Self, RenderError> {
|
||||
pub async fn new(
|
||||
window: &winit::window::Window,
|
||||
mode: RenderMode,
|
||||
) -> Result<Self, RenderError> {
|
||||
let (pipeline_modes, mut other_modes) = mode.split();
|
||||
// Enable seamless cubemaps globally, where available--they are essentially a
|
||||
// strict improvement on regular cube maps.
|
||||
@ -220,13 +223,13 @@ impl Renderer {
|
||||
#[allow(unsafe_code)]
|
||||
let surface = unsafe { instance.create_surface(window) };
|
||||
|
||||
let adapter = futures_executor::block_on(instance.request_adapter(
|
||||
&wgpu::RequestAdapterOptionsBase {
|
||||
let adapter = instance
|
||||
.request_adapter(&wgpu::RequestAdapterOptionsBase {
|
||||
power_preference: wgpu::PowerPreference::HighPerformance,
|
||||
compatible_surface: Some(&surface),
|
||||
},
|
||||
))
|
||||
.ok_or(RenderError::CouldNotFindAdapter)?;
|
||||
})
|
||||
.await
|
||||
.ok_or(RenderError::CouldNotFindAdapter)?;
|
||||
|
||||
let info = adapter.get_info();
|
||||
info!(
|
||||
@ -244,47 +247,44 @@ impl Renderer {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let (device, queue) = futures_executor::block_on(adapter.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
// TODO
|
||||
label: None,
|
||||
features: wgpu::Features::DEPTH_CLAMPING
|
||||
| wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER
|
||||
| wgpu::Features::PUSH_CONSTANTS
|
||||
| (adapter.features() & wgpu_profiler::GpuProfiler::REQUIRED_WGPU_FEATURES),
|
||||
limits,
|
||||
},
|
||||
std::env::var_os("WGPU_TRACE_DIR").as_ref().map(|v| {
|
||||
let path = std::path::Path::new(v);
|
||||
// We don't want to continue if we can't actually collect the api trace
|
||||
if !path.exists() {
|
||||
panic!(
|
||||
"WGPU_TRACE_DIR is set to the path \"{}\" which doesn't exist",
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
if !path.is_dir() {
|
||||
panic!(
|
||||
"WGPU_TRACE_DIR is set to the path \"{}\" which is not a directory",
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
if path
|
||||
.read_dir()
|
||||
let trace_path = std::env::var_os("WGPU_TRACE_DIR").map(|v| {
|
||||
let path = std::path::PathBuf::from(v);
|
||||
// We don't want to continue if we can't actually collect the api trace
|
||||
assert!(
|
||||
path.exists(),
|
||||
"WGPU_TRACE_DIR is set to the path \"{}\" which doesn't exist",
|
||||
path.display()
|
||||
);
|
||||
assert!(
|
||||
path.is_dir(),
|
||||
"WGPU_TRACE_DIR is set to the path \"{}\" which is not a directory",
|
||||
path.display()
|
||||
);
|
||||
assert!(
|
||||
path.read_dir()
|
||||
.expect("Could not read the directory that is specified by WGPU_TRACE_DIR")
|
||||
.next()
|
||||
.is_some()
|
||||
{
|
||||
panic!(
|
||||
"WGPU_TRACE_DIR is set to the path \"{}\" which already contains other \
|
||||
files",
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
.is_some(),
|
||||
"WGPU_TRACE_DIR is set to the path \"{}\" which already contains other files",
|
||||
path.display()
|
||||
);
|
||||
|
||||
path
|
||||
}),
|
||||
))?;
|
||||
path
|
||||
});
|
||||
let (device, queue) = adapter
|
||||
.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
// TODO
|
||||
label: None,
|
||||
features: wgpu::Features::DEPTH_CLAMPING
|
||||
| wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER
|
||||
| wgpu::Features::PUSH_CONSTANTS
|
||||
| (adapter.features() & wgpu_profiler::GpuProfiler::REQUIRED_WGPU_FEATURES),
|
||||
limits,
|
||||
},
|
||||
trace_path.as_deref(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Set error handler for wgpu errors
|
||||
// This is better for use than their default because it includes the error in
|
||||
|
@ -1,4 +1,4 @@
|
||||
use common::{clock::Clock, consts::MIN_RECOMMENDED_TOKIO_THREADS};
|
||||
use common::clock::Clock;
|
||||
use crossbeam_channel::{bounded, unbounded, Receiver, Sender, TryRecvError};
|
||||
use server::{
|
||||
persistence::{DatabaseSettings, SqlLogMode},
|
||||
@ -6,14 +6,14 @@ use server::{
|
||||
};
|
||||
use std::{
|
||||
sync::{
|
||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
},
|
||||
thread::{self, JoinHandle},
|
||||
time::Duration,
|
||||
};
|
||||
use tokio::runtime::Runtime;
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
use tracing::{error, info, trace, warn};
|
||||
|
||||
const TPS: u64 = 30;
|
||||
|
||||
@ -22,7 +22,7 @@ const TPS: u64 = 30;
|
||||
pub struct Singleplayer {
|
||||
_server_thread: JoinHandle<()>,
|
||||
stop_server_s: Sender<()>,
|
||||
pub receiver: Receiver<Result<Arc<Runtime>, ServerError>>,
|
||||
pub receiver: Receiver<Result<(), ServerError>>,
|
||||
// Wether the server is stopped or not
|
||||
paused: Arc<AtomicBool>,
|
||||
// Settings that the server was started with
|
||||
@ -30,8 +30,7 @@ pub struct Singleplayer {
|
||||
}
|
||||
|
||||
impl Singleplayer {
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> Self {
|
||||
pub fn new(runtime: &Arc<Runtime>) -> Self {
|
||||
let (stop_server_s, stop_server_r) = unbounded();
|
||||
|
||||
// Determine folder to save server data in
|
||||
@ -82,22 +81,6 @@ impl Singleplayer {
|
||||
let settings = server::Settings::singleplayer(&server_data_dir);
|
||||
let editable_settings = server::EditableSettings::singleplayer(&server_data_dir);
|
||||
|
||||
// TODO: evaluate std::thread::available_concurrency as a num_cpus replacement
|
||||
let cores = num_cpus::get();
|
||||
debug!("Creating a new runtime for server");
|
||||
let runtime = Arc::new(
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.worker_threads((cores / 4).max(MIN_RECOMMENDED_TOKIO_THREADS))
|
||||
.thread_name_fn(|| {
|
||||
static ATOMIC_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
let id = ATOMIC_ID.fetch_add(1, Ordering::SeqCst);
|
||||
format!("tokio-sp-{}", id)
|
||||
})
|
||||
.build()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let settings2 = settings.clone();
|
||||
|
||||
// Relative to data_dir
|
||||
@ -117,24 +100,22 @@ impl Singleplayer {
|
||||
let (result_sender, result_receiver) = bounded(1);
|
||||
|
||||
let builder = thread::Builder::new().name("singleplayer-server-thread".into());
|
||||
let runtime = Arc::clone(runtime);
|
||||
let thread = builder
|
||||
.spawn(move || {
|
||||
trace!("starting singleplayer server thread");
|
||||
let mut server = None;
|
||||
if let Err(e) = result_sender.send(
|
||||
match Server::new(
|
||||
Server::new(
|
||||
settings2,
|
||||
editable_settings,
|
||||
database_settings,
|
||||
&server_data_dir,
|
||||
Arc::clone(&runtime),
|
||||
) {
|
||||
Ok(s) => {
|
||||
server = Some(s);
|
||||
Ok(runtime)
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
runtime,
|
||||
)
|
||||
.map(|s| {
|
||||
server = Some(s);
|
||||
}),
|
||||
) {
|
||||
warn!(
|
||||
?e,
|
||||
|
@ -398,7 +398,7 @@ pub struct Window {
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub fn new(settings: &Settings) -> Result<(Window, EventLoop), Error> {
|
||||
pub async fn new(settings: &Settings) -> Result<(Window, EventLoop), Error> {
|
||||
let event_loop = EventLoop::new();
|
||||
|
||||
let size = settings.graphics.window_size;
|
||||
@ -418,7 +418,7 @@ impl Window {
|
||||
|
||||
let window = win_builder.build(&event_loop).unwrap();
|
||||
|
||||
let renderer = Renderer::new(&window, settings.graphics.render_mode.clone())?;
|
||||
let renderer = Renderer::new(&window, settings.graphics.render_mode.clone()).await?;
|
||||
|
||||
let keypress_map = HashMap::new();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user