initial android support (fails on textures)

This commit is contained in:
griffi-gh 2023-05-21 03:14:04 +02:00
parent 50c25dac34
commit df3791af17
6 changed files with 318 additions and 271 deletions

20
Cargo.lock generated
View file

@ -48,6 +48,24 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "android_log-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27f0fc03f560e1aebde41c2398b691cb98b5ea5996a6184a7a67bbbb77448969"
[[package]]
name = "android_logger"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fa490e751f3878eb9accb9f18988eca52c2337ce000a8bf31ef50d4c723ca9e"
dependencies = [
"android_log-sys",
"env_logger",
"log",
"once_cell",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.71" version = "1.0.71"
@ -949,6 +967,7 @@ dependencies = [
"kubi-shared", "kubi-shared",
"log", "log",
"lz4_flex", "lz4_flex",
"ndk-glue",
"nohash-hasher", "nohash-hasher",
"postcard", "postcard",
"rayon", "rayon",
@ -964,6 +983,7 @@ dependencies = [
name = "kubi-logging" name = "kubi-logging"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"android_logger",
"env_logger", "env_logger",
"log", "log",
] ]

View file

@ -5,4 +5,9 @@ edition = "2021"
[dependencies] [dependencies]
log = "0.4" log = "0.4"
[target.'cfg(not(target_os = "android"))'.dependencies]
env_logger = "0.10" env_logger = "0.10"
[target.'cfg(target_os = "android")'.dependencies]
android_logger = "0.13"

View file

@ -1,14 +1,13 @@
//! Custom env_logger options and styling
/// Custom env_logger options and styling /// Custom env_logger options and styling
use env_logger::{fmt::Color, Builder, Env};
use log::Level;
use std::io::Write;
pub use log;
pub use env_logger;
#[inline] #[inline]
#[cfg(not(target_os = "android"))]
pub fn init() { pub fn init() {
use log::Level;
use std::io::Write;
use env_logger::{fmt::Color, Builder, Env};
let env = Env::default() let env = Env::default()
.filter_or("RUST_LOG", "trace,gilrs=warn,rusty_xinput=warn"); .filter_or("RUST_LOG", "trace,gilrs=warn,rusty_xinput=warn");
Builder::from_env(env) Builder::from_env(env)
@ -51,3 +50,14 @@ pub fn init() {
}) })
.init(); .init();
} }
/// Custom env_logger options and styling
#[inline]
#[cfg(target_os = "android")]
pub fn init() {
use log::LevelFilter;
use android_logger::Config;
android_logger::init_once(
Config::default().with_max_level(LevelFilter::Trace),
);
}

View file

@ -4,6 +4,9 @@ version = "0.0.0"
edition = "2021" edition = "2021"
publish = false publish = false
[lib]
crate-type = ["lib", "cdylib"]
[dependencies] [dependencies]
kubi-shared = { path = "../kubi-shared" } kubi-shared = { path = "../kubi-shared" }
kubi-logging = { path = "../kubi-logging" } kubi-logging = { path = "../kubi-logging" }
@ -25,6 +28,9 @@ serde_json = { version = "1.0", optional = true }
lz4_flex = { version = "0.10", default-features = false, features = ["std", "checked-decode"] } lz4_flex = { version = "0.10", default-features = false, features = ["std", "checked-decode"] }
static_assertions = "1.1" static_assertions = "1.1"
[target.'cfg(target_os = "android")'.dependencies]
ndk-glue = "0.7"
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3" } winapi = { version = "0.3" }

268
kubi/src/lib.rs Normal file
View file

