Skip to content

Commit

Permalink
plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
zmoth committed Jun 11, 2023
1 parent 5465ddc commit 1a264fd
Show file tree
Hide file tree
Showing 15 changed files with 611 additions and 6 deletions.
13 changes: 7 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ option(QT_NODES_FORCE_TEST_COLOR "Force colorized unit test output" OFF)

enable_testing()

include(GNUInstallDirs)
if(QT_NODES_DEVELOPER_DEFAULTS)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
endif()

if(BUILD_DEBUG_POSTFIX_D)
Expand Down Expand Up @@ -89,6 +90,7 @@ set(CPP_SOURCE_FILES
src/StyleCollection.cpp
src/UndoCommands.cpp
src/locateNode.cpp
src/PluginsManager.cpp
)

set(HPP_HEADER_FILES
Expand Down Expand Up @@ -122,6 +124,8 @@ set(HPP_HEADER_FILES
include/QtNodes/internal/Serializable.hpp
include/QtNodes/internal/Style.hpp
include/QtNodes/internal/StyleCollection.hpp
include/QtNodes/internal/PluginInterface.hpp
include/QtNodes/internal/PluginsManager.hpp
src/ConnectionPainter.hpp
src/DefaultHorizontalNodeGeometry.hpp
src/DefaultVerticalNodeGeometry.hpp
Expand Down Expand Up @@ -240,16 +244,13 @@ endif()
# Installation
##

include(GNUInstallDirs)

set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/QtNodes)

install(TARGETS QtNodes
EXPORT QtNodesTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

install(DIRECTORY include/
Expand Down
2 changes: 2 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ add_subdirectory(dynamic_ports)

add_subdirectory(lock_nodes_and_connections)

add_subdirectory(plugins_load)

8 changes: 8 additions & 0 deletions examples/plugins_load/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
file(GLOB_RECURSE CPPS ./*.cpp)
file(GLOB_RECURSE HPPS ./*.hpp)

add_executable(plugins_load ${CPPS} ${HPPS})

target_link_libraries(plugins_load QtNodes)

add_subdirectory(plugins/plugin_text)
69 changes: 69 additions & 0 deletions examples/plugins_load/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <QApplication>
#include <QFileDialog>
#include <QMenuBar>
#include <QObject>
#include <QVBoxLayout>

#include <QtNodes/DataFlowGraphModel>
#include <QtNodes/DataFlowGraphicsScene>
#include <QtNodes/GraphicsView>
#include <QtNodes/NodeDelegateModelRegistry>
#include <QtNodes/PluginInterface>
#include <QtNodes/PluginsManager>

using QtNodes::ConnectionStyle;
using QtNodes::DataFlowGraphicsScene;
using QtNodes::DataFlowGraphModel;
using QtNodes::GraphicsView;
using QtNodes::NodeDelegateModelRegistry;
using QtNodes::PluginInterface;
using QtNodes::PluginsManager;

void loadPluginsFromFolder()
{
PluginsManager *pluginsManager = PluginsManager::instance();
std::shared_ptr<NodeDelegateModelRegistry> registry = pluginsManager->registry();

// load plugins
pluginsManager->loadPlugins(QDir::cleanPath(QCoreApplication::applicationDirPath()
+ QDir::separator() + "plugins"),
QStringList() << "*.node"
<< "*.data");

for (auto l : pluginsManager->loaders()) {
PluginInterface *plugin = qobject_cast<PluginInterface *>(l.second->instance());
if (!plugin)
continue;

plugin->registerDataModels(registry);
}
}

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QWidget mainWidget;

// Load plugins and register models
loadPluginsFromFolder();

QVBoxLayout *l = new QVBoxLayout(&mainWidget);

DataFlowGraphModel dataFlowGraphModel(PluginsManager::instance()->registry());

auto scene = new DataFlowGraphicsScene(dataFlowGraphModel, &mainWidget);

auto view = new GraphicsView(scene);
l->addWidget(view);
l->setContentsMargins(0, 0, 0, 0);
l->setSpacing(0);

QObject::connect(scene, &DataFlowGraphicsScene::sceneLoaded, view, &GraphicsView::centerScene);

mainWidget.setWindowTitle("Data Flow: Plugins Load");
mainWidget.resize(800, 600);
mainWidget.show();

return app.exec();
}
20 changes: 20 additions & 0 deletions examples/plugins_load/plugins/plugin_text/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/plugins")

file(GLOB_RECURSE CPPS ./*.cpp)
file(GLOB_RECURSE HPPS ./*.hpp)

add_library(plugin_text SHARED ${CPPS} ${HPPS})

target_link_libraries(plugin_text QtNodes)

target_compile_definitions(plugin_text PUBLIC NODE_EDITOR_SHARED)

set_target_properties(plugin_text PROPERTIES SUFFIX ".node")

add_custom_command(
TARGET plugin_text
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/plugins"
"${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/plugins"
COMMENT "[plugin_text] copy_directory ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/plugins/ ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/plugins/"
)
22 changes: 22 additions & 0 deletions examples/plugins_load/plugins/plugin_text/PluginDefinition.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "PluginDefinition.hpp"

#include "TextModel.hpp"

Plugin *Plugin::_this_plugin = nullptr;

Plugin::Plugin()
{
_this_plugin = this;
}

Plugin::~Plugin()
{
// TODO: Unregister all models here
}

void Plugin::registerDataModels(std::shared_ptr<QtNodes::NodeDelegateModelRegistry> &reg)
{
assert(reg);

reg->registerModel<TextModel>();
}
34 changes: 34 additions & 0 deletions examples/plugins_load/plugins/plugin_text/PluginDefinition.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include <QObject>
#include <QtNodes/NodeDelegateModelRegistry>
#include <QtNodes/PluginInterface>

// This needs to be the same as the name of your project file ${PROJECT_NAME}
#ifdef plugin_text_EXPORTS
#define DLL_EXPORT Q_DECL_EXPORT
#else
#define DLL_EXPORT Q_DECL_IMPORT
#endif

#define PLUGIN_NAME "Text"

class DLL_EXPORT Plugin
: public QObject
, public QtNodes::PluginInterface
{
Q_OBJECT
Q_INTERFACES(QtNodes::PluginInterface)
Q_PLUGIN_METADATA(IID PLUGIN_NAME)

public:
Plugin();
~Plugin();

QString name() const override { return PLUGIN_NAME; };

void registerDataModels(std::shared_ptr<QtNodes::NodeDelegateModelRegistry> &reg) override;

private:
static Plugin *_this_plugin;
};
25 changes: 25 additions & 0 deletions examples/plugins_load/plugins/plugin_text/TextData.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <QtNodes/NodeData>

using QtNodes::NodeData;
using QtNodes::NodeDataType;

/// The class can potentially incapsulate any user data which
/// need to be transferred within the Node Editor graph
class TextData : public NodeData
{
public:
TextData() {}

TextData(QString const &text)
: _text(text)
{}

NodeDataType type() const override { return NodeDataType{"text", "Text"}; }

QString text() const { return _text; }

private:
QString _text;
};
66 changes: 66 additions & 0 deletions examples/plugins_load/plugins/plugin_text/TextModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "TextModel.hpp"

#include <QtWidgets/QTextEdit>

TextModel::TextModel() {}

unsigned int TextModel::nPorts(PortType portType) const
{
unsigned int result = 1;

switch (portType) {
case PortType::In:
result = 1;
break;

case PortType::Out:
result = 1;

default:
break;
}

return result;
}

void TextModel::onTextEdited()
{
Q_EMIT dataUpdated(0);
}

NodeDataType TextModel::dataType(PortType, PortIndex) const
{
return TextData().type();
}

std::shared_ptr<NodeData> TextModel::outData(PortIndex const portIndex)
{
Q_UNUSED(portIndex);
return std::make_shared<TextData>(_textEdit->toPlainText());
}

QWidget *TextModel::embeddedWidget()
{
if (!_textEdit) {
_textEdit = new QTextEdit();

connect(_textEdit, &QTextEdit::textChanged, this, &TextModel::onTextEdited);
}

return _textEdit;
}

void TextModel::setInData(std::shared_ptr<NodeData> data, PortIndex const)
{
auto textData = std::dynamic_pointer_cast<TextData>(data);

QString inputText;

if (textData) {
inputText = textData->text();
} else {
inputText = "";
}

_textEdit->setText(inputText);
}
55 changes: 55 additions & 0 deletions examples/plugins_load/plugins/plugin_text/TextModel.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once

#include <QtCore/QObject>

#include "TextData.hpp"

#include <QtNodes/NodeDelegateModel>

#include <iostream>

using QtNodes::NodeData;
using QtNodes::NodeDelegateModel;
using QtNodes::PortIndex;
using QtNodes::PortType;

class QTextEdit;

/// The model dictates the number of inputs and outputs for the Node.
/// In this example it has no logic.
class TextModel : public NodeDelegateModel
{
Q_OBJECT

public:
TextModel();

public:
QString caption() const override { return QString("Text"); }

bool captionVisible() const override { return true; }

static QString Name() { return QString("Text"); }

QString name() const override { return TextModel::Name(); }

public:
unsigned int nPorts(PortType portType) const override;

NodeDataType dataType(PortType portType, PortIndex portIndex) const override;

std::shared_ptr<NodeData> outData(PortIndex const portIndex) override;

void setInData(std::shared_ptr<NodeData>, PortIndex const) override;

QWidget *embeddedWidget() override;

bool resizable() const override { return true; }

private Q_SLOTS:

void onTextEdited();

private:
QTextEdit *_textEdit = nullptr;
};
1 change: 1 addition & 0 deletions include/QtNodes/PluginInterface
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "internal/PluginInterface.hpp"
1 change: 1 addition & 0 deletions include/QtNodes/PluginsManager
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "internal/PluginsManager.hpp"
21 changes: 21 additions & 0 deletions include/QtNodes/internal/PluginInterface.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include <QtPlugin>

namespace QtNodes {

class NodeDelegateModelRegistry;

class PluginInterface
{
public:
virtual ~PluginInterface() = default;

virtual QString name() const = 0;

virtual void registerDataModels(std::shared_ptr<QtNodes::NodeDelegateModelRegistry> &reg) = 0;
};

} // namespace QtNodes

Q_DECLARE_INTERFACE(QtNodes::PluginInterface, "QtNodes.PluginInterface/1.0")
Loading

0 comments on commit 1a264fd

Please sign in to comment.