예제 #1
0
        /// <summary>
        /// Gets all type declarations made in the current codebase that is being compiled. 
        /// This is a tool method to be used in more complex achievements.
        /// This method is caching and can be called without discretion, and is thread safe.
        /// </summary>
        /// <param name="buildInformation">BuildInformation object used to locate the codebase</param>
        /// <returns>Cached collection of TypeDeclarationInfo</returns>
        public IEnumerable<TypeDeclarationInfo> GetCodebaseTypeDeclarations(BuildInformation buildInformation)
        {
            lock (codebaseTypeDefinitionPadLock)
            {
                if (codebaseTypeDefinitions == null)
                {
                    codebaseTypeDefinitions = new List<TypeDeclarationInfo>();

                    foreach (var filename in buildInformation.CodeFiles)
                    {
                        var parser = GetParser(filename);
                        var typeDeclarationInfoVisitor = new TypeDeclarationVisitor();
                        parser.CompilationUnit.AcceptVisitor(typeDeclarationInfoVisitor, null);

                        codebaseTypeDefinitions.AddRange(typeDeclarationInfoVisitor.TypeDeclarations);
                    }
                }

                return codebaseTypeDefinitions;
            }
        }
예제 #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DetectionSession"/> class.
 /// </summary>
 /// <param name="buildInformation">The build information.</param>
 public DetectionSession(BuildInformation buildInformation)
 {
     BuildInformation = buildInformation;
 }
