blob: cd64bfbff33838f466552e66a666ce4729438756 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "RuntimeID.h"
#include <common/NamedElement.h>
#include <fml/common/SpecifierElement.h>
#include <fml/executable/BaseCompiledForm.h>
#include <fml/executable/BaseInstanceForm.h>
#include <fml/executable/ExecutableForm.h>
#include <fml/executable/InstanceOfMachine.h>
namespace sep
{
/**
* DEFAULT NULL
*/
RuntimeID RuntimeID::REF_NULL;
/**
* GETTER - SETTER
* mFullyQualifiedNameID
*/
std::string RuntimeID::getFullyQualifiedNameID() const
{
return( BaseCompiledForm::USE_ONLY_ID
? rid_pointer()->getNameID()
: rid_pointer()->getFullyQualifiedNameID() );
}
void _RuntimeID_::updateFullyQualifiedNameID()
{
if( (mParent != NULL) && (mInstance != NULL) )
{
mNameID = mInstance->getNameID();
mFullyQualifiedNameID = ( OSS()
<< mParent->getFullyQualifiedNameID()
<< '.' << mNameID );
mQualifiedNameID = ( OSS() << "run::pid#" << mRid << ':'
<< NamedElement::location(mFullyQualifiedNameID) );
}
else if( mInstance != NULL )
{
mNameID = mInstance->getNameID();
std::string aQualifiedNameID = NamedElement::location(
mInstance->getFullyQualifiedNameID() );
mFullyQualifiedNameID = "run::" + aQualifiedNameID;
mQualifiedNameID =
( OSS() << "run::pid#" << mRid << ':' << aQualifiedNameID );
}
else
{
mNameID = ( OSS() << "pid#" << mRid );
mFullyQualifiedNameID =
mQualifiedNameID = ( OSS() << "run::pid#" << mRid );
}
}
/**
* GETTER
* Executable
*/
ExecutableForm * _RuntimeID_::getExecutable() const
{
AVM_OS_ASSERT_FATAL_NULL_POINTER_EXIT( mInstance )
<< " Instance in _RID_ < "
<< "pid#" << mRid << ":" << getNameID() << " > !!!"
<< SEND_EXIT;
AVM_OS_ASSERT_FATAL_ERROR_EXIT( mInstance->hasExecutable() )
<< "Unexpected RID without Executable !!!"
<< SEND_EXIT;
return( mInstance->getExecutable() );
}
/**
* initialize
* finalize
*/
void RuntimeID::initialize()
{
// Attention:> Reference circulaire (a la destruction)!!!!
rid_pointer()->onRunning = StatementConstructor::newOptiNopCode(
OperatorManager::OPERATOR_RUN, *this, AVM_ARG_MACHINE_RID);
_RuntimeID_ * tmpRID;
// the first hierarchical composite (contained concurrency spec) container
if( getExecutable()->isCompositeComponent() )
{
rid_pointer()->mCompositeComponent = this->rid_pointer();
}
else if( (tmpRID = rid_pointer())->mParent != NULL )
{
tmpRID = tmpRID->mParent;
for( ; (tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( tmpRID->getExecutable()->isCompositeComponent() )
{
rid_pointer()->mCompositeComponent = tmpRID;
break;
}
}
AVM_OS_ASSERT_FATAL_NULL_POINTER_EXIT(
rid_pointer()->mCompositeComponent )
<< " as First Composite Parent Component of < "
<< this->strUniqId() << " > !!!"
<< SEND_EXIT;
}
// the first composite parent of the first composite container
if( rid_pointer()->mCompositeComponent != NULL )
{
rid_pointer()->mCompositeComponentParent =
tmpRID = rid_pointer()->mCompositeComponent;
if( tmpRID->mParent != NULL )
{
for( tmpRID = tmpRID->mParent ;
(tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( tmpRID->getExecutable()->isCompositeComponent() )
{
rid_pointer()->mCompositeComponentParent = tmpRID;
break;
}
}
}
}
// the first (or this) Communicator container of this
if( getExecutable()->isCommunicator() )
{
rid_pointer()->mCommunicator = this->rid_pointer();
}
else if( (tmpRID = rid_pointer())->mParent != NULL )
{
for( tmpRID = tmpRID->mParent ;
(tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( tmpRID->getExecutable()->isCommunicator() )
{
rid_pointer()->mCommunicator = tmpRID;
break;
}
}
}
// the first (or this) Lifeline container of this
if( getExecutable()->isLifeline() )
{
rid_pointer()->mLifeline = this->rid_pointer();
}
else if( (tmpRID = rid_pointer())->mParent != NULL )
{
for( tmpRID = tmpRID->mParent ;
(tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( tmpRID->getExecutable()->isLifeline() )
{
rid_pointer()->mLifeline = tmpRID;
break;
}
}
if( rid_pointer()->mLifeline == NULL )
{
rid_pointer()->mLifeline = rid_pointer()->mCommunicator;
}
}
// the first hierarchical main Component container
if( getExecutable()->isMainComponent() )
{
rid_pointer()->mComponentSelf = this->rid_pointer();
}
else if( (tmpRID = rid_pointer())->mParent != NULL )
{
tmpRID = tmpRID->mParent;
for( ; (tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( tmpRID->getExecutable()->isMainComponent() )
{
rid_pointer()->mComponentSelf = tmpRID;
break;
}
}
AVM_OS_ASSERT_FATAL_NULL_POINTER_EXIT(
rid_pointer()->mCompositeComponent )
<< " as Component Self of < " << this->strUniqId() << " > !!!"
<< SEND_EXIT;
}
// the main Component container of mComponentSelf
if( (rid_pointer()->mComponentSelf != NULL)
&& ((tmpRID = rid_pointer()->mComponentSelf)->mParent != NULL) )
{
for( tmpRID = tmpRID->mParent ;
(tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( tmpRID->getExecutable()->isMainComponent() )
{
rid_pointer()->mComponentParent = tmpRID;
break;
}
}
}
// the first (or this) main Component Communicator container of this
if( getExecutable()->isMainComponent() && getExecutable()->hasPort() )
{
rid_pointer()->mComponentCommunicator = this->rid_pointer();
}
else if( (tmpRID = rid_pointer())->mParent != NULL )
{
for( tmpRID = tmpRID->mParent ;
(tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( tmpRID->getExecutable()->isMainComponent() &&
tmpRID->getExecutable()->hasPort() )
{
rid_pointer()->mComponentCommunicator = tmpRID;
break;
}
}
}
}
/**
* GETTER API
* Specifier
*/
const Specifier & RuntimeID::getSpecifier() const
{
return( getExecutable()->getSpecifier() );
}
/**
* GETTER - SETTER
* mInstance
* son Executable
* ses variables
*/
// Model Machine
const InstanceOfMachine * RuntimeID::getModelInstance() const
{
return( rid_pointer()->mInstance->getInstanceModel() );
}
bool RuntimeID::hasModelInstance() const
{
return( (rid_pointer()->mInstance != NULL) &&
rid_pointer()->mInstance->hasInstanceModel() );
}
// Executable
ExecutableForm * RuntimeID::getExecutable() const
{
AVM_OS_ASSERT_FATAL_NULL_POINTER_EXIT( rid_pointer()->mInstance )
<< " Instance in RID < " << this->strUniqId() << " > !!!"
<< SEND_EXIT;
AVM_OS_ASSERT_FATAL_ERROR_EXIT(
rid_pointer()->mInstance->hasExecutable() )
<< "Unexpected RID without Executable !!!"
<< SEND_EXIT;
return( getInstance()->getExecutable() );
}
bool RuntimeID::hasExecutable() const
{
return( hasInstance() && getInstance()->hasExecutable() );
}
// Variable
const BF & RuntimeID::getVariable(avm_offset_t offset) const
{
return( getExecutable()->getData().get(offset) );
}
InstanceOfData * RuntimeID::rawVariable(avm_offset_t offset) const
{
return( getExecutable()->getData().rawAt(offset) );
}
bool RuntimeID::hasVariable() const
{
return( getExecutable()->hasData() );
}
/**
* GETTER - SETTER
* Instance->mOnCreate
*/
const BFCode & RuntimeID::getOnCreate() const
{
return( getInstance()->getOnCreate() );
}
bool RuntimeID::hasOnCreate() const
{
return( getInstance()->hasOnCreate() );
}
/**
* GETTER - SETTER
* Instance->mOnInit
*/
const BFCode & RuntimeID::getOnStart() const
{
return( getInstance()->getOnStart() );
}
bool RuntimeID::hasOnStart() const
{
return( getInstance()->hasOnStart() );
}
/**
* GETTER - SETTER
* Ancestor
*/
bool RuntimeID::hasAsAncestor(const RuntimeID & aRID) const
{
_RuntimeID_ * aPossibleAncestor = aRID.rid_pointer();
_RuntimeID_ * tmpRID = rid_pointer();
for( ; (tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( (tmpRID == aPossibleAncestor) )
{
return( true );
}
}
return( false );
}
bool RuntimeID::hasAsAncestor(const InstanceOfMachine * anInstance) const
{
ExecutableForm * aPossibleExecutableAncestor = anInstance->getExecutable();
_RuntimeID_ * tmpRID = rid_pointer();
for( ; (tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( (tmpRID->mInstance == anInstance)
|| (anInstance->getSpecifier().hasDesignModel()
&& (tmpRID->getExecutable() == aPossibleExecutableAncestor) ) )
{
return( true );
}
}
return( false );
}
RuntimeID RuntimeID::getAncestorContaining(
const BaseInstanceForm * anInstance) const
{
BaseAvmProgram * aPossibleExecutableAncestor = anInstance->getContainer();
_RuntimeID_ * tmpRID = rid_pointer();
for( ; (tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( tmpRID->getExecutable() == aPossibleExecutableAncestor )
{
return( smartPointerOf( tmpRID ) );
}
}
return( RuntimeID::REF_NULL );
}
/**
* GETTER - SETTER
* the Lifeline Ancestor container
*/
RuntimeID RuntimeID::getLifeline(InstanceOfMachine * aMachine) const
{
_RuntimeID_ * tmpRID = rid_pointer();
for( ; (tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( tmpRID->getExecutable() == aMachine->getContainer() )
{
return( smartPointerOf( tmpRID->mLifeline ) );
}
}
return( RuntimeID::REF_NULL );
}
RuntimeID RuntimeID::getLifeline(InstanceOfPort * aPort) const
{
if( aPort->hasAliasTarget() )
{
aPort = aPort->getAliasTarget()->as< InstanceOfPort >();
}
_RuntimeID_ * tmpRID = rid_pointer();
for( ; (tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( (tmpRID->getExecutable() == aPort->getContainer())
|| tmpRID->getExecutable()->getPort().contains(aPort) )
{
return( smartPointerOf( tmpRID->mLifeline ) );
}
}
return( RuntimeID::REF_NULL );
}
/**
* GETTER - SETTER
* the Communicator Ancestor container
*/
RuntimeID RuntimeID::getCommunicator(InstanceOfMachine * aMachine) const
{
_RuntimeID_ * tmpRID = rid_pointer();
for( ; (tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( tmpRID->getExecutable() == aMachine->getContainer() )
{
return( smartPointerOf( tmpRID->mCommunicator ) );
}
}
return( RuntimeID::REF_NULL );
}
RuntimeID RuntimeID::getCommunicator(InstanceOfPort * aPort) const
{
if( aPort->hasAliasTarget() )
{
aPort = aPort->getAliasTarget()->as< InstanceOfPort >();
}
_RuntimeID_ * tmpRID = rid_pointer();
for( ; (tmpRID != NULL) ; tmpRID = tmpRID->mParent )
{
if( (tmpRID->getExecutable() == aPort->getContainer())
|| tmpRID->getExecutable()->isCommunicatorWith(aPort) )
{
return( smartPointerOf( tmpRID->mCommunicator ) );
}
}
return( RuntimeID::REF_NULL );
}
/**
* Serialization
*/
void _RuntimeID_::toStream(OutStream & os) const
{
if( os.preferablyFQN() )
{
os << TAB << mQualifiedNameID;
return;
}
//
// os << TAB << "rid " << getFullyQualifiedNameID() << " {" << EOL;
//
// os << TAB2 << "rid = " << getRid() << ";" << EOL;
// os << TAB2 << "prid = " << getPRid() << ";" << EOL;
// os << TAB2 << "offset = " << getOffset() << ";" << EOL;
// os << TAB2 << "instance = "
// << getInstance()->getFullyQualifiedNameID() << ";" << EOL;
//
// os << TAB << "}" << EOL;
os << TAB << "rid< offset:" << mOffset
<< ( mDynamicLoaded ? " , dyna:true" : "" ) << " > "
// << "@" << avm_address_t( this ) << " "
<< getFullyQualifiedNameID() << " {" << EOL_TAB2;
os << "this = " << std::setw(3) << mRid << ";";
os << " this#parent = " << std::setw(3) << mRidOf( mParent ) << ";";
os << " this#lifeline = " << mRidOf( mLifeline ) << ";";
os << " cthis#com = " << mRidOf( mCommunicator ) << ";";
os << EOL_TAB2;
os << "self = " << std::setw(3) << mRidOf( mComponentSelf ) << ";";
os << " self#parent = " << std::setw(3)
<< mRidOf( mComponentParent ) << ";";
os << " cself#com = " << mRidOf( mComponentCommunicator ) << ";";
os << EOL_TAB2;
os << "this#composite = " << mRidOf( mCompositeComponent ) << ";";
os << " this#composite#parent = "
<< mRidOf( mCompositeComponentParent ) << ";";
os << EOL;
// os << TAB2 << "fqn = " << mFullyQualifiedNameID << ";" << EOL;
os << TAB2 << "instance = "
<< mInstance->getFullyQualifiedNameID() << ";" << EOL;
if( onRunning.valid() )
{
os << TAB2 << "@running{ " << onRunning.str() << " }" << EOL;
}
os << TAB << "}" << EOL_FLUSH;
}
}