From 1788126f385c0d656b6addb0731f6205cc4856e5 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sat, 14 May 2016 08:33:50 +0100 Subject: [PATCH] BufferManager now owns the Buffers instead of registering them --- src/buffer.cc | 2 -- src/buffer_manager.cc | 45 +++++++++++-------------------------------- src/buffer_manager.hh | 10 +++++----- src/buffer_utils.cc | 24 ++++++++++++++--------- src/commands.cc | 10 ++++++---- src/main.cc | 8 ++++---- 6 files changed, 41 insertions(+), 58 deletions(-) diff --git a/src/buffer.cc b/src/buffer.cc index cee8870a..3ad10fe5 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -70,7 +70,6 @@ Buffer::Buffer(String name, Flags flags, StringView data, m_last_save_undo_index(0), m_fs_timestamp(fs_timestamp) { - BufferManager::instance().register_buffer(*this); options().register_watcher(*this); ParsedLines parsed_lines = parse_lines(data); @@ -115,7 +114,6 @@ Buffer::~Buffer() run_hook_in_own_context("BufClose", m_name); options().unregister_watcher(*this); - BufferManager::instance().unregister_buffer(*this); m_values.clear(); } diff --git a/src/buffer_manager.cc b/src/buffer_manager.cc index 82b17037..95a27df4 100644 --- a/src/buffer_manager.cc +++ b/src/buffer_manager.cc @@ -20,55 +20,32 @@ BufferManager::~BufferManager() { // Make sure not clients exists ClientManager::instance().clear(); - - // delete remaining buffers - while (not m_buffers.empty()) - delete m_buffers.front().get(); } -void BufferManager::register_buffer(Buffer& buffer) +Buffer* BufferManager::create_buffer(String name, Buffer::Flags flags, + StringView data, timespec fs_timestamp) { - StringView name = buffer.name(); for (auto& buf : m_buffers) { if (buf->name() == name) throw name_not_unique(); } - m_buffers.emplace(m_buffers.begin(), &buffer); -} - -void BufferManager::unregister_buffer(Buffer& buffer) -{ - for (auto it = m_buffers.begin(); it != m_buffers.end(); ++it) - { - if (it->get() == &buffer) - { - m_buffers.erase(it); - return; - } - } - for (auto it = m_buffer_trash.begin(); it != m_buffer_trash.end(); ++it) - { - if (it->get() == &buffer) - { - m_buffer_trash.erase(it); - return; - } - } - kak_assert(false); + m_buffers.emplace(m_buffers.begin(), new Buffer{std::move(name), flags, + data, fs_timestamp}); + return m_buffers.front().get(); } void BufferManager::delete_buffer(Buffer& buffer) { - auto it = find_if(m_buffers, [&](const SafePtr& p) + auto it = find_if(m_buffers, [&](const std::unique_ptr& p) { return p.get() == &buffer; }); kak_assert(it != m_buffers.end()); ClientManager::instance().ensure_no_client_uses_buffer(buffer); + m_buffer_trash.emplace_back(std::move(*it)); m_buffers.erase(it); - m_buffer_trash.emplace_back(&buffer); } Buffer* BufferManager::get_buffer_ifp(StringView name) @@ -102,17 +79,17 @@ void BufferManager::backup_modified_buffers() void BufferManager::clear_buffer_trash() { - while (not m_buffer_trash.empty()) + for (auto& buffer : m_buffer_trash) { - Buffer* buffer = m_buffer_trash.back().get(); - // Do that again, to be tolerant in some corner cases, where a buffer is // deleted during its creation ClientManager::instance().ensure_no_client_uses_buffer(*buffer); ClientManager::instance().clear_window_trash(); - delete buffer; + buffer.reset(); } + + m_buffer_trash.clear(); } } diff --git a/src/buffer_manager.hh b/src/buffer_manager.hh index 014d241e..f992dcf6 100644 --- a/src/buffer_manager.hh +++ b/src/buffer_manager.hh @@ -1,6 +1,7 @@ #ifndef buffer_manager_hh_INCLUDED #define buffer_manager_hh_INCLUDED +#include "buffer.hh" #include "completion.hh" #include "utils.hh" #include "safe_ptr.hh" @@ -8,18 +9,17 @@ namespace Kakoune { -class Buffer; - class BufferManager : public Singleton { public: - using BufferList = Vector>; + using BufferList = Vector>; using iterator = BufferList::const_iterator; ~BufferManager(); - void register_buffer(Buffer& buffer); - void unregister_buffer(Buffer& buffer); + Buffer* create_buffer(String name, Buffer::Flags flags, + StringView data = {}, + timespec fs_timestamp = InvalidTime); void delete_buffer(Buffer& buffer); diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc index 0b86e510..8e61c28e 100644 --- a/src/buffer_utils.cc +++ b/src/buffer_utils.cc @@ -55,20 +55,22 @@ ByteCount get_byte_to_column(const Buffer& buffer, CharCount tabstop, CharCoord Buffer* open_file_buffer(StringView filename) { MappedFile file_data{filename}; - return new Buffer(filename.str(), Buffer::Flags::File, - file_data, file_data.st.st_mtim); + return BufferManager::instance().create_buffer( + filename.str(), Buffer::Flags::File, file_data, file_data.st.st_mtim); } Buffer* open_or_create_file_buffer(StringView filename) { + auto& buffer_manager = BufferManager::instance(); if (file_exists(filename)) { MappedFile file_data{filename}; - return new Buffer(filename.str(), Buffer::Flags::File, - file_data, file_data.st.st_mtim); + return buffer_manager.create_buffer(filename.str(), Buffer::Flags::File, + file_data, file_data.st.st_mtim); } - return new Buffer(filename.str(), Buffer::Flags::File | Buffer::Flags::New, - {}, InvalidTime); + return buffer_manager.create_buffer( + filename.str(), Buffer::Flags::File | Buffer::Flags::New, + {}, InvalidTime); } void reload_file_buffer(Buffer& buffer) @@ -82,14 +84,16 @@ Buffer* create_fifo_buffer(String name, int fd, bool scroll) { static ValueId s_fifo_watcher_id = ValueId::get_free_id(); - Buffer* buffer = BufferManager::instance().get_buffer_ifp(name); + auto& buffer_manager = BufferManager::instance(); + Buffer* buffer = buffer_manager.get_buffer_ifp(name); if (buffer) { buffer->flags() |= Buffer::Flags::NoUndo; buffer->reload({}, InvalidTime); } else - buffer = new Buffer(std::move(name), Buffer::Flags::Fifo | Buffer::Flags::NoUndo); + buffer = buffer_manager.create_buffer( + std::move(name), Buffer::Flags::Fifo | Buffer::Flags::NoUndo); auto watcher_deleter = [buffer](FDWatcher* watcher) { kak_assert(buffer->flags() & Buffer::Flags::Fifo); @@ -176,7 +180,9 @@ void write_to_debug_buffer(StringView str) else { String line = str + (eol_back ? "\n" : "\n\n"); - new Buffer(debug_buffer_name.str(), Buffer::Flags::NoUndo | Buffer::Flags::Debug, line, InvalidTime); + BufferManager::instance().create_buffer( + debug_buffer_name.str(), Buffer::Flags::NoUndo | Buffer::Flags::Debug, + line, InvalidTime); } } diff --git a/src/commands.cc b/src/commands.cc index efa61f80..61a4adbd 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -163,7 +163,7 @@ void edit(const ParametersParser& parser, Context& context, const ShellContext&) { if (Buffer* buf = buffer_manager.get_buffer_ifp(name)) buffer_manager.delete_buffer(*buf); - buffer = new Buffer(name, Buffer::Flags::None); + buffer = buffer_manager.create_buffer(name, Buffer::Flags::None); } else if (auto fifo = parser.get_switch("fifo")) buffer = open_fifo(name, *fifo, (bool)parser.get_switch("scroll")); @@ -423,7 +423,7 @@ void cycle_buffer(const ParametersParser& parser, Context& context, const ShellC { Buffer* oldbuf = &context.buffer(); auto it = find_if(BufferManager::instance(), - [oldbuf](const SafePtr& lhs) + [oldbuf](const std::unique_ptr& lhs) { return lhs.get() == oldbuf; }); kak_assert(it != BufferManager::instance().end()); @@ -1412,8 +1412,10 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func) { // copy buffer list as we might be mutating the buffer list // in the loop. - Vector> buffers{BufferManager::instance().begin(), - BufferManager::instance().end()}; + auto ptrs = BufferManager::instance() | + transform([](const std::unique_ptr& ptr) + { return ptr.get(); }); + Vector> buffers{ptrs.begin(), ptrs.end()}; for (auto buffer : buffers) context_wrap_for_buffer(*buffer); } diff --git a/src/main.cc b/src/main.cc index f3d8b41f..fb4c16d1 100644 --- a/src/main.cc +++ b/src/main.cc @@ -67,7 +67,7 @@ void register_env_vars() "buflist", false, [](StringView name, const Context& context) { return join(BufferManager::instance() | - transform([](const SafePtr& b) + transform([](const std::unique_ptr& b) { return b->display_name(); }), ':'); } }, { "timestamp", false, @@ -551,7 +551,7 @@ int run_server(StringView session, StringView init_command, write_to_debug_buffer(format("error while opening command line files: {}", error.what())); } else - new Buffer("*scratch*", Buffer::Flags::None); + buffer_manager.create_buffer("*scratch*", Buffer::Flags::None); if (not daemon) { @@ -664,8 +664,8 @@ int run_filter(StringView keystr, StringView commands, ConstArrayView