io/ipchandler: add prop get

This commit is contained in:
outfoxxed 2025-01-26 03:57:07 -08:00
parent 9417d6fa57
commit 4f2610dece
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
10 changed files with 262 additions and 31 deletions

View file

@ -21,16 +21,17 @@ namespace qs::io::ipc::comm {
struct NoCurrentGeneration: std::monostate {};
struct TargetNotFound: std::monostate {};
struct FunctionNotFound: std::monostate {};
struct EntryNotFound: std::monostate {};
using QueryResponse = std::variant<
std::monostate,
NoCurrentGeneration,
TargetNotFound,
FunctionNotFound,
EntryNotFound,
QVector<WireTargetDefinition>,
WireTargetDefinition,
WireFunctionDefinition>;
WireFunctionDefinition,
WirePropertyDefinition>;
void QueryMetadataCommand::exec(qs::ipc::IpcServerConnection* conn) const {
auto resp = conn->responseStream<QueryResponse>();
@ -44,16 +45,24 @@ void QueryMetadataCommand::exec(qs::ipc::IpcServerConnection* conn) const {
auto* handler = registry->findHandler(this->target);
if (handler) {
if (this->function.isEmpty()) {
if (this->name.isEmpty()) {
resp << handler->wireDef();
} else {
auto* func = handler->findFunction(this->function);
auto* func = handler->findFunction(this->name);
if (func) {
resp << func->wireDef();
} else {
resp << FunctionNotFound();
return;
}
auto* prop = handler->findProperty(this->name);
if (prop) {
resp << prop->wireDef();
return;
}
resp << EntryNotFound();
}
} else {
resp << TargetNotFound();
@ -64,8 +73,8 @@ void QueryMetadataCommand::exec(qs::ipc::IpcServerConnection* conn) const {
}
}
int queryMetadata(IpcClient* client, const QString& target, const QString& function) {
client->sendMessage(IpcCommand(QueryMetadataCommand {.target = target, .function = function}));
int queryMetadata(IpcClient* client, const QString& target, const QString& name) {
client->sendMessage(IpcCommand(QueryMetadataCommand {.target = target, .name = name}));
QueryResponse slot;
if (!client->waitForResponse(slot)) return -1;
@ -82,9 +91,11 @@ int queryMetadata(IpcClient* client, const QString& target, const QString& funct
qCInfo(logBare).noquote() << std::get<WireTargetDefinition>(slot).toString();
} else if (std::holds_alternative<WireFunctionDefinition>(slot)) {
qCInfo(logBare).noquote() << std::get<WireFunctionDefinition>(slot).toString();
} else if (std::holds_alternative<WirePropertyDefinition>(slot)) {
qCInfo(logBare).noquote() << std::get<WirePropertyDefinition>(slot).toString();
} else if (std::holds_alternative<TargetNotFound>(slot)) {
qCCritical(logBare) << "Target not found.";
} else if (std::holds_alternative<FunctionNotFound>(slot)) {
} else if (std::holds_alternative<EntryNotFound>(slot)) {
qCCritical(logBare) << "Function not found.";
} else if (std::holds_alternative<NoCurrentGeneration>(slot)) {
qCCritical(logBare) << "Not ready to accept queries yet.";
@ -119,7 +130,7 @@ using StringCallResponse = std::variant<
std::monostate,
NoCurrentGeneration,
TargetNotFound,
FunctionNotFound,
EntryNotFound,
ArgParseFailed,
Completed>;
@ -137,7 +148,7 @@ void StringCallCommand::exec(qs::ipc::IpcServerConnection* conn) const {
auto* func = handler->findFunction(this->function);
if (!func) {
resp << FunctionNotFound();
resp << EntryNotFound();
return;
}
@ -223,7 +234,7 @@ int callFunction(
qCCritical(logBare).noquote() << "Function definition:" << error.definition.toString();
} else if (std::holds_alternative<TargetNotFound>(slot)) {
qCCritical(logBare) << "Target not found.";
} else if (std::holds_alternative<FunctionNotFound>(slot)) {
} else if (std::holds_alternative<EntryNotFound>(slot)) {
qCCritical(logBare) << "Function not found.";
} else if (std::holds_alternative<NoCurrentGeneration>(slot)) {
qCCritical(logBare) << "Not ready to accept queries yet.";
@ -233,4 +244,74 @@ int callFunction(
return -1;
}
struct PropertyValue {
QString value;
};
DEFINE_SIMPLE_DATASTREAM_OPS(PropertyValue, data.value);
using StringPropReadResponse =
std::variant<std::monostate, NoCurrentGeneration, TargetNotFound, EntryNotFound, PropertyValue>;
void StringPropReadCommand::exec(qs::ipc::IpcServerConnection* conn) const {
auto resp = conn->responseStream<StringPropReadResponse>();
if (auto* generation = EngineGeneration::currentGeneration()) {
auto* registry = IpcHandlerRegistry::forGeneration(generation);
auto* handler = registry->findHandler(this->target);
if (!handler) {
resp << TargetNotFound();
return;
}
auto* prop = handler->findProperty(this->property);
if (!prop) {
resp << EntryNotFound();
return;
}
auto slot = IpcTypeSlot(prop->type);
prop->read(handler, slot);
resp << PropertyValue {
.value = slot.type()->toString(slot.get()),
};
} else {
conn->respond(StringCallResponse(NoCurrentGeneration()));
}
}
int getProperty(IpcClient* client, const QString& target, const QString& property) {
if (target.isEmpty()) {
qCCritical(logBare) << "Target required to send message.";
return -1;
} else if (property.isEmpty()) {
qCCritical(logBare) << "Property required to send message.";
return -1;
}
client->sendMessage(IpcCommand(StringPropReadCommand {.target = target, .property = property}));
StringPropReadResponse slot;
if (!client->waitForResponse(slot)) return -1;
if (std::holds_alternative<PropertyValue>(slot)) {
auto& result = std::get<PropertyValue>(slot);
QTextStream(stdout) << result.value << Qt::endl;
return 0;
} else if (std::holds_alternative<TargetNotFound>(slot)) {
qCCritical(logBare) << "Target not found.";
} else if (std::holds_alternative<EntryNotFound>(slot)) {
qCCritical(logBare) << "Property not found.";
} else if (std::holds_alternative<NoCurrentGeneration>(slot)) {
qCCritical(logBare) << "Not ready to accept queries yet.";
} else {
qCCritical(logIpc) << "Received invalid IPC response from" << client;
}
return -1;
}
} // namespace qs::io::ipc::comm