public static MLAPIVersion GetVersionDiff(MLAPIVersion v1, MLAPIVersion v2)
 {
     return(new MLAPIVersion()
     {
         MAJOR = (byte)(v1.MAJOR - v2.MAJOR),
         MINOR = (byte)(v1.MINOR - v2.MINOR),
         PATCH = (byte)(v1.PATCH - v2.PATCH)
     });
 }
 private GithubRelease GetReleaseOfVersion(MLAPIVersion version)
 {
     for (int i = 0; i < releases.Length; i++)
     {
         if (MLAPIVersion.Parse(releases[i].tag_name) == version)
         {
             return(releases[i]);
         }
     }
     return(null);
 }
    private List <MLAPIVersion> GetMajorVersionsBetween(MLAPIVersion currentVersion, MLAPIVersion targetVersion)
    {
        List <MLAPIVersion> versionsBetween = new List <MLAPIVersion>();

        for (int i = 0; i < releases.Length; i++)
        {
            MLAPIVersion version = MLAPIVersion.Parse(releases[i].tag_name);
            if (version >= currentVersion && version <= targetVersion)
            {
                MLAPIVersion diff = MLAPIVersion.GetVersionDiff(currentVersion, version);
                if (diff.MAJOR > 0)
                {
                    versionsBetween.Add(version);
                }
            }
        }
        return(versionsBetween);
    }
    private IEnumerator InstallRelease(int index)
    {
        PendingPackages.Clear();
        PendingPackageLock = true;
        bool                waiting             = true;
        bool                accepted            = false;
        MLAPIVersion        currentMLAPIVersion = MLAPIVersion.Parse(currentVersion);
        List <MLAPIVersion> versions            = GetMajorVersionsBetween(currentMLAPIVersion, MLAPIVersion.Parse(releases[index].tag_name));

        if (versions.Count > 0 && currentMLAPIVersion.IsValid() && currentMLAPIVersion > new MLAPIVersion()
        {
            MAJOR = 2, MINOR = 0, PATCH = 0
        })
        {
            VersionUpgradePopup window = ScriptableObject.CreateInstance <VersionUpgradePopup>();
            Rect  mainWindowRect       = MLAPIEditorExtensions.GetEditorMainWindowPos();
            float widthFill            = 0.5f;
            float heightFill           = 0.3f;
            window.position = new Rect(mainWindowRect.center.x - ((mainWindowRect.width * widthFill) / 2f), mainWindowRect.center.y - ((mainWindowRect.height * heightFill) / 2f), mainWindowRect.width * widthFill, mainWindowRect.height * heightFill);
            window.SetData(GetReleasesFromVersions(versions), (result) =>
            {
                //Called if the user proceeds with the upgrade.
                accepted = result;
                waiting  = false;
            });
            window.ShowPopup();
        }
        else
        {
            accepted = true;
            waiting  = false;
        }

        while (waiting)
        {
            yield return(null);
        }

        if (accepted)
        {
            showProgressBar = true;
            progressTarget  = releases[index].assets.Length;
            progress        = 0;

            statusMessage = "Cleaning lib folder";
            yield return(null);

            if (Directory.Exists(Application.dataPath + "/MLAPI/Lib/"))
            {
                Directory.Delete(Application.dataPath + "/MLAPI/Lib/", true);
            }

            Directory.CreateDirectory(Application.dataPath + "/MLAPI/Lib/");

            bool downloadFail = false;
            for (int i = 0; i < releases[index].assets.Length; i++)
            {
                UnityWebRequest www = UnityWebRequest.Get(releases[index].assets[i].browser_download_url);
                www.SendWebRequest();
                while (!www.isDone && string.IsNullOrEmpty(www.error))
                {
                    statusMessage = "Downloading " + releases[index].assets[i].name + "(" + (i + 1) + "/" + releases[index].assets.Length + ") " + www.downloadProgress + "%";
                    yield return(null);
                }

                if (!string.IsNullOrEmpty(www.error))
                {
                    //Some kind of error
                    downloadFail  = true;
                    statusMessage = "Failed to download asset " + releases[index].assets[i].name + ". Error: " + www.error;
                    double startTime = EditorApplication.timeSinceStartup;
                    //Basically = yield return new WaitForSeconds(5);
                    while (EditorApplication.timeSinceStartup - startTime <= 5f)
                    {
                        yield return(null);
                    }
                    statusMessage = "";
                }
                else
                {
                    statusMessage = "Writing " + releases[index].assets[i].name + " to disk";
                    yield return(null);

                    File.WriteAllBytes(Application.dataPath + "/MLAPI/Lib/" + releases[index].assets[i].name, www.downloadHandler.data);

                    if (releases[index].assets[i].name.EndsWith(".unitypackage"))
                    {
                        PendingPackages.Add(releases[index].assets[i].name);
                    }
                    yield return(null);
                }
                progress = i;
            }

            yield return(null);

            statusMessage = "";
            if (!downloadFail)
            {
                currentVersion = releases[index].tag_name; //Only set this if there was no fail. This is to allow them to still retry the download
            }
            AssetDatabase.Refresh();
        }
        showProgressBar    = false;
        statusMessage      = "";
        PendingPackageLock = false;
    }