Ejemplo n.º 1
0
        /// <summary>
        /// Excecute a command.
        /// </summary>
        /// <param name="isCommandEnabled">The options parameter, true if this command is enabled.</param>
        /// <param name="commandName">The friendly name of this command, for logging.</param>
        /// <param name="action">The method to be executed to carry out the command.</param>
        private void ExecuteCommand(bool isCommandEnabled, string commandName, Func <VsSelection, bool> action)
        {
            // DAB: I doubt if this is necessary, but the Microsoft sample SccProvider did this. Very defensive.
            if (!_sccService.IsSolutionLoaded)
            {
                Debug.Assert(false, "No solution, so the command should have been disabled");
                return;
            }

            // DAB: I doubt if this is necessary, I'm being defensive.
            if (!isCommandEnabled)
            {
                LogCommandError(commandName);
                return;
            }

            if (!SaveSolution())
            {
                return;
            }

            VsSelection selection = GetSelection();

            action(selection);

            // All nodes and fileNames in the selection will be refreshed when P4Cache.P4CacheUpdated is thrown.
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Add one or more fileNames to the cache. This is NOT done on a background thread.
        /// </summary>
        /// <param name="vsSelection">A list of files to add or update.</param>
        public void AddOrUpdateFiles(VsSelection vsSelection)
        {
            IList <string> fileNames = vsSelection.FileNamesUnPiped;

            Log.Debug(String.Format("P4Cache.AddOrUpdateFiles(): Setting cache for {0} files", fileNames.Count));
            Log.Debug("P4Cache:AddOrUpdateFiles: Starting SetFileStates().");
            SetFileStates(fileNames);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// This is intended for when a new solution has been loaded.
        ///     Clear the cache.
        ///     Reload the cache with the fileNames (duplicates are okay).
        ///     Then start a new thread to update the FileState for every file in fileNames.
        ///     Then throw an event when all fileStates have been updated, so VS can rediscover glyphs (from NotSet to whatever is the correct FileState).
        ///     All of this is to avoid sloooowww VS response time for large solutions while waiting for discovery of Perforce FileStates.
        /// </summary>
        /// <param name="vsSelection">A list of files to update and nodes to refresh.</param>
        public void Initialize(VsSelection vsSelection)
        {
            lock (_fileStatesLock)
            {
                _fileStates.Clear();
            }

            AddOrUpdateFilesBackground(vsSelection);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Add one or more fileNames to the cache. Also used to signal the need to update fileStates of existing files.
        ///     Then kick off a thread to update their fileStates.
        ///     Then start a new thread to update the FileState for every file in fileNames.
        ///     Then throw an event when all fileStates have been updated, so VS can rediscover glyphs (from NotSet to whatever is the correct FileState).
        ///     All of this is to avoid sloooowww VS response time for large solutions while waiting for discovery of Perforce FileStates.
        /// </summary>
        /// <param name="vsSelection">A list of files and nodes to refresh.</param>
        public void AddOrUpdateFilesBackground(VsSelection vsSelection)
        {
            if (vsSelection.FileNamesUnPiped.Count == 0)
            {
                return;
            }
            Trace.WriteLineIf(_traceSwitch.TraceVerbose, "P4Cache.AddOrUpdateFilesBackground started");
            Log.Debug(String.Format("P4Cache.AddOrUpdateFilesBackground(): {0} files for {1} nodes", vsSelection.FileNamesUnPiped.Count, vsSelection.Nodes.Count));
            SetFileStatesToNotSet(vsSelection);


            // Note: The updating flag *could* already be set if we get here between the time we release the lock and the
            // time the background thread is able to get the lock again.  In that case, just do nothing more, because the
            // background thread will eventually get to run and update the files we just added to _fileStates.
            if (!_cacheIsUpdating)
            {
                _cacheIsUpdating = true;

                // Now kick off a thread that updates the FileState for every fileNode in tLhe dictionary.  We do this
                // inside the lock, so that 2 threads can't do it at the same time.
                Trace.WriteLineIf(_traceSwitch.TraceVerbose, "P4Cache.AddOrUpdateFilesBackground starting SetFileStates on background thread");
                Log.Debug("P4Cache:AddOrUpdateFilesBackground: Starting SetFileStates() on background thread.");
                _cacheUpdateTask = Task.Factory.StartNew(() =>
                {
                    // Execute the entire background thread with the lock engaged, to prevent another call to
                    // AddOrUpdateFilesBackground from attempting to start us again until we've completed.  It is
                    // important that we reset the "is updating" flag while locked or we could get into this
                    // race condition.
                    lock (_fileStatesLock)
                    {
                        Trace.WriteLineIf(_traceSwitch.TraceVerbose, "Background thread acquired lock.");
                        try
                        {
                            SetFileStates(vsSelection);
                        }
                        catch (Exception ex)
                        {
                            Trace.WriteLineIf(_traceSwitch.TraceError,
                                              String.Format("Background update thread encountered exception: {0}",
                                                            ex.Message));
                            // Regardless of how many times we may have tried before to update the cache, now that
                            // it has failed, we must consider the cache inactive because it's not current and we
                            // apparently cannot make it current.
                            _cacheActive = false;
                        }
                        finally
                        {
                            // SetFileStates will reset this if it finishes successfully.  This is here mostly in
                            // case we get any exceptions.
                            _cacheIsUpdating = false;
                        }
                        Trace.WriteLineIf(_traceSwitch.TraceVerbose, "Background thread releasing lock.");
                    }
                });
            }
            Trace.WriteLineIf(_traceSwitch.TraceVerbose, "P4Cache.AddOrUpdateFilesBackground unlocking _fileStatesLock");
        }
Ejemplo n.º 5
0
        OLECMDF QueryStatus_icmdTimeLapse()
        {
            if (!_sccService.IsSolutionLoaded)
            {
                return(OLECMDF.OLECMDF_INVISIBLE);
            }

            if (!_sccService.Options.IsViewTimeLapseEnabled)
            {
                return(OLECMDF.OLECMDF_INVISIBLE);
            }

            VsSelection selection = GetSelection();

            return(selection.FileNames.Any(file => _sccService.IsEligibleForTimeLapse(file)) ? OLECMDF.OLECMDF_ENABLED : OLECMDF.OLECMDF_SUPPORTED);
        }
Ejemplo n.º 6
0
        OLECMDF QueryStatus_icmdGetLatestRevison()
        {
            if (!_sccService.IsSolutionLoaded)
            {
                return(OLECMDF.OLECMDF_INVISIBLE);
            }

            if (!_sccService.Options.IsGetLatestRevisionEnabled)
            {
                return(OLECMDF.OLECMDF_INVISIBLE);
            }

            VsSelection selection = GetSelection();

            return(selection.FileNames.Any(file => _sccService.IsEligibleForGetLatestRevision(file)) ? OLECMDF.OLECMDF_ENABLED : OLECMDF.OLECMDF_SUPPORTED);
        }
Ejemplo n.º 7
0
        OLECMDF QueryStatus_icmdRevertIfUnchanged()
        {
            if (!_sccService.IsSolutionLoaded)
            {
                return(OLECMDF.OLECMDF_INVISIBLE);
            }

            if (!_sccService.Options.IsRevertIfUnchangedEnabled)
            {
                return(OLECMDF.OLECMDF_INVISIBLE);
            }

            VsSelection selection = GetSelection();

            return(selection.FileNames.Any(file => _sccService.IsEligibleForRevertIfUnchanged(file)) ? OLECMDF.OLECMDF_ENABLED : OLECMDF.OLECMDF_SUPPORTED);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// This is intended for when a new solution has been loaded.
        ///     Clear the cache.
        ///     Reload the cache with the fileNames (duplicates are okay).
        ///     Then start a new thread to update the FileState for every file in fileNames.
        ///     Then throw an event when all fileStates have been updated, so VS can rediscover glyphs (from NotSet to whatever is the correct FileState).
        ///     All of this is to avoid sloooowww VS response time for large solutions while waiting for discovery of Perforce FileStates.
        /// </summary>
        /// <param name="vsSelection">A list of files to update and nodes to refresh.</param>
        public void Initialize(VsSelection vsSelection)
        {
            Trace.WriteLineIf(_traceSwitch.TraceVerbose, "Initializing P4Cache");
            lock (_fileStatesLock)
            {
                // Just to be safe, make sure we aren't already initializing or updating the cache...
                if (_cacheIsUpdating)
                {
                    throw new P4CacheUpdateException("Initialize called while Initialize or an update is already active.");
                }
                _cacheActive = true;
                _fileStates.Clear();

                AddOrUpdateFilesBackground(vsSelection);
            }
            Trace.WriteLineIf(_traceSwitch.TraceVerbose, "P4Cache initialized");
        }
Ejemplo n.º 9
0
        private void SetFileStatesToNotSet(VsSelection vsSelection)
        {
            IList <string> fileNames = vsSelection.FileNamesUnPiped;

            lock (_fileStatesLock)
            {
                foreach (var fileName in fileNames)
                {
                    Trace.WriteLineIf(_traceSwitch.TraceVerbose, String.Format("P4Cache.SetFileStatesToNotSet received filename {0}", fileName));
                    if (_fileStates.ContainsKey(fileName))
                    {
                        // Ignore duplicates. We may already have set their state.
                        continue;
                    }

                    _fileStates[fileName] = FileState.NotSet;
                }
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Add one or more fileNames to the cache. Also used to signal the need to update fileStates of existing files.
        ///     Then kick off a thread to update their fileStates.
        ///     Then start a new thread to update the FileState for every file in fileNames.
        ///     Then throw an event when all fileStates have been updated, so VS can rediscover glyphs (from NotSet to whatever is the correct FileState).
        ///     All of this is to avoid sloooowww VS response time for large solutions while waiting for discovery of Perforce FileStates.
        /// </summary>
        /// <param name="vsSelection">A list of files and nodes to refresh.</param>
        public void AddOrUpdateFilesBackground(VsSelection vsSelection)
        {
            IList <string> fileNames = vsSelection.FileNamesUnPiped;

            Log.Debug(String.Format("P4Cache.AddOrUpdateFilesBackground(): {0} files for {1} nodes", fileNames.Count, vsSelection.Nodes.Count));
            lock (_fileStatesLock)
            {
                foreach (var fileName in fileNames)
                {
                    if (_fileStates.ContainsKey(fileName))
                    {
                        // Ignore duplicates. We may already have set their state.
                        continue;
                    }

                    _fileStates[fileName] = FileState.NotSet;
                }
            }

            // Now kick off a thread that updates the FileState for every fileNode in tLhe dictionary.
            Log.Debug("P4Cache:AddOrUpdateFilesBackground: Starting SetFileStates() on background thread.");
            Task.Factory.StartNew(() => SetFileStates(vsSelection));
        }
Ejemplo n.º 11
0
 public P4CacheEventArgs(VsSelection vsSelection)
 {
     VsSelection = vsSelection;
 }