nodeeditor 源码阅读 - NodeDelegateModelRegistry节点代理模型注册器

目录

NodeDelegateModelRegistry.hpp 

NodeDelegateModelRegistry.cpp


NodeDelegateModelRegistry.hpp 

#include "Export.hpp"
#include "NodeData.hpp"
#include "NodeDelegateModel.hpp"
#include "QStringStdHash.hpp"

#include <QtCore/QString>

#include <functional>
#include <memory>
#include <set>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>

namespace QtNodes {

/// 用于注册和管理节点委托模型的类
class NODE_EDITOR_PUBLIC NodeDelegateModelRegistry
{
public:
    using RegistryItemPtr = std::unique_ptr<NodeDelegateModel>; // 存储节点委托模型的智能指针类型
    using RegistryItemCreator = std::function<RegistryItemPtr>(); // 创建节点委托模型的函数类型
    using RegisteredModelCreatorsMap = std::unordered_map<QString, RegistryItemCreator>; // 注册的节点模型创建器的映射
    using RegisteredModelsCategoryMap = std::unordered_map<QString, QString>; // 节点模型和其所属类别的映射
    using CategoriesSet = std::set<QString>; // 存储节点模型类别的集合

    NodeDelegateModelRegistry() = default; // 默认构造函数
    ~NodeDelegateModelRegistry() = default; // 析构函数

    NodeDelegateModelRegistry(NodeDelegateModelRegistry const &) = delete;
    NodeDelegateModelRegistry(NodeDelegateModelRegistry &&) = default;

    NodeDelegateModelRegistry &operator=(NodeDelegateModelRegistry const &) = delete;

    NodeDelegateModelRegistry &operator=(NodeDelegateModelRegistry &&) = default;

public:
    // 注册节点模型的模板函数,通过创建节点模型的函数和所属类别
    template<typename ModelType>
    void registerModel(RegistryItemCreator creator, QString const &category = "Nodes")
    {
        QString const name = computeName<ModelType>(HasStaticMethodName<ModelType>{}, creator);
        if (!_registeredItemCreators.count(name)) {
            _registeredItemCreators[name] = std::move(creator);
            _categories.insert(category);
            _registeredModelsCategory[name] = category;
        }
    }

    // 注册节点模型的模板函数,通过节点模型的类型和所属类别
    template<typename ModelType>
    void registerModel(QString const &category = "Nodes")
    {
        RegistryItemCreator creator = []() { return std::make_unique<ModelType>(); };
        registerModel<ModelType>(std::move(creator), category);
    }

    // 创建指定名称的节点委托模型
    std::unique_ptr<NodeDelegateModel> create(QString const &modelName);

    // 获取已注册节点模型创建器的映射
    RegisteredModelCreatorsMap const &registeredModelCreators() const;

    // 获取已注册节点模型和其所属类别的映射
    RegisteredModelsCategoryMap const &registeredModelsCategoryAssociation() const;

    // 获取已注册的节点模型类别集合
    CategoriesSet const &categories() const;

private:
    RegisteredModelsCategoryMap _registeredModelsCategory; // 存储已注册节点模型和其所属类别的映射

    CategoriesSet _categories; // 存储节点模型类别的集合

    RegisteredModelCreatorsMap _registeredItemCreators; // 存储已注册节点模型创建器的映射

private:
    // 如果已注册的 ModelType 类具有静态成员方法 `static QString Name();`,则使用该方法,否则使用非静态方法 `virtual QString name() const;`
    template<typename T, typename = void>
    struct HasStaticMethodName : std::false_type
    {};

    template<typename T>
    struct HasStaticMethodName<
        T,
        typename std::enable_if<std::is_same<decltype(T::Name()), QString>::value>::type>
        : std::true_type
    {};

    // 根据 ModelType 类型和创建器获取节点模型的名称
    template<typename ModelType>
    static QString computeName(std::true_type, RegistryItemCreator const &)
    {
        return ModelType::Name();
    }

    template<typename ModelType>
    static QString computeName(std::false_type, RegistryItemCreator const &creator)
    {
        return creator()->name();
    }

    // 用于解包 std::unique_ptr 类型并获取模型类型
    template<typename T>
    struct UnwrapUniquePtr
    {
        // 断言总是触发,但是编译器不知道这一点:
        static_assert(!std::is_same<T, T>::value,
                      "ModelCreator 必须返回 std::unique_ptr<T>,其中 T 继承自 NodeDelegateModel");
    };

    template<typename T>
    struct UnwrapUniquePtr<std::unique_ptr<T>>
    {
        static_assert(std::is_base_of<NodeDelegate

NodeDelegateModelRegistry.cpp

待续。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值