BufferManager now owns the Buffers instead of registering them

This commit is contained in:
Maxime Coste 2016-05-14 08:33:50 +01:00
parent ba421e45f7
commit 1788126f38
6 changed files with 41 additions and 58 deletions

View File

@ -70,7 +70,6 @@ Buffer::Buffer(String name, Flags flags, StringView data,
m_last_save_undo_index(0), m_last_save_undo_index(0),
m_fs_timestamp(fs_timestamp) m_fs_timestamp(fs_timestamp)
{ {
BufferManager::instance().register_buffer(*this);
options().register_watcher(*this); options().register_watcher(*this);
ParsedLines parsed_lines = parse_lines(data); ParsedLines parsed_lines = parse_lines(data);
@ -115,7 +114,6 @@ Buffer::~Buffer()
run_hook_in_own_context("BufClose", m_name); run_hook_in_own_context("BufClose", m_name);
options().unregister_watcher(*this); options().unregister_watcher(*this);
BufferManager::instance().unregister_buffer(*this);
m_values.clear(); m_values.clear();
} }

View File

@ -20,55 +20,32 @@ BufferManager::~BufferManager()
{ {
// Make sure not clients exists // Make sure not clients exists
ClientManager::instance().clear(); 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) for (auto& buf : m_buffers)
{ {
if (buf->name() == name) if (buf->name() == name)
throw name_not_unique(); throw name_not_unique();
} }
m_buffers.emplace(m_buffers.begin(), &buffer); m_buffers.emplace(m_buffers.begin(), new Buffer{std::move(name), flags,
} data, fs_timestamp});
return m_buffers.front().get();
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);
} }
void BufferManager::delete_buffer(Buffer& buffer) void BufferManager::delete_buffer(Buffer& buffer)
{ {
auto it = find_if(m_buffers, [&](const SafePtr<Buffer>& p) auto it = find_if(m_buffers, [&](const std::unique_ptr<Buffer>& p)
{ return p.get() == &buffer; }); { return p.get() == &buffer; });
kak_assert(it != m_buffers.end()); kak_assert(it != m_buffers.end());
ClientManager::instance().ensure_no_client_uses_buffer(buffer); ClientManager::instance().ensure_no_client_uses_buffer(buffer);
m_buffer_trash.emplace_back(std::move(*it));
m_buffers.erase(it); m_buffers.erase(it);
m_buffer_trash.emplace_back(&buffer);
} }
Buffer* BufferManager::get_buffer_ifp(StringView name) Buffer* BufferManager::get_buffer_ifp(StringView name)
@ -102,17 +79,17 @@ void BufferManager::backup_modified_buffers()
void BufferManager::clear_buffer_trash() 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 // Do that again, to be tolerant in some corner cases, where a buffer is
// deleted during its creation // deleted during its creation
ClientManager::instance().ensure_no_client_uses_buffer(*buffer); ClientManager::instance().ensure_no_client_uses_buffer(*buffer);
ClientManager::instance().clear_window_trash(); ClientManager::instance().clear_window_trash();
delete buffer; buffer.reset();
} }
m_buffer_trash.clear();
} }
} }

View File

