Skip to content

Incarnate

Set component to optional

Screenshot

Component won't incarnate automatically. If you want to use it you need to call incarnate.


Create attributes for incarnate

Open < Name >Caps -> State Diagram

Now create RegisterX and Attribute inside < Name >Caps -> Cc< Name > according to the pictures

create RegisterX

SUPER::RegisterX();

//################################################ Hardware Params ###########################################
//|### Parameter: HP_HasCover
//| HP_HasCover if is using cover, CxBool
//>
m_xbHasCover        .Register( *m_poXAggregation, "HP_HasCover",        CrXVar::GUIR_OWNR_INIHO, 0, true);
//<

Screenshot

Screenshot

Set Attribute m_xbHasCover in hardware.ini if you want incarnate.


Add incarnate

Screenshot

Open in: < Name >Caps -> State Diagram

After StartingUp -> StartupAddtionalComponents -> and open choose point accorting to the picture

Screenshot

if you write here you must call "CALLSUPER"

call CALLSUPER

if (!CALLSUPER)
    return (false);

Edit your component and attribute name: m_xbHasCover and CoverDI

if ( m_xbHasCover ) {
    m_oErrActorId = frame.incarnate( CoverDI );
    if( !m_oErrActorId.isValid() )
    {
        m_oLog.Open( CdLog::ErrorLog(),"DoIncarnations" );
        m_oLog.Write( "Incarnation of CoverDI visualisation client failed." );
        m_oLog.Close();

        return (false);
    }
}

If you have multiple incarnates:

  • create define example:

    #define UNWINDER_PLOTER_CUTTER_COUNT_INCARNATE  2
    
  • change type object m_oErrActorId to:

    RTActorId[UNWINDER_PLOTER_CUTTER_COUNT_INCARNATE]
    
  • and use for incarnate this code:

Edit your component and attribute name: m_xbHasDMCStaticScaner, m_xbHasBrushBeltDrive and DMCStaticReader, BrushBeltDrive

int counter = 0;
/*------------------ option 1 (different component types) -------------------------*/
if ( m_xbHasDMCStaticScaner ) {
    m_oErrActorId[counter] = frame.incarnate( DMCStaticReader );
    if( !m_oErrActorId[counter++].isValid() )
    {
        m_oLog.Open( CdLog::ErrorLog(),"DoIncarnations" );
        m_oLog.Write( "Incarnation of DMCStaticReader visualisation client failed." );
        m_oLog.Close();

        return (false);
    }
}

if ( m_xbHasBrushBeltDrive ) {
    m_oErrActorId[counter] = frame.incarnate( BrushBeltDrive );
    if( !m_oErrActorId[counter++].isValid() )
    {
        m_oLog.Open( CdLog::ErrorLog(),"DoIncarnations" );
        m_oLog.Write( "Incarnation of BrushBeltDrive visualisation client failed." );
        m_oLog.Close();

        return (false);
    }
}
/*------------------ option 2 (same component type) -------------------------*/
if ( m_xbHasDMCStaticScaner ) {
    for( int i = 0; i < DMC_SCANNER_COUNT; i++){
        m_oErrActorId[counter] = frame.incarnate( DMCStaticReader );
        if( !m_oErrActorId[counter++].isValid() )
        {
                        m_oLog.Open( CdLog::ErrorLog(),"DoIncarnations" );
                        m_oLog.Write( "Incarnation of DMCStaticReader visualisation client failed." );
                        m_oLog.Close();

                        return (false);
        }
    }
}
...

var counter continues with value of all incarneted components + 1


Destroy object

Now you must destroy object at finish

Open in: < Name >Caps -> State Diagram

After open path: StartingUp -> PoweringOff -> trigger DoDestructions

Screenshot

Screenshot

Edit your define: UNWINDER_PLOTER_CUTTER_COUNT_INCARNAT

CALLSUPER;
/*----------- option 1 (more safe) ----------------*/
for( int i = 0; i < UNWINDER_PLOTER_CUTTER_COUNT_INCARNATE ; i++ ){
    if (m_oErrActorId[i].isValid()){
        frame.destroy( m_oErrActorId[i] );
    }
}

/*----------- option 2 (dynamically checks cardinality of component) ----------------*/
for( int i = 0; i < Heating.size(); i++ ){
    if (m_oHeatingControllerActorId[i].isValid()){
        frame.destroy( m_oHeatingControllerActorId[i] );
    }
}

If you have only one incarnation you can use this code:

Tip

CALLSUPER;

if (m_oErrActorId.isValid()){
    frame.destroy( m_oErrActorId );
}


Use inside < Name >Logic

Create a choice point and write:

Edit your component: CoverDI

return CoverDI.isBoundAt(0);

Note

By calling < component >.size() you can get cardinality of the component

By calling < component >.isBoundAt(< number >) you can get number of incarnated components (objects)

Screenshot

If is HARDWARE.INI attribute true so execute your code

If is HARDWARE.INI attribute false so skip your code


Remove EmptySlot0 from path

If you have issue with incarnated path of subunits adding EmptySlot0, additional code must be added to initialize transition of said subunit.

Note

Incarnated path:

MachineName_EmptySlot0_SubunitName

Instead of expected:

MachineName_SubunitName

Screenshot

Edit your transition: initialize

CALLSUPER;

m_sIncarnationName.Empty();

// needs the value m_sIncarnationName from the m_oInitData
if ( rtdata )
{
    m_sIncarnationName = *((CdString*)rtdata);      // (received incarnation parameter)
    CrAssertExLog(!m_sIncarnationName.IsEmpty());
    m_bIncarnationNameIsSetManually = true; 
}

// find out RoleName of Capsule 
m_sSubstCapsuleRoleName = GetLongNameOfCapsule();

// set log caption

m_oLog.SetContainerName( m_sSubstCapsuleRoleName );

// set pointer to global data

m_oPubAttr4Innards.AddAttr( this, m_oLog, "Log" );
m_oPubAttr4Innards.AddAttr( this, (CrTV)m_sSubstCapsuleRoleName, "SubstCapsuleRoleName" );
m_oPubAttr4Innards.AddAttr( this, (CrTV)m_sDescription, "Description" );