mirror of
https://github.com/logos-co/logos-test-modules.git
synced 2026-08-27 10:11:12 +00:00
probe(qt-consumer): throwaway module proving interface_dependencies works on a Qt api-style module
test-qtbind-probe-module is type: core with NO `interface` key, so the backend picks apiStyle=qt. It declares interface_dependencies on full_api (a .lidl copy of the shared contract) plus concrete dependencies on both providers, forwards echoInt, and re-emits intEvent. Phase-1 throwaway: delete once the real Qt-typed proxy lands. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
44c0beca9d
commit
432812a2cc
@@ -173,6 +173,28 @@
|
||||
'';
|
||||
};
|
||||
|
||||
# THROWAWAY PROBE (feat/qt-consumer-proxy phase 1): a `type: core` module
|
||||
# with NO `interface` key — so the backend picks apiStyle=qt — that binds
|
||||
# the full_api interface at runtime. Answers whether
|
||||
# interface_dependencies works on a non-universal module and whether the
|
||||
# generated wrapper is genuinely Qt-typed.
|
||||
qtbindProbe = mkModule {
|
||||
src = ./test-qtbind-probe-module;
|
||||
configFile = ./test-qtbind-probe-module/metadata.json;
|
||||
flakeInputs = {
|
||||
test_fullapi_cpp = fullapiCpp;
|
||||
test_fullapi_rust = fullapiRust;
|
||||
};
|
||||
preConfigure = ''
|
||||
echo "Running logos-cpp-generator --provider-header for test_qtbind_probe..."
|
||||
logos-cpp-generator --provider-header "$(pwd)/src/test_qtbind_probe_impl.h" --output-dir "$(pwd)"
|
||||
if [ ! -f logos_provider_dispatch.cpp ]; then
|
||||
echo "ERROR: logos_provider_dispatch.cpp was not generated" >&2
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
# Universal QML+Qt UI plugin consuming full_api via an interface
|
||||
# dependency. mkQmlModule delegates to the same buildCppPlugin pipeline
|
||||
# (universal codegen + interface deps) and bundles the QML view.
|
||||
@@ -224,6 +246,7 @@
|
||||
test_fullapi_ext_cpp = fullapiExtCpp.packages.${system};
|
||||
test_fullapi_proxy = fullapiProxy.packages.${system};
|
||||
test_fullapi_proxy_rust = fullapiProxyRust.packages.${system};
|
||||
test_qtbind_probe = qtbindProbe.packages.${system};
|
||||
test_fullapi_ui = fullapiUi.packages.${system};
|
||||
test_fullapi_ui_qml = fullapiUiQml.packages.${system};
|
||||
test_context_module_cpp = contextCpp.packages.${system};
|
||||
@@ -248,6 +271,7 @@
|
||||
test_fullapi_ext_cpp = fullapiExtCpp.packages.${system}.default;
|
||||
test_fullapi_proxy = fullapiProxy.packages.${system}.default;
|
||||
test_fullapi_proxy_rust = fullapiProxyRust.packages.${system}.default;
|
||||
test_qtbind_probe = qtbindProbe.packages.${system}.default;
|
||||
test_fullapi_ui = fullapiUi.packages.${system}.default;
|
||||
test_fullapi_ui_qml = fullapiUiQml.packages.${system}.default;
|
||||
test_context_module_cpp = contextCpp.packages.${system}.default;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(TestQtbindProbePlugin LANGUAGES CXX)
|
||||
|
||||
if(DEFINED ENV{LOGOS_MODULE_BUILDER_ROOT})
|
||||
include($ENV{LOGOS_MODULE_BUILDER_ROOT}/cmake/LogosModule.cmake)
|
||||
elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/LogosModule.cmake")
|
||||
include(cmake/LogosModule.cmake)
|
||||
else()
|
||||
message(FATAL_ERROR "LogosModule.cmake not found")
|
||||
endif()
|
||||
|
||||
logos_module(
|
||||
NAME test_qtbind_probe
|
||||
PROVIDER_HEADER src/test_qtbind_probe_impl.h
|
||||
SOURCES
|
||||
src/test_qtbind_probe_loader.h
|
||||
src/test_qtbind_probe_impl.h
|
||||
src/test_qtbind_probe_impl.cpp
|
||||
logos_provider_dispatch.cpp
|
||||
)
|
||||
@@ -0,0 +1,54 @@
|
||||
module full_api {
|
||||
version "1.0.0"
|
||||
description "Full API contract: every supported method parameter/return type and event parameter type. Bound at runtime to test_fullapi_cpp, test_fullapi_rust, or either proxy."
|
||||
|
||||
method whoAmI() -> tstr
|
||||
method echoString(v: tstr) -> tstr
|
||||
method echoBytes(v: bstr) -> bstr
|
||||
method echoInt(v: int) -> int
|
||||
method echoUint(v: uint) -> uint
|
||||
method echoDouble(v: float64) -> float64
|
||||
method echoBool(v: bool) -> bool
|
||||
method echoAny(v: any) -> any
|
||||
method echoStringList(v: [tstr]) -> [tstr]
|
||||
method echoIntList(v: [int]) -> [int]
|
||||
method echoUintList(v: [uint]) -> [uint]
|
||||
method echoDoubleList(v: [float64]) -> [float64]
|
||||
method echoBoolList(v: [bool]) -> [bool]
|
||||
method echoList(v: [any]) -> [any]
|
||||
method echoMap(v: {tstr: any}) -> {tstr: any}
|
||||
method doVoid() -> void
|
||||
method echoTriple(i: int, s: tstr, b: bstr) -> tstr
|
||||
method makeResult(ok: bool) -> result
|
||||
method fireStringEvent(v: tstr) -> bool
|
||||
method fireBytesEvent(v: bstr) -> bool
|
||||
method fireIntEvent(v: int) -> bool
|
||||
method fireUintEvent(v: uint) -> bool
|
||||
method fireDoubleEvent(v: float64) -> bool
|
||||
method fireBoolEvent(v: bool) -> bool
|
||||
method fireAnyEvent(v: any) -> bool
|
||||
method fireStringListEvent(v: [tstr]) -> bool
|
||||
method fireIntListEvent(v: [int]) -> bool
|
||||
method fireUintListEvent(v: [uint]) -> bool
|
||||
method fireDoubleListEvent(v: [float64]) -> bool
|
||||
method fireBoolListEvent(v: [bool]) -> bool
|
||||
method fireListEvent(v: [any]) -> bool
|
||||
method fireMapEvent(v: {tstr: any}) -> bool
|
||||
method fireTripleEvent(i: int, s: tstr, b: bstr) -> bool
|
||||
|
||||
event stringEvent(v: tstr)
|
||||
event bytesEvent(v: bstr)
|
||||
event intEvent(v: int)
|
||||
event uintEvent(v: uint)
|
||||
event doubleEvent(v: float64)
|
||||
event boolEvent(v: bool)
|
||||
event anyEvent(v: any)
|
||||
event stringListEvent(v: [tstr])
|
||||
event intListEvent(v: [int])
|
||||
event uintListEvent(v: [uint])
|
||||
event doubleListEvent(v: [float64])
|
||||
event boolListEvent(v: [bool])
|
||||
event listEvent(v: [any])
|
||||
event mapEvent(v: {tstr: any})
|
||||
event tripleEvent(i: int, s: tstr, b: bstr)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "test_qtbind_probe",
|
||||
"version": "1.0.0",
|
||||
"type": "core",
|
||||
"category": "testing",
|
||||
"description": "THROWAWAY PROBE: smallest possible non-universal (Qt api-style) module that binds the full_api interface at runtime. Exists to answer whether interface_dependencies works on a module with no `interface` key, and whether the generated wrapper really is Qt-typed.",
|
||||
"main": "test_qtbind_probe_plugin",
|
||||
"dependencies": ["test_fullapi_cpp", "test_fullapi_rust"],
|
||||
"interface_dependencies": [
|
||||
{ "name": "full_api", "file": "interfaces/full_api.lidl" }
|
||||
],
|
||||
|
||||
"nix": {
|
||||
"packages": {
|
||||
"build": [],
|
||||
"runtime": []
|
||||
},
|
||||
"external_libraries": [],
|
||||
"cmake": {
|
||||
"find_packages": [],
|
||||
"extra_sources": []
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "test_qtbind_probe_impl.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
// Generated at build time. Because metadata.json declares
|
||||
// `interface_dependencies`, this umbrella carries a
|
||||
// `FullApi bind_full_api(const QString&)` factory. Because the module has NO
|
||||
// `interface` key (type: core), the backend picks apiStyle=qt, so `FullApi` is
|
||||
// the Qt-TYPED wrapper (QString / QByteArray / qlonglong / qulonglong /
|
||||
// QVariantList / QVariantMap / LogosResult).
|
||||
#include "logos_sdk.h"
|
||||
|
||||
void TestQtbindProbeImpl::onInit(LogosAPI* api)
|
||||
{
|
||||
m_api = api;
|
||||
delete m_logos;
|
||||
m_logos = new LogosModules(api);
|
||||
qDebug() << "TestQtbindProbeImpl: initialized (qt api style, bound interface)";
|
||||
}
|
||||
|
||||
bool TestQtbindProbeImpl::useProvider(const QString& moduleName)
|
||||
{
|
||||
if (!m_logos) return false;
|
||||
m_providerName = moduleName;
|
||||
delete m_target;
|
||||
// The whole point of the probe: a runtime-bound Qt-typed interface wrapper.
|
||||
m_target = new FullApi(m_logos->bind_full_api(moduleName));
|
||||
|
||||
// ONE event: subscribe through the generated typed accessor.
|
||||
m_target->onIntEvent([this](qlonglong v) {
|
||||
m_lastEvent = QString("intEvent:%1").arg(v);
|
||||
qDebug() << "TestQtbindProbeImpl: got intEvent" << v;
|
||||
emitEvent("intEvent", QVariantList() << QVariant::fromValue(v));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
QString TestQtbindProbeImpl::currentProvider()
|
||||
{
|
||||
return m_providerName;
|
||||
}
|
||||
|
||||
qlonglong TestQtbindProbeImpl::echoInt(qlonglong v)
|
||||
{
|
||||
if (!m_target) return 0;
|
||||
return m_target->echoInt(v);
|
||||
}
|
||||
|
||||
bool TestQtbindProbeImpl::fireIntEvent(qlonglong v)
|
||||
{
|
||||
if (!m_target) return false;
|
||||
return m_target->fireIntEvent(v);
|
||||
}
|
||||
|
||||
QString TestQtbindProbeImpl::getLastEvent()
|
||||
{
|
||||
return m_lastEvent;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef TEST_QTBIND_PROBE_IMPL_H
|
||||
#define TEST_QTBIND_PROBE_IMPL_H
|
||||
|
||||
#include "logos_provider_object.h"
|
||||
#include "logos_api.h"
|
||||
#include "logos_api_client.h"
|
||||
#include "logos_sdk.h"
|
||||
#include "logos_types.h"
|
||||
|
||||
// THROWAWAY PROBE. Binds the `full_api` interface at runtime through the
|
||||
// generated Qt-typed wrapper (`modules().bind_full_api(name)`), forwards ONE
|
||||
// method and subscribes to ONE event. Nothing else.
|
||||
class TestQtbindProbeImpl : public LogosProviderBase
|
||||
{
|
||||
LOGOS_PROVIDER(TestQtbindProbeImpl, "test_qtbind_probe", "1.0.0")
|
||||
|
||||
protected:
|
||||
void onInit(LogosAPI* api) override;
|
||||
|
||||
public:
|
||||
// Bind the interface to a concrete provider module name at runtime.
|
||||
LOGOS_METHOD bool useProvider(const QString& moduleName);
|
||||
LOGOS_METHOD QString currentProvider();
|
||||
|
||||
// The one forwarded method.
|
||||
LOGOS_METHOD qlonglong echoInt(qlonglong v);
|
||||
|
||||
// The one event: subscribe to the target's `intEvent`, record what arrived.
|
||||
LOGOS_METHOD bool fireIntEvent(qlonglong v);
|
||||
LOGOS_METHOD QString getLastEvent();
|
||||
|
||||
private:
|
||||
LogosAPI* m_api = nullptr;
|
||||
LogosModules* m_logos = nullptr;
|
||||
FullApi* m_target = nullptr;
|
||||
QString m_providerName;
|
||||
QString m_lastEvent;
|
||||
};
|
||||
|
||||
#endif // TEST_QTBIND_PROBE_IMPL_H
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef TEST_QTBIND_PROBE_LOADER_H
|
||||
#define TEST_QTBIND_PROBE_LOADER_H
|
||||
|
||||
#include <QObject>
|
||||
#include "interface.h"
|
||||
#include "logos_provider_object.h"
|
||||
#include "test_qtbind_probe_impl.h"
|
||||
|
||||
class TestQtbindProbeLoader : public QObject, public PluginInterface, public LogosProviderPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID LogosProviderPlugin_iid FILE "metadata.json")
|
||||
Q_INTERFACES(PluginInterface LogosProviderPlugin)
|
||||
|
||||
public:
|
||||
QString name() const override { return "test_qtbind_probe"; }
|
||||
QString version() const override { return "1.0.0"; }
|
||||
LogosProviderObject* createProviderObject() override { return new TestQtbindProbeImpl(); }
|
||||
};
|
||||
|
||||
#endif // TEST_QTBIND_PROBE_LOADER_H
|
||||
Reference in New Issue
Block a user