Example #1
0
inline Error processFileAdded(
               tcl::unique_tree<FileInfo>::tree_type* pParentNode,
               const FileChangeEvent& fileChange,
               bool recursive,
               const boost::function<bool(const FileInfo&)>& filter,
               tcl::unique_tree<FileInfo>* pTree,
               std::vector<FileChangeEvent>* pFileChanges)
{
   return processFileAdded(pParentNode,
                           fileChange,
                           recursive,
                           filter,
                           boost::function<Error(const FileInfo&)>(),
                           pTree,
                           pFileChanges);
}
Example #2
0
inline Error processFileAdded(
               tree<FileInfo>::iterator parentIt,
               const FileChangeEvent& fileChange,
               bool recursive,
               const boost::function<bool(const FileInfo&)>& filter,
               tree<FileInfo>* pTree,
               std::vector<FileChangeEvent>* pFileChanges)
{
   return processFileAdded(parentIt,
                           fileChange,
                           recursive,
                           filter,
                           boost::function<Error(const FileInfo&)>(),
                           pTree,
                           pFileChanges);
}
Example #3
0
Error discoverAndProcessFileChanges(
   const FileInfo& fileInfo,
   bool recursive,
   const boost::function<bool(const FileInfo&)>& filter,
   const boost::function<Error(const FileInfo&)>& onBeforeScanDir,
   tree<FileInfo>* pTree,
   const  boost::function<void(const std::vector<FileChangeEvent>&)>&
                                                               onFilesChanged)
{
   // find this path in our fileTree
   tree<FileInfo>::iterator it = std::find(pTree->begin(),
                                           pTree->end(),
                                           fileInfo);

   // if we don't find it then it may have been excluded by a filter, just bail
   if (it == pTree->end())
      return Success();

   // scan this directory into a new tree which we can compare to the old tree
   tree<FileInfo> subdirTree;
   FileScannerOptions options;
   options.recursive = recursive;
   options.yield = true;
   options.filter = filter;
   options.onBeforeScanDir = onBeforeScanDir;
   Error error = scanFiles(fileInfo, options, &subdirTree);
   if (error)
      return error;

   // handle recursive vs. non-recursive scan differnetly
   if (recursive)
   {
      // check for changes on full subtree
      std::vector<FileChangeEvent> fileChanges;
      tree<FileInfo> existingSubtree(it);
      collectFileChangeEvents(existingSubtree.begin(),
                              existingSubtree.end(),
                              subdirTree.begin(),
                              subdirTree.end(),
                              &fileChanges);

      // fire events
      onFilesChanged(fileChanges);

      // wholesale replace subtree
      pTree->insert_subtree_after(it, subdirTree.begin());
      pTree->erase(it);
   }
   else
   {
      // scan for changes on just the children
      std::vector<FileChangeEvent> childrenFileChanges;
      collectFileChangeEvents(pTree->begin(it),
                              pTree->end(it),
                              subdirTree.begin(subdirTree.begin()),
                              subdirTree.end(subdirTree.begin()),
                              &childrenFileChanges);

      // build up actual file changes and mutate the tree as appropriate
      std::vector<FileChangeEvent> fileChanges;
      BOOST_FOREACH(const FileChangeEvent& fileChange, childrenFileChanges)
      {
         switch(fileChange.type())
         {
         case FileChangeEvent::FileAdded:
         {
            Error error = processFileAdded(it,
                                           fileChange,
                                           recursive,
                                           filter,
                                           pTree,
                                           &fileChanges);
            if (error)
               LOG_ERROR(error);
            break;
         }
         case FileChangeEvent::FileModified:
         {
            processFileModified(it, fileChange, pTree, &fileChanges);
            break;
         }
         case FileChangeEvent::FileRemoved:
         {
            processFileRemoved(it,
                               fileChange,
                               recursive,
                               pTree,
                               &fileChanges);
            break;
         }
         case FileChangeEvent::None:
         default:
            break;
         }
      }

      // fire events
      onFilesChanged(fileChanges);
   }

   return Success();
}