11using System ;
2+ using System . Collections ;
23using System . Collections . Generic ;
34using System . IO ;
5+ using System . Text ;
46using UnityEditor ;
57using UnityEngine ;
68
@@ -23,6 +25,19 @@ public class GithubAsset
2325 public string name ;
2426}
2527
28+ [ Serializable ]
29+ public class AppveyorProject
30+ {
31+ public int repositoryBranch ;
32+ }
33+
34+ [ Serializable ]
35+ public class AppveyorBuild
36+ {
37+
38+ }
39+
40+ [ InitializeOnLoad ]
2641public class MLAPIEditor : EditorWindow
2742{
2843 private GithubRelease [ ] releases = new GithubRelease [ 0 ] ;
@@ -50,60 +65,83 @@ private long lastUpdated
5065 }
5166 }
5267
68+ private bool isFetching = false ;
69+ private bool isParsing = false ;
70+ private bool canRefetch => ! ( isFetching || isParsing ) ;
71+
72+ private int tab ;
73+
5374 [ MenuItem ( "Window/MLAPI" ) ]
5475 public static void ShowWindow ( )
5576 {
5677 GetWindow < MLAPIEditor > ( ) ;
5778 }
5879
80+ Vector2 scrollPos = Vector2 . zero ;
5981 private void OnGUI ( )
6082 {
61- if ( foldoutStatus != null )
83+ GUILayout . BeginArea ( new Rect ( 5 , 0 , position . width - 5 , position . height - 60 ) ) ;
84+ scrollPos = GUILayout . BeginScrollView ( scrollPos ) ;
85+ tab = GUILayout . Toolbar ( tab , new string [ ] { "GitHub" , "Commits" } ) ;
86+ if ( tab == 0 )
6287 {
63- for ( int i = 0 ; i < foldoutStatus . Length ; i ++ )
88+ if ( foldoutStatus != null )
6489 {
65- if ( releases [ i ] == null )
66- continue ;
67- foldoutStatus [ i ] = EditorGUILayout . Foldout ( foldoutStatus [ i ] , releases [ i ] . tag_name + " - " + releases [ i ] . name ) ;
68- if ( foldoutStatus [ i ] )
90+ for ( int i = 0 ; i < foldoutStatus . Length ; i ++ )
6991 {
70- EditorGUI . indentLevel ++ ;
71- EditorGUILayout . LabelField ( "Release notes" , EditorStyles . boldLabel ) ;
72- EditorGUILayout . LabelField ( releases [ i ] . body , EditorStyles . wordWrappedLabel ) ;
73- EditorGUILayout . Space ( ) ;
74- EditorGUILayout . Space ( ) ;
75- if ( releases [ i ] . prerelease )
76- {
77- GUIStyle style = new GUIStyle ( EditorStyles . boldLabel ) ;
78- style . normal . textColor = new Color ( 1f , 0.5f , 0f ) ;
79- EditorGUILayout . LabelField ( "Pre-release" , style ) ;
80- }
81- else
82- {
83- GUIStyle style = new GUIStyle ( EditorStyles . boldLabel ) ;
84- style . normal . textColor = new Color ( 0f , 1f , 0f ) ;
85- EditorGUILayout . LabelField ( "Stable-release" , style ) ;
86- }
87- if ( currentVersion == releases [ i ] . tag_name )
92+ if ( releases [ i ] == null )
93+ continue ;
94+ foldoutStatus [ i ] = EditorGUILayout . Foldout ( foldoutStatus [ i ] , releases [ i ] . tag_name + " - " + releases [ i ] . name ) ;
95+ if ( foldoutStatus [ i ] )
8896 {
89- GUIStyle boldStyle = new GUIStyle ( EditorStyles . boldLabel ) ;
90- boldStyle . normal . textColor = new Color ( 0.3f , 1f , 0.3f ) ;
91- EditorGUILayout . LabelField ( "Installed" , boldStyle ) ;
92- }
93- EditorGUILayout . LabelField ( "Release date: " + DateTime . Parse ( DateTime . Parse ( releases [ i ] . published_at ) . ToString ( ) ) , EditorStyles . miniBoldLabel ) ;
97+ EditorGUI . indentLevel ++ ;
98+ EditorGUILayout . LabelField ( "Release notes" , EditorStyles . boldLabel ) ;
99+ EditorGUILayout . LabelField ( releases [ i ] . body , EditorStyles . wordWrappedLabel ) ;
100+ EditorGUILayout . Space ( ) ;
101+ EditorGUILayout . Space ( ) ;
102+ if ( releases [ i ] . prerelease )
103+ {
104+ GUIStyle style = new GUIStyle ( EditorStyles . boldLabel ) ;
105+ style . normal . textColor = new Color ( 1f , 0.5f , 0f ) ;
106+ EditorGUILayout . LabelField ( "Pre-release" , style ) ;
107+ }
108+ else
109+ {
110+ GUIStyle style = new GUIStyle ( EditorStyles . boldLabel ) ;
111+ style . normal . textColor = new Color ( 0f , 1f , 0f ) ;
112+ EditorGUILayout . LabelField ( "Stable-release" , style ) ;
113+ }
114+ if ( currentVersion == releases [ i ] . tag_name )
115+ {
116+ GUIStyle boldStyle = new GUIStyle ( EditorStyles . boldLabel ) ;
117+ boldStyle . normal . textColor = new Color ( 0.3f , 1f , 0.3f ) ;
118+ EditorGUILayout . LabelField ( "Installed" , boldStyle ) ;
119+ }
120+ EditorGUILayout . LabelField ( "Release date: " + DateTime . Parse ( DateTime . Parse ( releases [ i ] . published_at ) . ToString ( ) ) , EditorStyles . miniBoldLabel ) ;
94121
95- if ( currentVersion != releases [ i ] . tag_name && GUILayout . Button ( "Install" ) )
96- InstallRelease ( i ) ;
122+ if ( currentVersion != releases [ i ] . tag_name && GUILayout . Button ( "Install" ) )
123+ InstallRelease ( i ) ;
97124
98- EditorGUI . indentLevel -- ;
125+ EditorGUI . indentLevel -- ;
126+ }
99127 }
100128 }
101129 }
130+ else if ( tab == 1 )
131+ {
132+ EditorGUILayout . LabelField ( "Not yet implemented. The rest API for AppVeyor is proper garbage and is needed to grab the artifact download URLs" , EditorStyles . wordWrappedLabel ) ;
133+ }
134+ GUILayout . EndScrollView ( ) ;
135+ GUILayout . EndArea ( ) ;
136+
137+ GUILayout . BeginArea ( new Rect ( 5 , position . height - 60 , position . width - 5 , 60 ) ) ;
102138
103- GUILayout . BeginArea ( new Rect ( 5 , position . height - 40 , position . width , 40 ) ) ;
139+ string lastUpdatedString = lastUpdated == 0 ? "Never" : new DateTime ( lastUpdated ) . ToShortTimeString ( ) ;
140+ GUILayout . Label ( "Last checked: " + lastUpdatedString , EditorStyles . centeredGreyMiniLabel ) ;
104141
105- if ( GUILayout . Button ( "Fetch releases" ) )
106- GetReleases ( ) ;
142+ string fetchButton = isFetching ? "Fetching..." : isParsing ? "Parsing..." : "Fetch releases" ;
143+ if ( GUILayout . Button ( fetchButton ) && canRefetch )
144+ EditorCoroutine . Start ( GetReleases ( ) ) ;
107145 if ( GUILayout . Button ( "Reset defaults" ) )
108146 {
109147 releases = new GithubRelease [ 0 ] ;
@@ -114,11 +152,8 @@ private void OnGUI()
114152
115153 GUILayout . EndArea ( ) ;
116154
117- string lastUpdatedString = lastUpdated == 0 ? "Never" : new DateTime ( lastUpdated ) . ToShortTimeString ( ) ;
118- EditorGUI . LabelField ( new Rect ( 5 , position . height - 60 , position . width , 20 ) , "Last checked: " + lastUpdatedString , EditorStyles . centeredGreyMiniLabel ) ;
119-
120155 if ( ( releases . Length == 0 && ( DateTime . Now - new DateTime ( lastUpdated ) ) . TotalSeconds > 600 ) || ( DateTime . Now - new DateTime ( lastUpdated ) ) . TotalSeconds > 3600 )
121- GetReleases ( ) ;
156+ EditorCoroutine . Start ( GetReleases ( ) ) ;
122157
123158 Repaint ( ) ;
124159 }
@@ -146,22 +181,26 @@ private void InstallRelease(int index)
146181 AssetDatabase . Refresh ( ) ;
147182 }
148183
149- private void GetReleases ( )
184+
185+ IEnumerator GetReleases ( )
150186 {
151187 lastUpdated = DateTime . Now . Ticks ;
152188
153189 WWW www = new WWW ( "https://api.github.com/repos/TwoTenPvP/MLAPI/releases" ) ;
190+ isFetching = true ;
154191 while ( ! www . isDone && string . IsNullOrEmpty ( www . error ) )
155192 {
156- EditorGUI . ProgressBar ( new Rect ( 5 , position . height - 60 , position . width , 20 ) , www . progress , "Fetching..." ) ;
193+ yield return null ;
157194 }
195+ isFetching = false ;
196+ isParsing = true ;
158197 string json = www . text ;
159198
160199 //This makes it from a json array to the individual objects in the array.
161200 //The JSON serializer cant take arrays. We have to split it up outselves.
162201 List < string > releasesJson = new List < string > ( ) ;
163202 int depth = 0 ;
164- string currentObject = "" ;
203+ StringBuilder builder = new StringBuilder ( ) ;
165204 for ( int i = 1 ; i < json . Length - 1 ; i ++ )
166205 {
167206 if ( json [ i ] == '[' )
@@ -174,12 +213,18 @@ private void GetReleases()
174213 depth -- ;
175214
176215 if ( ( depth == 0 && json [ i ] != ',' ) || depth > 0 )
177- currentObject += json [ i ] ;
216+ builder . Append ( json [ i ] ) ;
178217
179218 if ( depth == 0 && json [ i ] == ',' )
180219 {
181- releasesJson . Add ( currentObject ) ;
182- currentObject = "" ;
220+ releasesJson . Add ( builder . ToString ( ) ) ;
221+ builder . Length = 0 ;
222+ }
223+
224+ //Parse in smaller batches
225+ if ( i % ( json . Length / 30 ) == 0 )
226+ {
227+ yield return null ;
183228 }
184229 }
185230
@@ -193,6 +238,43 @@ private void GetReleases()
193238 foldoutStatus [ i ] = true ;
194239 else
195240 foldoutStatus [ i ] = false ;
241+
242+ if ( i % ( releasesJson . Count / 30f ) == 0 )
243+ {
244+ yield return null ;
245+ }
246+ }
247+ isParsing = false ;
248+ }
249+
250+ public class EditorCoroutine
251+ {
252+ public static EditorCoroutine Start ( IEnumerator routine )
253+ {
254+ EditorCoroutine coroutine = new EditorCoroutine ( routine ) ;
255+ coroutine . Start ( ) ;
256+ return coroutine ;
257+ }
258+
259+ private readonly IEnumerator coroutine ;
260+ EditorCoroutine ( IEnumerator routine )
261+ {
262+ coroutine = routine ;
263+ }
264+
265+ private void Start ( )
266+ {
267+ EditorApplication . update += Update ;
268+ }
269+
270+ private void Stop ( )
271+ {
272+ EditorApplication . update -= Update ;
273+ }
274+
275+ void Update ( )
276+ {
277+ if ( ! coroutine . MoveNext ( ) ) Stop ( ) ;
196278 }
197279 }
198280}
0 commit comments