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);
}
void FileChangeNotifier::Watch( const FileSystemUtils::Path& filename, IFileChangeListener *pListener )
{
	FileSystemUtils::Path fixedFilename = filename.DelimitersToOSDefault(); // Note this doesn't handle ../
	
#ifdef _WIN32
	// make filename lowercase to avoid case sensitivity issues with __FILE__ and ReadDirectoryChangesW output
	FileSystemUtils::ToLowerInPlace( fixedFilename.m_string );
#endif

	m_pFileMonitor->Watch(fixedFilename, this);
	m_fileListenerMap[fixedFilename].insert(pListener);
	pListener->OnRegisteredWithNotifier(this);
}
void FileMonitor::Watch( const FileSystemUtils::Path& filename, IFileMonitorListener *pListener /*= NULL*/ )
{
    FileSystemUtils::Path filepath = filename.DelimitersToOSDefault();


    // Is this a directory path or a file path?
    // Actually, we can't tell from a path, in general
    // foo/bar could be a filename with no extension
    // It seems reasonable to inspect the path using FileSystemUtils, check it actually exists
    // (it should, surely? otherwise error?) and determine whether it is a file or a folder
    // but for now - we cheat by assuming files have extensions
    bool bPathIsDir = !filepath.HasExtension();

    FileSystemUtils::Path pathDir = bPathIsDir ? filepath : filepath.ParentPath();
    TDirList::iterator dirIt = GetWatchedDirEntry(pathDir);    
    if (dirIt == m_DirWatchList.end())
    {
        // New directory entry
        m_DirWatchList.push_back( WatchedDir(pathDir) );
        dirIt = --(m_DirWatchList.end());
        StartWatchingDir(*dirIt);
    }
    assert(dirIt != m_DirWatchList.end());

    if (bPathIsDir)
    {
        if (!dirIt->bWatchDirItself)
        {
            assert(!dirIt->pListener);
            dirIt->pListener = pListener;
            dirIt->bWatchDirItself = true;
        }
    }
    else
    {
        // Add file to directory's watch list (if it's not already there)
        TFileList::iterator fileIt = GetWatchedFileEntry(filepath, dirIt->fileWatchList);
        if (fileIt == dirIt->fileWatchList.end())
        {
            dirIt->fileWatchList.push_back(WatchedFile(filepath, pListener));
        }
    }
}
Ejemplo n.º 4
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
}