diff --git a/Cargo.lock b/Cargo.lock index 184518c..251f789 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,9 +311,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" dependencies = [ "bytemuck_derive", ] @@ -665,6 +665,7 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" name = "element_bridge" version = "0.1.0" dependencies = [ + "bytemuck", "flume", "makepad-widgets", "mp_elements", @@ -1712,9 +1713,11 @@ name = "mp" version = "0.1.0" dependencies = [ "async-trait", + "bytemuck", "element_bridge", "futures", "glam", + "image", "indexmap", "log", "makepad-widgets", @@ -1764,6 +1767,7 @@ dependencies = [ "quick_cache", "regex", "rust-embed", + "thiserror 2.0.3", "wgpu", ] diff --git a/element_bridge/Cargo.toml b/element_bridge/Cargo.toml index 026df2e..a990bd0 100644 --- a/element_bridge/Cargo.toml +++ b/element_bridge/Cargo.toml @@ -9,3 +9,4 @@ makepad-widgets = { git = "https://github.com/makepad/makepad", branch = "rik", flume = "0.11.1" wgpu = "23.0.0" tokio = { version = "1.41.1", features = ["sync"] } +bytemuck = "1.20.0" diff --git a/element_bridge/src/lib.rs b/element_bridge/src/lib.rs index b1adcb6..f6f4a7f 100644 --- a/element_bridge/src/lib.rs +++ b/element_bridge/src/lib.rs @@ -9,26 +9,18 @@ pub use mp_elements::app::Window; #[derive(Clone, Debug)] pub struct TextureBridge { dirty: bool, - _buffer: Arc>>, window: Arc, - _texture: Texture, } impl TextureBridge { - pub fn new(texture: Texture, app: &App, window: Window) -> Self { + pub fn new(app: &App, window: Window) -> Self { let window = app.create_window(window); Self { dirty: true, - _buffer: Arc::new(tokio::sync::Mutex::new(vec![0u8; 256 * 256 * 4])), window: Arc::new(window), - _texture: texture, } } - pub fn texture(&self) -> &Texture { - &self._texture - } - pub fn window(&self) -> &RenderWindow { &self.window } @@ -41,7 +33,7 @@ impl TextureBridge { app.draw(&self.window, draw_list).await; } - pub async fn load_data(buffer: &mut Vec, ctx: &Ctx, render_window: &RenderWindow) { + pub async fn load_data(ctx: &Ctx, render_window: &RenderWindow) -> Vec { let output = &render_window.output().output_buffer; let (sender, receiver) = flume::bounded(1); @@ -52,18 +44,14 @@ impl TextureBridge { device.poll(wgpu::Maintain::wait()).panic_on_timeout(); receiver.recv_async().await.unwrap().unwrap(); - { + let result = { let view = slice.get_mapped_range(); - buffer.copy_from_slice(&view[..]); - } + + let new_vec: Vec = bytemuck::cast_slice(&view[..]).to_vec(); + new_vec + }; output.unmap(); - } - pub fn update_texture(&self, cx: &mut Cx, buffer: Vec) { - self._texture.put_back_vec_u8(cx, buffer, None); - } - - pub fn buffer(&self) -> Arc>> { - self._buffer.clone() + result } } diff --git a/image.png b/image.png new file mode 100644 index 0000000..9929998 Binary files /dev/null and b/image.png differ diff --git a/mp/Cargo.toml b/mp/Cargo.toml index dfe3ad3..e6689b1 100644 --- a/mp/Cargo.toml +++ b/mp/Cargo.toml @@ -21,3 +21,5 @@ futures = "0.3.31" async-trait = "0.1.83" thiserror = "2.0.3" indexmap = "2.6.0" +image = "0.25.5" +bytemuck = "1.20.0" diff --git a/mp/src/app.rs b/mp/src/app.rs index ff536b8..d13f13a 100644 --- a/mp/src/app.rs +++ b/mp/src/app.rs @@ -1,26 +1,22 @@ use crate::file::*; -use crate::menu::{handle_menu, spawn_background}; -use crate::widgets::area::TAreaWidgetRefExt; -use crate::widgets::selector::{ - ItemKey, ItemValue, SelectorListWidgetRefExt, SelectorWidgetRefExt, -}; - -use crate::windows_manager::WM; -use crate::{render_task::RenderTasks, PLUGIN_MANAGER, RUNTIME}; +use crate::menu::handle_menu; +use crate::selector::SelectorModalAction; +use crate::task_register::{BridgeManager, ConfigManager, TaskConfig, TaskManager}; +use crate::widgets::area::{TAreaAction, TAreaWidgetRefExt}; +use crate::widgets::loading::{self, LoadingModalWidgetRefExt}; +use crate::windows_manager::{WindowId, WindowsManager}; +use crate::PLUGIN_MANAGER; use ::log::info; -use element_bridge::TextureBridge; -use makepad_widgets::makepad_micro_serde::*; use makepad_widgets::*; use mp_elements::app::DrawList as DW; use std::path::PathBuf; -use std::sync::Arc; -use tokio::sync::Mutex; live_design! { import makepad_widgets::base::*; import makepad_widgets::theme_desktop_dark::*; import crate::app_ui::MainView; - import crate::widgets::selector::*; + import crate::selector::SelectorBase; + import crate::widgets::loading::*; HELLO = "Hello, World!"; @@ -62,7 +58,13 @@ live_design! { height: 470 width:650 show_bg: false - selector = {} + selector = {} + } + } + + loading_modal = { + content: { + inner_loading = {} } } @@ -144,15 +146,12 @@ pub enum AppAction { None, } -impl AppAction { - pub fn register_task(id: usize, bridge: Arc, draw_list: DW) -> AppAction { - AppAction::Task(TaskAction::Register(id, bridge, draw_list)) - } -} - #[derive(Debug, Clone)] pub enum TaskAction { - Register(usize, Arc, DW), + Register { + draw_list: DW, + configs: Vec>, + }, Unregister(), } @@ -162,20 +161,33 @@ pub enum FileAction { OpenFolder(PathBuf), } +#[derive(Default)] +pub struct WindowState { + pub all_windows_num: usize, + pub current_focus: Option, +} + +#[derive(Default)] +pub struct AppState { + pub window_state: WindowState, +} + #[derive(Live, LiveHook)] pub struct App { #[live] ui: WidgetRef, #[rust] - pub render_tasks: Arc>, + task_manager: TaskManager, #[rust] - windows_manager: WM, + windows_manager: WindowsManager, #[rust] - tex_reciver: ToUIReceiver>, - + bridge_manager: BridgeManager, #[rust] file_manager: FileManager, - + #[rust] + config_manager: ConfigManager, + #[rust] + app_state: AppState, #[rust] timer: Timer, } @@ -188,56 +200,45 @@ impl LiveRegister for App { crate::widgets::renderer::live_design(_cx); crate::widgets::background_text::live_design(_cx); crate::widgets::selector::live_design(_cx); + crate::widgets::loading::live_design(_cx); + crate::selector::live_design(_cx); + crate::widgets::element_panels::live_design(_cx); + crate::sidepanel::live_design(_cx); } } -#[derive(SerRon, DeRon)] -struct AppStateRon { - slide: usize, -} - impl MatchEvent for App { // Start UP fn handle_startup(&mut self, cx: &mut Cx) { info!("Starting up......"); let ui = self.ui.clone(); + + // New Area init let area = ui.tarea(id!(quad)); - area.set_windows(self.windows_manager.clone()); - // Listening to the render tasks - let render_tasks = self.render_tasks.clone(); - RUNTIME.spawn(async move { - let render_task = render_tasks.lock().await; - render_task.render().await; - }); + let id = self.windows_manager.add_window(area.clone()); + area.set_id(id.clone()); - let items = vec![( - ItemKey { - path: "path".to_string(), - category: "category".to_string(), - description: "description_1".to_string(), - }, - vec![ - ItemValue { - name: "Item 1".to_string(), - icon: "icon_radar.svg".to_string(), - }, - ItemValue { - name: "Item 2".to_string(), - icon: "icon_threed.svg".to_string(), - }, - ], - )]; + // Default Focus + self.app_state.window_state.current_focus = Some(id.clone()); - ui.selector(id!(selector)).set_items(cx, items); + // Default Bridge for Primary Renderer + self.bridge_manager.new_bridge(id); + + // Connect + self.task_manager.set_sender(self.windows_manager.sender()); + + info!("Rendering pipelines......"); + self.task_manager.run(); } fn handle_signal(&mut self, cx: &mut Cx) { self.file_manager.try_deal_file(&self.ui, cx); + self.windows_manager + .try_deal_render_result(cx, &self.bridge_manager); } fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions) { let ui = self.ui.clone(); - if ui.button(id!(start)).clicked(actions) { cx.action(AppAction::OpenFile); } @@ -274,17 +275,37 @@ impl MatchEvent for App { } AppAction::Task(task) => match task { - TaskAction::Register(bridge_id, bridge, draw_list) => { - info!( - "Register Task for {:?}, draw_list: {:?}", - bridge_id, draw_list - ); - let bridge = bridge.render_window(); - let sender = self.tex_reciver.sender(); - RUNTIME.block_on(async { - let mut render_tasks = self.render_tasks.lock().await; - render_tasks.register_task(sender, bridge_id, bridge, draw_list); - }); + TaskAction::Register { draw_list, configs } => { + info!("Register Task for draw_list"); + let current_window = &self.app_state.window_state.current_focus; + if let Some(window) = current_window.as_ref() { + let bridge = self + .bridge_manager + .get_bridge(window) + .expect("Bridge not found"); + + let render_window = bridge.render_window(); + + if let Ok(id) = self.task_manager.register_task_for_drawlist( + draw_list, + render_window, + configs.clone(), + ) { + info!("Task Registered"); + // Add Task Config to Config Manager + self.config_manager.register_config(id, configs); + + // Create Net for the Task + self.bridge_manager.create_net(id, window.clone()); + + // Redraw the window + self.task_manager.redraw(); + } else { + error!("Task Register Failed"); + } + } else { + info!("No window found"); + } } TaskAction::Unregister() => { @@ -296,6 +317,13 @@ impl MatchEvent for App { FileAction::OpenFile(file) => { info!("Open File: {:?}", file); self.file_manager.load_data(&file); + + let loading_modal = ui.modal(id!(loading_modal)); + let inner_loading = loading_modal.loading_modal(id!(inner_loading)); + + inner_loading + .set_state(_cx, loading::LoadingModalState::BackwardsPaginateUntilEvent); + loading_modal.open(_cx); } FileAction::OpenFolder(folder) => { @@ -313,16 +341,47 @@ impl MatchEvent for App { _ => {} } + + match e.as_widget_action().cast() { + SelectorModalAction::Close => { + let selector_modal = ui.modal(id!(selector_modal)); + selector_modal.close(_cx); + } + SelectorModalAction::RegisterTask { + elements, + data, + config, + } => { + if let Ok(draw_list) = self.task_manager.get_draw_list(&data, elements, &config) { + _cx.action(AppAction::Task(TaskAction::Register { + draw_list, + configs: config, + })); + } else { + error!("Draw List not found"); + } + } + _ => {} + } + + match e.as_widget_action().cast() { + TAreaAction::GetFocus(id) => { + info!("Get Focus: {:?}", id); + self.app_state.window_state.current_focus = Some(id); + } + _ => {} + } } } impl AppMain for App { fn handle_event(&mut self, cx: &mut Cx, event: &Event) { self.match_event(cx, event); - self.ui.handle_event(cx, event, &mut Scope::empty()); - spawn_background(self, event); - handle_menu(cx, event); + let scope = &mut Scope::with_data(&mut self.app_state); + self.ui.handle_event(cx, event, scope); + + handle_menu(cx, event); self.timer.is_event(event).map(|_| { let notifacion: PopupNotificationRef = self.ui.popup_notification(id!(notification)); notifacion.close(cx); @@ -330,6 +389,4 @@ impl AppMain for App { } } -impl App {} - app_main!(App); diff --git a/mp/src/app_ui.rs b/mp/src/app_ui.rs index d5679cd..e599750 100644 --- a/mp/src/app_ui.rs +++ b/mp/src/app_ui.rs @@ -6,9 +6,9 @@ live_design! { import crate::widgets::renderer::IRenderer; import makepad_draw::shader::std::*; - import crate::widgets::selector_modal::*; import crate::widgets::background_text::BackgroundLabel; import crate::widgets::selector::*; + import crate::sidepanel::*; HELLO = "Hello, World!"; @@ -63,14 +63,7 @@ live_design! { y: 0.5 }, - { - width: 600 - height: 500 - align: { - x: 0.5, - y: 0.5 - } - } + quad = {} } @@ -83,108 +76,10 @@ live_design! { Controller = { draw_bg: { color: (THEME_COLOR_U_1) } height: Fill, width: Fill - padding: 10., + // padding: 10., flow: Down, spacing: 15., - - scroll_bars: {show_scroll_x: false, show_scroll_y: true} - -

{ text: "Controller"} - - start =