@ -1,6 +1,7 @@
#ifndef buffer_manager_hh_INCLUDED #ifndef buffer_manager_hh_INCLUDED
#define buffer_manager_hh_INCLUDED #define buffer_manager_hh_INCLUDED
#include "buffer.hh"
#include "completion.hh" #include "completion.hh"
#include "utils.hh" #include "utils.hh"
#include "safe_ptr.hh" #include "safe_ptr.hh"
@ -8,18 +9,17 @@
namespace Kakoune namespace Kakoune
{ {
class Buffer;
class BufferManager : public Singleton<BufferManager> class BufferManager : public Singleton<BufferManager>
{ {
public: public:
using BufferList = Vector<SafePtr<Buffer>>; using BufferList = Vector<std::unique_ptr<Buffer>>;
using iterator = BufferList::const_iterator; using iterator = BufferList::const_iterator;
~BufferManager(); ~BufferManager();
void register_buffer(Buffer& buffer); Buffer* create_buffer(String name, Buffer::Flags flags,
void unregister_buffer(Buffer& buffer); StringView data = {},
timespec fs_timestamp = InvalidTime);
void delete_buffer(Buffer& buffer); void delete_buffer(Buffer& buffer);

View File

@ -55,20 +55,22 @@ ByteCount get_byte_to_column(const Buffer& buffer, CharCount tabstop, CharCoord
Buffer* open_file_buffer(StringView filename) Buffer* open_file_buffer(StringView filename)
{ {
MappedFile file_data{filename}; MappedFile file_data{filename};
return new Buffer(filename.str(), Buffer::Flags::File, return BufferManager::instance().create_buffer(
file_data, file_data.st.st_mtim); filename.str(), Buffer::Flags::File, file_data, file_data.st.st_mtim);
} }
Buffer* open_or_create_file_buffer(StringView filename) Buffer* open_or_create_file_buffer(StringView filename)
{ {
auto& buffer_manager = BufferManager::instance();
if (file_exists(filename)) if (file_exists(filename))
{ {
MappedFile file_data{filename}; MappedFile file_data{filename};
return new Buffer(filename.str(), Buffer::Flags::File, return buffer_manager.create_buffer(filename.str(), Buffer::Flags::File,
file_data, file_data.st.st_mtim); file_data, file_data.st.st_mtim);
} }
return new Buffer(filename.str(), Buffer::Flags::File | Buffer::Flags::New, return buffer_manager.create_buffer(
{}, InvalidTime); filename.str(), Buffer::Flags::File | Buffer::Flags::New,
{}, InvalidTime);
} }
void reload_file_buffer(Buffer& buffer) 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(); 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) if (buffer)
{ {
buffer->flags() |= Buffer::Flags::NoUndo; buffer->flags() |= Buffer::Flags::NoUndo;
buffer->reload({}, InvalidTime); buffer->reload({}, InvalidTime);
} }
else 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) { auto watcher_deleter = [buffer](FDWatcher* watcher) {
kak_assert(buffer->flags() & Buffer::Flags::Fifo); kak_assert(buffer->flags() & Buffer::Flags::Fifo);
@ -176,7 +180,9 @@ void write_to_debug_buffer(StringView str)
else else
{ {
String line = str + (eol_back ? "\n" : "\n\n"); 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);
} }
} }

View File

@ -163,7 +163,7 @@ void edit(const ParametersParser& parser, Context& context, const ShellContext&)
{ {
if (Buffer* buf = buffer_manager.get_buffer_ifp(name)) if (Buffer* buf = buffer_manager.get_buffer_ifp(name))
buffer_manager.delete_buffer(*buf); 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")) else if (auto fifo = parser.get_switch("fifo"))
buffer = open_fifo(name, *fifo, (bool)parser.get_switch("scroll")); 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(); Buffer* oldbuf = &context.buffer();
auto it = find_if(BufferManager::instance(), auto it = find_if(BufferManager::instance(),
[oldbuf](const SafePtr<Buffer>& lhs) [oldbuf](const std::unique_ptr<Buffer>& lhs)
{ return lhs.get() == oldbuf; }); { return lhs.get() == oldbuf; });
kak_assert(it != BufferManager::instance().end()); 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 // copy buffer list as we might be mutating the buffer list
// in the loop. // in the loop.
Vector<SafePtr<Buffer>> buffers{BufferManager::instance().begin(), auto ptrs = BufferManager::instance() |
BufferManager::instance().end()}; transform([](const std::unique_ptr<Buffer>& ptr)
{ return ptr.get(); });
Vector<SafePtr<Buffer>> buffers{ptrs.begin(), ptrs.end()};
for (auto buffer : buffers) for (auto buffer : buffers)
context_wrap_for_buffer(*buffer); context_wrap_for_buffer(*buffer);
} }

View File

@ -67,7 +67,7 @@ void register_env_vars()
"buflist", false, "buflist", false,
[](StringView name, const Context& context) [](StringView name, const Context& context)
{ return join(BufferManager::instance() | { return join(BufferManager::instance() |
transform([](const SafePtr<Buffer>& b) transform([](const std::unique_ptr<Buffer>& b)
{ return b->display_name(); }), ':'); } { return b->display_name(); }), ':'); }
}, { }, {
"timestamp", false, "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())); write_to_debug_buffer(format("error while opening command line files: {}", error.what()));
} }
else else
new Buffer("*scratch*", Buffer::Flags::None); buffer_manager.create_buffer("*scratch*", Buffer::Flags::None);
if (not daemon) if (not daemon)
{ {
@ -664,8 +664,8 @@ int run_filter(StringView keystr, StringView commands, ConstArrayView<StringView
} }
if (not isatty(0)) if (not isatty(0))
{ {
Buffer* buffer = new Buffer("*stdin*", Buffer::Flags::None, Buffer* buffer = buffer_manager.create_buffer(
read_fd(0), InvalidTime); "*stdin*", Buffer::Flags::None, read_fd(0), InvalidTime);
apply_to_buffer(*buffer); apply_to_buffer(*buffer);
write_buffer_to_fd(*buffer, 1); write_buffer_to_fd(*buffer, 1);
buffer_manager.delete_buffer(*buffer); buffer_manager.delete_buffer(*buffer);