use a factory

This commit is contained in:
numzero 2026-10-25 13:55:18 +03:00
parent ad47769e46
commit 74df2d95a4
8 changed files with 49 additions and 32 deletions

View File

@ -1,7 +1,6 @@
include(impl.cmake) include(impl.cmake)
qt_add_executable(PROJECT-NAME qt_add_executable(PROJECT-NAME
src/api.cxx
src/main.cxx src/main.cxx
src/main_window.cxx src/main_window.cxx
src/main_window.ui src/main_window.ui

View File

@ -1,16 +0,0 @@
#include "api.hxx"
#include <stdexcept>
#include <utility>
namespace ffi {
extern "C" ICore* rt4_viewport_create(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height);
} // namespace ffi
BoxCore BoxCore::from_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height) {
if (!connection)
throw std::logic_error("attempt to use a null connection");
if (!window)
throw std::logic_error("attempt to use a null window");
return BoxCore{ffi::rt4_viewport_create(connection, window, width, height)};
}

View File

@ -10,7 +10,6 @@ class IBoxed {
friend struct BoxDeleter; friend struct BoxDeleter;
private: private:
~IBoxed() = delete;
virtual void destroy() = 0; virtual void destroy() = 0;
}; };
@ -44,8 +43,12 @@ public:
virtual void redraw(const RedrawArgs& args) = 0; virtual void redraw(const RedrawArgs& args) = 0;
}; };
class BoxCore : public Box<ICore> { class ICoreFactory : public IBoxed {
private:
virtual ICore* new_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height) const = 0;
public: public:
using Box<ICore>::Box; Box<ICore> from_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height) const {
static BoxCore from_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height); return Box<ICore>{new_xcb(connection, window, width, height)};
}
}; };

View File

@ -1,15 +1,31 @@
#include "main_window.hxx"
#include <QApplication> #include <QApplication>
int main(int argc, char* argv[]) { #include "api.hxx"
#include "main_window.hxx"
extern "C" int run(int argc, char* argv[], ICoreFactory* factory) {
// only X11 is supported so, use XCB unless overriden // only X11 is supported so, use XCB unless overriden
setenv("QT_QPA_PLATFORM", "xcb", 0); setenv("QT_QPA_PLATFORM", "xcb", 0);
QApplication app(argc, argv); QApplication app(argc, argv);
auto w = new PROJECTNAME; auto w = new PROJECTNAME(factory);
w->show(); w->show();
return app.exec(); return app.exec();
} }
extern "C" ICore* rt4_viewport_create(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height);
class CoreFactory : public ICoreFactory {
public:
void destroy() override {}
ICore* new_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height) const override {
return rt4_viewport_create(connection, window, width, height);
}
};
int main(int argc, char* argv[]) {
CoreFactory factory;
return run(argc, argv, &factory);
}

View File

@ -2,10 +2,12 @@
#include "ui_main_window.h" #include "ui_main_window.h"
PROJECTNAME::PROJECTNAME(QWidget* parent) PROJECTNAME::PROJECTNAME(const ICoreFactory* factory, QWidget* parent)
: QMainWindow(parent), : QMainWindow(parent),
m_ui(new Ui::MainWindow) { m_ui(new Ui::MainWindow),
factory(factory) {
m_ui->setupUi(this); m_ui->setupUi(this);
m_ui->viewport->setFactory(factory);
updateView(); updateView();
} }

View File

@ -3,6 +3,8 @@
#include <memory> #include <memory>
#include "api.hxx"
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
} }
@ -11,7 +13,7 @@ class PROJECTNAME : public QMainWindow {
Q_OBJECT Q_OBJECT
public: public:
explicit PROJECTNAME(QWidget* parent = nullptr); explicit PROJECTNAME(const ICoreFactory* factory, QWidget* parent = nullptr);
~PROJECTNAME() override; ~PROJECTNAME() override;
public slots: public slots:
@ -19,4 +21,5 @@ public slots:
private: private:
const std::unique_ptr<Ui::MainWindow> m_ui; const std::unique_ptr<Ui::MainWindow> m_ui;
const ICoreFactory* factory;
}; };

View File

@ -14,6 +14,11 @@ Viewport::Viewport(QWidget* parent, Qt::WindowFlags f)
Viewport::~Viewport() = default; Viewport::~Viewport() = default;
void Viewport::setFactory(const ICoreFactory* new_factory) {
factory = new_factory;
update();
}
void Viewport::setView(RedrawArgs new_args) { void Viewport::setView(RedrawArgs new_args) {
args = new_args; args = new_args;
update(); update();
@ -37,6 +42,8 @@ bool Viewport::event(QEvent* event) {
void Viewport::paintEvent(QPaintEvent* event) { void Viewport::paintEvent(QPaintEvent* event) {
if (!core) if (!core)
recreate(); recreate();
if (!core)
return;
core->redraw(args); core->redraw(args);
} }
@ -48,6 +55,9 @@ void Viewport::resizeEvent(QResizeEvent* event) {
} }
void Viewport::recreate() try { void Viewport::recreate() try {
if (!factory)
return;
auto* app = qobject_cast<QGuiApplication*>(QApplication::instance()); auto* app = qobject_cast<QGuiApplication*>(QApplication::instance());
if (!app) if (!app)
throw std::runtime_error("not a GUI application (WTF?)"); throw std::runtime_error("not a GUI application (WTF?)");
@ -59,11 +69,9 @@ void Viewport::recreate() try {
auto* xcb_connection = native->connection(); auto* xcb_connection = native->connection();
std::uint32_t x11_window = winId(); std::uint32_t x11_window = winId();
fprintf(stderr, "connection %p, window %#08x\n", xcb_connection, x11_window);
const QSize device_size = size() * devicePixelRatio(); const QSize device_size = size() * devicePixelRatio();
core.reset(); core.reset();
core = BoxCore::from_xcb(xcb_connection, x11_window, device_size.width(), device_size.height()); core = factory->from_xcb(xcb_connection, x11_window, device_size.width(), device_size.height());
} catch (const std::exception& e) { } catch (const std::exception& e) {
fprintf(stderr, "failed to recreate the viewport: %s", e.what()); fprintf(stderr, "failed to recreate the viewport: %s", e.what());
} }

View File

@ -12,6 +12,7 @@ public:
~Viewport() override; ~Viewport() override;
QPaintEngine* paintEngine() const override; QPaintEngine* paintEngine() const override;
void setFactory(const ICoreFactory* new_factory);
void setView(RedrawArgs new_args); void setView(RedrawArgs new_args);
protected: protected:
@ -20,7 +21,8 @@ protected:
void resizeEvent(QResizeEvent* event) override; void resizeEvent(QResizeEvent* event) override;
private: private:
BoxCore core; const ICoreFactory* factory = nullptr;
Box<ICore> core;
RedrawArgs args = {}; RedrawArgs args = {};
void recreate(); void recreate();