void FileChangeNotifier::Watch( const FileSystemUtils::Path& filename, IFileChangeListener *pListener )
{
    FileSystemUtils::Path fixedFilename = filename.DelimitersToOSDefault(); // Note this doesn't handle ../
    
    fixedFilename = fixedFilename.GetCleanPath();
    fixedFilename.ToOSCanonicalCase();

    m_pFileMonitor->Watch(fixedFilename, this);
    m_fileListenerMap[fixedFilename].insert(pListener);
    pListener->OnRegisteredWithNotifier(this);
}
Ejemplo n.º 2
0
void RuntimeObjectSystem::SetupRuntimeFileTracking(const IAUDynArray<IObjectConstructor*>& constructors_)
{
#ifndef RCCPPOFF
	// for optimization purposes we skip some actions when running for the first time (i.e. no previous constructors)
	static bool bFirstTime = true;

	for (size_t i = 0, iMax = constructors_.Size(); i < iMax; ++i)
	{
		const char* pFilename = constructors_[i]->GetFileName(); // GetFileName returns full path including GetCompiledPath()
		if( !pFilename )
		{
			continue;
		}
		Path filePath = pFilename;
        filePath = filePath.GetCleanPath();
        filePath = FindFile( filePath );

        unsigned short projectId = constructors_[ i ]->GetProjectId();
        ProjectSettings& project = GetProject( projectId );
        AddToRuntimeFileList( filePath.c_str( ), projectId );

		if( !bFirstTime )
		{
 			//remove old include file mappings for this file
            TFileToFilesIterator itrCurr = project.m_RuntimeIncludeMap.begin( );
            while( itrCurr != project.m_RuntimeIncludeMap.end( ) )
			{
				if( itrCurr->second == filePath )
				{
                    TFileToFilesIterator itrErase = itrCurr;
                    ++itrCurr;
                    project.m_RuntimeIncludeMap.erase( itrErase );
				}
				else
				{
					++itrCurr;
				}
			}

            //remove previous link libraries for this file
            project.m_RuntimeLinkLibraryMap.erase( filePath );

            //remove previous source dependencies
            project.m_RuntimeSourceDependencyMap.erase( filePath );
		}

        //we need the compile path for some platforms where the __FILE__ path is relative to the compile path
		FileSystemUtils::Path compileDir = constructors_[i]->GetCompiledPath();

		//add include file mappings
		for (size_t includeNum = 0; includeNum <= constructors_[i]->GetMaxNumIncludeFiles(); ++includeNum)
		{
			const char* pIncludeFile = constructors_[i]->GetIncludeFile(includeNum);
			if( pIncludeFile )
			{
                FileSystemUtils::Path pathInc = compileDir / pIncludeFile;
                pathInc = FindFile( pathInc.GetCleanPath() );
				TFileToFilePair includePathPair;
				includePathPair.first = pathInc;
				includePathPair.second = filePath;
                AddToRuntimeFileList( pathInc.c_str(), projectId );
                project.m_RuntimeIncludeMap.insert( includePathPair );
			}
		}
            

 		//add link library file mappings
		for (size_t linklibraryNum = 0; linklibraryNum <= constructors_[i]->GetMaxNumLinkLibraries(); ++linklibraryNum)
		{
			const char* pLinkLibrary = constructors_[i]->GetLinkLibrary(linklibraryNum);
			if( pLinkLibrary )
			{
                // We do not use FindFiles for Linked Libraries as these are searched for on
                // the library paths, which are themselves searched for.
				TFileToFilePair linklibraryPathPair;
				linklibraryPathPair.first = filePath;
				linklibraryPathPair.second = pLinkLibrary;
                project.m_RuntimeLinkLibraryMap.insert( linklibraryPathPair );
			}
		}

        //add source dependency file mappings
		for (size_t num = 0; num <= constructors_[i]->GetMaxNumSourceDependencies(); ++num)
		{
			SourceDependencyInfo sourceDependency = constructors_[i]->GetSourceDependency(num);
			FileSystemUtils::Path pathInc[2];	// array of potential include files for later checks
			if( sourceDependency.filename )
			{
				FileSystemUtils::Path pathSrc;
				if( sourceDependency.relativeToPath )
				{
					pathSrc = sourceDependency.relativeToPath;
					if( pathSrc.HasExtension() )
					{
						pathInc[1] = compileDir / pathSrc;
						pathSrc =  compileDir / pathSrc.ParentPath() / sourceDependency.filename;
					}
					else
					{
						pathSrc =  compileDir / pathSrc / sourceDependency.filename;
					}
				}
				else
				{
					pathSrc = compileDir / sourceDependency.filename;
				}
                pathSrc.ToOSCanonicalCase();
                pathSrc = pathSrc.DelimitersToOSDefault();
                pathSrc = pathSrc.GetCleanPath();
				pathInc[0] = pathSrc;
				if( sourceDependency.extension )
				{
					pathSrc.ReplaceExtension( sourceDependency.extension );
				}
				pathSrc = FindFile( pathSrc.GetCleanPath() );
				TFileToFilePair sourcePathPair;
				sourcePathPair.first = filePath;
				sourcePathPair.second = pathSrc;
                project.m_RuntimeSourceDependencyMap.insert( sourcePathPair );
                
                // if the include file with a source dependancy is logged as an runtime include, then we mark this .cpp as compile dependencies on change
				for( int inc=0; inc<2; ++inc )
				{
					TFileToFilesEqualRange range = project.m_RuntimeIncludeMap.equal_range( pathInc[inc] );
					if( range.first != range.second )
					{
						// add source file to runtime file list
						AddToRuntimeFileList( pathSrc.c_str(), projectId );

						// also add this as a source dependency, so it gets force compiled on change of header (and not just compiled)
						TFileToFilePair includePathPair;
						includePathPair.first = pathInc[inc];
						includePathPair.second = pathSrc;
						project.m_RuntimeIncludeMap.insert( includePathPair );
					}
				}
			}
		}
	}

    bFirstTime = false;
#endif
}