URI: 
       Fixed some perf issues. - icy_draw - icy_draw is the successor to mystic draw. fork / mirror
  HTML git clone https://git.drkhsh.at/icy_draw.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 6e3a844fa570f6b2955d990994a7d4934c6713b6
   DIR parent e79f3403dea772636bcb59a328cd55aa781860f1
  HTML Author: Mike Krüger <mkrueger@posteo.de>
       Date:   Thu, 12 Oct 2023 20:37:41 +0200
       
       Fixed some perf issues.
       
       Diffstat:
         M src/model/tools/brush_imp.rs        |       8 ++++----
         M src/model/tools/draw_ellipse_fille… |      16 ++++++++++++++--
         M src/model/tools/draw_ellipse_imp.rs |      16 ++++++++++++++--
         M src/model/tools/draw_rectangle_fil… |      16 ++++++++++++++--
         M src/model/tools/draw_rectangle_imp… |      15 +++++++++++++--
         M src/model/tools/erase_imp.rs        |       6 +++---
         M src/model/tools/flip_imp.rs         |       4 ++--
         M src/model/tools/line_imp.rs         |      15 +++++++++++++--
         M src/model/tools/pipette_imp.rs      |       4 ++--
         M src/paint/mod.rs                    |       1 -
         M src/ui/dialogs/edit_layer_dialog.rs |       2 +-
         M src/ui/dialogs/settings_dialog.rs   |       4 ++--
         M src/ui/editor/ansi/mod.rs           |       5 ++---
         M src/ui/tools/layer_view.rs          |      21 ++++++++++++++++++---
       
       14 files changed, 102 insertions(+), 31 deletions(-)
       ---
   DIR diff --git a/src/model/tools/brush_imp.rs b/src/model/tools/brush_imp.rs
       @@ -54,7 +54,7 @@ impl BrushTool {
                }
        
                let use_selection = editor.buffer_view.lock().get_edit_state().is_something_selected();
       -        editor.buffer_view.lock().get_edit_state_mut().is_buffer_dirty = true;
       +        editor.buffer_view.lock().get_edit_state_mut().set_is_buffer_dirty();
        
                let offset = if let Some(layer) = editor.buffer_view.lock().get_edit_state().get_cur_layer() {
                    layer.get_offset()
       @@ -178,7 +178,7 @@ impl Tool for BrushTool {
                    return;
                }
                get_edit_state_mut.get_tool_overlay_mask_mut().clear();
       -        get_edit_state_mut.is_buffer_dirty = true;
       +        get_edit_state_mut.set_is_buffer_dirty();
            }
        
            fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, cur: Position, cur_abs: Position) -> egui::Response {
       @@ -196,7 +196,7 @@ impl Tool for BrushTool {
                                    layer.set_char(cur + pos + mid, AttributedChar::new(ch.ch, ch.attribute));
                                }
                            }
       -                    lock.get_edit_state_mut().is_buffer_dirty = true;
       +                    lock.get_edit_state_mut().set_is_buffer_dirty();
                        }
                    }
                } else {
       @@ -213,7 +213,7 @@ impl Tool for BrushTool {
                                get_tool_overlay_mask_mut.set_is_selected(pos, true);
                            }
                        }
       -                lock.get_edit_state_mut().is_buffer_dirty = true;
       +                lock.get_edit_state_mut().set_is_buffer_dirty();
                    }
                    editor.buffer_view.lock().get_buffer_mut().remove_overlay();
                }
   DIR diff --git a/src/model/tools/draw_ellipse_filled_imp.rs b/src/model/tools/draw_ellipse_filled_imp.rs
       @@ -4,7 +4,7 @@ use icy_engine_egui::TerminalCalc;
        
        use crate::{
            paint::{fill_ellipse, BrushMode, ColorMode},
       -    AnsiEditor, Message,
       +    AnsiEditor, Event, Message,
        };
        
        use super::{Position, Tool};
       @@ -13,6 +13,7 @@ pub struct DrawEllipseFilledTool {
            draw_mode: BrushMode,
            color_mode: ColorMode,
            char_code: std::rc::Rc<std::cell::RefCell<char>>,
       +    old_pos: Position,
        }
        
        impl Default for DrawEllipseFilledTool {
       @@ -21,6 +22,7 @@ impl Default for DrawEllipseFilledTool {
                    draw_mode: BrushMode::HalfBlock,
                    color_mode: crate::paint::ColorMode::Both,
                    char_code: std::rc::Rc::new(std::cell::RefCell::new('\u{00B0}')),
       +            old_pos: Position::default(),
                }
            }
        }
       @@ -55,10 +57,20 @@ impl Tool for DrawEllipseFilledTool {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       +    fn handle_drag_begin(&mut self, _editor: &mut AnsiEditor, _response: &egui::Response) -> Event {
       +        self.old_pos = Position::new(-1, -1);
       +        Event::None
       +    }
       +
            fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
       +        let p2 = editor.half_block_click_pos;
       +        if self.old_pos == p2 {
       +            return response;
       +        }
       +        self.old_pos = p2;
       +
                editor.clear_overlay_layer();
                let p1 = editor.drag_pos.start_half_block;
       -        let p2 = editor.half_block_click_pos;
                let start = Position::new(p1.x.min(p2.x), p1.y.min(p2.y));
                let end = Position::new(p1.x.max(p2.x), p1.y.max(p2.y));
                fill_ellipse(&mut editor.buffer_view.lock(), start, end, self.draw_mode.clone(), self.color_mode);
   DIR diff --git a/src/model/tools/draw_ellipse_imp.rs b/src/model/tools/draw_ellipse_imp.rs
       @@ -4,7 +4,7 @@ use icy_engine_egui::TerminalCalc;
        
        use crate::{
            paint::{draw_ellipse, BrushMode, ColorMode},
       -    AnsiEditor, Message,
       +    AnsiEditor, Event, Message,
        };
        
        use super::{Position, Tool};
       @@ -13,6 +13,7 @@ pub struct DrawEllipseTool {
            draw_mode: BrushMode,
            color_mode: ColorMode,
            char_code: std::rc::Rc<std::cell::RefCell<char>>,
       +    old_pos: Position,
        }
        
        impl Default for DrawEllipseTool {
       @@ -21,6 +22,7 @@ impl Default for DrawEllipseTool {
                    draw_mode: BrushMode::HalfBlock,
                    color_mode: crate::paint::ColorMode::Both,
                    char_code: std::rc::Rc::new(std::cell::RefCell::new('\u{00B0}')),
       +            old_pos: Position::default(),
                }
            }
        }
       @@ -55,10 +57,20 @@ impl Tool for DrawEllipseTool {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       +    fn handle_drag_begin(&mut self, _editor: &mut AnsiEditor, _response: &egui::Response) -> Event {
       +        self.old_pos = Position::new(-1, -1);
       +        Event::None
       +    }
       +
            fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
       +        let p2 = editor.half_block_click_pos;
       +        if self.old_pos == p2 {
       +            return response;
       +        }
       +        self.old_pos = p2;
       +
                editor.clear_overlay_layer();
                let p1 = editor.drag_pos.start_half_block;
       -        let p2 = editor.half_block_click_pos;
                let start = Position::new(p1.x.min(p2.x), p1.y.min(p2.y));
                let end = Position::new(p1.x.max(p2.x), p1.y.max(p2.y));
                draw_ellipse(&mut editor.buffer_view.lock(), start, end, self.draw_mode.clone(), self.color_mode);
   DIR diff --git a/src/model/tools/draw_rectangle_filled_imp.rs b/src/model/tools/draw_rectangle_filled_imp.rs
       @@ -5,7 +5,7 @@ use icy_engine_egui::TerminalCalc;
        
        use crate::{
            paint::{fill_rectangle, BrushMode, ColorMode},
       -    AnsiEditor, Message,
       +    AnsiEditor, Event, Message,
        };
        
        use super::Tool;
       @@ -14,6 +14,7 @@ pub struct DrawRectangleFilledTool {
            draw_mode: BrushMode,
            color_mode: ColorMode,
            char_code: std::rc::Rc<std::cell::RefCell<char>>,
       +    old_pos: Position,
        }
        
        impl Default for DrawRectangleFilledTool {
       @@ -22,6 +23,7 @@ impl Default for DrawRectangleFilledTool {
                    draw_mode: BrushMode::HalfBlock,
                    color_mode: crate::paint::ColorMode::Both,
                    char_code: std::rc::Rc::new(std::cell::RefCell::new('\u{00B0}')),
       +            old_pos: Position::default(),
                }
            }
        }
       @@ -56,10 +58,20 @@ impl Tool for DrawRectangleFilledTool {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       +    fn handle_drag_begin(&mut self, _editor: &mut AnsiEditor, _response: &egui::Response) -> Event {
       +        self.old_pos = Position::new(-1, -1);
       +        Event::None
       +    }
       +
            fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
       +        let p2 = editor.half_block_click_pos;
       +        if self.old_pos == p2 {
       +            return response;
       +        }
       +        self.old_pos = p2;
       +
                editor.clear_overlay_layer();
                let p1 = editor.drag_pos.start_half_block;
       -        let p2 = editor.half_block_click_pos;
                let start = Position::new(p1.x.min(p2.x), p1.y.min(p2.y));
                let end = Position::new(p1.x.max(p2.x), p1.y.max(p2.y));
                fill_rectangle(&mut editor.buffer_view.lock(), start, end, self.draw_mode.clone(), self.color_mode);
   DIR diff --git a/src/model/tools/draw_rectangle_imp.rs b/src/model/tools/draw_rectangle_imp.rs
       @@ -4,7 +4,7 @@ use icy_engine_egui::TerminalCalc;
        
        use crate::{
            paint::{draw_rectangle, BrushMode, ColorMode},
       -    AnsiEditor, Message,
       +    AnsiEditor, Event, Message,
        };
        
        use super::{Position, Tool};
       @@ -13,6 +13,7 @@ pub struct DrawRectangleTool {
            draw_mode: BrushMode,
            color_mode: ColorMode,
            pub char_code: std::rc::Rc<std::cell::RefCell<char>>,
       +    old_pos: Position,
        }
        
        impl Default for DrawRectangleTool {
       @@ -21,6 +22,7 @@ impl Default for DrawRectangleTool {
                    draw_mode: BrushMode::HalfBlock,
                    color_mode: crate::paint::ColorMode::Both,
                    char_code: std::rc::Rc::new(std::cell::RefCell::new('\u{00B0}')),
       +            old_pos: Position::default(),
                }
            }
        }
       @@ -54,10 +56,19 @@ impl Tool for DrawRectangleTool {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       +    fn handle_drag_begin(&mut self, _editor: &mut AnsiEditor, _response: &egui::Response) -> Event {
       +        self.old_pos = Position::new(-1, -1);
       +        Event::None
       +    }
            fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
       +        let p2 = editor.half_block_click_pos;
       +        if self.old_pos == p2 {
       +            return response;
       +        }
       +        self.old_pos = p2;
       +
                editor.clear_overlay_layer();
                let p1 = editor.drag_pos.start_half_block;
       -        let p2 = editor.half_block_click_pos;
                let start = Position::new(p1.x.min(p2.x), p1.y.min(p2.y));
                let end = Position::new(p1.x.max(p2.x), p1.y.max(p2.y));
                draw_rectangle(&mut editor.buffer_view.lock(), start, end, self.draw_mode.clone(), self.color_mode);
   DIR diff --git a/src/model/tools/erase_imp.rs b/src/model/tools/erase_imp.rs
       @@ -43,7 +43,7 @@ impl EraseTool {
                } else {
                    Position::default()
                };
       -        editor.buffer_view.lock().get_edit_state_mut().is_buffer_dirty = true;
       +        editor.buffer_view.lock().get_edit_state_mut().set_is_buffer_dirty();
                for y in 0..self.size {
                    for x in 0..self.size {
                        let pos = center + Position::new(x, y);
       @@ -118,7 +118,7 @@ impl Tool for EraseTool {
                    return;
                }
                get_edit_state_mut.get_tool_overlay_mask_mut().clear();
       -        get_edit_state_mut.is_buffer_dirty = true;
       +        get_edit_state_mut.set_is_buffer_dirty();
            }
        
            fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, cur: Position, cur_abs: Position) -> egui::Response {
       @@ -134,7 +134,7 @@ impl Tool for EraseTool {
                            get_tool_overlay_mask_mut.set_is_selected(pos, true);
                        }
                    }
       -            lock.get_edit_state_mut().is_buffer_dirty = true;
       +            lock.get_edit_state_mut().set_is_buffer_dirty();
                }
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
   DIR diff --git a/src/model/tools/flip_imp.rs b/src/model/tools/flip_imp.rs
       @@ -58,7 +58,7 @@ impl Tool for FlipTool {
                let get_edit_state_mut = lock.get_edit_state_mut();
                if !get_edit_state_mut.get_tool_overlay_mask_mut().is_empty() {
                    get_edit_state_mut.get_tool_overlay_mask_mut().clear();
       -            get_edit_state_mut.is_buffer_dirty = true;
       +            get_edit_state_mut.set_is_buffer_dirty();
                }
            }
        
       @@ -69,7 +69,7 @@ impl Tool for FlipTool {
                    let get_tool_overlay_mask_mut = lock.get_edit_state_mut().get_tool_overlay_mask_mut();
                    get_tool_overlay_mask_mut.clear();
                    get_tool_overlay_mask_mut.set_is_selected(cur_abs, true);
       -            lock.get_edit_state_mut().is_buffer_dirty = true;
       +            lock.get_edit_state_mut().set_is_buffer_dirty();
                }
        
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
   DIR diff --git a/src/model/tools/line_imp.rs b/src/model/tools/line_imp.rs
       @@ -4,7 +4,7 @@ use icy_engine_egui::TerminalCalc;
        
        use crate::{
            paint::{draw_line, BrushMode, ColorMode},
       -    AnsiEditor, Message,
       +    AnsiEditor, Event, Message,
        };
        
        use super::{Position, Tool};
       @@ -66,12 +66,23 @@ impl Tool for LineTool {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       +    fn handle_drag_begin(&mut self, _editor: &mut AnsiEditor, _response: &egui::Response) -> Event {
       +        self.old_pos = Position::new(-1, -1);
       +        Event::None
       +    }
       +
            fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
       +        let p2 = editor.half_block_click_pos;
       +        if self.old_pos == p2 {
       +            return response;
       +        }
       +        self.old_pos = p2;
       +
                editor.clear_overlay_layer();
                draw_line(
                    &mut editor.buffer_view.lock(),
                    editor.drag_pos.start_half_block,
       -            editor.half_block_click_pos,
       +            p2,
                    self.draw_mode.clone(),
                    self.color_mode,
                );
   DIR diff --git a/src/model/tools/pipette_imp.rs b/src/model/tools/pipette_imp.rs
       @@ -103,7 +103,7 @@ impl Tool for PipetteTool {
                    let get_tool_overlay_mask_mut = lock.get_edit_state_mut().get_tool_overlay_mask_mut();
                    get_tool_overlay_mask_mut.clear();
                    get_tool_overlay_mask_mut.set_is_selected(cur_abs, true);
       -            lock.get_edit_state_mut().is_buffer_dirty = true;
       +            lock.get_edit_state_mut().set_is_buffer_dirty();
                }
        
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
       @@ -127,7 +127,7 @@ impl Tool for PipetteTool {
                let get_edit_state_mut = lock.get_edit_state_mut();
                if !get_edit_state_mut.get_tool_overlay_mask_mut().is_empty() {
                    get_edit_state_mut.get_tool_overlay_mask_mut().clear();
       -            get_edit_state_mut.is_buffer_dirty = true;
       +            get_edit_state_mut.set_is_buffer_dirty();
                }
            }
        
   DIR diff --git a/src/paint/mod.rs b/src/paint/mod.rs
       @@ -290,7 +290,6 @@ pub fn plot_point(buffer_view: &mut BufferView, pos: impl Into<Position>, mut mo
                attribute.set_background(editor_attr.get_background());
            }
        
       -    buffer_view.get_edit_state_mut().is_buffer_dirty = true;
            if let Some(layer) = buffer_view.get_edit_state_mut().get_overlay_layer() {
                let overlay_ch = layer.get_char(text_pos);
                if overlay_ch.is_visible() {
   DIR diff --git a/src/ui/dialogs/edit_layer_dialog.rs b/src/ui/dialogs/edit_layer_dialog.rs
       @@ -172,7 +172,7 @@ impl ModalDialog for EditLayerDialog {
                layer.has_alpha_channel = self.has_alpha_channel;
                layer.is_alpha_channel_locked = self.is_alpha_channel_locked;
                layer.mode = self.mode;
       -        bv.get_edit_state_mut().is_buffer_dirty = true;
       +        bv.get_edit_state_mut().set_is_buffer_dirty();
                Ok(None)
            }
        }
   DIR diff --git a/src/ui/dialogs/settings_dialog.rs b/src/ui/dialogs/settings_dialog.rs
       @@ -316,7 +316,7 @@ impl SettingsDialog {
                    {
                        self.char_sets[0] = CharSetMapping::default();
                        for view in self.views.iter() {
       -                    view.lock().get_edit_state_mut().is_buffer_dirty = true;
       +                    view.lock().get_edit_state_mut().set_is_buffer_dirty();
                        }
                    }
                });
       @@ -380,7 +380,7 @@ impl SettingsDialog {
                        self.views[self.selected_view].lock().get_buffer_mut().layers[0].set_char((x, 0), AttributedChar::new(ch, TextAttribute::default()));
                    }
        
       -            self.views[self.selected_view].lock().get_edit_state_mut().is_buffer_dirty = true;
       +            self.views[self.selected_view].lock().get_edit_state_mut().set_is_buffer_dirty();
                }
        
                if ui.input(|i| i.key_pressed(egui::Key::ArrowLeft)) {
   DIR diff --git a/src/ui/editor/ansi/mod.rs b/src/ui/editor/ansi/mod.rs
       @@ -162,7 +162,7 @@ impl Document for AnsiEditor {
                if self.last_selected_tool != selected_tool {
                    self.last_selected_tool = selected_tool;
                    self.buffer_view.lock().get_edit_state_mut().get_tool_overlay_mask_mut().clear();
       -            self.buffer_view.lock().get_edit_state_mut().is_buffer_dirty = true;
       +            self.buffer_view.lock().get_edit_state_mut().set_is_buffer_dirty();
                }
        
                let mut scale = options.get_scale();
       @@ -339,7 +339,6 @@ impl AnsiEditor {
                    Position::default()
                };
        
       -
                let char_scroll_position = self.buffer_view.lock().calc.char_scroll_position;
                let terminal_rect = self.buffer_view.lock().calc.terminal_rect;
                let terminal_width = terminal_rect.width();
       @@ -721,7 +720,7 @@ impl AnsiEditor {
                    layer.set_offset(cur_offset);
                    layer.clear();
                }
       -        self.buffer_view.lock().get_edit_state_mut().is_buffer_dirty = true;
       +        self.buffer_view.lock().get_edit_state_mut().set_is_buffer_dirty();
            }
        
            pub fn backspace(&mut self) {
   DIR diff --git a/src/ui/tools/layer_view.rs b/src/ui/tools/layer_view.rs
       @@ -13,12 +13,19 @@ use crate::{AnsiEditor, Document, Message, ToolWindow, INVISIBLE_SVG, VISIBLE_SV
        
        pub struct LayerToolWindow {
            gl: Arc<glow::Context>,
       +    view_cache_id: usize,
       +    stack_len: usize,
            view_cache: Vec<Arc<eframe::epaint::mutex::Mutex<BufferView>>>,
        }
        
        impl LayerToolWindow {
            pub(crate) fn new(gl: Arc<glow::Context>) -> Self {
       -        Self { gl, view_cache: Vec::new() }
       +        Self {
       +            gl,
       +            view_cache: Vec::new(),
       +            view_cache_id: usize::MAX,
       +            stack_len: usize::MAX,
       +        }
            }
        
            pub fn get_buffer_view(&mut self, i: usize) -> Arc<eframe::epaint::mutex::Mutex<BufferView>> {
       @@ -58,6 +65,7 @@ impl LayerToolWindow {
                            if r.clicked() {
                                result = Some(Message::AddFloatingLayer);
                            }
       +
                            if let Some(layer) = editor.buffer_view.lock().get_edit_state().get_cur_layer() {
                                let role = layer.role;
                                if matches!(role, icy_engine::Role::PastePreview) {
       @@ -115,6 +123,12 @@ impl LayerToolWindow {
                });
        
                CentralPanel::default().show_inside(ui, |ui| {
       +            let redraw_layer_views = self.view_cache_id != editor.buffer_view.lock().id || editor.undo_stack_len() != self.stack_len;
       +            if redraw_layer_views {
       +                self.view_cache_id = editor.buffer_view.lock().id;
       +                self.stack_len = editor.undo_stack_len();
       +            }
       +
                    egui::ScrollArea::vertical().id_source("layer_view_scroll_area").show(ui, |ui| {
                        for i in (0..max).rev() {
                            ui.horizontal(|ui| {
       @@ -135,7 +149,7 @@ impl LayerToolWindow {
                                        ..Default::default()
                                    };
                                    let view = self.get_buffer_view(i);
       -                            {
       +                            if redraw_layer_views {
                                        view.lock().get_buffer_mut().layers.clear();
                                        let lock = &editor.buffer_view.lock();
                                        if let Some(layer) = lock.get_buffer().layers.get(i) {
       @@ -144,9 +158,10 @@ impl LayerToolWindow {
                                            view.lock().get_buffer_mut().set_font_table(lock.get_buffer().get_font_table());
                                            view.lock().get_buffer_mut().palette = lock.get_buffer().palette.clone();
                                            view.lock().get_buffer_mut().layers.push(l);
       -                                    view.lock().get_edit_state_mut().is_buffer_dirty = true;
       +                                    view.lock().get_edit_state_mut().set_is_buffer_dirty();
                                        }
                                    }
       +
                                    let (_, _) = icy_engine_egui::show_terminal_area(ui, view, opt);
                                });