Use helper template struct in MsgReader
This makes reads for all types, including String, Vector, and Optional, use the same interface in MsgReader.
This commit is contained in:
parent
17c5e7aa5f
commit
99be3ff5e2
177
src/remote.cc
177
src/remote.cc
|
@ -150,6 +150,58 @@ private:
|
||||||
|
|
||||||
class MsgReader
|
class MsgReader
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
template<typename T>
|
||||||
|
struct Reader {
|
||||||
|
static T read(MsgReader& reader)
|
||||||
|
{
|
||||||
|
static_assert(std::is_trivially_copyable<T>::value, "");
|
||||||
|
T res;
|
||||||
|
reader.read(reinterpret_cast<char*>(&res), sizeof(T));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, MemoryDomain domain>
|
||||||
|
struct Reader<Vector<T,domain>> {
|
||||||
|
static Vector<T, domain> read(MsgReader& reader)
|
||||||
|
{
|
||||||
|
uint32_t size = Reader<uint32_t>::read(reader);
|
||||||
|
Vector<T,domain> res;
|
||||||
|
res.reserve(size);
|
||||||
|
while (size--)
|
||||||
|
res.push_back(std::move(Reader<T>::read(reader)));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Key, typename Value, MemoryDomain domain>
|
||||||
|
struct Reader<HashMap<Key, Value, domain>> {
|
||||||
|
static HashMap<Key, Value, domain> read(MsgReader& reader)
|
||||||
|
{
|
||||||
|
uint32_t size = Reader<uint32_t>::read(reader);
|
||||||
|
HashMap<Key, Value, domain> res;
|
||||||
|
res.reserve(size);
|
||||||
|
while (size--)
|
||||||
|
{
|
||||||
|
auto key = Reader<Key>::read(reader);
|
||||||
|
auto val = Reader<Value>::read(reader);
|
||||||
|
res.insert({std::move(key), std::move(val)});
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Reader<Optional<T>> {
|
||||||
|
static Optional<T> read(MsgReader& reader)
|
||||||
|
{
|
||||||
|
if (not Reader<bool>::read(reader))
|
||||||
|
return {};
|
||||||
|
return Reader<T>::read(reader);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void read_available(int sock)
|
void read_available(int sock)
|
||||||
{
|
{
|
||||||
|
@ -198,44 +250,7 @@ public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T read()
|
T read()
|
||||||
{
|
{
|
||||||
static_assert(std::is_trivially_copyable<T>::value, "");
|
return Reader<T>::read(*this);
|
||||||
T res;
|
|
||||||
read(reinterpret_cast<char*>(&res), sizeof(T));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
Vector<T> read_vector()
|
|
||||||
{
|
|
||||||
uint32_t size = read<uint32_t>();
|
|
||||||
Vector<T> res;
|
|
||||||
res.reserve(size);
|
|
||||||
while (size--)
|
|
||||||
res.push_back(read<T>());
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Key, typename Val, MemoryDomain domain>
|
|
||||||
HashMap<Key, Val, domain> read_hash_map()
|
|
||||||
{
|
|
||||||
uint32_t size = read<uint32_t>();
|
|
||||||
HashMap<Key, Val, domain> res;
|
|
||||||
res.reserve(size);
|
|
||||||
while (size--)
|
|
||||||
{
|
|
||||||
auto key = read<Key>();
|
|
||||||
auto val = read<Val>();
|
|
||||||
res.insert({std::move(key), std::move(val)});
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
Optional<T> read_optional()
|
|
||||||
{
|
|
||||||
if (not read<bool>())
|
|
||||||
return {};
|
|
||||||
return read<T>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
|
@ -262,52 +277,62 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
String MsgReader::read<String>()
|
struct MsgReader::Reader<String> {
|
||||||
{
|
static String read(MsgReader& reader)
|
||||||
ByteCount length = read<ByteCount>();
|
|
||||||
String res;
|
|
||||||
if (length > 0)
|
|
||||||
{
|
{
|
||||||
res.force_size((int)length);
|
ByteCount length = Reader<ByteCount>::read(reader);
|
||||||
read(&res[0_byte], (int)length);
|
String res;
|
||||||
|
if (length > 0)
|
||||||
|
{
|
||||||
|
res.force_size((int)length);
|
||||||
|
reader.read(&res[0_byte], (int)length);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
return res;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
Color MsgReader::read<Color>()
|
struct MsgReader::Reader<Color> {
|
||||||
{
|
static Color read(MsgReader& reader)
|
||||||
Color res;
|
|
||||||
res.color = read<Color::NamedColor>();
|
|
||||||
if (res.color == Color::RGB)
|
|
||||||
{
|
{
|
||||||
res.r = read<unsigned char>();
|
Color res;
|
||||||
res.g = read<unsigned char>();
|
res.color = Reader<Color::NamedColor>::read(reader);
|
||||||
res.b = read<unsigned char>();
|
if (res.color == Color::RGB)
|
||||||
|
{
|
||||||
|
res.r = Reader<unsigned char>::read(reader);
|
||||||
|
res.g = Reader<unsigned char>::read(reader);
|
||||||
|
res.b = Reader<unsigned char>::read(reader);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
return res;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
DisplayAtom MsgReader::read<DisplayAtom>()
|
struct MsgReader::Reader<DisplayAtom> {
|
||||||
{
|
static DisplayAtom read(MsgReader& reader)
|
||||||
String content = read<String>();
|
{
|
||||||
return {std::move(content), read<Face>()};
|
String content = Reader<String>::read(reader);
|
||||||
}
|
return {std::move(content), Reader<Face>::read(reader)};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
DisplayLine MsgReader::read<DisplayLine>()
|
struct MsgReader::Reader<DisplayLine> {
|
||||||
{
|
static DisplayLine read(MsgReader& reader)
|
||||||
return {read_vector<DisplayAtom>()};
|
{
|
||||||
}
|
return {Reader<Vector<DisplayAtom>>::read(reader)};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
DisplayBuffer MsgReader::read<DisplayBuffer>()
|
struct MsgReader::Reader<DisplayBuffer> {
|
||||||
{
|
static DisplayBuffer read(MsgReader& reader)
|
||||||
DisplayBuffer db;
|
{
|
||||||
db.lines() = read_vector<DisplayLine>();
|
DisplayBuffer db;
|
||||||
return db;
|
db.lines() = Reader<Vector<DisplayLine>>::read(reader);
|
||||||
}
|
return db;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class RemoteUI : public UserInterface
|
class RemoteUI : public UserInterface
|
||||||
|
@ -603,7 +628,7 @@ RemoteClient::RemoteClient(StringView session, StringView name, std::unique_ptr<
|
||||||
{
|
{
|
||||||
case MessageType::MenuShow:
|
case MessageType::MenuShow:
|
||||||
{
|
{
|
||||||
auto choices = reader.read_vector<DisplayLine>();
|
auto choices = reader.read<Vector<DisplayLine>>();
|
||||||
auto anchor = reader.read<DisplayCoord>();
|
auto anchor = reader.read<DisplayCoord>();
|
||||||
auto fg = reader.read<Face>();
|
auto fg = reader.read<Face>();
|
||||||
auto bg = reader.read<Face>();
|
auto bg = reader.read<Face>();
|
||||||
|
@ -657,7 +682,7 @@ RemoteClient::RemoteClient(StringView session, StringView name, std::unique_ptr<
|
||||||
m_ui->refresh(reader.read<bool>());
|
m_ui->refresh(reader.read<bool>());
|
||||||
break;
|
break;
|
||||||
case MessageType::SetOptions:
|
case MessageType::SetOptions:
|
||||||
m_ui->set_ui_options(reader.read_hash_map<String, String, MemoryDomain::Options>());
|
m_ui->set_ui_options(reader.read<HashMap<String, String, MemoryDomain::Options>>());
|
||||||
break;
|
break;
|
||||||
case MessageType::Exit:
|
case MessageType::Exit:
|
||||||
m_exit_status = reader.read<int>();
|
m_exit_status = reader.read<int>();
|
||||||
|
@ -723,9 +748,9 @@ private:
|
||||||
auto pid = m_reader.read<int>();
|
auto pid = m_reader.read<int>();
|
||||||
auto name = m_reader.read<String>();
|
auto name = m_reader.read<String>();
|
||||||
auto init_cmds = m_reader.read<String>();
|
auto init_cmds = m_reader.read<String>();
|
||||||
auto init_coord = m_reader.read_optional<BufferCoord>();
|
auto init_coord = m_reader.read<Optional<BufferCoord>>();
|
||||||
auto dimensions = m_reader.read<DisplayCoord>();
|
auto dimensions = m_reader.read<DisplayCoord>();
|
||||||
auto env_vars = m_reader.read_hash_map<String, String, MemoryDomain::EnvVars>();
|
auto env_vars = m_reader.read<HashMap<String, String, MemoryDomain::EnvVars>>();
|
||||||
auto* ui = new RemoteUI{sock, dimensions};
|
auto* ui = new RemoteUI{sock, dimensions};
|
||||||
ClientManager::instance().create_client(
|
ClientManager::instance().create_client(
|
||||||
std::unique_ptr<UserInterface>(ui), pid, std::move(name),
|
std::unique_ptr<UserInterface>(ui), pid, std::move(name),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user