一、通过插件创建自定义类型的节点
在类Plugindemo 中添加一行
static kanzi::PropertyTypeEditorInfoSharedPtr makeEditorInfo();
之后,整体代码如下
class PLUGINDEMO_API Plugindemo : public kanzi::Node3D
{
public:
KZ_METACLASS_BEGIN(Plugindemo, Node3D, "qweasdzxc")
KZ_METACLASS_END()
static kanzi::PropertyTypeEditorInfoSharedPtr makeEditorInfo();
// Creates a Plugindemo.
static PlugindemoSharedPtr create(kanzi::Domain* domain, kanzi::string_view name);
protected:
// Constructor.
explicit Plugindemo(kanzi::Domain* domain, kanzi::string_view name):
kanzi::Node3D(domain, name)
{
}
// Initializes the created Kanzi Engine plugin.
// Kanzi node classes typically have a static create() member function, which creates the instance of a node,
// initializes it, and returns a shared pointer to the instance. To initialize the instance, the initialize()
// function is called on it. You must initialize a node in the initialize() function, not in the constructor.
void initialize();
};
其中
KZ_METACLASS_BEGIN(Plugindemo, Node3D, "qweasdzxc")
KZ_METACLASS_END()
是一个整体,展开之后是这样的
#define KZ_METACLASS_BEGIN(thisClass, baseClass, name)\
virtual const ::kanzi::Metaclass* getDynamicMetaclass() const KZ_OVERRIDE\
{\
return getStaticMetaclass();\
}\
static const ::kanzi::Metaclass* getStaticMetaclass()\
{\
typedef thisClass ThisClass;\
typedef baseClass BaseClass;\
KZ_STATIC_ASSERT((::kanzi::is_base_of<BaseClass, ThisClass>::value), "Metaclass: incorrect base provided.");\
static ::kanzi::MetaclassImpl<ThisClass> metaclass(BaseClass::getStaticMetaclass(), kzMakeFixedString(name));\
if (!metaclass.isSealed())\
{\
/* Ensure that the base metaclass is initialized in case of metadata system restart.*/\
BaseClass::getStaticMetaclass();
#define KZ_METACLASS_END()\
metaclass.setEditorInfo(::kanzi::PropertyTypeEditorInfoSharedPtr(makeEditorInfo()));\
metaclass.seal();\
}\
return &metaclass;\
}
也就是说,这两个宏的作用实质就是两个成员函数,其中的getStaticMetaclass的作用就是创建一个元对象并返回
函数makeEditorInfo的实现如下
PropertyTypeEditorInfoSharedPtr Plugindemo::makeEditorInfo()
{
return PropertyTypeEditorInfoSharedPtr(
KZ_PROPERTY_TYPE_EDITOR_INFO(
[]() -> PropertyTypeEditorInfo::AttributeDictionary {
PropertyTypeEditorInfo::AttributeDictionary dict;
//设置您要在 Kanzi Studio 中为您的节点使用的名称。
dict.displayName = "My Node";
//设置您要在 Kanzi Studio 创建 (Create) 菜单中使用的工具提示。
dict.tooltip = "This example custom node uses custom properties.";
//添加水平对齐 (Horizontal Alignment) 和垂直对齐 (Vertical Alignment) 属性到该节点。
dict["AutomaticallyAddedProperties"] = "Node.HorizontalAlignment, Node.VerticalAlignment";
//添加状态机 (State Manager) 属性作为常用属性,用户可以通过点击该属性名旁的 进行添加。
dict["FrequentlyAddedProperties"] = "Node.StateManager";
//让用户使用添加属性 (Add Property) 上下文菜单或添加属性 (Add Properties) 窗口的上下文选项卡添加焦点范围 (Focus Scope) 属性。
dict["ContextProperties"] = "FocusManager.FocusScope";
return dict;
}()));
}
其中的宏KZ_PROPERTY_TYPE_EDITOR_INFO的定义如下
#define KZ_PROPERTY_TYPE_EDITOR_INFO(x) new kanzi::PropertyTypeEditorInfo(x)
所以,上述代码中的x其实是个lambda表达式,该表达式的结果是一个已经设置好各个属性的AttributeDictionary对象,将该AttributeDictionary对象传入PropertyTypeEditorInfo的构造函数
PropertyTypeEditorInfo的构造函数如下
explicit PropertyTypeEditorInfo()
{
}
explicit PropertyTypeEditorInfo(AttributeDictionary dictionary) : attributes(dictionary)
{
}
可将传入的参数用来初始化其成员attributes,
上述过程结束后,一个PropertyTypeEditorInfo对象就创建好了,然后将这个PropertyTypeEditorInfo对象传入对应的智能指针,然后返回该智能指针
编译插件模块,然后在Kanzi studio中更新插件,就可以创建自定义的节点了
可见,自定义节点已经可以创建了,其属性如下
至此,通过插件创建自定义节点就完成了
参考
《Kanzi官方文档》