blob: ef89839a1d4a8e7968780a59413aa3aeaed7e738 [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
*
* Created on: 18 févr. 2011
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "Machine.h"
#include <fml/type/TypeManager.h>
#include <fml/infrastructure/Buffer.h>
#include <fml/infrastructure/Channel.h>
#include <fml/infrastructure/Connector.h>
#include <fml/infrastructure/Port.h>
#include <fml/infrastructure/Routine.h>
#include <fml/infrastructure/Variable.h>
#include <fml/infrastructure/BehavioralPart.h>
#include <fml/infrastructure/CompositePart.h>
#include <fml/infrastructure/InstanceSpecifierPart.h>
#include <fml/infrastructure/InteractionPart.h>
#include <fml/infrastructure/ModelOfComputationPart.h>
#include <fml/infrastructure/PropertyPart.h>
namespace sep
{
////////////////////////////////////////////////////////////////////////////////
// MACHINE POINTER
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// MACHINE SMART POINTER
////////////////////////////////////////////////////////////////////////////////
/**
* CONSTRUCTOR
* Default
*/
Machine::Machine(Machine * aContainer,
const std::string & aNameID, const Specifier & aMocSpecifier)
: BehavioralElement(CLASS_KIND_T( Machine ), aContainer, aNameID),
SpecifierImpl( aMocSpecifier ),
mGroupId( ),
mOwnedElements( ),
mOwnedElementsSpecifier( ),
mModel( ),
mPropertyDeclaration( this , "property" ),
mModelOfComputation( NULL ),
mCompositeSpecification( new CompositePart(this, "composite") ),
mInteractionSpecification( NULL ),
mBehavioralSpecification( NULL ),
mInstanceSpecifier( new InstanceSpecifierPart(this, "instance") )
{
//!! NOTHING
}
/**
* CONSTRUCTOR
* Other
*/
Machine::Machine(Machine * aContainer, const std::string & aNameID,
const Specifier & aMocSpecifier, const BF & aModel,
avm_size_t anInitialInstanceCount, avm_size_t aMaximalInstanceCount)
: BehavioralElement(CLASS_KIND_T( Machine ), aContainer, aNameID),
SpecifierImpl( aMocSpecifier ),
mGroupId( ),
mOwnedElements( ),
mOwnedElementsSpecifier( ),
mModel( aModel ),
mPropertyDeclaration( this , "property" ),
mModelOfComputation( NULL ),
mCompositeSpecification( new CompositePart(this, "composite") ),
mInteractionSpecification( NULL ),
mBehavioralSpecification( NULL ),
mInstanceSpecifier( new InstanceSpecifierPart(this, aModel,
anInitialInstanceCount, aMaximalInstanceCount, "instance") )
{
//!! NOTHING
}
Machine::Machine(class_kind_t aClassKind, Machine * aContainer,
const std::string & aFullyQualifiedNameID, const std::string & aNameID,
const std::string & name, const Specifier & aMocSpecifier)
: BehavioralElement(aClassKind, aContainer, aFullyQualifiedNameID, aNameID, name),
SpecifierImpl( aMocSpecifier ),
mGroupId( ),
mOwnedElements( ),
mOwnedElementsSpecifier( ),
mModel( ),
mPropertyDeclaration( this , "property" ),
mModelOfComputation( NULL ),
mCompositeSpecification( new CompositePart(this, "composite") ),
mInteractionSpecification( NULL ),
mBehavioralSpecification( NULL ),
mInstanceSpecifier( new InstanceSpecifierPart(this, "instance") )
{
//!! NOTHING
}
/**
* DESTRUCTOR
*/
Machine::~Machine()
{
delete mModelOfComputation;
delete mCompositeSpecification;
delete mInteractionSpecification;
delete mBehavioralSpecification;
delete mInstanceSpecifier;
}
/**
* SETTER
* mGroupId
*/
void Machine::setGroupId()
{
if( getSpecifier().hasGroupMask() )
{
StringOutStream oss;
oss << ( getSpecifier().isGroupEvery() ? "[*" :
( getSpecifier().isGroupExcept() ? "[^" : "[" ) );
if( mGroupId.nonempty() )
{
ListOfString::const_iterator it = mGroupId.begin();
ListOfString::const_iterator endIt = mGroupId.end();
oss << (*it);
for( ++it ; it != endIt ; ++it)
{
oss << " , " << (*it);
}
}
oss << "]";
fullyUpdateAllNameID( oss.str() );
}
}
void Machine::expandGroupStatemachine()
{
if( mCompositeSpecification != NULL )
{
mCompositeSpecification->expandGroupStatemachine();
}
}
/**
* GETTER
* the machine container
* LC[R]A
*/
const Machine * Machine::LCA(const Machine * aMachine) const
{
List< const Machine * > containerListOfThis;
const Machine * itContainer = this->getContainerMachine();
for ( ; itContainer != NULL ;
itContainer = itContainer->getContainerMachine() )
{
containerListOfThis.push_back(itContainer);
}
List< const Machine * >::iterator it;
List< const Machine * >::iterator endIt = containerListOfThis.end();
itContainer = aMachine->getContainerMachine();
for ( ; itContainer != NULL ;
itContainer = itContainer->getContainerMachine() )
{
for ( it = containerListOfThis.begin() ; it != endIt ; ++it )
{
if ( (*it) == itContainer )
{
// AVM_OS_LOG << "LCA( " << this->getFullyQualifiedNameID()
// << " , " << aMachine->getFullyQualifiedNameID()
// << " ) = " << itContainer->getFullyQualifiedNameID();
return( itContainer );
}
}
}
return( NULL );
}
/**
* DISPATCH
* mOwnedElements
*/
void Machine::dispatchOwnedElement(const BF & anElement)
{
AVM_OS_ASSERT_FATAL_NULL_SMART_POINTER_EXIT( anElement )
<< "Executable Machine owned element !!!"
<< SEND_EXIT;
switch( anElement.classKind() )
{
// PROPERTY ELEMENT
case FORM_XFSP_VARIABLE_KIND:
case FORM_XFSP_DATATYPE_KIND:
case FORM_XFSP_BUFFER_KIND:
case FORM_XFSP_CHANNEL_KIND:
case FORM_XFSP_PORT_KIND:
{
mPropertyDeclaration.dispatchOwnedElement( anElement );
break;
}
// COMPOSITE STRUCTURE ELEMENT
case FORM_XFSP_MACHINE_KIND:
{
addOwnedElementSpecifier(
anElement.to_ptr< Machine >()->getSpecifier() );
getUniqCompositePart()->dispatchOwnedElement( anElement );
break;
}
case FORM_XFSP_TRANSITION_KIND:
{
getUniqBehaviorPart()->appendOutgoingTransition( anElement );
break;
}
// INTERACTION ELEMENT
case FORM_XFSP_CONNECTOR_KIND:
{
getUniqInteraction()->appendConnector( anElement );
break;
}
// BEHAVIORAL ELEMENT
case FORM_XFSP_ROUTINE_KIND:
{
getUniqBehaviorPart()->appendRoutine( anElement );
break;
}
case FORM_XFSP_PACKAGE_KIND:
default:
{ // TODO
AVM_OS_FATAL_ERROR_EXIT
<< "dispatchOwnedElement() unexpected object, typeinfo: "
<< anElement.classKindInfo() << "\n\t<< "
<< anElement.to_ptr< ObjectElement >()->strHeader()
<< " >> !!!"
<< SEND_EXIT;
break;
}
}
}
/**
* GETTER - SETTER
* mModelOfComputation
*/
ModelOfComputationPart * Machine::getUniqModelOfComputation()
{
if( mModelOfComputation == NULL )
{
mModelOfComputation = new ModelOfComputationPart(this, "moc");
}
return( mModelOfComputation );
}
/**
* GETTER - SETTER
* mCompositeSpecification
*/
CompositePart * Machine::getUniqCompositePart()
{
if( mCompositeSpecification == NULL )
{
mCompositeSpecification = new CompositePart(this, "composite");
}
return( mCompositeSpecification );
}
/**
* GETTER - SETTER
* mCompositeSpecification->mProcedures
*/
bool Machine::hasProcedure() const
{
return( (mCompositeSpecification != NULL) &&
mCompositeSpecification->hasProcedure() );
}
void Machine::saveProcedure(Machine * aProcedure)
{
mCompositeSpecification->saveProcedure( aProcedure );
}
/**
* GETTER - SETTER
* mCompositeSpecification->mStates
*/
bool Machine::hasState() const
{
return( (mCompositeSpecification != NULL) &&
mCompositeSpecification->hasState() );
}
/**
* GETTER - SETTER
* mCompositeSpecification->mMachines
*/
bool Machine::hasMachine() const
{
return( (mCompositeSpecification != NULL) &&
mCompositeSpecification->hasMachine() );
}
void Machine::saveMachine(Machine * aMachine)
{
mCompositeSpecification->saveMachine( aMachine );
}
/**
* GETTER - SETTER
* mInteractionSpecification
*/
InteractionPart * Machine::getUniqInteraction()
{
if( mInteractionSpecification == NULL )
{
mInteractionSpecification = new InteractionPart(this, "com");
}
return( mInteractionSpecification );
}
/**
* GETTER - SETTER
* mBehavioralSpecification
*/
BehavioralPart * Machine::getUniqBehaviorPart()
{
if( mBehavioralSpecification == NULL )
{
mBehavioralSpecification = new BehavioralPart(this, "moe");
}
return( mBehavioralSpecification );
}
bool Machine::hasRunnableBehavior() const
{
return( (mBehavioralSpecification != NULL)
&& (mBehavioralSpecification->hasOnRun()
|| mBehavioralSpecification->hasOnSchedule()
|| mBehavioralSpecification->hasOnConcurrency()) );
}
bool Machine::hasOnEnable() const
{
return( ( (mBehavioralSpecification != NULL)
&& mBehavioralSpecification->hasOnEnable() )
|| getSpecifier().hasPseudostateHistory() );
}
bool Machine::isInlinableEnable() const
{
return( (not getSpecifier().isPseudostate())
&& (mBehavioralSpecification != NULL)
&& (mBehavioralSpecification->hasOnEnable()
|| mBehavioralSpecification->hasOnIEnable()) );
}
/**
* GETTER - SETTER
* mBehavioralSpecification->mOutgoingTransitions
* mBehavioralSpecification->mIncomingTransitions
*/
bool Machine::hasOutgoingTransition() const
{
return( (mBehavioralSpecification != NULL)
&& mBehavioralSpecification->hasOutgoingTransition() );
}
bool Machine::hasIncomingTransition() const
{
return( (mBehavioralSpecification != NULL)
&& mBehavioralSpecification->hasIncomingTransition() );
}
/**
* GETTER - SETTER
* mInstanceSpecifier
*/
InstanceSpecifierPart * Machine::getUniqInstanceSpecifier()
{
if( mInstanceSpecifier == NULL )
{
mInstanceSpecifier = new InstanceSpecifierPart(this, "instance");
}
return( mInstanceSpecifier );
}
/**
* GETTER - SETTER
* "autostart" modifier of Instance
*/
bool Machine::isAutoStart() const
{
return( hasInstanceSpecifier()
&& getInstanceSpecifier()->isAutoStart() );
}
void Machine::setAutoStart(bool bAutoStart)
{
getUniqInstanceSpecifier()->setAutoStart( bAutoStart );
}
/**
* GETTER - SETTER
* mDeclarationParameter
*/
const TableOfVariable & Machine::getVariableParameters() const
{
return( mPropertyDeclaration.getVariableParameters() );
}
const BF & Machine::getVariableParameter(avm_size_t offset) const
{
return( mPropertyDeclaration.getVariableParameter(offset) );
}
avm_size_t Machine::getVariableParametersCount() const
{
return( mPropertyDeclaration.getVariableParametersCount() );
}
avm_offset_t Machine::getVariableParameterOffset(const std::string & aNameID) const
{
return( mPropertyDeclaration.getVariableParameterOffsetByNameID(aNameID) );
}
/**
* GETTER - SETTER
* mDeclarationReturn
*/
const TableOfVariable & Machine::getVariableReturns() const
{
return( mPropertyDeclaration.getVariableReturns() );
}
const BF & Machine::getVariableReturn(avm_size_t offset) const
{
return( mPropertyDeclaration.getVariableReturn(offset) );
}
avm_offset_t Machine::getVariableReturnsCount() const
{
return( mPropertyDeclaration.getVariableReturnsCount() );
}
avm_offset_t Machine::getVariableReturnOffset(const std::string & aNameID) const
{
return( mPropertyDeclaration.getVariableReturnOffsetByNameID(aNameID) );
}
/**
* GETTER - SETTER
* mPropertyPart
*/
bool Machine::hasProperty() const
{
return( mPropertyDeclaration.nonempty() );
}
bool Machine::hasPortSignal() const
{
return( mPropertyDeclaration.hasPort()
|| mPropertyDeclaration.hasSignal() );
}
/**
* Serialization
*/
void Machine::header(OutStream & os) const
{
os << getModifier().toString()
<< getSpecifier().strDesign_not(
Specifier::DESIGN_PROTOTYPE_STATIC_KIND)
<< getSpecifier().keywordComponent();
bool hasChevron = false;
if( hasSpecifier_otherThan( Specifier(
getSpecifier().getComponentKind() ).setStateMocSIMPLE() ) )
{
Specifier aSpecifier( getSpecifier() );
aSpecifier.unsetComponentKind();
aSpecifier.remStateMoc( Specifier::STATE_SIMPLE_MOC );
aSpecifier.unsetDesignKind();
if( aSpecifier.isDefined() )
{
hasChevron = true;
os << "< " << aSpecifier.str();
}
}
if( hasOwnedElementsSpecifier() )
{
Specifier aSpecifier( getOwnedElementsSpecifier() );
aSpecifier.unsetDesignKind();
if( aSpecifier.isDefined() )
{
if( hasChevron ) { os << " , "; }
else { os << "< "; hasChevron = true; }
os << "owned: " << aSpecifier.str();
}
}
if( hasInstanceSpecifier() )
{
mInstanceSpecifier->header(os, hasChevron);
}
os << ( hasChevron ? " > " : " " );
if( getSpecifier().hasGroupMask() )
{
os << ( getSpecifier().isGroupEvery() ? "[*" :
( getSpecifier().isGroupExcept() ? "[^" : "[" ) );
if( mGroupId.nonempty() )
{
ListOfString::const_iterator it = mGroupId.begin();
ListOfString::const_iterator endIt = mGroupId.end();
os << (*it);
for( ++it ; it != endIt ; ++it)
{
os << " , " << (*it);
}
}
os << "]";
}
else
{
os << getNameID();
}
}
void Machine::strHeader(OutStream & os) const
{
header( os );
mPropertyDeclaration.strVariableParameters(os, " [ ", " ]", ", ");
mPropertyDeclaration.strVariableReturns(os, " returns: [ ", " ]", ", ");
}
void Machine::toStream(OutStream & os) const
{
os << TAB;
header( os );
os << " {" << EOL;
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//
if( mOwnedElements.nonempty() )
{
os << TAB << "/*owned: [" << EOL_INCR_INDENT
<< str_header( mOwnedElements ) << DECR_INDENT_TAB
<< "] // end owned*/" << EOL2_FLUSH;
}
//
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
if( hasProperty() )
{
mPropertyDeclaration.toStream(os);
os << EOL;
}
if( (mBehavioralSpecification != NULL) &&
mBehavioralSpecification->hasAnyRoutine() )
{
mBehavioralSpecification->toStreamAnyRoutine( os );
}
if( mCompositeSpecification != NULL )
{
mCompositeSpecification->toStream( os );
}
if( mModelOfComputation != NULL )
{
mModelOfComputation->toStream(os);
}
if( mInteractionSpecification != NULL )
{
mInteractionSpecification->toStream(os);
os << EOL;
}
if( mBehavioralSpecification != NULL )
{
mBehavioralSpecification->toStreamMoe(os);
os << EOL;
}
os << TAB << "}" << EOL_FLUSH;
}
}