예제 #3
0
        public void TestAchievements()
        {
            ObjectFactory.Configure(a => a.For<IAchievementRepository>().Singleton().Use<AppDataXmlCompletedAchievementsRepository>());
            var achievementRepository = ObjectFactory.GetInstance<IAchievementRepository>();
            achievementRepository.LoadFromAssembly(typeof(NRefactoryAchievement).Assembly);

            var achievementTests = GetType().Assembly.GetTypes().Where(a => a.GetCustomAttributes(typeof (ExpectUnlockAttribute), true).Length > 0);
            foreach(var test in achievementTests)
            {
                var sourceFile = Path.GetFullPath("TestCases/" + test.Name + ".cs");
                var buildInformation = new BuildInformation()
                                           {
                                               ActiveFile = sourceFile,
                                               ActiveProject = null,
                                               ActiveProjectOutputDirectory = Path.GetDirectoryName(sourceFile),
                                               ChangedFiles = new []{sourceFile}
                                           };

                var expectedAchievements = test.GetCustomAttributes(typeof(ExpectUnlockAttribute), true).Select(a => ((ExpectUnlockAttribute)a).ExpectedAchievementType).ToList();

                using (var detectionSession = new DetectionSession(buildInformation))
                {
                    var achievements = achievementRepository.GetAchievements().ToList();

                    var tasks = new Task[achievements.Count()];
                    var i = 0;

                    var unlockedAchievements = new List<Type>();
                    foreach (var uncompletedAchievement in achievements)
                    {
                        var a = uncompletedAchievement;

                        tasks[i++] = Task.Factory.StartNew(() =>
                                                               {
                                                                    var achievementType = a.AchievementType;
                                                                    var achievement = (AchievementBase)Activator.CreateInstance(achievementType);

                                                                    var achievementUnlocked = achievement.DetectAchievement(detectionSession);

                                                                    if (achievementUnlocked)
                                                                    {
                                                                        a.CodeLocation = achievement.AchievementCodeLocation;
                                                                        a.IsCompleted = true;
                                                                        unlockedAchievements.Add(achievementType);
                                                                    }
                                                                });
                    }

                    Task.WaitAll(tasks);

                    //Test that expected achievements unlocked
                    foreach(var expectedAchievement in expectedAchievements)
                    {
                        Assert.IsTrue(unlockedAchievements.Contains(expectedAchievement), Path.GetFileName(sourceFile) + " did not unlock expected achievement: " + expectedAchievement.FullName);
                    }

                    //Test that only expected achievements unlocked
                    var unexpectedAchievements = unlockedAchievements.Except(expectedAchievements).Except(_globallyIgnoredAchievements).ToList();
                    Assert.IsTrue(unexpectedAchievements.Count() == 0, Path.GetFileName(sourceFile) + " unlocks unexpected achievements: " + string.Join(", ", unexpectedAchievements.Select(a => a.Name)));
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Dispatches handling of achievement detection in the file(s) specified
        /// in the passed BuildInformation object.
        ///
        /// This method is detection method agnostic. It simply forwards the
        /// BuildInformation object to all implementations of the Achievement class.
        /// </summary>
        /// <param name="buildInformation">
        ///     Objects specifying documents to parse for achievements.
        /// </param>
        public static bool Dispatch(BuildInformation buildInformation)
        {
            AchievementContext.OnAchievementDetectionStarting(null, new EventArgs());

            var unlockedAchievements            = new List <Achievement>();
            var achievementDescriptorRepository = ObjectFactory.GetInstance <IAchievementRepository>();

            using (var detectionSession = new DetectionSession(buildInformation))
            {
                var unlockableAchievements = achievementDescriptorRepository.GetUnlockableAchievements();

                var stopWatch = new Stopwatch();
                stopWatch.Start();

                var tasks = new Task[unlockableAchievements.Count()];
                var i     = 0;

                foreach (var uncompletedAchievement in unlockableAchievements)
                {
                    var a = uncompletedAchievement;

                    tasks[i++] = Task.Factory.StartNew(() =>
                    {
                        var achievement = (AchievementBase)Activator.CreateInstance(a.AchievementType);

                        var achievementUnlocked = achievement.DetectAchievement(detectionSession);

                        if (achievementUnlocked)
                        {
                            a.CodeLocation = achievement.AchievementCodeLocation;
                            a.IsCompleted  = true;
                            unlockedAchievements.Add(a);
                        }
                    });
                }

                Task.WaitAll(tasks);

                stopWatch.Stop();

                OnDetectionCompleted(null, new DetectionCompletedEventArgs()
                {
                    AchievementsTested  = unlockableAchievements.Count(),
                    ElapsedMilliseconds = (int)stopWatch.ElapsedMilliseconds
                });
            }

            if (unlockedAchievements.Count() > 0)
            {
                foreach (var completedAchievement in unlockedAchievements.Where(a => a != null))
                {
                    achievementDescriptorRepository.MarkAchievementAsCompleted(completedAchievement);
                }

                AchievementContext.OnAchievementsUnlocked(null, unlockedAchievements);

                return(true);
            }

            return(false);
        }
예제 #5
0
        /// <summary>
        /// Called when a build is completed.
        /// </summary>
        /// <param name="fSucceeded"><c>true</c> if no update actions failed.</param>
        /// <param name="fModified"><c>true</c> if any update action succeeded.</param>
        /// <param name="fCancelCommand"><c>true</c> if update actions were canceled.</param>
        /// <returns>
        /// If the method succeeds, it returns <c>S_OK</c>. If it fails, it returns an error code.
        /// </returns>
        int IVsUpdateSolutionEvents.UpdateSolution_Done(int fSucceeded, int fModified, int fCancelCommand)
        {
            if (fSucceeded != 0)
            {
                try
                {
                    ProjectTypeDef projectTypeDef = null;

                    if (dte.ActiveDocument != null && dte.ActiveDocument.ProjectItem != null && dte.ActiveDocument.ProjectItem.ContainingProject != null)
                    {
                        var containingProject = dte.ActiveDocument.ProjectItem.ContainingProject;

                        var projectFile = containingProject.FileName;
                        if (!string.IsNullOrEmpty(projectFile) && !projectTypeDefCache.TryGetValue(projectFile, out projectTypeDef))
                        {
                            XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
                            var csProj = XDocument.Load(containingProject.FileName);
                            var strokesAchievementTypeNodes = csProj.Descendants(ns + "StrokesProjectType");
                            var strokesAchievementTypeNode = strokesAchievementTypeNodes.FirstOrDefault();
                            if (strokesAchievementTypeNode != null && strokesAchievementTypeNode.HasElements)
                            {
                                projectTypeDef = new ProjectTypeDef()
                                {
                                    IsAchievementProject = strokesAchievementTypeNode.Elements().Any(a => a.Name == ns + "Achievements" && a.Value == "true"),
                                    IsChallengeProject = strokesAchievementTypeNode.Elements().Any(a => a.Name == ns + "Challenges" && a.Value == "true")
                                };

                                projectTypeDefCache.Add(projectFile, projectTypeDef);
                            }
                        }
                    }

                    if (projectTypeDef == null)
                    {
                        projectTypeDef = new ProjectTypeDef(); // Assume default values (false, false);
                    }

                    // Return out if we're not compiling an achievement project.
                    if (!projectTypeDef.IsAchievementProject && !projectTypeDef.IsChallengeProject)
                    {
                        return VSConstants.S_OK;
                    }

                    // Get all .cs files in solution projects, that has changed since lastAchievementCheck
                    var changedFiles = FileTracker.GetFiles(dte.Solution);

                    // Update lastAchievementCheck
                    lastAchievementCheck = DateTime.Now;

                    // Construct build information
                    var buildInformation = new BuildInformation();
                    buildInformation.CodeFiles = FileTracker.GetFiles(dte.Solution).ToArray();

                    var activeDocument = dte.ActiveDocument;
                    if (activeDocument != null)
                    {
                        var documentFile = activeDocument.FullName;

                        if (documentFile.EndsWith(".cs"))
                        {
                            buildInformation.ActiveFile = documentFile;

                            if (!changedFiles.Contains(documentFile))
                            {
                                // Always check active document.
                                changedFiles.Add(documentFile);
                            }

                            // Fill relevant values on buildInformation
                            var projectItem = activeDocument.ProjectItem.ContainingProject;
                            buildInformation.ActiveProject = projectItem.FileName;
                            buildInformation.ActiveProjectOutputDirectory = FileTracker.GetProjectOutputDirectory(projectItem);
                        }
                    }

                    buildInformation.ChangedFiles = changedFiles.ToArray();

                    // Validate build information
                    if (buildInformation.ActiveProject == null && buildInformation.ChangedFiles.Length == 0)
                    {
                        // Build information contains nothing - so we won't detect achievements
                        return VSConstants.S_OK;
                    }

                    // Lock builds while detection is occuring - this prevents parallel detection
                    isAchievementDetectionRunning = true;

                    DetectionDispatcher.Dispatch(buildInformation);
                }
                finally
                {
                    // Unlock builds
                    isAchievementDetectionRunning = false;
                }
            }

            return VSConstants.S_OK;
        }
예제 #6
0
        /// <summary>
        /// Dispatches handling of achievement detection in the file(s) specified 
        /// in the passed BuildInformation object.
        /// 
        /// This method is detection method agnostic. It simply forwards the 
        /// BuildInformation object to all implementations of the Achievement class.
        /// </summary>
        /// <param name="buildInformation">
        ///     Objects specifying documents to parse for achievements.
        /// </param>
        public static bool Dispatch(BuildInformation buildInformation)
        {
            AchievementContext.OnAchievementDetectionStarting(null, new EventArgs());

            var unlockedAchievements = new List<Achievement>();
            var achievementDescriptorRepository = ObjectFactory.GetInstance<IAchievementRepository>();

            using (var detectionSession = new DetectionSession(buildInformation))
            {
                var unlockableAchievements = achievementDescriptorRepository.GetUnlockableAchievements();

                var stopWatch = new Stopwatch();
                stopWatch.Start();

                var tasks = new Task[unlockableAchievements.Count()];
                var i = 0;

                foreach (var uncompletedAchievement in unlockableAchievements)
                {
                    var a = uncompletedAchievement;

                    tasks[i++] = Task.Factory.StartNew(() =>
                    {
                        var achievement = (AchievementBase)Activator.CreateInstance(a.AchievementType);

                        var achievementUnlocked = achievement.DetectAchievement(detectionSession);

                        if (achievementUnlocked)
                        {
                            a.CodeLocation = achievement.AchievementCodeLocation;
                            a.IsCompleted = true;
                            unlockedAchievements.Add(a);
                        }
                    });
                }

                Task.WaitAll(tasks);

                stopWatch.Stop();

                OnDetectionCompleted(null, new DetectionCompletedEventArgs()
                {
                    AchievementsTested = unlockableAchievements.Count(),
                    ElapsedMilliseconds = (int)stopWatch.ElapsedMilliseconds
                });
            }

            if (unlockedAchievements.Count() > 0)
            {
                foreach (var completedAchievement in unlockedAchievements.Where(a => a != null))
                {
                    achievementDescriptorRepository.MarkAchievementAsCompleted(completedAchievement);
                }

                AchievementContext.OnAchievementsUnlocked(null, unlockedAchievements);

                return true;
            }

            return false;
        }