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_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();
}

View File

@ -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<Buffer>& p)
auto it = find_if(m_buffers, [&](const std::unique_ptr<Buffer>& 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();
}
}

View File

@ -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<BufferManager>
{
public:
using BufferList = Vector<SafePtr<Buffer>>;
using BufferList = Vector<std::unique_ptr<Buffer>>;
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);

View File

@ -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);
}
}

View File

@ -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<Buffer>& lhs)
[oldbuf](const std::unique_ptr<Buffer>& 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<SafePtr<Buffer>> buffers{BufferManager::instance().begin(),
BufferManager::instance().end()};
auto ptrs = BufferManager::instance() |
transform([](const std::unique_ptr<Buffer>& ptr)
{ return ptr.get(); });
Vector<SafePtr<Buffer>> buffers{ptrs.begin(), ptrs.end()};
for (auto buffer : buffers)
context_wrap_for_buffer(*buffer);
}

View File

@ -67,7 +67,7 @@ void register_env_vars()
"buflist", false,
[](StringView name, const Context& context)
{ return join(BufferManager::instance() |
transform([](const SafePtr<Buffer>& b)
transform([](const std::unique_ptr<Buffer>& 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<StringView
}
if (not isatty(0))
{
Buffer* buffer = new Buffer("*stdin*", Buffer::Flags::None,
read_fd(0), InvalidTime);
Buffer* buffer = buffer_manager.create_buffer(
"*stdin*", Buffer::Flags::None, read_fd(0), InvalidTime);
apply_to_buffer(*buffer);
write_buffer_to_fd(*buffer, 1);
buffer_manager.delete_buffer(*buffer);