Skip to content

Commit

Permalink
Merge branch 'feature' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
renanwolf committed Sep 26, 2022
2 parents 528bf6f + 6960ca6 commit 0fd877c
Show file tree
Hide file tree
Showing 52 changed files with 2,558 additions and 843 deletions.
34 changes: 33 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
# Changelog

## [3.0.0] - 2022-09-26
### Added
- New editor tracker window to make it easy to debug requests lifecycle. It's accessible through `Window > UniRate Tracker`.
### Changed
- Refactored rates/interval management to allow easy testability.
- **Breaking:** `RateManager.Instance.UpdateRate` now returns the update rate controller instance instead of the current update rate per seconds value, which is now accessible through `RateManager.Instance.UpdateRate.Current`.
- **Breaking:** `RateManager.Instance.FixedUpdateRate` now returns the fixed update rate controller instance instead of the current fixed update rate per seconds value, which is now accessible through `RateManager.Instance.FixedUpdateRate.Current`.
- **Breaking:** `RateManager.Instance.RenderInterval` now returns the render interval controller instance instead of the current render interval value, which is now accessible through `RateManager.Instance.RenderInterval.Current`.
### Deprecated
- `RateManager.Instance.UpdateRateMode` is now deprecated, use `RateManager.Instance.UpdateRate.Mode` instead.
- `RateManager.Instance.MinimumUpdateRate` is now deprecated, use `RateManager.Instance.UpdateRate.Minimum` instead.
- `RateManager.Instance.TargetUpdateRate` is now deprecated, use `RateManager.Instance.UpdateRate.Target` instead.
- `RateManager.Instance.UpdateRateModeChanged` is now deprecated, use `RateManager.Instance.UpdateRate.ModeChanged` instead.
- `RateManager.Instance.UpdateRateChanged` is now deprecated, use `RateManager.Instance.UpdateRate.CurrentChanged` instead.
- `RateManager.Instance.MinimumFixedUpdateRate` is now deprecated, use `RateManager.Instance.FixedUpdateRate.Minimum` instead.
- `RateManager.Instance.TargetFixedUpdateRate` is now deprecated, use `RateManager.Instance.FixedUpdateRate.Target` instead.
- `RateManager.Instance.FixedUpdateRateChanged` is now deprecated, use `RateManager.Instance.FixedUpdateRate.CurrentChanged` instead.
- `RateManager.Instance.TargetFixedUpdateRateChanged` is now deprecated, use `RateManager.Instance.FixedUpdateRate.TargetChanged` instead.
- `RateManager.Instance.MaximumRenderInterval` is now deprecated, use `RateManager.Instance.RenderInterval.Maximum` instead.
- `RateManager.Instance.TargetRenderInterval` is now deprecated, use `RateManager.Instance.RenderInterval.Target` instead.
- `RateManager.Instance.RenderIntervalChanged` is now deprecated, use `RateManager.Instance.RenderInterval.CurrentChanged` instead.
- `RateManager.Instance.TargetRenderIntervalChanged` is now deprecated, use `RateManager.Instance.RenderInterval.TargetChanged` instead.
- `RateManager.Instance.RenderRate` is now deprecated, use `RateManager.Instance.RenderInterval.CurrentRenderRate` instead.
- `RateManager.Instance.WillRender` is now deprecated, use `RateManager.Instance.RenderInterval.WillRender` instead.
- `RateManager.Instance.IsRenderIntervalSupported` is now deprecated, use `RateManager.Instance.RenderInterval.IsSupported` instead.
- `RateManager.Instance.RequestUpdateRate(int)` is now deprecated, use `RateManager.Instance.UpdateRate.Request(int)` instead.
- `RateManager.Instance.RequestFixedUpdateRate(int)` is now deprecated, use `RateManager.Instance.FixedUpdateRate.Request(int)` instead.
- `RateManager.Instance.RequestRenderInterval(int)` is now deprecated, use `RateManager.Instance.RenderInterval.Request(int)` instead.
### Fixed
- Fixed `ArgumentNullException` when application is quitting ([#2](https://github.com/renanwolf/UniRate/issues/2)).

## [2.2.2] - 2021-07-28
### Fixed
- Fixed compilation error on `RateManager` for Unity versions below 2019.3 ([#1](https://github.com/renanwolf/UniRate/pull/1)), by [@Chrisdbhr](https://github.com/Chrisdbhr).
Expand Down Expand Up @@ -35,7 +66,8 @@
- Renamed `LogLevel` to `RateLogLevel`.
- Increased `RateDebug.LogLevel` default value.

[Unreleased]: https://github.com/renanwolf/UniRate/compare/v2.2.2...HEAD
[Unreleased]: https://github.com/renanwolf/UniRate/compare/v3.0.0...HEAD
[3.0.0]: https://github.com/renanwolf/UniRate/releases/tag/v3.0.0
[2.2.2]: https://github.com/renanwolf/UniRate/releases/tag/v2.2.2
[2.2.1]: https://github.com/renanwolf/UniRate/releases/tag/v2.2.1
[2.2.0]: https://github.com/renanwolf/UniRate/releases/tag/v2.2.0
Expand Down
224 changes: 224 additions & 0 deletions Editor/RateRequestTrackerTreeView.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UniRate.Debug;

namespace UniRate.Editor {

public class RateRequestTrackerTreeView : TreeView {

#region <<---------- Class Item ---------->>

public class Item : TreeViewItem {

public Item(RateRequestTrackInfo trackInfo) : base(trackInfo.Identifier, 0) {
this.TrackInfo = trackInfo;
}

public RateRequestTrackInfo TrackInfo { get; }
}

#endregion <<---------- Class Item ---------->>




#region <<---------- Initializers ---------->>

public RateRequestTrackerTreeView() : this(new MultiColumnHeader(new MultiColumnHeaderState(new[] {
new MultiColumnHeaderState.Column() {
headerContent = new GUIContent("Request Type"),
canSort = false,
allowToggleVisibility = false,
minWidth = 60,
maxWidth = 120
},
new MultiColumnHeaderState.Column() {
headerContent = new GUIContent("Rate or Interval"),
canSort = false,
allowToggleVisibility = false,
minWidth = 40,
maxWidth = 100
},
new MultiColumnHeaderState.Column() {
headerContent = new GUIContent("Status"),
canSort = false,
allowToggleVisibility = false,
minWidth = 40,
maxWidth = 80
},
new MultiColumnHeaderState.Column() {
headerContent = new GUIContent("Time"),
canSort = true,
allowToggleVisibility = false,
minWidth = 58,
maxWidth = 100
},
new MultiColumnHeaderState.Column() {
headerContent = new GUIContent("StackTrace"),
canSort = false,
allowToggleVisibility = false,
minWidth = 60
}
}))) {

}

private RateRequestTrackerTreeView(MultiColumnHeader header) : base(new TreeViewState(), header) {
this._header = header;
this._source = new List<RateRequestTrackInfo>();

this.rowHeight = 20;
this.showAlternatingRowBackgrounds = true;
this.showBorder = true;

this.Reload();
this._header.ResizeToFit();
this._header.SetSorting(
SessionState.GetInt($"{nameof(RateRequestTrackerTreeView)}_header_sort_column_index", 3),
SessionState.GetBool($"{nameof(RateRequestTrackerTreeView)}_header_sort_ascending", false)
);

this._header.sortingChanged += this.OnHeaderSortChanged;
}

#endregion <<---------- Initializers ---------->>




#region <<---------- Properties and Fields ---------->>

private readonly MultiColumnHeader _header;

public IReadOnlyList<RateRequestTrackInfo> Source => this._source;
private readonly List<RateRequestTrackInfo> _source;

private bool _headerAutoResizeAfterFirstItems;

public event Action<RateRequestTrackerTreeView, IList<int>> SelectedIdsChanged {
add {
this._selectedIdsChanged -= value;
this._selectedIdsChanged += value;
}
remove {
this._selectedIdsChanged -= value;
}
}
private Action<RateRequestTrackerTreeView, IList<int>> _selectedIdsChanged;

#endregion <<---------- Properties and Fields ---------->>




#region <<---------- Callbacks ---------->>

private void OnHeaderSortChanged(MultiColumnHeader header) {
int columnIndex = header.sortedColumnIndex;
bool isAscending = header.IsSortedAscending(columnIndex);
SessionState.SetInt($"{nameof(RateRequestTrackerTreeView)}_header_sort_column_index", header.sortedColumnIndex);
SessionState.SetBool($"{nameof(RateRequestTrackerTreeView)}_header_sort_ascending", isAscending);

this.rootItem.children.Sort((a, b) => {
var itemA = (Item)a;
var itemB = (Item)b;
switch (columnIndex) {
case 3:
var aTime = itemA.TrackInfo.IsActive ? itemA.TrackInfo.StartedTime : itemA.TrackInfo.FinishedTime;
var bTime = itemB.TrackInfo.IsActive ? itemB.TrackInfo.StartedTime : itemB.TrackInfo.FinishedTime;
return isAscending ? aTime.CompareTo(bTime) : bTime.CompareTo(aTime);
default: throw new NotImplementedException($"{nameof(this.OnHeaderSortChanged)}() not handling column index {columnIndex.ToString()}");
}
});

this.BuildRows(this.rootItem);
}

#endregion <<---------- Callbacks ---------->>




#region <<---------- TreeView ---------->>

protected override TreeViewItem BuildRoot() {
var root = new TreeViewItem() {
depth = -1
};
if (this._source.Count > 0) {
foreach (var trackInfo in this._source) {
root.AddChild(new Item(trackInfo));
}
SetupDepthsFromParentsAndChildren(root);
}
else {
root.children = new List<TreeViewItem>();
}
return root;
}

protected override void RowGUI(RowGUIArgs args) {
var item = (Item)args.item;

for (int iVisibleColumn = 0; iVisibleColumn < args.GetNumVisibleColumns(); iVisibleColumn++) {
var rect = args.GetCellRect(iVisibleColumn);
this.CenterRectUsingSingleLineHeight(ref rect);
int iColumn = args.GetColumn(iVisibleColumn);

switch (iColumn) {
case 0: // request type
EditorGUI.LabelField(rect, item.TrackInfo.Type.ToString());
break;
case 1: // rate or interval value
EditorGUI.LabelField(rect, item.TrackInfo.Value.ToString());
break;
case 2: // status
EditorGUI.LabelField(rect, item.TrackInfo.GetStatusFormatted());
break;
case 3: // time
if (item.TrackInfo.IsActive) {
EditorGUI.LabelField(rect, item.TrackInfo.GetStartedTimeFormatted());
}
else {
EditorGUI.LabelField(rect, item.TrackInfo.GetFinishedTimeFormatted());
}
break;
case 4: // stack trace
EditorGUI.LabelField(rect, item.TrackInfo.IsActive ? item.TrackInfo.StackTraceStartFirstLine : item.TrackInfo.StackTraceFinishFirstLine);
break;
default: throw new NotImplementedException($"{nameof(this.RowGUI)}() not handling column index {iColumn.ToString()}");
}
}
}

protected override void SelectionChanged(IList<int> selectedIds) {
base.SelectionChanged(selectedIds);
var e = this._selectedIdsChanged;
if (e == null) return;
e(this, selectedIds);
}

#endregion <<---------- TreeView ---------->>




#region <<---------- General ---------->>

public void Reload(IEnumerable<RateRequestTrackInfo> source) {
this._source.Clear();
this._source.AddRange(source);
this.Reload();
if (!this._headerAutoResizeAfterFirstItems && this._source.Count > 0) {
this._headerAutoResizeAfterFirstItems = true;
this._header.ResizeToFit();
}
this.OnHeaderSortChanged(this._header);
}

#endregion <<---------- General ---------->>
}
}
11 changes: 11 additions & 0 deletions Editor/RateRequestTrackerTreeView.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0fd877c

Please sign in to comment.