diff --git a/.vs/AlphabeticalKerbals/v14/.suo b/.vs/AlphabeticalKerbals/v14/.suo index 6e13616..5250dd4 100644 Binary files a/.vs/AlphabeticalKerbals/v14/.suo and b/.vs/AlphabeticalKerbals/v14/.suo differ diff --git a/AlphabeticalKerbals/KerbalSorter.cs b/AlphabeticalKerbals/KerbalSorter.cs index b6fc702..03ee7b1 100644 --- a/AlphabeticalKerbals/KerbalSorter.cs +++ b/AlphabeticalKerbals/KerbalSorter.cs @@ -11,6 +11,12 @@ namespace AlphabeticalKerbals class KerbalSorter { static void print(string s) { MonoBehaviour.print("AlphabeticalKerbals: " + s); } + + /// + /// Sorts the kerbals in the CrewAssignmentDialog + /// Will not work on dialogs that do not use the CrewAssignmentDialog GUI element + /// + /// success static public bool Sort_Kerbals() { if (CrewAssignmentDialog.Instance == null) @@ -21,7 +27,7 @@ namespace AlphabeticalKerbals { UIList avail = CrewAssignmentDialog.Instance.scrollListAvail; - UIList_QSort(avail, 0, avail.Count-1); + UIList_QSort(avail, 0, avail.Count - 1); #if DEBUG for (int i = 0; i < avail.Count; i++) @@ -33,41 +39,19 @@ namespace AlphabeticalKerbals #endif return true; - + /* - print("AlphabeticalKerbals: OnEditorCrewOpened has CrewAssignmentDialog yay!!!"); - UIList avail = CrewAssignmentDialog.Instance.scrollListAvail; - UIListItem first = avail.GetUilistItemAt(0); - - print("AlphabeticalKerbals: Got first item in UIList"); - - if (first == null) - { - //happens on first load - print("AlphabeticalKerbals: Uhhh.... first is null?"); - } - if (first.gameObject == null) - { - print("AlphabeticalKerbals: Uhhh.... gameObject is null?"); - } - Component[] comps = first.gameObject.GetComponents(); - print("AlphabeticalKerbals: Uhhh.... got components???"); for (int i = 0; i < comps.Length; ++i) { print($"Component {i}: {comps[i].GetType()}"); } - CrewListItem firstdata = first.GetComponent(); - print("AlphabeticalKerbals: Got a component for crew list item"); - print("AlphabeticalKerbals: Got crew name: " + firstdata.GetName()); - - print("AlphabeticalKerbals: Got component list"); foreach (Component comp in firstdata) { - print("AlphabeticalKerbals: Got a component"); - print("AlphabeticalKerbals: Component name is " + comp.name); - print("AlphabeticalKerbals: Component type is " + comp.GetType().Name); - print("AlphabeticalKerbals: Component string is " + comp.ToString()); + print("Got a component"); + print("Component name is " + comp.name); + print("Component type is " + comp.GetType().Name); + print("Component string is " + comp.ToString()); } */ @@ -77,6 +61,57 @@ namespace AlphabeticalKerbals return false; } + /// + /// Sorts Kerbals, but first checks the list to make sure it's not already sorted. + /// Overall, this ends up using more resources than just blind-sorting, but in cases + /// where the list is almost always going to be correctly sorted, it may save some time. + /// + /// success + static public bool Sort_Kerbals_If_Needed() + { + if (CrewAssignmentDialog.Instance == null) + { + print("OnEditorCrewOpened has no CrewAssignmentDialog yet..."); + return false; + } + else + { + UIList avail = CrewAssignmentDialog.Instance.scrollListAvail; + bool unsorted = false; + + int i = 0; + for (; i < (avail.Count - 1); i++) + { + UIListItem li = avail.GetUilistItemAt(i); + UIListItem li2 = avail.GetUilistItemAt(i + 1); + CrewListItem crew = li.GetComponent(); + if (UIList_Cmp(li, li2) > 0) + { + unsorted = true; + + break; + } + + } + + if (unsorted) + { + print("Change in Kerbal List detected, re-sorting"); +#if DEBUG + print("Sort_If_Needed: Sort IS needed due to i = " + i.ToString()); + for (i = 0; i < avail.Count; i++) + { + UIListItem li = avail.GetUilistItemAt(i); + CrewListItem crew = li.GetComponent(); + print("BEFORE SORT = " + crew.GetName()); + } +#endif + Sort_Kerbals(); + } + return true; + } + } + /// /// Return value positive means left > right, return value negative means left < right /// @@ -85,16 +120,21 @@ namespace AlphabeticalKerbals /// static int UIList_Cmp(UIListItem left, UIListItem right) { - if (left == null) { return 1; } // null values are considered greatest, so they are sorted at the end - if (right == null) { return -1; } // null values are considered greatest, so they are sorted at the end - CrewListItem ldata = null; CrewListItem rdata = null; try { ldata = left.GetComponent(); } catch { return 1; } try { rdata = right.GetComponent(); } catch { return -1; } +#if DEBUG if (ldata == null) { return 1; } if (rdata == null) { return -1; } +#endif + + bool ltourist = ldata.GetCrewRef().type == ProtoCrewMember.KerbalType.Tourist; + bool rtourist = rdata.GetCrewRef().type == ProtoCrewMember.KerbalType.Tourist; + + if (ltourist && !rtourist) { return 1; } // tourists are also sorted to the end + if (!ltourist && rtourist) { return -1; } // tourists are also sorted to the end return ldata.GetName().CompareTo(rdata.GetName()); } diff --git a/AlphabeticalKerbals/Properties/AssemblyInfo.cs b/AlphabeticalKerbals/Properties/AssemblyInfo.cs index 024eef3..becac0e 100644 --- a/AlphabeticalKerbals/Properties/AssemblyInfo.cs +++ b/AlphabeticalKerbals/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("0.1.0.0")] +[assembly: AssemblyVersion("0.2.0.0")] +[assembly: AssemblyFileVersion("0.2.0.0")] diff --git a/AlphabeticalKerbals/SceneHooks.cs b/AlphabeticalKerbals/SceneHooks.cs index d8f74c5..7c5e612 100644 --- a/AlphabeticalKerbals/SceneHooks.cs +++ b/AlphabeticalKerbals/SceneHooks.cs @@ -10,12 +10,19 @@ using System.Text; namespace AlphabeticalKerbals { + public class AlphabetStatic + { + public static readonly TimeSpan update_interval = new TimeSpan(0, 0, 0, 0, 750); + } + [KSPAddon(KSPAddon.Startup.EditorAny, false)] public class AlphabetVAB : MonoBehaviour { public bool HasBeenSorted; public EditorScreen CurrentEditorScreen; private int sortAttempts; + private DateTime last_update; + /// /// Module initialization @@ -73,19 +80,19 @@ namespace AlphabeticalKerbals { try { - CurrentEditorScreen = screen; - HasBeenSorted = false; - sortAttempts = 0; - - if (screen == EditorScreen.Crew) + if (CurrentEditorScreen != EditorScreen.Crew && screen == EditorScreen.Crew) { + last_update = DateTime.Now; + HasBeenSorted = false; + sortAttempts = 0; OnEditorCrewOpened(); } } catch (Exception e) { print("AlphabeticalKerbals: There was an error in OnEditorScreenChange"); - } + } + CurrentEditorScreen = screen; } /// @@ -109,6 +116,26 @@ namespace AlphabeticalKerbals } } + public void Update() + { + if (CurrentEditorScreen == EditorScreen.Crew) + { + if (last_update + AlphabetStatic.update_interval < DateTime.Now) + { + // polling 3-4 times per second for crew panel updates + OnCrewPanelTick(); + last_update = DateTime.Now; + } + + } + } + + public void OnCrewPanelTick() + { + KerbalSorter.Sort_Kerbals_If_Needed(); + } + + } @@ -116,10 +143,68 @@ namespace AlphabeticalKerbals [KSPAddon(KSPAddon.Startup.SpaceCentre, false)] public class AlphabetSC : MonoBehaviour { + public bool DialogUp = false; + + private DateTime last_update; + public void Start() { print("AlphabeticalKerbals: AlphabetSC started!"); } + public void Update() + { + if (!DialogUp) + { + if (VesselSpawnDialog.Instance != null && VesselSpawnDialog.Instance.Visible) + { + if (CrewAssignmentDialog.Instance != null && CrewAssignmentDialog.Instance.isActiveAndEnabled) + { + OnLaunchDialog(); + DialogUp = true; + last_update = DateTime.Now; + } + } + + } + else if (DialogUp) + { + if (VesselSpawnDialog.Instance == null || !VesselSpawnDialog.Instance.Visible) + { + if (CrewAssignmentDialog.Instance == null || !CrewAssignmentDialog.Instance.isActiveAndEnabled) + { + OnLaunchDialogClose(); + DialogUp = false; + } + + } + else if (last_update + AlphabetStatic.update_interval < DateTime.Now) + { + // polling 3-4 times per second for crew panel updates + OnLaunchDialogTick(); + last_update = DateTime.Now; + } + + } + } + + public void OnLaunchDialog() + { + print("Alphabetical Kerbals: Vessel Spawn Dialog detected."); + + KerbalSorter.Sort_Kerbals(); + + } + + public void OnLaunchDialogClose() + { + } + + public void OnLaunchDialogTick() + { + KerbalSorter.Sort_Kerbals_If_Needed(); + } + + } } diff --git a/distrib/AlphabeticalKerbals.zip b/distrib/AlphabeticalKerbals.zip index 9db0f6e..7c77231 100644 Binary files a/distrib/AlphabeticalKerbals.zip and b/distrib/AlphabeticalKerbals.zip differ diff --git a/distrib/AlphabeticalKerbals/AlphabeticalKerbals.dll b/distrib/AlphabeticalKerbals/AlphabeticalKerbals.dll index 94d6653..0cd5eab 100644 Binary files a/distrib/AlphabeticalKerbals/AlphabeticalKerbals.dll and b/distrib/AlphabeticalKerbals/AlphabeticalKerbals.dll differ