@@ -40,6 +40,7 @@ public class AppveyorBuild
40
40
[ InitializeOnLoad ]
41
41
public class MLAPIEditor : EditorWindow
42
42
{
43
+ private const string API_URL = "https://api.github.com/repos/MidLevel/MLAPI/releases" ;
43
44
private GithubRelease [ ] releases = new GithubRelease [ 0 ] ;
44
45
private bool [ ] foldoutStatus = new bool [ 0 ] ;
45
46
private string currentVersion
@@ -68,6 +69,7 @@ private long lastUpdated
68
69
private bool isFetching = false ;
69
70
private bool isParsing = false ;
70
71
private bool canRefetch => ! ( isFetching || isParsing ) ;
72
+ private string statusMessage ;
71
73
72
74
private int tab ;
73
75
@@ -80,7 +82,7 @@ public static void ShowWindow()
80
82
Vector2 scrollPos = Vector2 . zero ;
81
83
private void OnGUI ( )
82
84
{
83
- GUILayout . BeginArea ( new Rect ( 5 , 0 , position . width - 5 , position . height - 60 ) ) ;
85
+ GUILayout . BeginArea ( new Rect ( 5 , 0 , position . width - 5 , position . height - ( 40 + ( ( string . IsNullOrEmpty ( statusMessage ) ? 0 : 20 ) + ( canRefetch ? 20 : 0 ) ) ) ) ) ;
84
86
scrollPos = GUILayout . BeginScrollView ( scrollPos ) ;
85
87
tab = GUILayout . Toolbar ( tab , new string [ ] { "GitHub" , "Commits" } ) ;
86
88
if ( tab == 0 )
@@ -120,7 +122,7 @@ private void OnGUI()
120
122
EditorGUILayout . LabelField ( "Release date: " + DateTime . Parse ( DateTime . Parse ( releases [ i ] . published_at ) . ToString ( ) ) , EditorStyles . miniBoldLabel ) ;
121
123
122
124
if ( currentVersion != releases [ i ] . tag_name && GUILayout . Button ( "Install" ) )
123
- InstallRelease ( i ) ;
125
+ EditorCoroutine . Start ( InstallRelease ( i ) ) ;
124
126
125
127
EditorGUI . indentLevel -- ;
126
128
}
@@ -129,19 +131,20 @@ private void OnGUI()
129
131
}
130
132
else if ( tab == 1 )
131
133
{
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 ) ;
134
+ EditorGUILayout . LabelField ( "Not yet implemented. The rest API for AppVeyor is proper garbage and is needed to grab the artifact download URLs" , EditorStyles . wordWrappedMiniLabel ) ;
133
135
}
134
136
GUILayout . EndScrollView ( ) ;
135
137
GUILayout . EndArea ( ) ;
136
138
137
- GUILayout . BeginArea ( new Rect ( 5 , position . height - 60 , position . width - 5 , 60 ) ) ;
139
+ GUILayout . BeginArea ( new Rect ( 5 , position . height - ( 40 + ( ( string . IsNullOrEmpty ( statusMessage ) ? 0 : 20 ) + ( canRefetch ? 20 : 0 ) ) ) , position . width - 5 , ( 60 + ( ( string . IsNullOrEmpty ( statusMessage ) ? 0 : 20 ) + ( canRefetch ? 20 : 0 ) ) ) ) ) ;
138
140
139
141
string lastUpdatedString = lastUpdated == 0 ? "Never" : new DateTime ( lastUpdated ) . ToShortTimeString ( ) ;
140
142
GUILayout . Label ( "Last checked: " + lastUpdatedString , EditorStyles . centeredGreyMiniLabel ) ;
141
143
142
- string fetchButton = isFetching ? "Fetching..." : isParsing ? "Parsing..." : "Fetch releases" ;
143
- if ( GUILayout . Button ( fetchButton ) && canRefetch )
144
+ if ( canRefetch && GUILayout . Button ( "Fetch releases" ) )
144
145
EditorCoroutine . Start ( GetReleases ( ) ) ;
146
+ if ( ! string . IsNullOrEmpty ( statusMessage ) )
147
+ GUILayout . Label ( statusMessage , EditorStyles . centeredGreyMiniLabel ) ;
145
148
if ( GUILayout . Button ( "Reset defaults" ) )
146
149
{
147
150
releases = new GithubRelease [ 0 ] ;
@@ -158,93 +161,147 @@ private void OnGUI()
158
161
Repaint ( ) ;
159
162
}
160
163
161
- private void InstallRelease ( int index )
164
+ private IEnumerator InstallRelease ( int index )
162
165
{
166
+ statusMessage = "Cleaning lib folder" ;
167
+ yield return null ;
168
+
169
+ if ( Directory . Exists ( Application . dataPath + "/MLAPI/Lib/" ) )
170
+ Directory . Delete ( Application . dataPath + "/MLAPI/Lib/" , true ) ;
171
+
172
+ Directory . CreateDirectory ( Application . dataPath + "/MLAPI/Lib/" ) ;
173
+
174
+ bool downloadFail = false ;
163
175
for ( int i = 0 ; i < releases [ index ] . assets . Length ; i ++ )
164
176
{
165
177
WWW www = new WWW ( releases [ index ] . assets [ i ] . browser_download_url ) ;
166
178
while ( ! www . isDone && string . IsNullOrEmpty ( www . error ) )
167
179
{
168
- EditorGUI . ProgressBar ( new Rect ( 5 , position . height - 60 , position . width , 20 ) , www . progress , "Installing " + i + "/" + releases [ index ] . assets . Length ) ;
180
+ statusMessage = "Downloading " + releases [ index ] . assets [ i ] . name + "(" + ( i + 1 ) + "/" + releases [ index ] . assets . Length + ") " + www . progress + "%" ;
181
+ yield return null ;
169
182
}
170
183
171
- if ( ! Directory . Exists ( Application . dataPath + "/MLAPI/Lib/" ) )
172
- Directory . CreateDirectory ( Application . dataPath + "/MLAPI/Lib/" ) ;
184
+ if ( ! string . IsNullOrEmpty ( www . error ) )
185
+ {
186
+ //Some kind of error
187
+ downloadFail = true ;
188
+ statusMessage = "Failed to download asset " + releases [ index ] . assets [ i ] . name + ". Error: " + www . error ;
189
+ double startTime = EditorApplication . timeSinceStartup ;
190
+ //Basically = yield return new WaitForSeconds(5);
191
+ while ( EditorApplication . timeSinceStartup - startTime <= 5f )
192
+ yield return null ;
193
+ statusMessage = "" ;
194
+ }
195
+ else
196
+ {
197
+ statusMessage = "Writing " + releases [ index ] . assets [ i ] . name + " to disk" ;
198
+ yield return null ;
199
+
200
+ File . WriteAllBytes ( Application . dataPath + "/MLAPI/Lib/" + releases [ index ] . assets [ i ] . name , www . bytes ) ;
173
201
174
- File . WriteAllBytes ( Application . dataPath + "/MLAPI/Lib/" + releases [ index ] . assets [ i ] . name , www . bytes ) ;
202
+ if ( releases [ index ] . assets [ i ] . name . EndsWith ( ".unitypackage" ) )
203
+ {
204
+ statusMessage = "Installing " + releases [ index ] . assets [ i ] . name ;
205
+ yield return null ;
206
+ AssetDatabase . ImportPackage ( Application . dataPath + "/MLAPI/Lib/" + releases [ index ] . assets [ i ] . name , false ) ;
207
+ }
175
208
176
- if ( releases [ index ] . assets [ i ] . name . EndsWith ( ".unitypackage" ) )
177
- AssetDatabase . ImportPackage ( Application . dataPath + "/MLAPI/Lib/" + releases [ index ] . assets [ i ] . name , false ) ;
209
+ yield return null ;
210
+ }
178
211
}
179
212
180
- currentVersion = releases [ index ] . tag_name ;
213
+ yield return null ;
214
+ statusMessage = "" ;
215
+ if ( ! downloadFail )
216
+ currentVersion = releases [ index ] . tag_name ; //Only set this if there was no fail. This is to allow them to still retry the download
181
217
AssetDatabase . Refresh ( ) ;
182
218
}
183
219
184
220
185
- IEnumerator GetReleases ( )
221
+ private IEnumerator GetReleases ( )
186
222
{
187
223
lastUpdated = DateTime . Now . Ticks ;
188
224
189
- WWW www = new WWW ( "https://api.github.com/repos/TwoTenPvP/MLAPI/releases" ) ;
225
+ WWW www = new WWW ( API_URL ) ;
190
226
isFetching = true ;
191
227
while ( ! www . isDone && string . IsNullOrEmpty ( www . error ) )
192
228
{
229
+ statusMessage = "Fetching releases " + www . progress + "%" ;
193
230
yield return null ;
194
231
}
195
- isFetching = false ;
196
- isParsing = true ;
197
- string json = www . text ;
198
-
199
- //This makes it from a json array to the individual objects in the array.
200
- //The JSON serializer cant take arrays. We have to split it up outselves.
201
- List < string > releasesJson = new List < string > ( ) ;
202
- int depth = 0 ;
203
- StringBuilder builder = new StringBuilder ( ) ;
204
- for ( int i = 1 ; i < json . Length - 1 ; i ++ )
205
- {
206
- if ( json [ i ] == '[' )
207
- depth ++ ;
208
- else if ( json [ i ] == ']' )
209
- depth -- ;
210
- else if ( json [ i ] == '{' )
211
- depth ++ ;
212
- else if ( json [ i ] == '}' )
213
- depth -- ;
214
-
215
- if ( ( depth == 0 && json [ i ] != ',' ) || depth > 0 )
216
- builder . Append ( json [ i ] ) ;
217
-
218
- if ( depth == 0 && json [ i ] == ',' )
219
- {
220
- releasesJson . Add ( builder . ToString ( ) ) ;
221
- builder . Length = 0 ;
222
- }
223
232
224
- //Parse in smaller batches
225
- if ( i % ( json . Length / 30 ) == 0 )
226
- {
233
+ if ( ! string . IsNullOrEmpty ( www . error ) )
234
+ {
235
+ //Some kind of error
236
+ statusMessage = "Failed to fetch releases. Error: " + www . error ;
237
+ double startTime = EditorApplication . timeSinceStartup ;
238
+ //Basically = yield return new WaitForSeconds(5);
239
+ while ( EditorApplication . timeSinceStartup - startTime <= 5f )
227
240
yield return null ;
228
- }
241
+ statusMessage = "" ;
229
242
}
243
+ else
244
+ {
245
+ isFetching = false ;
246
+ isParsing = true ;
247
+ string json = www . text ;
248
+
249
+ //This makes it from a json array to the individual objects in the array.
250
+ //The JSON serializer cant take arrays. We have to split it up outselves.
251
+ List < string > releasesJson = new List < string > ( ) ;
252
+ int depth = 0 ;
253
+ StringBuilder builder = new StringBuilder ( ) ;
254
+ for ( int i = 1 ; i < json . Length - 1 ; i ++ )
255
+ {
256
+ if ( json [ i ] == '[' )
257
+ depth ++ ;
258
+ else if ( json [ i ] == ']' )
259
+ depth -- ;
260
+ else if ( json [ i ] == '{' )
261
+ depth ++ ;
262
+ else if ( json [ i ] == '}' )
263
+ depth -- ;
264
+
265
+ if ( ( depth == 0 && json [ i ] != ',' ) || depth > 0 )
266
+ builder . Append ( json [ i ] ) ;
267
+
268
+ if ( depth == 0 && json [ i ] == ',' )
269
+ {
270
+ releasesJson . Add ( builder . ToString ( ) ) ;
271
+ builder . Length = 0 ;
272
+ }
230
273
231
- releases = new GithubRelease [ releasesJson . Count ] ;
232
- foldoutStatus = new bool [ releasesJson . Count ] ;
274
+ //Parse in smaller batches
275
+ if ( i % ( json . Length / 100 ) == 0 )
276
+ {
277
+ statusMessage = "Splitting JSON " + ( i / ( float ) json . Length ) * 100f + "%" ;
278
+ yield return null ;
279
+ }
233
280
234
- for ( int i = 0 ; i < releasesJson . Count ; i ++ )
235
- {
236
- releases [ i ] = JsonUtility . FromJson < GithubRelease > ( releasesJson [ i ] ) ;
237
- if ( i == 0 )
238
- foldoutStatus [ i ] = true ;
239
- else
240
- foldoutStatus [ i ] = false ;
281
+ statusMessage = "" ;
282
+ }
241
283
242
- if ( i % ( releasesJson . Count / 30f ) == 0 )
284
+ releases = new GithubRelease [ releasesJson . Count ] ;
285
+ foldoutStatus = new bool [ releasesJson . Count ] ;
286
+
287
+ for ( int i = 0 ; i < releasesJson . Count ; i ++ )
243
288
{
244
- yield return null ;
289
+ releases [ i ] = JsonUtility . FromJson < GithubRelease > ( releasesJson [ i ] ) ;
290
+ if ( i == 0 )
291
+ foldoutStatus [ i ] = true ;
292
+ else
293
+ foldoutStatus [ i ] = false ;
294
+
295
+ if ( i % ( releasesJson . Count / 30f ) == 0 )
296
+ {
297
+ yield return null ;
298
+ statusMessage = "Parsing JSON " + ( i / ( float ) releasesJson . Count ) * 100f + "%" ;
299
+ }
245
300
}
301
+
302
+ statusMessage = "" ;
303
+ isParsing = false ;
246
304
}
247
- isParsing = false ;
248
305
}
249
306
250
307
public class EditorCoroutine
0 commit comments