Exemple #1
0
bool
CDataNode::Compare( const CDataNode& other        ,
                    const TStringSet& excludeList ) const
{GUCEF_TRACE;

    // identical nodes should of course have identical names
    if ( _name == other._name )
    {
        const TKeyValuePair* att;
        const TKeyValuePair* att2;
        const UInt32 count = other._atts.size();
        
        // if one has a bigger list then the other then they cannot be the same
        if ( _atts.size() == count )
        {
            // same number of entries in the lists, we will have to compare each item
            for ( UInt32 i=0; i<count; ++i )
            {
                    att = other[ i ];
                    if ( att )
                    {
                        if ( excludeList.end() == excludeList.find( att->first ) )
                        {
                            att2 = GetAttribute( att->first );
                            if ( att2 )
                            {
                                if ( att->second != att2->second )
                                {
                                        return false;
                                }
                            }                            
                        }
                    }                                                        
            }
            
            // Everything checked out,.. nodes are identical content wise when taking
            // the exclusion list into account.
            return true;
        }
        return false;             
    }
    return false;    
}
void ClientInfoManager::CheckInfoProc()
{
	TStringVector clientidList;
	CommManager::GetInstanceRef().ListAvailableClient(clientidList);

	TStringSet clientidSet;
	TStringVector2TStringSet(clientidList, clientidSet);

	m_infoMapSection.Enter();
	{
		//从m_clientBaseInfoMap中删除已经不可用的clientinfo
		ClientBaseInfoMap::iterator infoIter = m_clientBaseInfoMap.begin();
		while (infoIter != m_clientBaseInfoMap.end())
		{
			if (clientidSet.find(infoIter->first) == clientidSet.end())
			{
				CLIENT_INFO clientInfo = {0};
				TransferInfo(infoIter->first.c_str(), &infoIter->second, clientInfo);
				if (NULL != m_fnCallback && (infoIter->second.bAdd == FALSE))
					m_fnCallback(WM_DEL_CLIENT, (LPVOID)&clientInfo, m_lpParameter);
				infoIter = m_clientBaseInfoMap.erase(infoIter);
			}
			else
			{
				infoIter++;
			}
		}

		//遍历clientidList,更新m_clientBaseInfoMap
		TStringVector::iterator clientidIter = clientidList.begin();
		for (; clientidIter != clientidList.end(); clientidIter++)
		{
			const tstring& clientid = *clientidIter;

			infoIter = m_clientBaseInfoMap.find(clientid.c_str());

			//如果m_clientBaseInfoMap中没有该客户端的信息,则请求客户端上报
			if (infoIter == m_clientBaseInfoMap.end())
			{
				CLIENT_BASE_INFO info;
				info.bValid = FALSE;
				info.bAdd = TRUE;
				RequestReportInfo(clientid.c_str());
				m_clientBaseInfoMap[clientid] = info;
			}
			else
			{
				if (infoIter->second.installModMsgIDMap.size() > 0)
				{
					HandleInstalMsg(clientid,infoIter->second);
				}

				if (infoIter->second.bValid && infoIter->second.bAdd)
				{
					CLIENT_INFO info;
					TransferInfo(clientid.c_str(),&m_clientBaseInfoMap[clientid.c_str()],info);
					if (NULL != m_fnCallback) m_fnCallback(WM_ADD_CLIENT, (LPVOID)&info, m_lpParameter);
					infoIter->second.bAdd = FALSE;
				}
			}

		}
	}
	m_infoMapSection.Leave();
}
CORE::CString
GenerateContentForAndroidMakefile( const TModuleInfoEntryPairVector& mergeLinks ,
                                   const TModuleInfo& moduleInfo                ,
                                   const CORE::CString& moduleRoot              ,
                                   bool addGeneratorCompileTimeToOutput         ,
                                   TStringSet& ndkModulesUsed                   )
{GUCEF_TRACE;

    CORE::CString contentPrefix = makefileHeader;

    if ( addGeneratorCompileTimeToOutput )
    {
        contentPrefix +=
          "#"
          "# The project generator version used was compiled on " __TIME__ __DATE__ "\n"
          "#\n\n";
    }

    contentPrefix +=
      "ifndef MY_MODULE_PATH\n"
      "  MY_MODULE_PATH := $(call my-dir)\n"
      "endif\n"
      "LOCAL_PATH := $(MY_MODULE_PATH)\n\n"
      "include $(CLEAR_VARS)\n\n"
      "@echo Module path: $(MY_MODULE_PATH)\n"
      "LOCAL_MODULE := " + moduleInfo.name + "\n";

    if ( ( MODULETYPE_SHARED_LIBRARY == moduleInfo.moduleType ) ||
         ( MODULETYPE_STATIC_LIBRARY == moduleInfo.moduleType )  )
    {
        contentPrefix += "LOCAL_MODULE_FILENAME := lib" + moduleInfo.name + "\n";
    }
    contentPrefix += "@echo Module name: $(LOCAL_MODULE)\n\n";

    // Generate the source files section
    CORE::CString srcFilesSection = "LOCAL_SRC_FILES := \\\n";
    bool firstLoop = true;
    TStringVectorMap::const_iterator i = moduleInfo.sourceDirs.begin();
    while ( i != moduleInfo.sourceDirs.end() )
    {
        const CORE::CString& srcDir = (*i).first;
        const TStringVector& srcFiles = (*i).second;

        TStringVector::const_iterator n = srcFiles.begin();
        while ( n != srcFiles.end() )
        {
            if ( !firstLoop )
            {
                srcFilesSection += " \\\n";
            }
            firstLoop = false;

            CORE::CString relFilePath = srcDir;
            CORE::AppendToPath( relFilePath, (*n) );

            srcFilesSection += "  " + relFilePath.ReplaceChar( '\\', '/' );

            ++n;
        }
        ++i;
    }

    // Add some spacing for readability
    srcFilesSection += "\n\n";

    // Generate the included files section
    // for android make files we only need the path
    // it will locate the header file on its own
    CORE::CString includeFilesSection = "LOCAL_C_INCLUDES := \\\n";
    i = moduleInfo.includeDirs.begin();
    firstLoop = true;
    while ( i != moduleInfo.includeDirs.end() )
    {
        if ( !firstLoop )
        {
            includeFilesSection += " \\\n";
        }
        firstLoop = false;

        const CORE::CString& dir = (*i).first;
        if ( !dir.IsNULLOrEmpty() )
        {
            includeFilesSection += "  $(MY_MODULE_PATH)/" + dir.ReplaceChar( '\\', '/' );
        }
        else
        {
            // Support the use-case where the include dir is empty because the moduleinfo dir == include dir
            includeFilesSection += "  $(MY_MODULE_PATH)";
        }

        ++i;
    }

    // We also need to add the include paths required to find headers
    // refered to because of dependencies
    TStringSet::const_iterator n = moduleInfo.dependencyIncludeDirs.begin();
    while ( n != moduleInfo.dependencyIncludeDirs.end() )
    {
        if ( !firstLoop )
        {
            includeFilesSection += " \\\n";
        }
        firstLoop = false;

        includeFilesSection += "  $(MY_MODULE_PATH)/" + (*n).ReplaceChar( '\\', '/' );

        ++n;
    }

    // Add some spacing for readability
    includeFilesSection += "\n\n";

    // Now we add the preprocessor definitions
    CORE::CString preprocessorSection;
    if ( !moduleInfo.preprocessorSettings.defines.empty() )
    {
        preprocessorSection = "LOCAL_CFLAGS :=";

        TStringSet::const_iterator m = moduleInfo.preprocessorSettings.defines.begin();
        while ( m != moduleInfo.preprocessorSettings.defines.end() )
        {
            preprocessorSection += " -D" + (*m);
            ++m;
        }

        // Add some spacing for readability
        preprocessorSection += "\n\n";
    }

    // Now we add the compiler flags, if any
    // For Android we only support the GCC compilers
    CORE::CString compilerSection;
    TStringMap::const_iterator p = moduleInfo.compilerSettings.compilerFlags.find( "GCC" );
    if ( p != moduleInfo.compilerSettings.compilerFlags.end() )
    {
        compilerSection = "LOCAL_CFLAGS +=" + (*p).second + "\n\n";
    }
    p = moduleInfo.compilerSettings.compilerFlags.find( "G++" );
    if ( p != moduleInfo.compilerSettings.compilerFlags.end() )
    {
        compilerSection = "LOCAL_CPPFLAGS +=" + (*p).second + "\n\n";
    }

    // Now we will add all the dependency linking instructions.
    // For some reason it matters, at specification time, to Android's build
    // system whether the module you are linking to is a dynamically linked module
    // or a statically linked module. As such we have to figure out which is which.
    //
    // We make an alphabetical list instead of creating the section right away because
    // we dont want the order to vary in the makefile because such changes cause the NDK
    // to build the code again for no reason.
    CORE::CString linkingErrorSection;
    TStringSet linkedSharedLibraries;
    TStringSet linkedStaticLibraries;
    TStringSet linkedRuntimeLibraries;
    TModuleTypeMap::const_iterator m = moduleInfo.linkerSettings.linkedLibraries.begin();
    while ( m != moduleInfo.linkerSettings.linkedLibraries.end() )
    {
        const CORE::CString& linkedLibName = (*m).first;
        TModuleType linkedLibType = (*m).second;
        switch ( linkedLibType )
        {
            case MODULETYPE_EXECUTABLE:
            {
                // This is really nasty but the best option for now...
                // It is possible to link to exported symbols from an executable
                // under linux and as such we will leverage this here
                linkedSharedLibraries.insert( linkedLibName );
                break;
            }
            case MODULETYPE_SHARED_LIBRARY:
            {
                linkedSharedLibraries.insert( linkedLibName );
                break;
            }
            case MODULETYPE_STATIC_LIBRARY:
            {
                linkedStaticLibraries.insert( linkedLibName );
                break;
            }
            case MODULETYPE_CODE_INTEGRATE_LOCATION:
            case MODULETYPE_HEADER_INTEGRATE_LOCATION:
            case MODULETYPE_HEADER_INCLUDE_LOCATION:
            {
                // Skip this, no linking required
                break;
            }
            default:
            {
                // Since the depedendency module type was not predefined we will investigate among
                // the other modules to try to determine the nature of the linked module
                const TModuleInfo* linkedDependency = FindModuleByName( mergeLinks, linkedLibName );
                if ( NULL != linkedDependency )
                {
                    // The module we are linking too is part of this project.
                    // As such we can simply check the other module's info
                    // to find out wheter its a dynamically linked module or not
                    // which in turn tells us how to instruct the Android build system
                    // to link.
                    switch( linkedDependency->moduleType )
                    {
                        case MODULETYPE_SHARED_LIBRARY:
                        {
                            linkedSharedLibraries.insert( linkedLibName );
                            break;
                        }
                        case MODULETYPE_STATIC_LIBRARY:
                        {
                            linkedStaticLibraries.insert( linkedLibName );
                            break;
                        }
                        case MODULETYPE_EXECUTABLE:
                        {
                            // This is really nasty but the best option for now...
                            // It is possible to link to exported symbols from an executable
                            // under linux and as such we will leverage this here
                            linkedSharedLibraries.insert( linkedLibName );
                            break;
                        }
                        case MODULETYPE_HEADER_INTEGRATE_LOCATION:
                        case MODULETYPE_CODE_INTEGRATE_LOCATION:
                        {
                            // Dont do anything.
                            // The files for this 'module' have already been merged into the dependent module
                            break;
                        }
                        case MODULETYPE_HEADER_INCLUDE_LOCATION:
                        {
                            // Don't have to do anything.
                            // Due to the auto-dependency tracking of include paths the header paths will have been added to
                            // whatever module depends on this 'module'
                            break;
                        }
                        default:
                        {
                            linkingErrorSection +=
                              "# *** ERROR *** Finish me\n"
                              "# Unable to determing module type from the source information\n"
                              "# Please edit the line below to manually set the correct linking method for this dependency\n";
                            linkingErrorSection += "#LOCAL_<(LDLIBS???)> += " + moduleInfo.name + "\n\n";

                            GUCEF_ERROR_LOG( CORE::LOGLEVEL_NORMAL, "Error: the module " + moduleInfo.name + " does not have a useable module type set, you will have to manually edit the file to correct the error" );
                            break;
                        }
                    }
                }
                else
                {
                    // If we get here then this dependency is not on a module which is part of the project
                    // As such we cannot build this module thus the only approriote linking method would seem
                    // to be the one where we simply instruct the linker to load this dependency at runtime.
                    // This will typically be the case for any Android NDK modules we have to link to.
                    linkedRuntimeLibraries.insert( linkedLibName );
                }
            }
        }
        ++m;
    }

    CORE::CString linkingSection;
    CORE::CString linkedSharedLibrariesSection = "\nLOCAL_SHARED_LIBRARIES := \\\n";
    CORE::CString linkedStaticLibrariesSection = "\nLOCAL_STATIC_LIBRARIES := \\\n";
    CORE::CString linkedRuntimeLibrariesSection = "\nLOCAL_LDLIBS := \\\n";

    // Based on what was found we will construct the linking section
    bool first = true;
    n = linkedSharedLibraries.begin();
    while ( n != linkedSharedLibraries.end() )
    {
        if ( !first )
        {
             linkedSharedLibrariesSection += " \\\n";
        }
        linkedSharedLibrariesSection += "  " + (*n);
        first = false;
        ++n;
    }
    first = true;
    n = linkedStaticLibraries.begin();
    while ( n != linkedStaticLibraries.end() )
    {
        if ( !first )
        {
             linkedStaticLibrariesSection += " \\\n";
        }
        linkedStaticLibrariesSection += "  " + (*n);
        first = false;
        ++n;
    }
    first = true;
    n = linkedRuntimeLibraries.begin();
    while ( n != linkedRuntimeLibraries.end() )
    {
        if ( !first )
        {
             linkedRuntimeLibrariesSection += " \\\n";
        }
        linkedRuntimeLibrariesSection += "  -l" + (*n);
        first = false;
        ++n;
    }

    if ( !linkedSharedLibraries.empty() )
    {
        linkingSection += linkedSharedLibrariesSection + "\n\n";
    }
    if ( !linkedStaticLibraries.empty() )
    {
        linkingSection += linkedStaticLibrariesSection + "\n\n";
    }
    if ( !linkedRuntimeLibraries.empty() )
    {
        linkingSection += linkedRuntimeLibrariesSection + "\n\n";
    }
    linkingSection += linkingErrorSection;

    // Check if we have a file on disk of information which is to be inserted into
    // our automatically generated make file
    CORE::CString manualContent;
    CORE::CString manualContentFilePath = moduleRoot;
    CORE::AppendToPath( manualContentFilePath, "AndroidAddition.mk" );
    if ( CORE::FileExists( manualContentFilePath ) )
    {
        if ( CORE::LoadTextFileAsString( manualContentFilePath ,
                                         manualContent         ) )
        {
            GUCEF_LOG( CORE::LOGLEVEL_NORMAL, "Successfully loaded manually defined content for module " + moduleInfo.name + " from addition file " + manualContentFilePath );
        }
        else
        {
            manualContent =
              "# *** ERROR *** Finish me\n"
              "# Unable to load manually defined content from detected AndroidAddition.mk file\n"
              "# Please manually insert its contents here\n\n";
            GUCEF_ERROR_LOG( CORE::LOGLEVEL_NORMAL, "Error: the module " + moduleInfo.name + " has manually defined content in a AndroidAddition.mk file but it could not be loaded, you will have to manually edit the file to correct the error" );
        }
    }

    // Now generate the latter part of the file which contains more meta data about the module
    CORE::CString contentSuffix;
    switch ( moduleInfo.moduleType )
    {
        case MODULETYPE_SHARED_LIBRARY:
        {
            contentSuffix += "include $(BUILD_SHARED_LIBRARY)\n\n";
            break;
        }
        case MODULETYPE_STATIC_LIBRARY:
        {
            contentSuffix += "include $(BUILD_STATIC_LIBRARY)\n\n";
            break;
        }
        case MODULETYPE_EXECUTABLE:
        {
            contentSuffix += "include $(BUILD_EXECUTABLE)\n\n";
            break;
        }
        default:
        {
            contentSuffix +=
              "# *** ERROR *** Finish me\n"
              "# Unable to determine module type from the source information\n"
              "# Please edit the line below to manually set the correct module type to build\n"
              "#include $(BUILD_???)\n\n";

            GUCEF_ERROR_LOG( CORE::LOGLEVEL_NORMAL, "Error: the module " + moduleInfo.name + " does not have a useable module type set, you will have to manually edit the file to correct the error" );
            break;
        }
    }

    // Check for NDK static libraries to import
    if ( !linkedStaticLibraries.empty() )
    {
        TStringSet::iterator a = linkedStaticLibraries.find( "android_native_app_glue" );
        if ( a != linkedStaticLibraries.end() )
        {
            ndkModulesUsed.insert( "android_native_app_glue" );
            contentSuffix += "$(call import-module,android/native_app_glue)\n";
        }
        a = linkedStaticLibraries.find( "cpufeatures" );
        if ( a != linkedStaticLibraries.end() )
        {
            ndkModulesUsed.insert( "cpufeatures" );
            contentSuffix += "$(call import-module,android/cpufeatures)\n";
        }
    }

    return contentPrefix + srcFilesSection + includeFilesSection + preprocessorSection + compilerSection + linkingSection + manualContent + contentSuffix;
}