Browse Source

Fixed:
- Slow sorting with Newest sorting method. Tested 4000 songs and there is no longer a massive delay.
- Lots of little fixes regarding making it more testable.
- Migrated the test code into a plugin that a dev can install into BeatSaber if they want.

Stephen Damm 5 years ago
parent
commit
b0d7520b40

+ 11 - 0
SongBrowserPlugin/DataAccess/BeatSaberSongList.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Linq;
 using System.Text;
 using UnityEngine;
@@ -18,11 +19,16 @@ namespace SongBrowserPlugin.DataAccess
         {
             _log.Debug("AcquireSongList()");
 
+            Stopwatch stopwatch = Stopwatch.StartNew();
+
             var gameScenesManager = Resources.FindObjectsOfTypeAll<GameScenesManager>().FirstOrDefault();
             var gameDataModel = PersistentSingleton<GameDataModel>.instance;
 
             List<LevelStaticData> songList = gameDataModel.gameStaticData.worldsData[0].levelsData.ToList();
 
+            stopwatch.Stop();
+            _log.Info("Acquiring Song List from Beat Saber took {0}ms", stopwatch.ElapsedMilliseconds);
+
             return songList;
         }
 
@@ -32,8 +38,13 @@ namespace SongBrowserPlugin.DataAccess
         /// <param name="newSongList"></param>
         public void OverwriteBeatSaberSongList(List<LevelStaticData> newSongList)
         {
+            Stopwatch stopwatch = Stopwatch.StartNew();
+
             var gameDataModel = PersistentSingleton<GameDataModel>.instance;
             ReflectionUtil.SetPrivateField(gameDataModel.gameStaticData.worldsData[0], "_levelsData", newSongList.ToArray());
+
+            stopwatch.Stop();
+            _log.Info("Overwriting the beat saber song list took {0}ms", stopwatch.ElapsedMilliseconds);
         }
     }
 }

+ 1 - 1
SongBrowserPlugin/Logger.cs

