65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.48/5 (6投票s)

2020年2月7日

MIT

5分钟阅读

viewsIcon

31187

一个多功能、跨平台、免费开源的 C++ 框架。本文将重点介绍 CoreModifiable 属性。

Kigs Logo

目录

引言

在本系列的前几篇文章(这里这里)中,我们概述了 Kigs 框架并详细介绍了 CoreModifiable 类。

本文将重点介绍 CoreModifiable 属性。

CoreModifiable 属性可以看作是你可以通过其名称(字符串形式)访问(getter/setter)的成员变量,而无需知道实例的运行时类型(你可以直接通过 CoreModifiable 指针调用 getter/setter)。
它们还可以自动序列化,你可以使用反射来了解属性是否可用或获取实例的属性列表。

主要有三种 CoreModifiable 属性:
- 'maType' 属性:如 maIntmaFloatmaReference 等('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:当调用 getValuesetValue 时,调用 CoreModifiable 所有者实例上给定的方法来计算参数。参数不存储,而是在每次调用时重新计算。

动态属性

可以在运行时向实例添加属性。

instance2->AddDynamicAttribute
(CoreModifiable::ATTRIBUTE_TYPE::STRING, "DynamicAttribute", "initValue");
AddDynamicAttribute(CoreModifiable::ATTRIBUTE_TYPE::UINT, "DynamicAttribute", 1250);

然后可以像其他属性一样访问它们(如下一节所述)。

当然,也可以删除动态属性。

// remove "DynamicAttribute" from this
RemoveDynamicAttribute("DynamicAttribute");

访问

可以使用所有者实例上的 setValuegetValue 方法通过名称访问 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
}

数组访问

可以使用 getValuesetValue 访问 vectormatrix

// 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 项目中(浏览代码)。

本系列已发布文章

  1. Kigs框架介绍 (1/8) - 概述
  2. Kigs框架介绍 (2/8) - CoreModifiable
  3. Kigs框架介绍 (3/8) - 属性
  4. Kigs框架介绍 (4/8) - 方法
  5. Kigs框架介绍 (5/8) - CoreItem
  6. Kigs框架介绍 (6/8) - 信号,槽,通知
  7. Kigs框架介绍 (7/8) - Lua绑定
  8. 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 日:框架重构后更新文章。
© . All rights reserved.