Kigs框架介绍 (3/8) - 属性






3.48/5 (6投票s)
一个多功能、跨平台、免费开源的 C++ 框架。本文将重点介绍 CoreModifiable 属性。
目录
引言
在本系列的前几篇文章(这里和这里)中,我们概述了 Kigs 框架并详细介绍了 CoreModifiable
类。
本文将重点介绍 CoreModifiable
属性。
CoreModifiable
属性可以看作是你可以通过其名称(字符串形式)访问(getter/setter)的成员变量,而无需知道实例的运行时类型(你可以直接通过 CoreModifiable
指针调用 getter/setter)。
它们还可以自动序列化,你可以使用反射来了解属性是否可用或获取实例的属性列表。
主要有三种 CoreModifiable
属性:
- 'maType' 属性:如 maInt
、maFloat
、maReference
等('ma' 前缀表示可修改属性),是你用来声明 CoreModifiable
属性成员变量的特定类型。
- 映射属性:你声明经典的成员变量(例如 `int mIntValue = 0;`),然后使用 WRAP_ATTRIBUTES
辅助宏将其声明为 CoreModifiable
属性。
- 动态属性:你可以为 CoreModifiable
实例添加(并在以后删除,如果它是动态添加的)动态属性,当你只需要某些特定实例(而不是同一类的所有实例)使用此属性,或者该属性仅临时需要时。
声明
'maType' 属性
CoreModifiable
属性可以在编译时定义为 CoreModifiable
的成员变量,也可以在运行时定义为动态属性。
当定义为成员变量时,有两种定义/声明方式:
现代 C++ 风格
使用辅助宏 BASE_ATTRIBUTE
// declare m_val member variable as a integer CoreModifiable attribute with
// name "IntValue" and with default value 12
maInt m_val=BASE_ATTRIBUTE(IntValue,12);
// declare m_fval member variable as a float 'Init' CoreModifiable attribute with
// name "FloatValue" and with default value -1.0f
// once owning instance is initialized, m_fval is read only ( init attribute )
maFloatInit m_fval=BASE_ATTRIBUTE(FloatValue,-1.0f);
每种 'maType' 类型都有一个关联的 'maTypeInit' 类型,表示在初始化 CoreModifiable
时需要该属性。一旦 CoreModifiable
初始化完成,初始化属性就会被设置为只读。
经典构造函数初始化
在类声明中
// declare m_val member variable as a integer CoreModifiable attribute
maInt m_val;
// declare m_fval member variable as a float 'Init' CoreModifiable attribute
maFloatInit m_fval;
在类构造函数中
IMPLEMENT_CONSTRUCTOR(SimpleClass)
// attribute name and default value is given to the constructor
, m_val(*this,"IntValue",12)
// attribute name and default value is given to the constructor
, m_fval(* this, "FloatValue",-1.0f)
{
}
所属类访问
所属类通常可以直接使用 'maType' CoreModifiable
属性,就像使用经典成员变量一样。
// change m_val value
// (read only is not used when direct access is done)
m_val+=5;
// use m_val directly without getValue
float result = 5+m_val;
映射属性
还可以使用 WRAP_ATTRIBUTES
宏将 CoreModifiable
属性映射到现有成员变量上。
// declare and init member variables
std::string mStringMemberVariable="a text";
u32 mUIntMemberVariable = 50;
// indicates mStringMemberVariable and mUIntMemberVariable are CoreModifiable attributes that can be access using
// "StringMemberVariable" and "UIntMemberVariable" names
// the variables will also be serialized when exporting/importing the instance.
WRAP_ATTRIBUTES(mStringMemberVariable,mUIntMemberVariable);
Types
基本类型
数值类型
maChar
:管理有符号 8 位整数。maShort
:管理有符号 16 位整数。maInt
:管理有符号 32 位整数。maLong
:管理有符号 64 位整数。maUChar
:管理无符号 8 位整数。maUShort
:管理无符号 16 位整数。maUInt
:管理无符号 32 位整数。maULong
:管理无符号 64 位整数。maFloat
:管理浮点数值。maDouble
:管理双精度浮点数值。
字符串类型
maString
:管理std::string
值。maUSString
:管理 UTF16 字符串值。
其他基本类型
maBool
:管理布尔值。maEnum
:管理一个枚举。maEmum
需要模板参数来指定可能的枚举值数量。这是一个maEnum
声明的示例。
// m_RequestType enum can take values "GET", "POST", "PUT", "DELETE"
maEnum<4> m_RequestType = BASE_ATTRIBUTE(Type, "GET", "POST", "PUT", "DELETE");
高级类型
数组 / 向量类型
maVect2DF
:管理二维浮点数值向量。maVect2DI
:管理二维整数(32 位)数值向量。maVect3DF
:管理三维浮点数值向量。maVect3DI
:管理三维整数(32 位)数值向量。maVect4DF
:管理四维浮点数值向量。maVect16DF
:管理十六维浮点数值向量(<=> 4x4 矩阵)。maMatrix22DF
:管理 2x2 浮点矩阵。maMatrix33DF
:管理 3x3 浮点矩阵。
参考
maReference
:管理一个对CoreModifiable
实例的引用。
引用通常用一个字符串初始化,该字符串指定所需实例的路径。基本路径可以采用以下形式:
"classtype:classname
"。
maReference
不会改变被引用对象的引用计数。
所属类可以通过将对 CoreModifiable
的指针进行转换来检索被引用实例的指针。
CoreModifiable* other = (CoreModifiable*)m_Ref;
也可以使用 getValue
。
CMSP other;
instance->getValue("Reference",other);
原始缓冲区
maBuffer
:管理原始数据(二进制)缓冲区。
CoreItem
maCoreItem
:管理类似 JSON 的对象结构。
CoreItem
类将在下一篇文章中详细介绍。
计算得到的数值参数
maComputedNumeric
:当调用getValue
或setValue
时,调用CoreModifiable
所有者实例上给定的方法来计算参数。参数不存储,而是在每次调用时重新计算。
动态属性
可以在运行时向实例添加属性。
instance2->AddDynamicAttribute
(CoreModifiable::ATTRIBUTE_TYPE::STRING, "DynamicAttribute", "initValue");
AddDynamicAttribute(CoreModifiable::ATTRIBUTE_TYPE::UINT, "DynamicAttribute", 1250);
然后可以像其他属性一样访问它们(如下一节所述)。
当然,也可以删除动态属性。
// remove "DynamicAttribute" from this
RemoveDynamicAttribute("DynamicAttribute");
访问
可以使用所有者实例上的 setValue
和 getValue
方法通过名称访问 CoreModifiable
属性,如下所示:
instance->setValue("IntValue", 16);
// retrieve value using templated "getValue" method
int v = instance->getValue<int>("IntValue");
// or with reference parameter
int v1;
if(!instance->getValue("IntValue",v1))
{
// instance does not own "IntValue" parameter
}
数组访问
可以使用 getValue
和 setValue
访问 vector
和 matrix
。
// accessing vector
v4f vect;
instance1->getValue("Vector", vect);
std::cout << "vector values : [" << vect.x << "," << vect.y << ","
<< vect.z << "," << vect.w << "]" << std::endl;
// set value with string
instance1->setValue("Vector", "[2.0,1.0,0.0,-1.0]");
或者使用 setArrayValue
/ getArrayValue
。
// access with array of values
float arrayv[4];
instance1->getArrayValue("Vector", arrayv, 4);
std::cout << "vector values : [" << arrayv[0] << "," << arrayv[1] << ","
<< arrayv[2] << "," << arrayv[3] << "]" << std::endl;
arrayv[2] = 10.0f;
instance1->setArrayValue("Vector", arrayv,4);
或者使用 getArrayElementValue
/ setArrayElementValue
来访问特定元素。
// by element
instance1->getArrayElementValue("Vector", arrayv[0], 0,2);
std::cout << "vector values : [" << arrayv[0] << "," << arrayv[1] << ","
<< arrayv[2] << "," << arrayv[3] << "]" << std::endl;
所有者通知
属性的所有者可以在该属性上调用 setValue
时请求通知。
// NotifyUpdate method will be called when a setValue occur on "StringValue"
setOwnerNotification("StringValue",true);
所有者类应覆盖 NotifyUpdate
方法以接收通知。
void SimpleClass::NotifyUpdate(const u32 labelid)
{
if (labelid == KigsID("StringValue")._id)
{
std::cout << "StringValue new value is : " << m_StringValue << std::endl;
}
}
序列化
在 XML 文件中,类属性的定义如下:
<Attr N="IntValue" V="10"/>
或者动态属性的定义如下:
<Attr N="FloatValue" T="float" V="5.5" Dyn="yes"/>
初始值可以直接在上面的 V
标签中设置,或者像这样从表达式求值:
<Attr N="FloatValue" V="eval(32.4*4.2)"/>
可以实现更复杂的表达式,这些表达式将在关于 CoreItem
的文章中进行解释。
在此文章中找到所有示例代码,位于 Sample3 项目中(浏览代码)。
本系列已发布文章
- Kigs框架介绍 (1/8) - 概述
- Kigs框架介绍 (2/8) - CoreModifiable
- Kigs框架介绍 (3/8) - 属性
- Kigs框架介绍 (4/8) - 方法
- Kigs框架介绍 (5/8) - CoreItem
- Kigs框架介绍 (6/8) - 信号,槽,通知
- Kigs框架介绍 (7/8) - Lua绑定
- Kigs框架介绍 (8/8) - 数据驱动应用程序
历史
- 2020 年 2 月 7 日:初始版本
- 2020年2月14日:将文章(4/8)添加到本系列
- 2020 年 2 月 21 日:将文章 (5/8) 添加到系列中,并对代码进行了小错误修复。
- 2020年3月2日:将文章(6/8)添加到本系列
- 2020 年 3 月 19 日:将文章 (7/8) 添加到系列中。
- 2020年6月17日:添加了该系列的最后一篇文章
- 2023 年 3 月 1 日:框架重构后更新文章。