This article will focus on CoreModifiable attributes of the Kigs framework; a lightweight, fast, scalable framework. We will go over: Declaration, Types, Dynamic Attributes, Access, Attribute Modifiers, Owner Notification, and Serialization.

Table of Contents
In the previous articles of this series (here and here), we overviewed the Kigs framework and detailed CoreModifiable
class.
This article will focus on CoreModifiable
attributes.
CoreModifiable
attributes can be seen as member variables you can access (getters/setters) by their name (given as a string), without knowing the runtime type of your instance (you can call getters/setters directly using a CoreModifiable
pointer).
They are also automatically serialized, and you can use reflexion to know if an attribute is available or get the list of attribute of an instance.
There are three main CoreModifiable
attributes:
- 'maType' attributes: like maInt
, maFloat
, maReference
... ('ma' prefix if for modifiable attribute), are specific types you can use to declare CoreModifiable
attribute member variables.
- mapped attributes: you declare classic member variables (int mIntValue = 0;) then you declare them as CoreModifiable
attributes using the WRAP_ATTRIBUTES
helper macro.
- dynamic attributes: you can add dynamic attribute (and remove it later, if it was added dynamically) to a CoreModifiable
instance, when you want only some specific instances (and not all the instances of the same class) to use this attribute or when the attribute is needed only temporarily.
CoreModifiable
attributes can be defined at compile time as member variable of a CoreModifiable
or at runtime as dynamic attributes.
When defined as member variable, two definitions/declarations are possible:
Using the helper macros BASE_ATTRIBUTE
:
maInt m_val=BASE_ATTRIBUTE(IntValue,12);
maFloatInit m_fval=BASE_ATTRIBUTE(FloatValue,-1.0f);
Each 'maType' type has an associated 'maTypeInit' type indicating the attribute is needed to initialize the CoreModifiable
. Once the CoreModifiable
initialized, an init attribute is set as read only.
In class declaration:
maInt m_val;
maFloatInit m_fval;
In class constructor:
IMPLEMENT_CONSTRUCTOR(SimpleClass)
, m_val(*this,"IntValue",12)
, m_fval(* this, "FloatValue",-1.0f)
{
}
The owning class can often use 'maType' CoreModifiable
attributes directly like a classic member variable :
m_val+=5;
float result = 5+m_val;
It is also possible to map CoreModifiable
attributes on existing member variables using the WRAP_ATTRIBUTES
macro.
std::string mStringMemberVariable="a text";
u32 mUIntMemberVariable = 50;
WRAP_ATTRIBUTES(mStringMemberVariable,mUIntMemberVariable);
maChar
: manage signed 8 bits integer maShort
: manage signed 16 bits integer maInt
: manage signed 32 bits integer maLong
: manage signed 64 bits integer maUChar
: manage unsigned 8 bits integer maUShort
: manage unsigned 16 bits integer maUInt
: manage unsigned 32 bits integer maULong
: manage unsigned 64 bits integer maFloat
: manage float value maDouble
: manage double value
maString
: manage std::string
value maUSString
: manage UTF16 string value
maBool
: manage bool value maEnum
: manage an énumération. maEmum
needs template parameter for the possible enumeration value count. Here is an example of maEnum
declaration:
maEnum<4> m_RequestType = BASE_ATTRIBUTE(Type, "GET", "POST", "PUT", "DELETE");
maVect2DF
: manage 2d floating point value vector maVect2DI
: manage 2d integer (32 bits) value vector maVect3DF
: manage 3d floating point value vector maVect3DI
: manage 3d integer (32 bits) value vector maVect4DF
: manage 4d floating point value vector maVect16DF
: manage 16 floating point value vector ( <=> 4x4 matrix ) maMatrix22DF
: manage 2x2 floating point matrix maMatrix33DF
: manage 3x3 floating point matrix
maReference
: manage a reference on a CoreModifiable
instance.
A reference is generally initialized with a string giving a path to the wanted instance. Basic path can have this form:
"classtype:classname
".
maReference
does not change reference counting of the referenced object.
Owning class can retrieve pointer on the referenced instance with a cast on CoreModifiable
:
CoreModifiable* other = (CoreModifiable*)m_Ref;
getValue
can also be used:
CMSP other;
instance->getValue("Reference",other);
maBuffer
: manage raw data (binary) buffer
maCoreItem
: manage JSon style object structures
CoreItem
class is detailed in a next article.
maComputedNumeric
: call given methods on CoreModifiable
owner instance to compute parameter when getValue
or setValue
are called. The parameter is not stored but recomputed at each call.
Attributes can be added to an instance at runtime:
instance2->AddDynamicAttribute
(CoreModifiable::ATTRIBUTE_TYPE::STRING, "DynamicAttribute", "initValue");
AddDynamicAttribute(CoreModifiable::ATTRIBUTE_TYPE::UINT, "DynamicAttribute", 1250);
and then accessed like other attributes (as described in the next section).
Of course, dynamic attributes can also be removed:
RemoveDynamicAttribute("DynamicAttribute");
CoreModifiable
attributes can be accessed by their names using setValue
and getValue
methods on owning instance like this:
instance->setValue("IntValue", 16);
int v = instance->getValue<int>("IntValue");
int v1;
if(!instance->getValue("IntValue",v1))
{
}
vector
and matrix
can be accessed using getValue
and setValue
:
v4f vect;
instance1->getValue("Vector", vect);
std::cout << "vector values : [" << vect.x << "," << vect.y << ","
<< vect.z << "," << vect.w << "]" << std::endl;
instance1->setValue("Vector", "[2.0,1.0,0.0,-1.0]");
or with setArrayValue
/ getArrayValue
:
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);
or for a given element with getArrayElementValue
/ setArrayElementValue
:
instance1->getArrayElementValue("Vector", arrayv[0], 0,2);
std::cout << "vector values : [" << arrayv[0] << "," << arrayv[1] << ","
<< arrayv[2] << "," << arrayv[3] << "]" << std::endl;
The owner of an attribute can ask to be notified when a setValue
is called on this attribute:
setOwnerNotification("StringValue",true);
The owner class should override NotifyUpdate
method to receive the notification:
void SimpleClass::NotifyUpdate(const u32 labelid)
{
if (labelid == KigsID("StringValue")._id)
{
std::cout << "StringValue new value is : " << m_StringValue << std::endl;
}
}
In XML files, attributes are defined like this for class attributes:
<Attr N="IntValue" V="10"/>
or like this for dynamic attributes:
<Attr N="FloatValue" T="float" V="5.5" Dyn="yes"/>
The initial value can be set directly in V
tag like above, or be evaluated from an expression like this:
<Attr N="FloatValue" V="eval(32.4*4.2)"/>
More complex expressions are possible and are explained in the article about CoreItem
.
Find all the sample code from this article in Sample3 project (browse the code).
Already Published in this Series
- Kigs Framework Introduction (1/8) - Overview
- Kigs Framework Introduction (2/8) - CoreModifiable
- Kigs Framework Introduction (3/8) - Attributes
- Kigs Framework Introduction (4/8) - Methods
- Kigs Framework Introduction (5/8) - CoreItem
- Kigs Framework Introduction (6/8) - Signal, Slot, Notification
- Kigs Framework Introduction (7/8) - Lua Binding
- Kigs Framework Introduction (8/8) - Data Driven Application
- 7th February, 2020: Initial version
- 14th February, 2020: Article (4/8) added to the series
- 21st February, 2020: Article (5/8) added to the series and small bug fix in code
- 2nd March, 2020: Article (6/8) added to the series
- 19th March, 2020: Article (7/8) added to the series
- 17th June, 2020 : Added final article of the series
- 1st March, 2023: Article update after framework refactory