Skip to content

Commit

Permalink
Fixed project retrieval issues and renamed some methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Bengston committed Jul 9, 2017
1 parent e2c8935 commit b35afa4
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 48 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# Change Log

## v0.3 - in progress
All dates in DD/MM/YY format.

## v0.3 - 09/07/17

- Added heartbeat throttling.
- Changed how callback linking is handled.
- Renamed some methods so they would make more sense.
- Fixed issue where changing projects would fail due to an out of range index error.
- Fixed issue where current branch would not show up in preferences.
- Changed project retrieval to be synchronous and visualized by a cancellable progress window.

## v0.2 - 08/07/17

Expand Down
128 changes: 81 additions & 47 deletions Plugins/Editor/WakaTime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* WakaTime support for Unity.
*
* v0.2
* v0.3
* Matt Bengston (@bengsfort) <[email protected]>
*/
namespace Bengsfort.Unity
Expand All @@ -26,7 +26,7 @@ public class WakaTime
/// <summary>
/// The current plugin version.
/// </summary>
public const double Version = 0.2;
public const double Version = 0.3;

/// <summary>
/// The author of the plugin.
Expand Down Expand Up @@ -175,7 +175,7 @@ static WakaTime()
return;

// Initialize with a heartbeat
SendHeartbeat();
PostHeartbeat();

// Frame callback
EditorApplication.update += OnUpdate;
Expand All @@ -197,7 +197,7 @@ static void OnUpdate()
[DidReloadScripts()]
static void OnScriptReload()
{
SendHeartbeat();
PostHeartbeat();
// Relink all of our callbacks
LinkCallbacks(true);
}
Expand All @@ -207,39 +207,39 @@ static void OnScriptReload()
/// </summary>
static void OnPlaymodeStateChanged()
{
SendHeartbeat();
PostHeartbeat();
}

/// <summary>
/// Send a heartbeat every time the user clicks on the context menu.
/// </summary>
static void OnPropertyContextMenu(GenericMenu menu, SerializedProperty property)
{
SendHeartbeat();
PostHeartbeat();
}

/// <summary>
/// Send a heartbet everytime the hierarchy changes.
/// </summary>
static void OnHierarchyWindowChanged()
{
SendHeartbeat();
PostHeartbeat();
}

/// <summary>
/// Send a heartbeat every time the scene is saved.
/// </summary>
static void OnSceneSaved(Scene scene)
{
SendHeartbeat(true);
PostHeartbeat(true);
}

/// <summary>
/// Send a heartbeat every time a scene is opened.
/// </summary>
static void OnSceneOpened(Scene scene, OpenSceneMode mode)
{
SendHeartbeat();
PostHeartbeat();
}

/// <summary>
Expand All @@ -249,22 +249,23 @@ static void OnSceneOpened(Scene scene, OpenSceneMode mode)
/// @TODO: the send heartbeat needs to be modified to accept a scene overload.
/// If it's overloaded, it should use that instead Then this can switch to
/// OnSceneClosed instead of Closing.
/// </remarks>
static void OnSceneClosing(Scene scene, bool removingScene)
{
SendHeartbeat();
PostHeartbeat();
}

/// <summary>
/// Send a heartbeat every time a scene is created.
/// </summary>
static void OnSceneCreated(Scene scene, NewSceneSetup setup, NewSceneMode mode)
{
SendHeartbeat();
PostHeartbeat();
}
#endregion

#region ApiCalls
static string GetApiUrl(string path)
static string FormatApiUrl(string path)
{
return ApiBase + path + "?api_key=" + ApiKey;
}
Expand All @@ -277,7 +278,7 @@ static string GetApiUrl(string path)
/// provided key. If it is a valid key, it shouldn't return an error.
/// </remarks>
/// <param name="key">The API key.</param>
static void ValidateApiKey()
static void GetCurrentUser()
{
// If the user has deliberatly entered nothing, then reset the key
if (ApiKey == "")
Expand All @@ -287,7 +288,7 @@ static void ValidateApiKey()
}

// Initialize a GET request
UnityWebRequest auth = UnityWebRequest.Get(GetApiUrl("users/current"));
UnityWebRequest auth = UnityWebRequest.Get(FormatApiUrl("users/current"));
var req = auth.Send();

// Display a progress bar while the request is active
Expand All @@ -299,8 +300,8 @@ static void ValidateApiKey()
req.progress
);
}
// Clear the progress bar and parse the result
EditorUtility.ClearProgressBar();

// Parse the result
var result = JsonUtility.FromJson<ResponseSchema<CurrentUserSchema>>(auth.downloadHandler.text);
// If the result returned an error, the key is likely no good
if (result.error != null)
Expand All @@ -314,6 +315,9 @@ static void ValidateApiKey()
User = result.data;
ApiKeyValidated = true;
}

// Clear the progress bar
EditorUtility.ClearProgressBar();
}

/// <summary>
Expand All @@ -325,39 +329,62 @@ static void GetUserProjects()
return;

s_RetrievingProjects = true;
var www = UnityWebRequest.Get(GetApiUrl("users/current/projects"));
var www = UnityWebRequest.Get(FormatApiUrl("users/current/projects"));
var request = www.Send();