@ -0,0 +1,268 @@
#![allow(clippy::too_many_arguments)] // allowed because systems often need a lot of arguments
use shipyard::{
World, Workload, IntoWorkload,
UniqueView, UniqueViewMut,
NonSendSync, WorkloadModificator,
SystemModificator
};
use glium::{
glutin::{
event_loop::{EventLoop, ControlFlow},
event::{Event, WindowEvent}
}
};
use glam::vec3;
use std::time::Instant;
pub use kubi_shared::transform;
pub(crate) mod rendering;
pub(crate) mod world;
pub(crate) mod player;
pub(crate) mod prefabs;
pub(crate) mod settings;
pub(crate) mod camera;
pub(crate) mod events;
pub(crate) mod input;
pub(crate) mod fly_controller;
pub(crate) mod block_placement;
pub(crate) mod delta_time;
pub(crate) mod cursor_lock;
pub(crate) mod control_flow;
pub(crate) mod state;
pub(crate) mod gui;
pub(crate) mod networking;
pub(crate) mod init;
pub(crate) mod color;
pub(crate) mod loading_screen;
pub(crate) mod connecting_screen;
pub(crate) mod fixed_timestamp;
use world::{
init_game_world,
loading::update_loaded_world_around_player,
raycast::update_raycasts,
queue::apply_queued_blocks,
tasks::{ChunkTaskManager},
};
use player::{spawn_player, MainPlayer};
use prefabs::load_prefabs;
use settings::{load_settings, GameSettings};
use camera::compute_cameras;
use events::{
clear_events,
process_glutin_events,
initial_resize_event,
player_actions::generate_move_events,
};
use input::{init_input, process_inputs};
use fly_controller::update_controllers;
use rendering::{
Renderer,
RenderTarget,
BackgroundColor,
clear_background,
init_window_size,
update_window_size,
primitives::init_primitives,
world::{draw_world, draw_current_chunk_border},
selection_box::render_selection_box,
entities::render_entities,
};
use block_placement::update_block_placement;
use delta_time::{DeltaTime, init_delta_time};
use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now};
use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow};
use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state, is_connecting};
use networking::{update_networking, update_networking_late, is_multiplayer, disconnect_on_exit, is_singleplayer};
use init::initialize_from_args;
use gui::{render_gui, init_gui, update_gui};
use loading_screen::update_loading_screen;
use connecting_screen::switch_to_loading_if_connected;
use fixed_timestamp::init_fixed_timestamp_storage;
/// stuff required to init the renderer and other basic systems
fn pre_startup() -> Workload {
(
load_settings,
).into_sequential_workload()
}
fn startup() -> Workload {
(
init_fixed_timestamp_storage,
initial_resize_event,
init_window_size,
load_prefabs,
init_primitives,
insert_lock_state,
init_state,
initialize_from_args,
lock_cursor_now,
init_input,
init_gui,
insert_control_flow_unique,
init_delta_time,
).into_sequential_workload()
}
fn update() -> Workload {
(
update_window_size,
update_cursor_lock_state,
process_inputs,
(
init_game_world.run_if_missing_unique::<ChunkTaskManager>(),
(
spawn_player.run_if_storage_empty::<MainPlayer>(),
).into_sequential_workload().run_if(is_singleplayer),
).into_sequential_workload().run_if(is_ingame_or_loading),
update_networking().run_if(is_multiplayer),
(
switch_to_loading_if_connected
).into_sequential_workload().run_if(is_connecting),
(
update_loading_screen,
).into_sequential_workload().run_if(is_loading),
(
update_loaded_world_around_player,
).into_sequential_workload().run_if(is_ingame_or_loading),
(
update_controllers,
generate_move_events,
update_raycasts,
update_block_placement,
apply_queued_blocks,
).into_sequential_workload().run_if(is_ingame),
update_networking_late.run_if(is_multiplayer),
compute_cameras,
update_gui,
update_state,
exit_on_esc,
disconnect_on_exit.run_if(is_multiplayer),
).into_sequential_workload()
}
fn render() -> Workload {
(
clear_background,
(
draw_world,
draw_current_chunk_border,
render_selection_box,
render_entities,
).into_sequential_workload().run_if(is_ingame),
render_gui,
).into_sequential_workload()
}
fn after_frame_end() -> Workload {
(
clear_events,
).into_sequential_workload()
}
#[cfg(all(windows, not(debug_assertions)))]
fn attach_console() {
use winapi::um::wincon::{AttachConsole, ATTACH_PARENT_PROCESS};
unsafe { AttachConsole(ATTACH_PARENT_PROCESS); }
}
#[no_mangle]
#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))]
pub fn kubi_main() {
//Attach console on release builds on windows
#[cfg(all(windows, not(debug_assertions)))] attach_console();
//Print version
println!("{:─^54}", format!("[ ▄▀ Kubi client v. {} ]", env!("CARGO_PKG_VERSION")));
//Init env_logger
kubi_logging::init();
//Create a shipyard world
let mut world = World::new();
//Register workloads
world.add_workload(pre_startup);
world.add_workload(startup);
world.add_workload(update);
world.add_workload(render);
world.add_workload(after_frame_end);
//Run pre-startup procedure
world.run_workload(pre_startup).unwrap();
//Create event loop
let event_loop = EventLoop::new();
//Initialize renderer
{
let settings = world.borrow::<UniqueView<GameSettings>>().unwrap();
world.add_unique_non_send_sync(Renderer::init(&event_loop, &settings));
}
world.add_unique(BackgroundColor(vec3(0.5, 0.5, 1.)));
//Save _visualizer.json
#[cfg(feature = "generate_visualizer_data")]
std::fs::write(
"_visualizer.json",
serde_json::to_string(&world.workloads_info()).unwrap(),
).unwrap();
//Run startup systems
world.run_workload(startup).unwrap();
//Run the event loop
let mut last_update = Instant::now();
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
process_glutin_events(&mut world, &event);
#[allow(clippy::collapsible_match, clippy::single_match)]
match event {
Event::WindowEvent { event, .. } => match event {
WindowEvent::CloseRequested => {
log::info!("exit requested");
*control_flow = ControlFlow::Exit;
},
_ => (),
},
Event::MainEventsCleared => {
//Update delta time (maybe move this into a system?)
{
let mut dt_view = world.borrow::<UniqueViewMut<DeltaTime>>().unwrap();
let now = Instant::now();
dt_view.0 = now - last_update;
last_update = now;
}
//Run update workflows
world.run_workload(update).unwrap();
//Start rendering (maybe use custom views for this?)
let target = {
let renderer = world.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap();
renderer.display.draw()
};
world.add_unique_non_send_sync(RenderTarget(target));
//Run render workflow
world.run_workload(render).unwrap();
//Finish rendering
let target = world.remove_unique::<RenderTarget>().unwrap();
target.0.finish().unwrap();
//After frame end
world.run_workload(after_frame_end).unwrap();
//Process control flow changes
if let Some(flow) = world.borrow::<UniqueView<SetControlFlow>>().unwrap().0 {
*control_flow = flow;
}
},
_ => (),
};
});
}

