Esempio n. 1
0
void wxSFLayoutHorizontalTree::ProcessNode(wxSFShapeBase* node, double x)
{
	wxASSERT( node );
	
	if( node )
	{
		node->MoveTo( x, m_nMinY );
		
		wxRect rctBB = node->GetBoundingBox();
		if( rctBB.GetHeight() > m_nCurrMaxHeight ) m_nCurrMaxHeight = rctBB.GetHeight();
		
		ShapeList lstNeighbours;
		node->GetNeighbours( lstNeighbours, CLASSINFO(wxSFShapeBase), wxSFShapeBase::lineSTARTING );

		if( lstNeighbours.IsEmpty() )
		{
			m_nMinY += m_nCurrMaxHeight + m_VSpace;
		}
		else
		{
			for( ShapeList::iterator it = lstNeighbours.begin(); it != lstNeighbours.end(); ++it )
			{
				if( ! (*it)->GetParentShape() )	ProcessNode( *it, x + rctBB.GetWidth() + m_HSpace );
			}
		}
	}
}
void udLoopCaseAlgorithm::ProcessState(wxSFShapeBase *state)
{
    wxASSERT(state);
    if(!state)return;

    // check whether the state is already processed
    if( m_lstProcessedElements.IndexOf(state) != wxNOT_FOUND )return;

    wxSFDiagramManager *pDiagManager = state->GetShapeManager();
	udLanguage *pLang = m_pParentGenerator->GetActiveLanguage();
	
	pLang->SingleLineCommentCmd(wxT("State ID: ") + m_pParentGenerator->MakeIDName(state));

    // find state neighbours
    ShapeList lstNeighbours;
    pDiagManager->GetNeighbours(state, lstNeighbours, CLASSINFO(umlTransitionItem), wxSFShapeBase::lineSTARTING, sfDIRECT);
	// find next processable state
    if( !lstNeighbours.IsEmpty() && ( m_lstProcessedElements.IndexOf(lstNeighbours.GetFirst()->GetData()) == wxNOT_FOUND ) )
    {
        m_pNextElement = lstNeighbours.GetFirst()->GetData();
    }
    else
        m_pNextElement = NULL;
	
    // process given element
    udElementProcessor *pProcessor = GetElementProcessor(state->GetClassInfo()->GetClassName());
    if(pProcessor)
    {
        pProcessor->ProcessElement(state);
    }
    else
    {
        pLang->SingleLineCommentCmd(wxString::Format(wxT( "!!! WARNING: UNSUPPORTED ELEMENT ('%s') !!!"), ((udProjectItem*)state->GetUserData())->GetName().c_str()));
        IPluginManager::Get()->Log(wxString::Format(wxT("WARNING: '%s' element is not supported by this algorithm."), ((udProjectItem*)state->GetUserData())->GetName().c_str()));
    }

    // set the state as processes
    m_lstProcessedElements.Append(state);
	m_pPrevElement = state;

    // process connected states
    ShapeList::compatibility_iterator node = lstNeighbours.GetFirst();
    while(node)
    {
		wxSFShapeBase *pNext = node->GetData();

		ProcessState( pNext );
			
        node = node->GetNext();
    }
}
Esempio n. 3
0
void wxSFLayoutHorizontalTree::DoLayout(ShapeList& shapes)
{
	ShapeList lstConnections;
	ShapeList lstRoots;
	
	wxRealPoint nStart = GetTopLeft( shapes );
	m_nMinY = nStart.y;
	
	// find root items
	for( ShapeList::iterator it = shapes.begin(); it != shapes.end(); ++ it )
	{
		wxSFShapeBase *pShape = *it;
		
		lstConnections.Clear();
		pShape->GetAssignedConnections( CLASSINFO(wxSFLineShape), wxSFShapeBase::lineENDING, lstConnections );
		
		if( lstConnections.IsEmpty() )
		{
			m_nCurrMaxHeight = 0;
			ProcessNode( pShape, nStart.x );
		}
	}
}
void udCPPClassElementProcessor::ProcessClassDeclaration(wxSFShapeBase* element)
{
	udLanguage *pLang = m_pParentGenerator->GetActiveLanguage();
	udClassAlgorithm *pAlg = (udClassAlgorithm*) m_pParentGenerator->GetActiveAlgorithm();
	
	// get base classes if exists
	ShapeList lstBases;
	umlClassDiagram::GetBaseClasses( (umlClassItem*)element, lstBases );
	
	int nTemplateIndex = 0;
	
	wxString sBases;
	for( ShapeList::iterator it = lstBases.begin(); it != lstBases.end(); ++it )
	{
		if( it != lstBases.begin() ) sBases << wxT(", ");
		
		sBases << pLang->MakeValidIdentifier( udPROJECT::GetDiagramElement(*it)->GetName() );
		
		// add template parameter if exists
		umlClassTemplateItem *pTemplate = wxDynamicCast( *it, umlClassTemplateItem );
		if( pTemplate )
		{
			// find corespondent template binding connection
			ShapeList lstConnections;
			element->GetShapeManager()->GetAssignedConnections( element, CLASSINFO(umlTemplateBindItem), wxSFShapeBase::lineSTARTING, lstConnections );
			if( !lstConnections.IsEmpty() )
			{
				// append bind type to the base name
				udTemplateBindElementItem *pBindElement = wxDynamicCast( udPROJECT::GetDiagramElement( lstConnections.Item(nTemplateIndex)->GetData() ), udTemplateBindElementItem );
				if( pBindElement )
				{
					sBases << wxT("<") << pBindElement->GetBindType() << wxT(">");
				}
			}
			nTemplateIndex++;
		}
	}
	
	udClassElementItem *pClass = (udClassElementItem*) udPROJECT::GetDiagramElement(element);
	
	//generate comment if requested
	pLang->WriteCodeBlocks( udGenerator::GetComment( pClass, pLang) );
	
	// write template definition if needed
	udClassTemplateElementItem *pClassTempl = wxDynamicCast( pClass, udClassTemplateElementItem );
	if( pClassTempl )
	{
		pLang->WriteCodeBlocks( wxT("template <typename ") + pClassTempl->GetTemplateName() + wxT(">") );
	}
	
	// generate class declaration
	pLang->ClassDeclCmd( pLang->MakeValidIdentifier( pClass->GetName() ), sBases );
	
	pLang->BeginCmd();
	
	// declare class members
	int nAccessType = 0;
	wxClassInfo *pPrevType;
	
	SerializableList lstMembers;
	ShapeList lstAssocs;
	
	while( pLang->GetAccessTypeString( (udLanguage::ACCESSTYPE) nAccessType ) != wxEmptyString )
	{
		pLang->WriteCodeBlocks( pLang->GetAccessTypeString( (udLanguage::ACCESSTYPE) nAccessType ) + wxT(":") );
		pLang->IncIndentation();
		
		lstMembers.Clear();
		lstAssocs.Clear();
		pPrevType = NULL;
		
		// process associations
		umlClassDiagram::GetClassAssociations( (umlClassItem*) element, CLASSINFO(wxSFLineShape), wxSFLineShape::lineSTARTING, (udLanguage::ACCESSTYPE) nAccessType, lstAssocs );
		for( ShapeList::iterator it = lstAssocs.begin(); it != lstAssocs.end(); ++it )
		{
			udElementProcessor *pProcessor = pAlg->GetElementProcessor( (*it)->GetClassInfo()->GetClassName() );
			if( pProcessor ) pProcessor->ProcessElement( *it );
		}
		
		// process class members
		umlClassDiagram::GetClassMembers( (umlClassItem*) element, CLASSINFO(udMemberDataLinkItem), (udLanguage::ACCESSTYPE) nAccessType, lstMembers);
		umlClassDiagram::GetClassMembers( (umlClassItem*) element, CLASSINFO(udMemberFunctionLinkItem), (udLanguage::ACCESSTYPE) nAccessType, lstMembers);
		for( SerializableList::iterator it = lstMembers.begin(); it != lstMembers.end(); ++it )
		{
			if( pPrevType && ((*it)->GetClassInfo() != pPrevType) ) pLang->NewLine();
			
			// generate comment
			pLang->WriteCodeBlocks( udGenerator::GetComment( ((udCodeLinkItem*)*it)->GetOriginal(), pLang ) );
			// generate function decl
			pLang->WriteCodeBlocks( ((udCodeLinkItem*)*it)->ToString( udCodeItem::cfDECLARATION, pLang ) );
			
			pPrevType = (*it)->GetClassInfo();
		}
		
		nAccessType++;
		
		pLang->DecIndentation();
		pLang->NewLine();
	}
	
	// insert class ending with delimiter
	pLang->PushCode();
	pLang->EndCmd();
	wxString sEnding = pLang->GetCodeBuffer().Trim() + pLang->Delimiter();
	pLang->PopCode();
	
	pLang->WriteCodeBlocks( sEnding );
	
	pLang->NewLine();	
}
void udLoopCaseAlgorithm::ProcessAlgorithm(udDiagramItem *src)
{
    // test "prerequisites"
    wxASSERT(m_pParentGenerator);
    if(!m_pParentGenerator)return;

    wxASSERT(m_pParentGenerator->GetActiveLanguage());
    if(!m_pParentGenerator->GetActiveLanguage())return;

    wxSFDiagramManager *pDiagManager = &src->GetDiagramManager();
    udLanguage *pLang = m_pParentGenerator->GetActiveLanguage();
	
	udSStateChartDiagramItem *pSCH = wxDynamicCast( src, udSStateChartDiagramItem );
	if( ! pSCH ) return;
	
	bool fNonBlocking = pSCH->IsNonBlocking();
	bool fHasFinalState = pDiagManager->Contains(CLASSINFO(umlFinalItem));

    // get inital states
    ShapeList lstInitialStates;
    pDiagManager->GetShapes(CLASSINFO(umlInitialItem), lstInitialStates);
    pDiagManager->GetShapes(CLASSINFO(umlEntryItem), lstInitialStates);

    // create diagram function declaration
	if( !pSCH->IsInline() )
	{
		udFunctionItem *pDeclFcn = IPluginManager::Get()->GetProject()->GetFunctionImplementedBy( pSCH );
		if( pDeclFcn )
		{
			pLang->WriteCodeBlocks( pDeclFcn->ToString( udCodeItem::cfDEFINITION, pLang ) );
		}
		else
		{
			if( fHasFinalState )
				pLang->FunctionDefCmd(wxT("STATE_T"), m_pParentGenerator->MakeValidIdentifier(pSCH->GetName()), wxEmptyString );
			else
				pLang->FunctionDefCmd(pLang->GetDataTypeString(udLanguage::DT_VOID), m_pParentGenerator->MakeValidIdentifier(pSCH->GetName()), wxEmptyString );
		}			
		pLang->BeginCmd();
	}

    if( !lstInitialStates.IsEmpty() )
    {
        m_lstProcessedElements.Clear();

        wxSFShapeBase *pHistory, *pTarget, *pInitial = lstInitialStates.GetFirst()->GetData();
		
        // declare state variable
        pLang->SingleLineCommentCmd( wxT("set initial state") );
		
		if( fNonBlocking )
			pLang->VariableDeclAssignCmd( wxT("static STATE_T"), wxT("state"), m_pParentGenerator->MakeIDName(pInitial) );
		else
			pLang->VariableDeclAssignCmd( wxT("STATE_T"), wxT("state"), m_pParentGenerator->MakeIDName(pInitial) );
		
		// declare all history states and set history variables to proper values
		if( src->IsKindOf( CLASSINFO(udHStateChartDiagramItem) ) )
		{
			ShapeList lstHistoryStates, lstOutTrans;
			pDiagManager->GetShapes( CLASSINFO( umlHistoryItem ), lstHistoryStates );
			
			if( !lstHistoryStates.IsEmpty() ) pLang->SingleLineCommentCmd(wxT("set history states"));
			
			ShapeList::compatibility_iterator node = lstHistoryStates.GetFirst();
			while( node )
			{
				// find first processed state in a history level
				pHistory = node->GetData();
				
				lstOutTrans.Clear();
				pDiagManager->GetNeighbours( pHistory, lstOutTrans, CLASSINFO( umlTransitionItem ),  wxSFShapeBase::lineSTARTING, sfDIRECT );
				// there can be only one outcomming transition in hierarchical state with history
				if( !lstOutTrans.IsEmpty() )
				{
					pTarget = lstOutTrans.GetFirst()->GetData();
				
					if( fNonBlocking )
						pLang->VariableDeclAssignCmd( wxT("static STATE_T"), pLang->MakeValidIdentifier( udLABEL::GetContent( pHistory, udLABEL::ltTITLE ) ).Lower(), m_pParentGenerator->MakeIDName(pTarget) );
					else
						pLang->VariableDeclAssignCmd( wxT("STATE_T"), pLang->MakeValidIdentifier( udLABEL::GetContent( pHistory, udLABEL::ltTITLE ) ).Lower(), m_pParentGenerator->MakeIDName(pTarget) );
				}
				
				node = node->GetNext();
			}
		}
		
        pLang->NewLine();
        // create infinite loop
		if( !fNonBlocking )
		{
			pLang->InfiniteLoopCmd();
			pLang->BeginCmd();
		}
		// try to generate input action if set
		udFunctionItem *pInputAction = (udFunctionItem*) IPluginManager::Get()->GetProject()->GetProjectItem( CLASSINFO(udFunctionItem), pSCH->GetInputAction() );
		if( pInputAction )
		{
			pLang->SingleLineCommentCmd( wxT("Input action") );
			if( !pInputAction->IsInline() )  pLang->WriteCodeBlocks( pInputAction->ToString( udCodeItem::cfCALL, pLang ) );
			else
			{
				pLang->SingleLineCommentCmd( udGenerator::GetBeginCodeMark( pInputAction ) );
				pLang->WriteCodeBlocks( pInputAction->GetCode() );
				pLang->SingleLineCommentCmd( udGenerator::GetEndCodeMark( pInputAction ) );
			}
			pLang->SingleLineCommentCmd( wxT("State machine") );
		}
			
        pLang->SwitchCmd( wxT("state") );
        pLang->BeginCmd();

        // process diagram items (only one initial state is assumed)
        ProcessState( pInitial );

        pLang->EndCmd();
        if( !fNonBlocking ) pLang->EndCmd();
		/*else if( !pSCH->IsInline() && fHasFinalState )
		{
			pLang->NewLine();
			pLang->ReturnCmd( wxT("state") );
		}*/
    }

    //pLang->ReturnCmd(pLang->NullValue());
   if( !pSCH->IsInline() ) pLang->EndCmd();
}