Click here to Skip to main content
15,867,488 members
Articles / Programming Languages / C++

Kigs Framework Introduction (3/8) - Attributes

Rate me:
Please Sign up or sign in to vote.
3.48/5 (6 votes)
1 Mar 2023MIT5 min read 30.4K   7   1
A multi-purpose, cross-platform, free and Open Source C++ framework. This article will focus on CoreModifiable attributes.
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.

Kigs Logo

Table of Contents

Introduction

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. 

Declaration

'maType' attributes

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:

Modern C++ Style

Using the helper macros BASE_ATTRIBUTE:

C++
// 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);

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.

Classic Constructor Init

In class declaration:

C++
// 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;

In class constructor:

C++
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)
{
    
}

Owning Class Access

The owning class can often use 'maType' CoreModifiable attributes directly like a classic member variable :

C++
// 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;

Mapped attributes

It is also possible to map CoreModifiable attributes on existing member variables using the WRAP_ATTRIBUTES macro.

C++
// 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

Basic Types

Numeric Types

  • 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

String Types

  • maString: manage std::string value
  • maUSString: manage UTF16 string value

Other Basic Types

  • 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:
C++
// m_RequestType enum can take values "GET", "POST", "PUT", "DELETE"
maEnum<4> m_RequestType = BASE_ATTRIBUTE(Type, "GET", "POST", "PUT", "DELETE");

Advanced Types

Array / Vector Types

  • 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

Reference

  • 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:

C++
CoreModifiable* other = (CoreModifiable*)m_Ref;

getValue can also be used:

C++
CMSP other;
instance->getValue("Reference",other);

Raw Buffer

  • maBuffer: manage raw data (binary) buffer

CoreItem

  • maCoreItem: manage JSon style object structures

CoreItem class is detailed in a next article.

Computed Numeric Parameter

  • 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.

Dynamic Attributes

Attributes can be added to an instance at runtime:

C++
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:

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

Access

CoreModifiable attributes can be accessed by their names using setValue and getValue methods on owning instance like this:

C++
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
}

Array Access

vector and matrix can be accessed using getValue and setValue:

C++
// 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]");

or with setArrayValue / getArrayValue:

C++
// 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);

or for a given element with getArrayElementValue / setArrayElementValue:

C++
// by element
instance1->getArrayElementValue("Vector", arrayv[0], 0,2);
std::cout << "vector values : [" << arrayv[0] << "," << arrayv[1] << "," 
          << arrayv[2] << "," << arrayv[3] << "]" << std::endl;

Owner Notification

The owner of an attribute can ask to be notified when a setValue is called on this attribute:

C++
// NotifyUpdate method will be called when a setValue occur on "StringValue"
setOwnerNotification("StringValue",true);

The owner class should override NotifyUpdate method to receive the notification:

C++
void SimpleClass::NotifyUpdate(const u32 labelid)
{
    if (labelid == KigsID("StringValue")._id)
    {
        std::cout << "StringValue new value is : " <<  m_StringValue << std::endl;
    }
}

Serialization

In XML files, attributes are defined like this for class attributes:

XML
<Attr N="IntValue" V="10"/>

or like this for dynamic attributes:

XML
<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:

XML
<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

  1. Kigs Framework Introduction (1/8) - Overview
  2. Kigs Framework Introduction (2/8) - CoreModifiable
  3. Kigs Framework Introduction (3/8) - Attributes
  4. Kigs Framework Introduction (4/8) - Methods
  5. Kigs Framework Introduction (5/8) - CoreItem
  6. Kigs Framework Introduction (6/8) - Signal, Slot, Notification
  7. Kigs Framework Introduction (7/8) - Lua Binding
  8. Kigs Framework Introduction (8/8) - Data Driven Application

History

  • 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

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Software Developer (Senior) LVCim
France France
Senior software developer.
Kigs framework is an educational/experimental/RAD open source C++ framework.

Comments and Discussions

 
GeneralMy vote of 5 Pin
FenderBaba20-Mar-20 22:36
FenderBaba20-Mar-20 22:36 
Very interesting article serie. Thank You for sharing !

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.