View file

@ -2,269 +2,7 @@
all(windows, not(debug_assertions)), all(windows, not(debug_assertions)),
windows_subsystem = "windows" windows_subsystem = "windows"
)] )]
#![allow(clippy::too_many_arguments)] // allowed because systems often need a lot of arguments
use shipyard::{
World, Workload, IntoWorkload,
UniqueView, UniqueViewMut,
NonSendSync, WorkloadModificator,
SystemModificator
};
use glium::{
glutin::{
event_loop::{EventLoop, ControlFlow},
event::{Event, WindowEvent}
}
};
use glam::vec3;
use std::time::Instant;
pub use kubi_shared::transform;
pub(crate) mod rendering;
pub(crate) mod world;
pub(crate) mod player;
pub(crate) mod prefabs;
pub(crate) mod settings;
pub(crate) mod camera;
pub(crate) mod events;
pub(crate) mod input;
pub(crate) mod fly_controller;
pub(crate) mod block_placement;
pub(crate) mod delta_time;
pub(crate) mod cursor_lock;
pub(crate) mod control_flow;
pub(crate) mod state;
pub(crate) mod gui;
pub(crate) mod networking;
pub(crate) mod init;
pub(crate) mod color;
pub(crate) mod loading_screen;
pub(crate) mod connecting_screen;
pub(crate) mod fixed_timestamp;
use world::{
init_game_world,
loading::update_loaded_world_around_player,
raycast::update_raycasts,
queue::apply_queued_blocks,
tasks::{ChunkTaskManager},
};
use player::{spawn_player, MainPlayer};
use prefabs::load_prefabs;
use settings::{load_settings, GameSettings};
use camera::compute_cameras;
use events::{
clear_events,
process_glutin_events,
initial_resize_event,
player_actions::generate_move_events,
};
use input::{init_input, process_inputs};
use fly_controller::update_controllers;
use rendering::{
Renderer,
RenderTarget,
BackgroundColor,
clear_background,
init_window_size,
update_window_size,
primitives::init_primitives,
world::{draw_world, draw_current_chunk_border},
selection_box::render_selection_box,
entities::render_entities,
};
use block_placement::update_block_placement;
use delta_time::{DeltaTime, init_delta_time};
use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now};
use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow};
use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state, is_connecting};
use networking::{update_networking, update_networking_late, is_multiplayer, disconnect_on_exit, is_singleplayer};
use init::initialize_from_args;
use gui::{render_gui, init_gui, update_gui};
use loading_screen::update_loading_screen;
use connecting_screen::switch_to_loading_if_connected;
use fixed_timestamp::init_fixed_timestamp_storage;
/// stuff required to init the renderer and other basic systems
fn pre_startup() -> Workload {
(
load_settings,
).into_sequential_workload()
}
fn startup() -> Workload {
(
init_fixed_timestamp_storage,
initial_resize_event,
init_window_size,
load_prefabs,
init_primitives,
insert_lock_state,
init_state,
initialize_from_args,
lock_cursor_now,
init_input,
init_gui,
insert_control_flow_unique,
init_delta_time,
).into_sequential_workload()
}
fn update() -> Workload {
(
update_window_size,
update_cursor_lock_state,
process_inputs,
(
init_game_world.run_if_missing_unique::<ChunkTaskManager>(),
(
spawn_player.run_if_storage_empty::<MainPlayer>(),
).into_sequential_workload().run_if(is_singleplayer),
).into_sequential_workload().run_if(is_ingame_or_loading),
update_networking().run_if(is_multiplayer),
(
switch_to_loading_if_connected
).into_sequential_workload().run_if(is_connecting),
(
update_loading_screen,
).into_sequential_workload().run_if(is_loading),
(
update_loaded_world_around_player,
).into_sequential_workload().run_if(is_ingame_or_loading),
(
update_controllers,
generate_move_events,
update_raycasts,
update_block_placement,
apply_queued_blocks,
).into_sequential_workload().run_if(is_ingame),
update_networking_late.run_if(is_multiplayer),
compute_cameras,
update_gui,
update_state,
exit_on_esc,
disconnect_on_exit.run_if(is_multiplayer),
).into_sequential_workload()
}
fn render() -> Workload {
(
clear_background,
(
draw_world,
draw_current_chunk_border,
render_selection_box,
render_entities,
).into_sequential_workload().run_if(is_ingame),
render_gui,
).into_sequential_workload()
}
fn after_frame_end() -> Workload {
(
clear_events,
).into_sequential_workload()
}
#[cfg(all(windows, not(debug_assertions)))]
fn attach_console() {
use winapi::um::wincon::{AttachConsole, ATTACH_PARENT_PROCESS};
unsafe { AttachConsole(ATTACH_PARENT_PROCESS); }
}
fn main() { fn main() {
//Attach console on release builds on windows kubi::kubi_main();
#[cfg(all(windows, not(debug_assertions)))] attach_console();
//Print version
println!("{:─^54}", format!("[ ▄▀ Kubi client v. {} ]", env!("CARGO_PKG_VERSION")));
//Init env_logger
kubi_logging::init();
//Create a shipyard world
let mut world = World::new();
//Register workloads
world.add_workload(pre_startup);
world.add_workload(startup);
world.add_workload(update);
world.add_workload(render);
world.add_workload(after_frame_end);
//Run pre-startup procedure
world.run_workload(pre_startup).unwrap();
//Create event loop
let event_loop = EventLoop::new();
//Initialize renderer
{
let settings = world.borrow::<UniqueView<GameSettings>>().unwrap();
world.add_unique_non_send_sync(Renderer::init(&event_loop, &settings));
}
world.add_unique(BackgroundColor(vec3(0.5, 0.5, 1.)));
//Save _visualizer.json
#[cfg(feature = "generate_visualizer_data")]
std::fs::write(
"_visualizer.json",
serde_json::to_string(&world.workloads_info()).unwrap(),
).unwrap();
//Run startup systems
world.run_workload(startup).unwrap();
//Run the event loop
let mut last_update = Instant::now();
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
process_glutin_events(&mut world, &event);
#[allow(clippy::collapsible_match, clippy::single_match)]
match event {
Event::WindowEvent { event, .. } => match event {
WindowEvent::CloseRequested => {
log::info!("exit requested");
*control_flow = ControlFlow::Exit;
},
_ => (),
},
Event::MainEventsCleared => {
//Update delta time (maybe move this into a system?)
{
let mut dt_view = world.borrow::<UniqueViewMut<DeltaTime>>().unwrap();
let now = Instant::now();
dt_view.0 = now - last_update;
last_update = now;
}
//Run update workflows
world.run_workload(update).unwrap();
//Start rendering (maybe use custom views for this?)
let target = {
let renderer = world.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap();
renderer.display.draw()
};
world.add_unique_non_send_sync(RenderTarget(target));
//Run render workflow
world.run_workload(render).unwrap();
//Finish rendering
let target = world.remove_unique::<RenderTarget>().unwrap();
target.0.finish().unwrap();
//After frame end
world.run_workload(after_frame_end).unwrap();
//Process control flow changes
if let Some(flow) = world.borrow::<UniqueView<SetControlFlow>>().unwrap().0 {
*control_flow = flow;
}
},
_ => (),
};
});
} }