Skip to content

CoreModifiable attributes

Kigs-framework edited this page Mar 1, 2023 · 20 revisions

Table of contents

Introduction

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

'maType' attributes can be defined at compile time as member variable or at runtime as dynamic attributes.

When defined as member variable, two definition / declaration are possible :

Modern c++ style

Using the helper macros 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);

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 :

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

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 :

// change m_val value (read only is not used when direct access is done)
m_val+=5;
// use m_val directltly 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.

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

CoreModifiable* other = (CoreModifiable*)m_Ref;

getValue can also be used :

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 this specific Wiki page : CoreItem.

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 :

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

and then accessed like other attributes ( as described in next section ).

Of course, dynamic attributes can also be removed :

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

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 :

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

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

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

// NotifyUpdate method will be called when a setValue occur on "StringValue" 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;
	}
}

Serialization

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 expression are possible and will be explained in the CoreItem section of this wiki.

Find all the sample code from this wiki section in Sample3 project (browse the code)