@@ -3,7 +3,7 @@
 
 namespace SongBrowserPlugin
 {
-    class Logger
+    public class Logger
     {
         private string loggerName;
 

+ 3 - 8
SongBrowserPlugin/Plugin.cs

@@ -9,14 +9,12 @@ using IllusionPlugin;
 using TMPro;
 using UnityEngine.UI;
 using System.Collections;
-using SongBrowserPlugin.Tests;
+
 
 namespace SongBrowserPlugin
 {
 	public class Plugin : IPlugin
 	{
-        public const bool RunTests = false;
-
 		public string Name
 		{
 			get { return "Song Browser"; }
@@ -24,15 +22,12 @@ namespace SongBrowserPlugin
 
 		public string Version
 		{
-			get { return "v1.0-alpha"; }
+			get { return "v1.0-rc2"; }
 		}
 		
 		public void OnApplicationStart()
 		{
-            if (RunTests)
-            {
-                new SongBrowserTestRunner().RunTests();
-            }
+
         }
 
 		public void OnApplicationQuit()

+ 19 - 16
SongBrowserPlugin/SongBrowserMasterViewController.cs

@@ -377,43 +377,46 @@ namespace SongBrowserPlugin
         /// </summary>
         public void RefreshSongList(List<LevelStaticData> songList)
         {
-            LevelStaticData[] songListArray = songList.ToArray();
-
             _log.Debug("Attempting to refresh the song list view.");
             try
             {
+                // Check a couple of possible situations that we can't refresh
                 if (!_songSelectionMasterView.isActiveAndEnabled)
                 {
                     _log.Debug("No song list to refresh.");
                     return;
                 }
 
-                // Refresh the master view
-                bool useLocalLeaderboards = ReflectionUtil.GetPrivateField<bool>(_songSelectionMasterView, "_useLocalLeaderboards");
-                bool showDismissButton = true;
-                bool showPlayerStats = ReflectionUtil.GetPrivateField<bool>(_songSelectionMasterView, "_showPlayerStats");
-                GameplayMode gameplayMode = ReflectionUtil.GetPrivateField<GameplayMode>(_songSelectionMasterView, "_gameplayMode");
-
-                _songSelectionMasterView.Init(
-                    _songSelectionMasterView.levelId,
-                    _songSelectionMasterView.difficulty,
-                    songListArray,
-                    useLocalLeaderboards, showDismissButton, showPlayerStats, gameplayMode);
-
-                // Refresh the song list
                 SongListTableView songTableView = _songListViewController.GetComponentInChildren<SongListTableView>();
                 if (songTableView == null)
                 {
                     return;
                 }
 
-                ReflectionUtil.SetPrivateField(songTableView, "_levels", songListArray);
                 TableView tableView = ReflectionUtil.GetPrivateField<TableView>(songTableView, "_tableView");
                 if (tableView == null)
                 {
                     return;
                 }
 
+                // Convert to Array once in-case this is costly.
+                LevelStaticData[] songListArray = songList.ToArray();
+
+                // Refresh the master view
+                bool useLocalLeaderboards = ReflectionUtil.GetPrivateField<bool>(_songSelectionMasterView, "_useLocalLeaderboards");
+                bool showDismissButton = true;
+                bool showPlayerStats = ReflectionUtil.GetPrivateField<bool>(_songSelectionMasterView, "_showPlayerStats");
+                GameplayMode gameplayMode = ReflectionUtil.GetPrivateField<GameplayMode>(_songSelectionMasterView, "_gameplayMode");
+
+                _songSelectionMasterView.Init(
+                    _songSelectionMasterView.levelId,
+                    _songSelectionMasterView.difficulty,
+                    songListArray,
+                    useLocalLeaderboards, showDismissButton, showPlayerStats, gameplayMode
+                );
+
+                // Refresh the table views
+                ReflectionUtil.SetPrivateField(songTableView, "_levels", songListArray);
                 tableView.ReloadData();
 
                 // Clear Force selection of index 0 so we don't end up in a weird state.

+ 6 - 1
SongBrowserPlugin/SongBrowserModel.cs

@@ -2,6 +2,7 @@
 using SongBrowserPlugin.DataAccess;
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.IO;
 using System.Linq;
 using System.Text;
@@ -112,6 +113,7 @@ namespace SongBrowserPlugin
         private void ProcessSongList()
         {
             _log.Debug("ProcessSongList()");
+            Stopwatch stopwatch = Stopwatch.StartNew();
 
             // Weights used for keeping the original songs in order
             // Invert the weights from the game so we can order by descending and make LINQ work with us...
@@ -154,7 +156,7 @@ namespace SongBrowserPlugin
                     _sortedSongs = _originalSongs
                         .AsQueryable()
                         .OrderBy(x => weights.ContainsKey(x.levelId) ? weights[x.levelId] : 0)
-                        .ThenByDescending(x => x.levelId.StartsWith("Level") ? DateTime.MinValue : File.GetLastWriteTimeUtc(_levelIdToCustomSongInfo[x.levelId].path))
+                        .ThenByDescending(x => x.levelId.StartsWith("Level") ? DateTime.MinValue.Millisecond : File.GetLastWriteTimeUtc(_levelIdToCustomSongInfo[x.levelId].path).Millisecond)
                         .ToList();
                     break;
                 case SongSortMode.Default:
@@ -168,6 +170,9 @@ namespace SongBrowserPlugin
                     break;
             }
 
+            stopwatch.Stop();
+            _log.Info("Sorting songs took {0}ms", stopwatch.ElapsedMilliseconds);
+
             this._beatSaberSongAccessor.OverwriteBeatSaberSongList(_sortedSongs);
         }        
     }

+ 0 - 3
SongBrowserPlugin/SongBrowserPlugin.csproj

@@ -88,9 +88,6 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="SongBrowserModel.cs" />
     <Compile Include="SongBrowserSettings.cs" />
-    <Compile Include="Tests\ISongBrowserTest.cs" />
-    <Compile Include="Tests\SongBrowserModelTests.cs" />
-    <Compile Include="Tests\SongBrowserTestRunner.cs" />
     <Compile Include="UIBuilder.cs" />
   </ItemGroup>
   <ItemGroup>

+ 5 - 5
SongBrowserPlugin/SongBrowserPlugin.sln

@@ -5,7 +5,7 @@ VisualStudioVersion = 15.0.27703.2026
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SongBrowserPlugin", "SongBrowserPlugin.csproj", "{6F9B6801-9F4B-4D1F-805D-271C95733814}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SongBrowserPluginTest", "..\SongBrowserPluginTest\SongBrowserPluginTest.csproj", "{13964166-3EB2-4BC2-B41C-9E807543683F}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SongBrowserPluginTest", "..\SongBrowserPluginTest\SongBrowserPluginTest.csproj", "{E5465EF3-B227-47BE-B7D1-624E0DAC275D}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -17,10 +17,10 @@ Global
 		{6F9B6801-9F4B-4D1F-805D-271C95733814}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{6F9B6801-9F4B-4D1F-805D-271C95733814}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{6F9B6801-9F4B-4D1F-805D-271C95733814}.Release|Any CPU.Build.0 = Release|Any CPU
-		{13964166-3EB2-4BC2-B41C-9E807543683F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{13964166-3EB2-4BC2-B41C-9E807543683F}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{13964166-3EB2-4BC2-B41C-9E807543683F}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{13964166-3EB2-4BC2-B41C-9E807543683F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E5465EF3-B227-47BE-B7D1-624E0DAC275D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E5465EF3-B227-47BE-B7D1-624E0DAC275D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E5465EF3-B227-47BE-B7D1-624E0DAC275D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E5465EF3-B227-47BE-B7D1-624E0DAC275D}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 0 - 12
SongBrowserPlugin/Tests/ISongBrowserTest.cs

@@ -1,12 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace SongBrowserPlugin.Tests
-{
-    interface ISongBrowserTest
-    {
-        void RunTest();
-    }
-}

+ 0 - 87
SongBrowserPlugin/Tests/SongBrowserModelTests.cs

@@ -1,87 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Text;
-
-namespace SongBrowserPlugin.Tests
-{
-    class MockBeatSaberSongList : SongBrowserPlugin.DataAccess.IBeatSaberSongList
-    {
-        List<LevelStaticData> testList;
-
-        public MockBeatSaberSongList()
-        {
-            testList = new List<LevelStaticData>();
-            for (int i = 0; i < 10000; i++)
-            {
-                LevelStaticData level = new LevelStaticData();
-                SongBrowserPlugin.ReflectionUtil.SetPrivateField(level, "_songName", "SongName" + i);
-                SongBrowserPlugin.ReflectionUtil.SetPrivateField(level, "_authorName", "AuthorName" + i);
-                SongBrowserPlugin.ReflectionUtil.SetPrivateField(level, "_levelId", "LevelId" + i);
-                testList.Add(level);
-            }
-
-        }
-
-        public List<LevelStaticData> AcquireSongList()
-        {
-            return testList;
-        }
-
-        public void OverwriteBeatSaberSongList(List<LevelStaticData> newSongList)
-        {
-            return;
-        }
-    }
-
-    class SongBrowserModelTests : ISongBrowserTest
-    {
-        private Logger _log = new Logger("SongBrowserModelTests");
-
-        public void RunTest()
-        {
-            _log.Info("SongBrowserModelTests - All tests in Milliseconds");
-
-            Stopwatch stopwatch = Stopwatch.StartNew();
-            SongBrowserModel model = new SongBrowserModel();
-            model.Init(new MockBeatSaberSongList());
-            stopwatch.Stop();
-            _log.Info("Created a bunch of LevelStaticData: {0}", stopwatch.ElapsedMilliseconds);
-
-            stopwatch = Stopwatch.StartNew();
-            model.Settings.sortMode = SongSortMode.Original;
-            model.UpdateSongLists(false);
-            stopwatch.Stop();
-            _log.Info("Song Loading and Sorting as original: {0}", stopwatch.ElapsedMilliseconds);
-
-            stopwatch = Stopwatch.StartNew();
-            model.Settings.sortMode = SongSortMode.Default;
-            model.UpdateSongLists(false);
-            stopwatch.Stop();        
-            _log.Info("Song Loading and Sorting as favorites: {0}", stopwatch.ElapsedMilliseconds);
-
-            stopwatch = Stopwatch.StartNew();
-            model.Settings.sortMode = SongSortMode.Favorites;
-            model.UpdateSongLists(false);
-            stopwatch.Stop();
-            _log.Info("Song Loading and Sorting as favorites: {0}", stopwatch.ElapsedMilliseconds);
-
-            stopwatch = Stopwatch.StartNew();
-            model.Settings.sortMode = SongSortMode.Newest;
-            model.UpdateSongLists(false);
-            stopwatch.Stop();
-            _log.Info("Song Loading and Sorting as newest: {0}", stopwatch.ElapsedMilliseconds);
-
-            stopwatch = Stopwatch.StartNew();
-            for (int i = 0; i < 1; i++)
-            {
-                var m1 = model.SortedSongList.ToArray();
-                var m2 = model.SortedSongList.ToArray();
-                var m3 = model.SortedSongList.ToArray();
-            }
-            stopwatch.Stop();
-            _log.Info("Converting big list into array a bunch of times: {0}", stopwatch.ElapsedMilliseconds);
-        }
-    }
-}

+ 0 - 24
SongBrowserPlugin/Tests/SongBrowserTestRunner.cs

@@ -1,24 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace SongBrowserPlugin.Tests
-{
-    public class SongBrowserTestRunner
-    {
-        private Logger _log = new Logger("SongBrowserTestRunner");
-
-        public SongBrowserTestRunner()
-        {
-
-        }
-
-        public void RunTests()
-        {
-            _log.Info("Running Song Browser Tests");
-
-            new SongBrowserModelTests().RunTest();
-        }
-    }
-}

+ 1 - 1
SongBrowserPluginTest/Plugin.cs

@@ -7,7 +7,7 @@ namespace SongBrowserPluginTest
 {
     public class Plugin : IPlugin
     {
-        public const bool RunTests = true;
+        public const bool RunTests = false;
 
         private bool _didRunTests = false;
 

+ 3 - 2
scripts/clone_song.ps1

@@ -4,6 +4,7 @@ Careful with this.
 #>
 for($i=1;$i -le 2000;$i++)
 {
-    copy-item Believer -destination $i -Recurse
-    (Get-Content $i\info.json).replace('Believer', "Believer$i") | Set-Content $i\info.json    
+    copy-item Sunset -destination $i -Recurse
+    (Get-Content $i\info.json).replace('Sunset', "Sunset$i") | Set-Content $i\info.json    
+    (Get-Content $i\info.json).replace('from Deemo', "SunsetAuthor$i") | Set-Content $i\info.json    
 }