void CComponentProxyManager::SetCurrentViewFileId(uint32_t uCurViewFileId)
{
    // Rebuild the m_proxyInCurScene
    m_proxyInCurScene.clear();
    const std::map<uint32_t, std::map<uint32_t, std::set<uint32_t> > >* pFileToComponentMap = m_pProject->GetFileToComponentMap();
    auto fileToComponentIter = pFileToComponentMap->find(uCurViewFileId);
    if (fileToComponentIter != pFileToComponentMap->end())
    {
        for (auto subIter = fileToComponentIter->second.begin(); subIter != fileToComponentIter->second.end(); ++subIter)
        {
            for (auto idIter = subIter->second.begin(); idIter != subIter->second.end(); ++idIter)
            {
                uint32_t uComponentId = *idIter;
                BEATS_ASSERT(m_proxyInCurScene.find(uComponentId) == m_proxyInCurScene.end());
                CComponentProxy* pProxy = static_cast<CComponentProxy*>(CComponentProxyManager::GetInstance()->GetComponentInstance(uComponentId));
                // If the component is deleted in code, it is possible that proxy is null.
                BEATS_ASSERT(pProxy != NULL || GetComponentTemplate(m_pProject->QueryComponentGuid(uComponentId)) == NULL);
                if (pProxy != NULL)
                {
                    m_proxyInCurScene[uComponentId] = pProxy;
                }
            }
        }
    }
    m_uCurrViewFileId = uCurViewFileId;
}
TString CComponentProxyManager::QueryComponentName(uint32_t uGuid) const
{
    TString strRet;
    std::map<uint32_t, TString>::const_iterator iter = m_abstractComponentNameMap.find(uGuid);
    if (iter != m_abstractComponentNameMap.end())
    {
        strRet = iter->second;
    }
    else
    {
        CComponentBase* pComponent = GetComponentTemplate(uGuid);
        if (pComponent != NULL)
        {
            strRet = pComponent->GetClassStr();
        }
    }
    return strRet;
}
void FSCSDiff::OnSCSEditorUpdateSelectionFromNodes(const TArray<FSCSEditorTreeNodePtrType>& SelectedNodes)
{
	FText InspectorTitle = FText::GetEmpty();
	TArray<UObject*> InspectorObjects;
	InspectorObjects.Empty(SelectedNodes.Num());
	for (auto NodeIt = SelectedNodes.CreateConstIterator(); NodeIt; ++NodeIt)
	{
		auto NodePtr = *NodeIt;
		if(NodePtr.IsValid() && NodePtr->CanEditDefaults())
		{
			InspectorTitle = FText::FromString(NodePtr->GetDisplayString());
			InspectorObjects.Add(NodePtr->GetComponentTemplate());
		}
	}

	if( Inspector.IsValid() )
	{
		SKismetInspector::FShowDetailsOptions Options(InspectorTitle, true);
		Inspector->ShowDetailsForObjects(InspectorObjects, Options);
	}
}
void CComponentProxyManager::SaveToFile(const TCHAR* pszFileName, std::map<uint32_t, std::vector<CComponentProxy*>>& components)
{
    rapidxml::xml_document<> doc;
    rapidxml::xml_node<>* pDecl = doc.allocate_node(rapidxml::node_declaration);
    rapidxml::xml_attribute<>* pDecl_ver = doc.allocate_attribute("version", "1.0");
    pDecl->append_attribute(pDecl_ver);
    doc.append_node(pDecl);
    rapidxml::xml_node<>* pRootElement = doc.allocate_node(rapidxml::node_element, "Root");
    doc.append_node(pRootElement);

    rapidxml::xml_node<>* pComponentListElement = doc.allocate_node(rapidxml::node_element, "Components");
    pRootElement->append_node(pComponentListElement);
    for (std::map<uint32_t, std::vector<CComponentProxy*>>::iterator iter = components.begin(); iter != components.end(); ++iter)
    {
        rapidxml::xml_node<>* pComponentElement = doc.allocate_node(rapidxml::node_element, "Component");
        char szGUIDHexStr[32] = {0};
        sprintf(szGUIDHexStr, "0x%x", iter->first);
        pComponentElement->append_attribute(doc.allocate_attribute("GUID", doc.allocate_string(szGUIDHexStr)));
        pComponentElement->append_attribute(doc.allocate_attribute("Name", doc.allocate_string(GetComponentTemplate(iter->first)->GetClassStr())));
        pComponentListElement->append_node(pComponentElement);
        for (uint32_t i = 0; i < iter->second.size(); ++i)
        {
            CComponentProxy* pProxy = static_cast<CComponentProxy*>(iter->second.at(i));
            pProxy->Save();
            pProxy->SaveToXML(pComponentElement, false);
        }
    }

    TString strOut;
#if (BEYONDENGINE_PLATFORM == PLATFORM_WIN32)
    rapidxml::print(std::back_inserter(strOut), doc, 0);
#endif
    std::ofstream out(pszFileName);
    out << strOut;
    out.close();
}
void CComponentProxyManager::LoadFile(uint32_t uFileId, std::vector<CComponentBase*>* pComponentContainer)
{
    const TString& strFilePath = m_pProject->GetComponentFileName(uFileId);
    BEATS_ASSERT(strFilePath.length() > 0);
    if (CFilePathTool::GetInstance()->Exists(strFilePath.c_str()))
    {
        rapidxml::file<> fdoc(strFilePath.c_str());
        rapidxml::xml_document<> doc;
        try
        {
            doc.parse<rapidxml::parse_default>(fdoc.data());
            doc.m_pszFilePath = strFilePath.c_str();
        }
        catch (rapidxml::parse_error &e)
        {
            TCHAR info[MAX_PATH];
            _stprintf(info, _T("Load file :%s Failed! error :%s"), strFilePath.c_str(), e.what());
            MessageBox(BEYONDENGINE_HWND, info, _T("Load File Failed"), MB_OK | MB_ICONERROR);
        }
        BEATS_ASSERT(std::find(m_loadedFiles.begin(), m_loadedFiles.end(), uFileId) == m_loadedFiles.end());
        m_loadedFiles.push_back(uFileId);

        rapidxml::xml_node<>* pRootElement = doc.first_node("Root");
        rapidxml::xml_node<>* pComponentListNode = pRootElement->first_node("Components");
        if (pComponentListNode != NULL)
        {
            bool bRestoreLoadingPhase = CComponentInstanceManager::GetInstance()->IsInLoadingPhase();
            CComponentInstanceManager::GetInstance()->SetLoadPhaseFlag(true);
            std::vector<CComponentProxy*> loadedProxyList;
            rapidxml::xml_node<>* pComponentElement = pComponentListNode->first_node("Component");
            while (pComponentElement != NULL)
            {
                const char* pGuidStr = pComponentElement->first_attribute("GUID")->value();
                char* pStopPos = NULL;
                int guid = strtoul(pGuidStr, &pStopPos, 16);
                BEATS_ASSERT(*pStopPos == 0, _T("Guid value %s is not a 0x value at file %s."), pGuidStr, strFilePath.c_str());
                if (GetComponentTemplate(guid) == NULL)
                {
                    CComponentProxyManager::GetInstance()->GetRefreshFileList().insert(uFileId);
                    BEATS_ASSERT(false, _T("Can't create component with \nGUID 0x%x\nName %s\nFile id:%d Name:%s\nHave you removed this component class?"), guid, pComponentElement->first_attribute("Name")->value(), uFileId, strFilePath.c_str());
                }
                else
                {
                    rapidxml::xml_node<>* pInstanceElement = pComponentElement->first_node();
                    while (pInstanceElement != NULL)
                    {
                        int id = atoi(pInstanceElement->first_attribute("Id")->value());
                        BEATS_ASSERT(id != -1);
                        CComponentProxy* pComponentProxy = NULL;
                        if (strcmp(pInstanceElement->name(), "Instance") == 0)
                        {
                            pComponentProxy = down_cast<CComponentProxy*>(CreateComponent(guid, false, false, id, false, NULL, false));
                        }
                        pComponentProxy->LoadFromXML(pInstanceElement);
                        loadedProxyList.push_back(pComponentProxy);
                        if (pComponentContainer != nullptr)
                        {
                            pComponentContainer->push_back(pComponentProxy);
                        }
                        pInstanceElement = pInstanceElement->next_sibling();
                    }
                }
                pComponentElement = pComponentElement->next_sibling("Component");
            }
            ResolveDependency();
            CComponentInstanceManager::GetInstance()->SetLoadPhaseFlag(bRestoreLoadingPhase);
            if (!CComponentProxyManager::GetInstance()->IsExporting())
            {
                // Call component proxy's initialize means we have sync all value to host component, so we call host component's load function.
                for (size_t i = 0; i < loadedProxyList.size(); ++i)
                {
                    loadedProxyList[i]->Initialize();
                }
                for (size_t i = 0; i < loadedProxyList.size(); ++i)
                {
                    CComponentInstance* pHostComponent = static_cast<CComponentProxy*>(loadedProxyList[i])->GetHostComponent();
                    if (pHostComponent != nullptr)
                    {
                        pHostComponent->Load();
                    }
                    else
                    {
                        BEATS_ASSERT(m_bCreateInstanceWithProxy == false, "Only when m_bCreateInstanceWithProxy is set to false, we can't get the host component");
                    }
                }
            }
        }
    }
}