use log::*; use std::{cell::RefCell, path::PathBuf, rc::Rc}; use crate::{ data_loader::Data, errors::*, graphics::{ colormap::linear::LinearColormap, ppi::PPI, threed::Trackball, AttaWithBuffer, AttaWithProgram, Graphics, }, ui::{ helper::{self, Helper}, State, GUI, }, utils::{ cache::{Cache, CachedData}, resources::{ ManagedResource, RcGlBuffer, RcGlFramebuffer, RcGlRcFramebuffer, RcGlRcRenderbuffer, RcGlRcResource, RcGlRenderbuffer, RcGlResource, RcGlVertexArray, GL, }, }, }; use glow::HasContext; use imgui::Ui; use super::layout_type::{self, Layout}; use super::{ModulePackage, Programs}; use crate::{font_manager::FontManager, graphics::font::Text}; pub struct App<'gl> { gl: &'gl GL, context: Context<'gl>, gui: GUI, layout: Layout<'gl>, } impl<'gl> App<'gl> { pub fn new(gl: &'gl GL, helper: Helper) -> Result { let programs = Programs::new(gl).unwrap(); let mut default_state = State::default(); let mut gui = GUI::new(State::default()); let layout = gui.layout(gl); let context = Context::new(gl, Cache::new(), helper, programs); Ok(Self { gui, gl, context, layout, }) } pub fn prepare(&mut self) { if let Err(e) = self.context.programs.prepare() { error!("prepare failed: {:?}", e); } } fn gl(&self) -> &GL { &self.context.gl } fn datapool(&mut self) -> &mut Cache> { &mut self.context.datapool } pub fn render<'a>(&'a mut self) { if let Err(e) = self.layout.launch_render_task(&mut self.context) { error!("draw_program failed: {:?}", e); } } pub fn render_ui<'a>(&'a mut self, ui: &Ui, window: &winit::window::Window, run: &mut bool) { *run = self.gui.render(ui, &mut self.context, &mut self.layout); } pub fn destroy(&mut self) { self.context.programs.destroy().unwrap(); } pub fn resize(&mut self, size: [f32; 2]) {} } pub struct Context<'gl> { pub gl: &'gl GL, pub helper: Helper, pub programs: Programs<'gl>, pub datapool: Cache>, } impl<'gl> Context<'gl> { fn new( gl: &'gl GL, datapool: Cache>, helper: Helper, programs: Programs<'gl>, ) -> Self { let context = Context { helper, datapool, programs, gl, }; context } pub fn load_data>(&mut self, path: P) -> Result> { let data = self.datapool.get_or_insert(path.into())?; let module_cursor = self.programs.load_data(data)?; Ok(module_cursor) } }