Refactor message writing

This commit is contained in:
Jason Felice 2019-05-22 14:03:49 -04:00
parent 2bef1f1eb8
commit b82cf38338

View File

@ -50,8 +50,8 @@ public:
MsgWriter(RemoteBuffer& buffer, MessageType type) MsgWriter(RemoteBuffer& buffer, MessageType type)
: m_buffer{buffer}, m_start{(uint32_t)buffer.size()} : m_buffer{buffer}, m_start{(uint32_t)buffer.size()}
{ {
write(type); write_field(type);
write((uint32_t)0); // message size, to be patched on write write_field((uint32_t)0); // message size, to be patched on write
} }
~MsgWriter() ~MsgWriter()
@ -60,87 +60,94 @@ public:
memcpy(m_buffer.data() + m_start + sizeof(MessageType), &count, sizeof(uint32_t)); memcpy(m_buffer.data() + m_start + sizeof(MessageType), &count, sizeof(uint32_t));
} }
void write(const char* val, size_t size) template<typename ...Args>
void write(Args&&... args)
{
(write_field(std::forward<Args>(args)), ...);
}
private:
void write_raw(const char* val, size_t size)
{ {
m_buffer.insert(m_buffer.end(), val, val + size); m_buffer.insert(m_buffer.end(), val, val + size);
} }
template<typename T> template<typename T>
void write(const T& val) void write_field(const T& val)
{ {
static_assert(std::is_trivially_copyable<T>::value, ""); static_assert(std::is_trivially_copyable<T>::value, "");
write((const char*)&val, sizeof(val)); write_raw((const char*)&val, sizeof(val));
} }
void write(StringView str) void write_field(StringView str)
{ {
write(str.length()); write_field(str.length());
write(str.data(), (int)str.length()); write_raw(str.data(), (int)str.length());
}; };
void write(const String& str) void write_field(const String& str)
{ {
write(StringView{str}); write_field(StringView{str});
} }
template<typename T> template<typename T>
void write(ConstArrayView<T> view) void write_field(ConstArrayView<T> view)
{ {
write<uint32_t>(view.size()); write_field<uint32_t>(view.size());
for (auto& val : view) for (auto& val : view)
write(val); write_field(val);
} }
template<typename T, MemoryDomain domain> template<typename T, MemoryDomain domain>
void write(const Vector<T, domain>& vec) void write_field(const Vector<T, domain>& vec)
{ {
write(ConstArrayView<T>(vec)); write_field(ConstArrayView<T>(vec));
} }
template<typename Key, typename Val, MemoryDomain domain> template<typename Key, typename Val, MemoryDomain domain>
void write(const HashMap<Key, Val, domain>& map) void write_field(const HashMap<Key, Val, domain>& map)
{ {
write<uint32_t>(map.size()); write_field<uint32_t>(map.size());
for (auto& val : map) for (auto& val : map)
{ {
write(val.key); write_field(val.key);
write(val.value); write_field(val.value);
} }
} }
template<typename T> template<typename T>
void write(const Optional<T>& val) void write_field(const Optional<T>& val)
{ {
write((bool)val); write_field((bool)val);
if (val) if (val)
write(*val); write_field(*val);
} }
void write(Color color) void write_field(Color color)
{ {
write(color.color); write_field(color.color);
if (color.color == Color::RGB) if (color.color == Color::RGB)
{ {
write(color.r); write_field(color.r);
write(color.g); write_field(color.g);
write(color.b); write_field(color.b);
} }
} }
void write(const DisplayAtom& atom) void write_field(const DisplayAtom& atom)
{ {
write(atom.content()); write_field(atom.content());
write(atom.face); write_field(atom.face);
} }
void write(const DisplayLine& line) void write_field(const DisplayLine& line)
{ {
write(line.atoms()); write_field(line.atoms());
} }
void write(const DisplayBuffer& display_buffer) void write_field(const DisplayBuffer& display_buffer)
{ {
write(display_buffer.lines()); write_field(display_buffer.lines());
} }
private: private:
@ -375,6 +382,14 @@ public:
void exit(int status); void exit(int status);
private: private:
template<typename ...Args>
void send_message(MessageType type, Args&&... args)
{
MsgWriter msg{m_send_buffer, type};
msg.write(std::forward<Args>(args)...);
m_socket_watcher.events() |= FdEvents::Write;
}
FDWatcher m_socket_watcher; FDWatcher m_socket_watcher;
MsgReader m_reader; MsgReader m_reader;
DisplayCoord m_dimensions; DisplayCoord m_dimensions;
@ -453,96 +468,63 @@ void RemoteUI::menu_show(ConstArrayView<DisplayLine> choices,
DisplayCoord anchor, Face fg, Face bg, DisplayCoord anchor, Face fg, Face bg,
MenuStyle style) MenuStyle style)
{ {
MsgWriter msg{m_send_buffer, MessageType::MenuShow}; send_message(MessageType::MenuShow, choices, anchor, fg, bg, style);
msg.write(choices);
msg.write(anchor);
msg.write(fg);
msg.write(bg);
msg.write(style);
m_socket_watcher.events() |= FdEvents::Write;
} }
void RemoteUI::menu_select(int selected) void RemoteUI::menu_select(int selected)
{ {
MsgWriter msg{m_send_buffer, MessageType::MenuSelect}; send_message(MessageType::MenuSelect, selected);
msg.write(selected);
m_socket_watcher.events() |= FdEvents::Write;
} }
void RemoteUI::menu_hide() void RemoteUI::menu_hide()
{ {
MsgWriter msg{m_send_buffer, MessageType::MenuHide}; send_message(MessageType::MenuHide);
m_socket_watcher.events() |= FdEvents::Write;
} }
void RemoteUI::info_show(StringView title, StringView content, void RemoteUI::info_show(StringView title, StringView content,
DisplayCoord anchor, Face face, DisplayCoord anchor, Face face,
InfoStyle style) InfoStyle style)
{ {
MsgWriter msg{m_send_buffer, MessageType::InfoShow}; send_message(MessageType::InfoShow, title, content, anchor, face, style);
msg.write(title);
msg.write(content);
msg.write(anchor);
msg.write(face);
msg.write(style);
m_socket_watcher.events() |= FdEvents::Write;
} }
void RemoteUI::info_hide() void RemoteUI::info_hide()
{ {
MsgWriter msg{m_send_buffer, MessageType::InfoHide}; send_message(MessageType::InfoHide);
m_socket_watcher.events() |= FdEvents::Write;
} }
void RemoteUI::draw(const DisplayBuffer& display_buffer, void RemoteUI::draw(const DisplayBuffer& display_buffer,
const Face& default_face, const Face& default_face,
const Face& padding_face) const Face& padding_face)
{ {
MsgWriter msg{m_send_buffer, MessageType::Draw}; send_message(MessageType::Draw, display_buffer, default_face, padding_face);
msg.write(display_buffer);
msg.write(default_face);
msg.write(padding_face);
m_socket_watcher.events() |= FdEvents::Write;
} }
void RemoteUI::draw_status(const DisplayLine& status_line, void RemoteUI::draw_status(const DisplayLine& status_line,
const DisplayLine& mode_line, const DisplayLine& mode_line,
const Face& default_face) const Face& default_face)
{ {
MsgWriter msg{m_send_buffer, MessageType::DrawStatus}; send_message(MessageType::DrawStatus, status_line, mode_line, default_face);
msg.write(status_line);
msg.write(mode_line);
msg.write(default_face);
m_socket_watcher.events() |= FdEvents::Write;
} }
void RemoteUI::set_cursor(CursorMode mode, DisplayCoord coord) void RemoteUI::set_cursor(CursorMode mode, DisplayCoord coord)
{ {
MsgWriter msg{m_send_buffer, MessageType::SetCursor}; send_message(MessageType::SetCursor, mode, coord);
msg.write(mode);
msg.write(coord);
m_socket_watcher.events() |= FdEvents::Write;
} }
void RemoteUI::refresh(bool force) void RemoteUI::refresh(bool force)
{ {
MsgWriter msg{m_send_buffer, MessageType::Refresh}; send_message(MessageType::Refresh, force);
msg.write(force);
m_socket_watcher.events() |= FdEvents::Write;
} }
void RemoteUI::set_ui_options(const Options& options) void RemoteUI::set_ui_options(const Options& options)
{ {
MsgWriter msg{m_send_buffer, MessageType::SetOptions}; send_message(MessageType::SetOptions, options);
msg.write(options);
m_socket_watcher.events() |= FdEvents::Write;
} }
void RemoteUI::exit(int status) void RemoteUI::exit(int status)
{ {
MsgWriter msg{m_send_buffer, MessageType::Exit}; send_message(MessageType::Exit, status);
msg.write(status);
m_socket_watcher.events() |= FdEvents::Write;
} }
String get_user_name() String get_user_name()
@ -595,12 +577,7 @@ RemoteClient::RemoteClient(StringView session, StringView name, std::unique_ptr<
{ {
MsgWriter msg{m_send_buffer, MessageType::Connect}; MsgWriter msg{m_send_buffer, MessageType::Connect};
msg.write(pid); msg.write(pid, name, init_command, init_coord, m_ui->dimensions(), env_vars);
msg.write(name);
msg.write(init_command);
msg.write(init_coord);
msg.write(m_ui->dimensions());
msg.write(env_vars);
} }
m_ui->set_on_key([this](Key key){ m_ui->set_on_key([this](Key key){