blob: f7def3d9998113674c64aa58447f2a51d9077cdf [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: 20 mai 2010
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "AvmStatusPrimitive.h"
#include <common/BF.h>
#include <computer/EvaluationEnvironment.h>
#include <computer/ExecutionDataFactory.h>
#include <computer/ExecutionEnvironment.h>
#include <fml/expression/ExpressionComparer.h>
#include <fml/expression/ExpressionConstant.h>
#include <fml/expression/ExpressionConstructor.h>
#include <fml/operator/Operator.h>
#include <fml/runtime/ExecutionConfiguration.h>
#include <fml/runtime/ExecutionData.h>
#include <fml/runtime/RuntimeID.h>
namespace sep
{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///// COMPUTE STATUS STATE
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
static bool firedTraceIsRun(const BF & aFiredTrace, const RuntimeID & aRID)
{
if( aFiredTrace.invalid() )
{
return false;
}
switch( aFiredTrace.classKind() )
{
case FORM_AVMCODE_KIND:
{
const AvmCode * anAvmCode = aFiredTrace.to_ptr< AvmCode >();
AvmCode::const_iterator it = anAvmCode->begin();
AvmCode::const_iterator itEnd = anAvmCode->end();
for( ; it != itEnd ; ++it )
{
if( firedTraceIsRun((*it), aRID) )
{
return( true );
}
}
break;
}
case FORM_EXECUTION_CONFIGURATION_KIND:
{
const ExecutionConfiguration * anExecConf =
aFiredTrace.to_ptr< ExecutionConfiguration >();
if( aRID == anExecConf->getRuntimeID() )
{
return( anExecConf->getOperator()->
isOpCode( AVM_OPCODE_RUN ) );
}
break;
}
case FORM_EXECUTION_CONTEXT_KIND:
{
return( firedTraceIsRun( aFiredTrace.to_ptr<
ExecutionContext >()->getRunnableElementTrace(), aRID) );
}
case FORM_EXECUTION_DATA_KIND:
{
return( firedTraceIsRun(aFiredTrace.to_ptr<
ExecutionData >()->getRunnableElementTrace(), aRID)
|| firedTraceIsRun(aFiredTrace.to_ptr< ExecutionData >()->
getExecutionContext()->getRunnableElementTrace(), aRID) );
}
default:
{
break;
}
}
return( false );
}
static bool computeStatusStateIs(const APExecutionData & apED,
const RuntimeID & aRID, const AVM_OPCODE op)
{
switch( op )
{
case AVM_OPCODE_RUN:
{
return( apED->isRunning(aRID) || firedTraceIsRun(apED, aRID) );
}
case AVM_OPCODE_SCHEDULE_INVOKE:
{
return( apED->isIdle(aRID) );
}
case AVM_OPCODE_START:
case AVM_OPCODE_RESTART:
{
return( apED->isDefinedPES(aRID) &&
(! apED->isLoaded(aRID)) &&
(! apED->isStarting(aRID)) &&
(! apED->isFinalized(aRID)) &&
(! apED->isDestroyed(aRID))
);
}
case AVM_OPCODE_ENABLE_INVOKE:
{
return( apED->isIdleOrRunning(aRID) );
}
case AVM_OPCODE_DISABLE_INVOKE:
case AVM_OPCODE_ABORT_INVOKE:
{
return( apED->isDisableOrAborted(aRID) );
}
case AVM_OPCODE_FINAL:
{
return( apED->isFinalized(aRID) );
}
case AVM_OPCODE_DESTROY:
{
return( apED->isDestroyed(aRID) );
}
case AVM_OPCODE_SUSPEND:
{
return( apED->isSuspended(aRID) );
}
case AVM_OPCODE_STOP:
{
return( apED->isStopped(aRID) );
}
case AVM_OPCODE_WAIT:
{
return( apED->isWaiting(aRID) );
}
default:
{
return( false );
}
}
}
static bool computeStatusBeing(const APExecutionData & prevED,
const APExecutionData & anED, const RuntimeID & aRID, AVM_OPCODE op)
{
switch( op )
{
case AVM_OPCODE_RUN:
{
if( prevED.valid() )
{
return( (! firedTraceIsRun(prevED, aRID) ) &&
(anED->isRunning(aRID) || firedTraceIsRun(anED, aRID)) );
}
else
{
return( anED->isRunning(aRID) );
}
}
case AVM_OPCODE_SCHEDULE_INVOKE:
{
if( prevED.valid() )
{
return( (! prevED->isIdle(aRID)) && anED->isIdle(aRID) );
}
else
{
return( anED->isRunning(aRID) );
}
}
case AVM_OPCODE_START:
case AVM_OPCODE_RESTART:
{
if( prevED.valid() )
{
return( (! prevED->isStarting(aRID)) &&
anED->isStarting(aRID) );
}
else
{
return( anED->isStarting(aRID) );
}
}
case AVM_OPCODE_FINAL:
{
if( prevED.valid() )
{
return( (! prevED->isFinalizing(aRID)) &&
anED->isFinalizing(aRID) );
}
else
{
return( anED->isFinalizing(aRID) );
}
}
case AVM_OPCODE_ENABLE_INVOKE:
{
if( prevED.valid() )
{
return( prevED->isDisableOrAborted(aRID) &&
anED->isIdleOrRunning(aRID) );
}
else
{
return( anED->isIdleOrRunning(aRID) );
}
}
case AVM_OPCODE_DISABLE_INVOKE:
{
if( prevED.valid() )
{
return( prevED->isIdleOrRunning(aRID) &&
anED->isDisable(aRID) );
}
else
{
return( anED->isIdleOrRunning(aRID) );
}
}
case AVM_OPCODE_ABORT_INVOKE:
{
if( prevED.valid() )
{
return( prevED->isIdleOrRunning(aRID) &&
anED->isAborted(aRID) );
}
else
{
return( anED->isIdleOrRunning(aRID) );
}
}
case AVM_OPCODE_SUSPEND:
{
if( prevED.valid() )
{
return( (! prevED->isSuspended(aRID)) &&
anED->isSuspended(aRID) );
}
else
{
return( anED->isSuspended(aRID) );
}
}
case AVM_OPCODE_WAIT:
{
if( prevED.valid() )
{
return( (! prevED->isWaiting(aRID)) &&
anED->isWaiting(aRID) );
}
else
{
return( anED->isWaiting(aRID) );
}
}
default:
{
return( false );
}
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///// STATUS WAS
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
bool AvmPrimitive_StatusWas::seval(EvaluationEnvironment & ENV)
{
if( ENV.inEC->hasPrevious() )
{
Operator * anOperator = ENV.mARG->at(0).to_ptr< Operator >();
switch( anOperator->getAvmOpCode() )
{
case AVM_OPCODE_ASSIGN:
{
ENV.outVAL = ExpressionConstructor::newBoolean(
ENV.isAssigned(ENV.mARG->outED.getPrevious(),
ENV.mARG->outED->mRID,
ENV.mARG->at(1).to_ptr< InstanceOfData >()));
return( true );
}
default:
{
const RuntimeID & aRID = ENV.mARG->at(1).bfRID();
if( aRID.valid() )
{
ENV.outVAL = ExpressionConstructor::newBoolean(
computeStatusStateIs(ENV.mARG->outED.getPrevious(),
aRID, anOperator->getAvmOpCode()));
return( true );
}
else
{
return( false );
}
}
}
}
else
{
ENV.outVAL = ExpressionConstant::BOOLEAN_FALSE;
return( true );
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///// STATUS IS
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
bool AvmPrimitive_StatusIs::seval(EvaluationEnvironment & ENV)
{
Operator * anOperator = ENV.mARG->at(0).to_ptr< Operator >();
switch( anOperator->getAvmOpCode() )
{
case AVM_OPCODE_ASSIGN:
{
ENV.outVAL = ExpressionConstructor::newBoolean(
ENV.isAssigned(ENV.mARG->outED,
ENV.mARG->outED->mRID,
ENV.mARG->at(1).to_ptr< InstanceOfData >()) );
return( true );
}
default:
{
const RuntimeID & aRID = ENV.mARG->at(1).bfRID();
if( aRID.valid() )
{
ENV.outVAL = ExpressionConstructor::newBoolean(
computeStatusStateIs(ENV.mARG->outED, aRID,
anOperator->getAvmOpCode()));
return( true );
}
else
{
return( false );
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///// STATUS BEING
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
bool AvmPrimitive_StatusBeing::seval(EvaluationEnvironment & ENV)
{
if( ENV.inEC->hasPrevious() )
{
Operator * anOperator = ENV.mARG->at(0).to_ptr< Operator >();
switch( anOperator->getAvmOpCode() )
{
case AVM_OPCODE_ASSIGN:
{
ENV.outVAL = ExpressionConstructor::newBoolean(
ENV.isAssigned(ENV.mARG->outED,
ENV.mARG->outED->mRID,
ENV.mARG->at(1).to_ptr< InstanceOfData >()) );
return( true );
}
default:
{
const RuntimeID & aRID = ENV.mARG->at(1).bfRID();
if( aRID.valid() )
{
ENV.outVAL = ExpressionConstructor::newBoolean(
computeStatusBeing(ENV.mARG->outED.getPrevious(),
ENV.mARG->outED, aRID,
anOperator->getAvmOpCode()));
return( true );
}
else
{
return( false );
}
}
}
}
else
{
ENV.outVAL = ExpressionConstant::BOOLEAN_FALSE;
}
return( true );
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///// STATUS WILL
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
bool AvmPrimitive_StatusWill::seval(EvaluationEnvironment & ENV)
{
Operator * anOperator = ENV.mARG->at(0).to_ptr< Operator >();
bool evalStatusFlag = false;
switch( anOperator->getAvmOpCode() )
{
case AVM_OPCODE_ASSIGN:
{
InstanceOfData * lvalue = ENV.mARG->at(1).to_ptr< InstanceOfData >();
ExecutionContext::child_iterator endEC = ENV.inEC->end();
ExecutionContext::child_iterator itEC;
evalStatusFlag = false;
for( itEC = ENV.inEC->begin() ; itEC != endEC ; ++itEC )
{
if( ENV.isAssigned((*itEC)->getAPExecutionData(),
ENV.mARG->outED->mRID, lvalue) )
{
evalStatusFlag = true;
break;
}
}
ENV.outVAL = ExpressionConstructor::newBoolean(evalStatusFlag);
return( true );
}
default:
{
const RuntimeID & aRID = ENV.mARG->at(1).bfRID();
if( aRID.valid() )
{
ExecutionContext::child_iterator endEC = ENV.inEC->end();
ExecutionContext::child_iterator itEC;
for( itEC = ENV.inEC->begin() ; itEC != endEC ; ++itEC )
{
if( computeStatusStateIs((*itEC)->getAPExecutionData(),
aRID, anOperator->getAvmOpCode()) )
{
evalStatusFlag = true;
break;
}
}
ENV.outVAL =
ExpressionConstructor::newBoolean(
evalStatusFlag);
return( true );
}
else
{
return( false );
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///// CHANGED
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
bool AvmPrimitive_Changed::seval(EvaluationEnvironment & ENV)
{
InstanceOfData * lvalue = ENV.mARG->at(0).to_ptr< InstanceOfData >();
bool isChangedFlag = true;
if( ENV.isAssigned(ENV.mARG->outED, ENV.mARG->outED->mRID, lvalue) )
{
isChangedFlag = true;
const BF & currentValue = ENV.getRvalue(ENV.mARG->outED,
ENV.mARG->outED->mRID, lvalue);
if( ENV.inEC->hasPrevious() )
{
isChangedFlag = currentValue.strNEQ(
ENV.getRvalue(ENV.mARG->outED.getPrevious(),
ENV.mARG->outED->mRID, lvalue));
}
if( (! isChangedFlag) && ENV.mARG->outED->hasExecutionContext() &&
(ENV.mARG->outED->getExecutionContext()->
getAPExecutionData() != ENV.mARG->outED) )
{
isChangedFlag = currentValue.strNEQ(
ENV.getRvalue(ENV.mARG->outED->getExecutionContext()->
getAPExecutionData(), ENV.mARG->outED->mRID, lvalue));
}
else
{
isChangedFlag = false;
}
}
else
{
isChangedFlag = false;
}
ENV.outVAL = ExpressionConstructor::newBoolean( isChangedFlag );
return( true );
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///// CHANGED TO
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//!! TODO OPTIMIZATION
bool AvmPrimitive_ChangedTo::seval(EvaluationEnvironment & ENV)
{
InstanceOfData * lvalue = ENV.mARG->at(0).to_ptr< InstanceOfData >();
if( ENV.isAssigned(ENV.mARG->outED, ENV.mARG->outED->mRID, lvalue) )
{
const BF & currentValue = ENV.getRvalue(ENV.mARG->outED,
ENV.mARG->outED->mRID, lvalue);
ENV.outVAL = ExpressionConstructor::newBoolean(
currentValue.strNEQ( ENV.mARG->at(1) ) );
}
else
{
ENV.outVAL = ExpressionConstant::BOOLEAN_FALSE;
}
return( true );
}
}