Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assets and inputs related update #197

Merged
merged 4 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ pub use utils::Id;

/// World
pub mod world;
pub use world::{Entity, World};
pub use world::{Camera, Entity, World};

/// Window API and input events
pub mod window;
pub use window::{ReadInput, Window};
pub use window::{Input, ReadInput, Window};

//pub use utils::{ Id };

Expand Down
22 changes: 19 additions & 3 deletions src/loaders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ pub struct ResourceFile {
}

/// Target asset inside of a resource to be loaded
#[derive(Eq, PartialEq, Hash, Clone)]
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
pub struct ResourceTarget {
type_id: std::any::TypeId,
name: String,
pub type_id: std::any::TypeId,
pub name: String,
}

impl ResourceFile {
Expand Down Expand Up @@ -67,6 +67,22 @@ pub struct ResourceBundle {
pub bundle: HashMap<ResourceTarget, Option<Box<dyn Asset>>>,
}

impl ResourceBundle {
pub fn extract<T: Asset>(&mut self, name: &str) -> Option<T> {
let target = ResourceTarget {
type_id: std::any::TypeId::of::<T>(),
name: String::from(name),
};
self.bundle
.remove(&target)
.and_then(|asset| asset)
.map(|asset| unsafe {
let raw: *mut dyn Asset = Box::into_raw(asset);
*Box::from_raw(raw as *mut T)
})
}
}

pub struct ResourceReport {
pub resource: PathBuf,
pub report: HashMap<ResourceTarget, Option<(u64, u64)>>,
Expand Down
4 changes: 0 additions & 4 deletions src/models/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -901,10 +901,6 @@ impl RenderModels {
}
// try to get mesh to store it in buffer
if let Some(mesh) = assets.get(mesh_id) {
if mesh.indices::<u8>().is_some() {
panic!("Index buffer is not implemented yet");
}

let vertex_data_and_skin_info = mesh
.buffer::<VertexBufferSkinMeshLayout>()
.map(|vertex_data| {
Expand Down
11 changes: 11 additions & 0 deletions src/tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ impl<'a> Scheduler<'a> {
))
.expect("Message to be sent to Scheduler");
}

/// Set state
pub fn push_state<T: context::Context + Send>(&self, state: T) {
self.guard
.send(scheduler::Message::PushState(
std::any::TypeId::of::<T>(),
std::any::type_name::<T>().into(),
Box::new(state),
))
.expect("Message to be sent to Scheduler");
}
}

impl TaskManager {
Expand Down
17 changes: 14 additions & 3 deletions src/tasks/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,13 +309,13 @@ impl Manager {
pub fn match_dependencies(&self, dependencies: &Dependencies) -> Option<Dependencies> {
let mut result = dependencies.clone();
for (type_id, dependency) in dependencies.data.iter() {
let entry = match self.outputs.get(type_id) {
let dependency_output = match self.outputs.get(type_id) {
Some(dependency) => dependency,
None => {
return None;
}
};
let instances_len = entry.instances.len();
let instances_len = dependency_output.instances.len();
match dependency {
DependencyType::Any(index) => {
if instances_len > 0 && *index < instances_len {
Expand All @@ -328,7 +328,13 @@ impl Manager {
}
}
DependencyType::All(count) => {
if *count == 0 && instances_len >= entry.providers {
log::debug!(
"All({:?}) && {} >= {}",
count,
instances_len,
dependency_output.providers
);
if *count == 0 && instances_len >= dependency_output.providers {
result
.data
.insert(*type_id, DependencyType::All(instances_len));
Expand Down Expand Up @@ -402,6 +408,11 @@ impl Manager {
}
}

/// Pushes single boxed state into stack
pub fn push_state_slot(&mut self, state: StateSlot) {
self.states_stack.push(state);
}

/// Calculates providers graph
pub unsafe fn calculate_providers<T: Context>(
&mut self,
Expand Down
30 changes: 30 additions & 0 deletions src/tasks/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub enum Message {
Output(Task, Box<dyn Any + 'static + Send>),
/// Store a new global context
Store(TypeId, Box<dyn Any + 'static + Send>),
/// Push state for the global context
PushState(TypeId, String, Box<dyn Any + 'static + Send>),
/// Register dependency type (with Name)
Register(TypeId, String, usize),
/// Provide dependency data for tasks
Expand Down Expand Up @@ -104,6 +106,14 @@ pub fn spawn<T: context::Context>(
Message::Store(type_id, ctx) => {
context_manager.lock().unwrap().store_boxed(type_id, ctx);
}
Message::PushState(id, name, data) => context_manager
.lock()
.unwrap()
.push_state_slot(context::StateSlot {
id,
name,
data: data.into(),
}),
Message::Register(type_id, name, providers) => {
context_manager
.lock()
Expand Down Expand Up @@ -145,12 +155,25 @@ pub fn spawn<T: context::Context>(

let default_state = TypeId::of::<()>();
let current_state = ctx.current_state();
log::debug!("current state: {:?}", current_state);
if current_state != default_state {
if let Some(tasks) = pool.select_for_state(&default_state) {
for task in tasks.iter() {
log::debug!(
"tasks for default state: {:?}",
pool.get(*task).and_then(|t| t.name())
);
}
queue.extend_from_slice(tasks);
}
}
if let Some(tasks) = pool.select_for_state(&current_state) {
for task in tasks.iter() {
log::debug!(
"tasks for current state: {:?}",
pool.get(*task).and_then(|t| t.name())
);
}
queue.extend_from_slice(tasks);
}

Expand Down Expand Up @@ -178,6 +201,13 @@ pub fn spawn<T: context::Context>(
log::debug!("task({}): begin control", task.name());
if !task.is_scheduled() {
log::debug!("task({}): not scheduled yet", task.name());
if task.name() == "dotrix::window::input::ReadInput" {
log::debug!(
"task({}): not scheduled yet: {:?}",
task.name(),
task.dependencies()
);
}
if let Some(dependencies_state) = context_manager
.lock()
.unwrap()
Expand Down
11 changes: 11 additions & 0 deletions src/tasks/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,12 @@ pub struct Slot {
task: Option<Box<dyn Executable>>,
}

impl Slot {
pub fn name(&self) -> Option<&str> {
self.task.as_ref().map(|t| t.name())
}
}

/// Tasks pool
#[derive(Default)]
pub struct Pool {
Expand All @@ -245,6 +251,11 @@ impl Pool {
self.tasks.contains_key(&id)
}

/// Returns immutable reference for a task
pub fn get(&self, id: Id<Slot>) -> Option<&Slot> {
self.tasks.get(&id)
}

/// Stores task in the `Pool`
pub fn store(&mut self, task: Box<dyn Executable>) {
let task_id = task.id();
Expand Down
65 changes: 48 additions & 17 deletions src/window.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
mod input;
// mod map;

pub mod event;

use std::sync::Arc;
use std::time;

pub use event::Event;
pub use input::Input;
pub use input::ReadInput;
use winit::event::StartCause;

Expand Down Expand Up @@ -74,14 +74,17 @@ impl<T: Application> EventLoop<T> {
.map(|fps_request| 1.0 / fps_request)
.unwrap_or(0.0),
);
let task_manager = TaskManager::new::<graphics::FramePresenter>(workers);
task_manager.register::<Event>(0);

Self {
application: Some(application),
frame_duration,
request_redraw: false,
wait_cancelled: false,
close_requested: false,
window_instance: None,
task_manager: TaskManager::new::<graphics::FramePresenter>(workers),
task_manager,
}
}

Expand Down Expand Up @@ -167,6 +170,8 @@ impl<T: Application> winit::application::ApplicationHandler for EventLoop<T> {
let submit_frame_task = graphics::SubmitFrame::default();
scheduler.add_task(submit_frame_task);

scheduler.add_task(input::ReadInput::default());

app.startup(&scheduler, &mut display);

// add Display context
Expand All @@ -184,33 +189,58 @@ impl<T: Application> winit::application::ApplicationHandler for EventLoop<T> {
_window_id: winit::window::WindowId,
event: winit::event::WindowEvent,
) {
log::info!("{event:?}");
match event {
winit::event::WindowEvent::CloseRequested => {
self.close_requested = true;
}
winit::event::WindowEvent::KeyboardInput {
event:
winit::event::KeyEvent {
logical_key: key,
state: winit::event::ElementState::Pressed,
..
winit::event::WindowEvent::KeyboardInput { event, .. } => {
let button = event::Button::from(&event);
let input_event = match event.state {
winit::event::ElementState::Pressed => event::Event::ButtonPress {
button,
text: event.text.as_ref().map(|smol_str| smol_str.to_string()),
},
winit::event::ElementState::Released => event::Event::ButtonRelease { button },
};
self.task_manager.provide(input_event);
}
winit::event::WindowEvent::MouseWheel { delta, .. } => {
let input_event = match delta {
winit::event::MouseScrollDelta::LineDelta(x, y) => event::MouseScroll::Lines {
horizontal: x,
vertical: y,
},
winit::event::MouseScrollDelta::PixelDelta(position) => {
event::MouseScroll::Pixels {
horizontal: position.x,
vertical: position.y,
}
}
};
self.task_manager.provide(input_event);
}
winit::event::WindowEvent::MouseInput { state, button, .. } => {
let mouse_button = event::Button::from(&button);
let input_event = match state {
winit::event::ElementState::Pressed => event::Event::ButtonPress {
button: mouse_button,
text: None,
},
winit::event::ElementState::Released => event::Event::ButtonRelease {
button: mouse_button,
},
..
} => {
log::info!("input: {key:?}");
// TODO: map to window::Event and provide
// self.task_manager.provide(event);
};
self.task_manager.provide(input_event);
}
winit::event::WindowEvent::RedrawRequested => {
if let Some(instance) = self.window_instance.as_ref() {
instance.winit_window.pre_present_notify();
}
log::info!("Wait for presenter...");
log::debug!("Wait for presenter...");
self.task_manager
.wait_for::<graphics::FramePresenter>()
.present();
log::info!("...presented");
log::debug!("...presented");
self.task_manager.run();
// Note: can be used for debug
// fill::fill_window(window);
Expand All @@ -228,12 +258,13 @@ impl<T: Application> winit::application::ApplicationHandler for EventLoop<T> {
}

fn about_to_wait(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
log::debug!(
/* log::debug!(
"about_to_wait(request_redraw: {}, wait_cancelled: {}, close_requested: {})",
self.request_redraw,
self.wait_cancelled,
self.close_requested,
);
*/

// NOTE: to wait
// event_loop.set_control_flow(winit::event_loop::ControlFlow::Wait),
Expand Down
Loading
Loading