From d3499ecd9cc7b2b685d1bc96ac7591f29a1752ce Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Thu, 8 Sep 2011 00:13:19 +0000 Subject: [PATCH] Window lifetime is now handled by it's buffer. A window cannot outlive it's buffer, so it makes sense to keep only a reference on it hand have the buffer manage the window lifetime. --- src/buffer.cc | 20 ++++++++++++++++++++ src/buffer.hh | 9 +++++++++ src/main.cc | 14 +++++++------- src/window.cc | 45 +++++++++++++++++++++++---------------------- src/window.hh | 17 ++++++++--------- 5 files changed, 67 insertions(+), 38 deletions(-) diff --git a/src/buffer.cc b/src/buffer.cc index 2a09cc5b..81ba07e6 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -1,8 +1,10 @@ #include "buffer.hh" #include "buffer_manager.hh" +#include "window.hh" #include +#include namespace Kakoune { @@ -314,4 +316,22 @@ void Buffer::append_modification(Modification&& modification) m_current_undo_group.push_back(modification); } +struct window_already_registered {}; + +void Buffer::register_window(Window* window) +{ + if (std::find(m_windows.begin(), m_windows.end(), window) != m_windows.end()) + throw window_already_registered(); + + m_windows.push_front(std::unique_ptr(window)); +} + +void Buffer::delete_window(Window* window) +{ + assert(&window->buffer() == this); + auto window_it = std::find(m_windows.begin(), m_windows.end(), window); + assert(window_it != m_windows.end()); + m_windows.erase(window_it); +} + } diff --git a/src/buffer.hh b/src/buffer.hh index 60306647..28a87fc4 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -3,6 +3,8 @@ #include #include +#include +#include #include "utils.hh" @@ -10,6 +12,8 @@ namespace Kakoune { class Buffer; +class Window; + typedef int BufferPos; typedef int BufferSize; typedef char BufferChar; @@ -96,6 +100,9 @@ public: const BufferString& content() const { return m_content; } + void register_window(Window* window); + void delete_window(Window* window); + private: BufferChar at(BufferPos position) const; @@ -140,6 +147,8 @@ private: void revert_modification(const Modification& modification); void append_modification(Modification&& modification); + + std::list> m_windows; }; } diff --git a/src/main.cc b/src/main.cc index 491d48f1..b39b8be4 100644 --- a/src/main.cc +++ b/src/main.cc @@ -152,7 +152,7 @@ void do_insert(Window& window) print_status(""); } -std::shared_ptr current_window; +Window* current_window; void edit(const CommandParameters& params) { @@ -162,14 +162,14 @@ void edit(const CommandParameters& params) std::string filename = params[0]; try { - std::shared_ptr buffer(create_buffer_from_file(filename)); + Buffer* buffer = create_buffer_from_file(filename); if (buffer) - current_window = std::make_shared(buffer); + current_window = new Window(*buffer); } catch (file_not_found& what) { print_status("new file " + filename); - current_window = std::make_shared(std::make_shared(filename)); + current_window = new Window(*new Buffer(filename)); } } @@ -178,7 +178,7 @@ void write_buffer(const CommandParameters& params) if (params.size() > 1) throw wrong_argument_count(); - Buffer& buffer = *current_window->buffer(); + Buffer& buffer = current_window->buffer(); std::string filename = params.empty() ? buffer.name() : params[0]; write_buffer_to_file(buffer, filename); @@ -292,8 +292,8 @@ int main() try { - auto buffer = std::make_shared(""); - current_window = std::make_shared(buffer); + auto buffer = new Buffer(""); + current_window = new Window(*buffer); draw_window(*current_window); int count = 0; diff --git a/src/window.cc b/src/window.cc index eedc32d6..2694aef8 100644 --- a/src/window.cc +++ b/src/window.cc @@ -5,29 +5,30 @@ namespace Kakoune { -Window::Window(const std::shared_ptr buffer) +Window::Window(Buffer& buffer) : m_buffer(buffer), m_position(0, 0), m_cursor(0, 0), m_dimensions(0, 0) { + m_buffer.register_window(this); } void Window::erase() { - m_buffer->begin_undo_group(); + m_buffer.begin_undo_group(); if (m_selections.empty()) { BufferIterator cursor = iterator_at(m_cursor); - m_buffer->erase(cursor, cursor+1); + m_buffer.erase(cursor, cursor+1); } for (auto sel = m_selections.begin(); sel != m_selections.end(); ++sel) { - m_buffer->erase(sel->begin, sel->end); + m_buffer.erase(sel->begin, sel->end); sel->end = sel->begin; } - m_buffer->end_undo_group(); + m_buffer.end_undo_group(); } static WindowCoord measure_string(const Window::String& string) @@ -48,25 +49,25 @@ static WindowCoord measure_string(const Window::String& string) void Window::insert(const String& string) { - m_buffer->begin_undo_group(); + m_buffer.begin_undo_group(); if (m_selections.empty()) { - m_buffer->insert(iterator_at(m_cursor), string); + m_buffer.insert(iterator_at(m_cursor), string); move_cursor(measure_string(string)); } for (auto sel = m_selections.begin(); sel != m_selections.end(); ++sel) { - m_buffer->insert(sel->begin, string); + m_buffer.insert(sel->begin, string); sel->begin += string.length(); sel->end += string.length(); } - m_buffer->end_undo_group(); + m_buffer.end_undo_group(); } void Window::append(const String& string) { - m_buffer->begin_undo_group(); + m_buffer.begin_undo_group(); if (m_selections.empty()) { move_cursor(WindowCoord(0 , 1)); @@ -75,19 +76,19 @@ void Window::append(const String& string) for (auto sel = m_selections.begin(); sel != m_selections.end(); ++sel) { - m_buffer->insert(sel->end, string); + m_buffer.insert(sel->end, string); } - m_buffer->end_undo_group(); + m_buffer.end_undo_group(); } bool Window::undo() { - return m_buffer->undo(); + return m_buffer.undo(); } bool Window::redo() { - return m_buffer->redo(); + return m_buffer.redo(); } BufferCoord Window::window_to_buffer(const WindowCoord& window_pos) const @@ -104,12 +105,12 @@ WindowCoord Window::buffer_to_window(const BufferCoord& buffer_pos) const BufferIterator Window::iterator_at(const WindowCoord& window_pos) const { - return m_buffer->iterator_at(window_to_buffer(window_pos)); + return m_buffer.iterator_at(window_to_buffer(window_pos)); } WindowCoord Window::line_and_column_at(const BufferIterator& iterator) const { - return buffer_to_window(m_buffer->line_and_column_at(iterator)); + return buffer_to_window(m_buffer.line_and_column_at(iterator)); } void Window::empty_selections() @@ -141,7 +142,7 @@ void Window::move_cursor(const WindowCoord& offset) window_to_buffer(WindowCoord(m_cursor.line + offset.line, m_cursor.column + offset.column)); - m_cursor = buffer_to_window(m_buffer->clamp(target_position)); + m_cursor = buffer_to_window(m_buffer.clamp(target_position)); scroll_to_keep_cursor_visible_ifn(); } @@ -154,29 +155,29 @@ void Window::update_display_buffer() std::sort(sorted_selections.begin(), sorted_selections.end(), [](const Selection& lhs, const Selection& rhs) { return lhs.begin < rhs.begin; }); - BufferIterator current_position = m_buffer->iterator_at(m_position); + BufferIterator current_position = m_buffer.iterator_at(m_position); for (Selection& sel : sorted_selections) { if (current_position != sel.begin) { DisplayAtom atom; - atom.content = m_buffer->string(current_position, sel.begin); + atom.content = m_buffer.string(current_position, sel.begin); m_display_buffer.append(atom); } if (sel.begin != sel.end) { DisplayAtom atom; - atom.content = m_buffer->string(sel.begin, sel.end); + atom.content = m_buffer.string(sel.begin, sel.end); atom.attribute = UNDERLINE; m_display_buffer.append(atom); } current_position = sel.end; } - if (current_position != m_buffer->end()) + if (current_position != m_buffer.end()) { DisplayAtom atom; - atom.content = m_buffer->string(current_position, m_buffer->end()); + atom.content = m_buffer.string(current_position, m_buffer.end()); m_display_buffer.append(atom); } } diff --git a/src/window.hh b/src/window.hh index 3b014b98..92c28301 100644 --- a/src/window.hh +++ b/src/window.hh @@ -1,7 +1,6 @@ #ifndef window_hh_INCLUDED #define window_hh_INCLUDED -#include #include #include "utils.hh" @@ -35,7 +34,7 @@ public: typedef BufferString String; typedef std::function Selector; - Window(const std::shared_ptr buffer); + Window(Buffer& buffer); Window(const Window&) = delete; void erase(); @@ -45,7 +44,7 @@ public: const BufferCoord& position() const { return m_position; } const WindowCoord& cursor_position() const { return m_cursor; } - const std::shared_ptr& buffer() const { return m_buffer; } + Buffer& buffer() const { return m_buffer; } BufferCoord window_to_buffer(const WindowCoord& window_pos) const; WindowCoord buffer_to_window(const BufferCoord& buffer_pos) const; @@ -72,12 +71,12 @@ public: private: void scroll_to_keep_cursor_visible_ifn(); - std::shared_ptr m_buffer; - BufferCoord m_position; - WindowCoord m_cursor; - WindowCoord m_dimensions; - SelectionList m_selections; - DisplayBuffer m_display_buffer; + Buffer& m_buffer; + BufferCoord m_position; + WindowCoord m_cursor; + WindowCoord m_dimensions; + SelectionList m_selections; + DisplayBuffer m_display_buffer; }; }