// Enqueue handling of the request
AsyncHelper.Add(new RequestEnumerator(www.Send(), () =>
bool cancelled = false;

// Wait until we've finished, but allow the user to cancel
while (!request.isDone)
{
var result = JsonUtility.FromJson<ResponseSchema<ProjectSchema[]>>(www.downloadHandler.text);
cancelled = EditorUtility.DisplayCancelableProgressBar(
"WakaTime Api",
"Getting your projects from WakaTime...",
request.progress
);
}

// If the result returned an error, the key is likely no good
if (result.error != null)
{
UnityEngine.Debug.LogError("<WakaTime> Failed to get projects from WakaTime API.");
}
else
{
UnityEngine.Debug.Log("<WakaTime> Successfully retrieved project list from WakaTime API.");
// Abort the operation and return if the user cancelled.
if (cancelled)
{
s_RetrievingProjects = false;
www.Abort();
return;
}

// Parse the result
var result = JsonUtility.FromJson<ResponseSchema<ProjectSchema[]>>(www.downloadHandler.text);

// If the result returned an error, the key is likely no good
if (result.error != null)
{
UnityEngine.Debug.LogError("<WakaTime> Failed to get projects from WakaTime API.");
}
else
{
UnityEngine.Debug.Log("<WakaTime> Successfully retrieved project list from WakaTime API.");

foreach(ProjectSchema project in result.data)
foreach(ProjectSchema project in result.data)
{
if (Application.productName == project.name)
{
if (Application.productName == project.name)
{
UnityEngine.Debug.Log("<WakaTime> Found a project with identical name to current Unity project; setting it to active.");
ActiveProject = project;
}
UnityEngine.Debug.Log("<WakaTime> Found a project with identical name to current Unity project; setting it to active.");
ActiveProject = project;
}
s_UserProjects = result.data;
}

s_RetrievingProjects = false;
}));
s_UserProjects = result.data;
}

s_RetrievingProjects = false;
EditorUtility.ClearProgressBar();
}

static void SendHeartbeat(bool fromSave = false)
/// <summary>
/// Sends a heartbeat to the WakaTime API.
/// </summary>
/// <param name="fromSave">Was this triggered from a save?</param>
static void PostHeartbeat(bool fromSave = false)
{
if (!ApiKeyValidated)
return;
Expand All @@ -373,15 +400,13 @@ static void SendHeartbeat(bool fromSave = false)

// If it hasn't been longer than the last heartbeat buffer, ignore if
// the heartbeat isn't triggered by a save or the scene changing.
UnityEngine.Debug.Log("time elapsed since last heartbeat " + (heartbeat.time - s_LastHeartbeat.time));
UnityEngine.Debug.Log("Heartbeat buffer is: " + HeartbeatBuffer);
if ((heartbeat.time - s_LastHeartbeat.time < HeartbeatBuffer) && !fromSave
&& (heartbeat.entity == s_LastHeartbeat.entity))
return;

var heartbeatJson = JsonUtility.ToJson(heartbeat);
var www = UnityWebRequest.Post(
GetApiUrl("users/current/heartbeats"),
FormatApiUrl("users/current/heartbeats"),
string.Empty
);
// Manually add an upload handler so the data isn't corrupted
Expand All @@ -407,6 +432,10 @@ static void SendHeartbeat(bool fromSave = false)
#endregion

#region Helpers
/// <summary>
/// Subscribes the plugin event handlers to the editor events.
/// </summary>
/// <param name="clean">Should we remove old callbacks before linking?</param>
static void LinkCallbacks(bool clean = false)
{
// Remove old callbacks before adding them back again
Expand Down Expand Up @@ -443,13 +472,19 @@ static string[] GetProjectDropdownOptions()

// Initialize a request to get the projects if there are none
if (s_UserProjects.Length == 0 && !s_RetrievingProjects)
{
GetUserProjects();

// If we are trying to get the projects, let the user know
if (s_RetrievingProjects)
{
options.Add("Retrieving projects...");
return options.ToArray();
}

// Add a default no-project option first
options.Add("Choose a project");

// Iterate through the projects and add the names to the list
for (int i = 0; i < s_UserProjects.Length; i++)
{
options.Add(s_UserProjects[i].name);
Expand All @@ -459,7 +494,6 @@ static string[] GetProjectDropdownOptions()

return options.ToArray();
}

#endregion

#region PreferencesView
Expand Down Expand Up @@ -547,7 +581,7 @@ static void WakaTimePreferencesView()
if (EnableVersionControl)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Currently on branch: " + GitHelper.branch);
EditorGUILayout.LabelField("Currently on branch: " + GitHelper.branch);
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndToggleGroup();
Expand All @@ -559,7 +593,7 @@ static void WakaTimePreferencesView()
// Has the active project changed?
if (s_ActiveProjectIndex != projectSelection)
{
ActiveProject = s_UserProjects[projectSelection];
ActiveProject = s_UserProjects[Mathf.Max(projectSelection - 1, 0)];
}

// If the Api Key has changed, reset the validation
Expand All @@ -570,7 +604,7 @@ static void WakaTimePreferencesView()
}

if (validateKeyButton && !ApiKeyValidated)
ValidateApiKey();
GetCurrentUser();
}
}

Expand Down

0 comments on commit b35afa4

Please sign in to comment.