/** * get target id paths for all targets from target tree. * * @param [in] rtIdMap: id map with id -> id path data * @see */ BOOL CInstanceTree::GetTargetsFromTargetTree(TStringList& listTargets) { // get all targets as id paths SAFEARRAY* parrTargets; m_pProjectManager->getAllTargetsAsIdPaths(&parrTargets); BSTR HUGEP *pbstr; BSTR bstr; HRESULT hr; unsigned long i; // Get a pointer to the elements of the array. hr = ::SafeArrayAccessData(parrTargets, (void HUGEP**)&pbstr); if(FAILED(hr)) { return FALSE; } CString strIdPath; for (i = 0; i < (parrTargets->rgsabound[0]).cElements; i++) { bstr = pbstr[i]; strIdPath = (CString)bstr; listTargets.AddTail(strIdPath); } ::SafeArrayUnaccessData(parrTargets); ::SafeArrayDestroy(parrTargets); return TRUE; }
BOOL CInstanceTree::UpdateTargets() { // only do update if something has changed in the target view if (!(m_pProjectManager->GetTargetTree())->m_bTargetTreeChanged) { return TRUE; } BOOL ret; CXMLDocument tTargetDoc; TStringList listNewTargets; CXMLNode nodeTargetRoot; CXMLNode nodeInstanceRoot; // update lists TStringList listUpdateChanged; TStringList listUpdateNew; TStringList listUpdateDeleted; (m_pProjectManager->GetTargetTree())->m_bTargetTreeChanged = FALSE; // get instance tree root node if (!m_domDocument.GetRootNode(nodeInstanceRoot)) { return FALSE; } // get root node of target view IUnknown* pTmp = NULL; HRESULT hr = m_pProjectManager->GetTargetViewDOM(&pTmp); if(hr != S_OK) { return FALSE; } tTargetDoc.SetIXMLDocument(pTmp); pTmp->Release(); // add target nodes as children if(!tTargetDoc.GetRootNode(nodeTargetRoot)) { return FALSE; } // get new targets from target view if (!GetTargetsFromTargetTree(listNewTargets)) { return FALSE; } // empty xml tree nodeInstanceRoot.RemoveAllChilds(); // mark all nodes not used: POSITION posH = m_mapInstanceTargets.GetStartPosition(); while(posH) { CString strId; TInstanceTargetInfo* pInfo; m_mapInstanceTargets.GetNextAssoc(posH, strId, pInfo); if (pInfo) { pInfo->bUsed = FALSE; } } // look at all new targets, hang targets into the tree: // test if target is a new target or the attributes have changed or it is the same // in the last two cases, take the old node and only change attributes if necessary POSITION posNewTargets = listNewTargets.GetHeadPosition(); while(posNewTargets) { CXMLNode nodeTarget; CXMLNode nodeInstance; CXMLNode nodeLink; // attributes of the target node CString strTText; // node text CString strTId; // node id CString strTType; // node type (KAD type) CString strTAddress; // connect info CString strTUserAddress; // user connect info CString strTConsoleAddress; // console address CString strTAssignedResource; // assigned resource CString strTSource; // source file for add on action CString strParseSource; // parser source help var CString strParseSourceNew; // parser source CString strInstType; // type of the instance node CString strIdPathTarg; // id path of target node in target tree CString strIdPathInst; // id path of target instance in instance tree CString strTargetId; CString strWaitForTarget; strIdPathTarg = listNewTargets.GetNext(posNewTargets); strTargetId = strIdPathTarg; int iFind = strTargetId.ReverseFind(CE_XML_IDPATH_SEP_CHAR); ASSERT(iFind>0); if (iFind>0) { strTargetId = strTargetId.Mid(iFind+1); } // get target node ret = nodeTargetRoot.GetNodeFromIdPath(strIdPathTarg, nodeTarget); ASSERT(ret); if (!ret) { continue; } // get attributes of the target node nodeTarget.GetAttribute(CE_XMLATTR_TEXT, strTText); nodeTarget.GetAttribute(CE_XMLATTR_ID, strTId); nodeTarget.GetAttribute(CE_XMLATTR_TYPE, strTType); nodeTarget.GetAttribute(CE_XMLATTR_ADDR, strTAddress); nodeTarget.GetAttribute(CE_XMLATTR_USERADDR, strTUserAddress); nodeTarget.GetAttribute(CE_XMLATTR_CONSOLE_ADDR, strTConsoleAddress); nodeTarget.GetAttribute(CE_XMLATTR_RESOURCE, strTAssignedResource); nodeTarget.GetAttribute(CE_XMLATTR_SOURCE, strTSource); nodeTarget.GetAttribute(CE_XMLATTR_WAIT_TARGET_CONN , strWaitForTarget); strInstType = strTType + CE_XML_INST_ADD; strParseSource = strTId + _T(".") + CE_INSTANCE_EXT; strParseSourceNew = CString(CE_GEN_PATH) + _T("\\") + strTId + _T("\\") + strParseSource; // does node already exist in instance tree: TInstanceTargetInfo* pInstTargetInfo = NULL; CString strLowerId = strTargetId; strLowerId.MakeLower(); if (m_mapInstanceTargets.Lookup(strLowerId, pInstTargetInfo)) { // *** existing node *** ASSERT(pInstTargetInfo); pInstTargetInfo->bUsed = TRUE; nodeInstance = pInstTargetInfo->xmlNode; ret = nodeInstanceRoot.AppendChild(nodeInstance, TRUE); ASSERT(ret); // check if attributes have changed // get instance node attributes CString strInstText; CString strInstId; //CString strInstType; CString strInstAddress; CString strInstUserAddress; CString strInstConsoleAddress; CString strInstAssignedResource; CString strInstSource; nodeInstance.GetAttribute(CE_XMLATTR_TEXT, strInstText); nodeInstance.GetAttribute(CE_XMLATTR_ID, strInstId); //nodeInstance.GetAttribute(CE_XMLATTR_TYPE, strInstType); // type can't change nodeInstance.GetAttribute(CE_XMLATTR_ADDR, strInstAddress); nodeInstance.GetAttribute(CE_XMLATTR_USERADDR, strInstUserAddress); nodeInstance.GetAttribute(CE_XMLATTR_CONSOLE_ADDR, strInstConsoleAddress); nodeInstance.GetAttribute(CE_XMLATTR_RESOURCE, strInstAssignedResource); nodeInstance.GetAttribute(CE_XMLATTR_SOURCE, strInstSource); if ((strInstText.CompareNoCase(strTText)!=0) || (strInstId.CompareNoCase(strTId)!=0) //|| (strInstType.CompareNoCase(strType)!=0) || (strInstAddress.CompareNoCase(strTAddress)!=0) || (strInstConsoleAddress.CompareNoCase(strTConsoleAddress)!=0) || (strInstAssignedResource.CompareNoCase(strTAssignedResource)!=0) || (strInstSource.CompareNoCase(strTSource) != 0)) { // node has changed -> update nodes nodeInstance.SetAttribute(CE_XMLATTR_TEXT, strTText); nodeInstance.SetAttribute(CE_XMLATTR_ID, strTId); //nodeInstance.SetAttribute(CE_XMLATTR_TYPE, strType); nodeInstance.SetAttribute(CE_XMLATTR_ADDR, strTAddress); nodeInstance.SetAttribute(CE_XMLATTR_USERADDR, strTUserAddress); nodeInstance.SetAttribute(CE_XMLATTR_CONSOLE_ADDR, strTConsoleAddress); nodeInstance.SetAttribute(CE_XMLATTR_RESOURCE, strTAssignedResource); nodeInstance.SetAttribute(CE_XMLATTR_SOURCE, strTSource); listUpdateChanged.AddTail(pInstTargetInfo->strIdPath); } } else // *** new node *** { if(!m_domDocument.CreateNode(nodeInstance, CE_XMLTAG_NODE)) { continue; } // set attributes of target instance node nodeInstance.SetAttribute(CE_XMLATTR_TEXT, strTText); nodeInstance.SetAttribute(CE_XMLATTR_ID, strTId); nodeInstance.SetAttribute(CE_XMLATTR_ADDR, strTAddress); nodeInstance.SetAttribute(CE_XMLATTR_USERADDR, strTUserAddress); nodeInstance.SetAttribute(CE_XMLATTR_CONSOLE_ADDR, strTConsoleAddress); nodeInstance.SetAttribute(CE_XMLATTR_RESOURCE, strTAssignedResource); nodeInstance.SetAttribute(CE_XMLATTR_TARGET_TYPE, strTType); nodeInstance.SetAttribute(CE_XMLATTR_SOURCE, strTSource); nodeInstance.SetAttribute(CE_XMLATTR_TYPE, strInstType); if (!strWaitForTarget.IsEmpty()) { nodeInstance.SetAttribute(CE_XMLATTR_WAIT_TARGET_CONN, strWaitForTarget); } // create new instance info struct ASSERT(pInstTargetInfo==NULL); pInstTargetInfo = new TInstanceTargetInfo; ASSERT(pInstTargetInfo); if (!pInstTargetInfo) { continue; } ret = nodeInstanceRoot.AppendChild(nodeInstance, TRUE); ASSERT(ret); nodeInstance.GetIdPath(strIdPathInst); pInstTargetInfo->strIdPath = strIdPathInst; pInstTargetInfo->strTargetId = strTId; pInstTargetInfo->xmlNode = nodeInstance; pInstTargetInfo->bUsed = TRUE; strLowerId = strTId; strLowerId.MakeLower(); m_mapInstanceTargets.SetAt(strLowerId, pInstTargetInfo); // add to update list (new node) listUpdateNew.AddTail(strIdPathInst); // now create target link node: the link that will be replaced by compiler outpu if((!m_domDocument.CreateNode(nodeLink, CE_XMLTAG_LINK)) ||(!nodeInstance.AppendChild(nodeLink)) ) { continue; } nodeLink.SetAttribute(CE_XMLATTR_PARSERSOURCE, strParseSourceNew); nodeLink.SetAttribute(CE_XMLATTR_ID, strTId); TSourceFileInfo* pFileInfo; pFileInfo = CreateSourceFileInfo(strParseSourceNew, nodeLink, ""); SourceFileMap_SetAt(strParseSourceNew, pFileInfo, m_mapSourceFiles); AddSourceFileToReparse(strParseSourceNew); } } // find deleted nodes: posH = m_mapInstanceTargets.GetStartPosition(); while(posH) { CString strId; TInstanceTargetInfo* pInfo; m_mapInstanceTargets.GetNextAssoc(posH, strId, pInfo); if (pInfo) { if (pInfo->bUsed == FALSE) { listUpdateDeleted.AddTail(pInfo->strIdPath); delete pInfo; m_mapInstanceTargets.RemoveKey(strId); } } } if (m_bInit) { return TRUE; } // send update messages POSITION lPos; lPos = listUpdateDeleted.GetHeadPosition(); while(lPos) { CString strIdPath = listUpdateDeleted.GetNext(lPos); if (!strIdPath.IsEmpty()) { FireUpdateTree(strIdPath, eUpdateDelete); CString strId = strIdPath; int iFind = strId.ReverseFind(CE_XML_IDPATH_SEP_CHAR); ASSERT(iFind>0); if (iFind>0) { strId = strId.Mid(iFind+1); } CComBSTR sId = strId; m_pProjectManager->Fire_TargetInstanceRemoved(sId); } } lPos = listUpdateChanged.GetHeadPosition(); while(lPos) { CString strIdPath = listUpdateChanged.GetNext(lPos); if (!strIdPath.IsEmpty()) { FireUpdateTree(strIdPath, eUpdateAttributes); CString strId = strIdPath; int iFind = strId.ReverseFind(CE_XML_IDPATH_SEP_CHAR); ASSERT(iFind>0); if (iFind>0) { strId = strId.Mid(iFind+1); } CComBSTR sId = strId; CComBSTR sIdPath = strIdPath; m_pProjectManager->Fire_TargetInstanceAdded(sId, sIdPath); } } lPos = listUpdateNew.GetHeadPosition(); while(lPos) { CString strIdPath = listUpdateNew.GetNext(lPos); if (!strIdPath.IsEmpty()) { FireUpdateTree(strIdPath, eUpdateInsert); CString strId = strIdPath; int iFind = strId.ReverseFind(CE_XML_IDPATH_SEP_CHAR); ASSERT(iFind>0); if (iFind>0) { strId = strId.Mid(iFind+1); } CComBSTR sId = strId; CComBSTR sIdPath = strIdPath; m_pProjectManager->Fire_TargetInstanceAdded(sId, sIdPath); } } Reparse(FALSE); return TRUE; }