Skip to content

Commit

Permalink
Unity Impl
Browse files Browse the repository at this point in the history
  • Loading branch information
neuecc committed Jan 7, 2024
1 parent 4b34336 commit b914f50
Show file tree
Hide file tree
Showing 46 changed files with 1,784 additions and 8 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,10 @@ public abstract class Observer<T> : IDisposable
public void OnCompleted(Result result);
}
```



## Unity

lower supported version: Unity 2021.3

2 changes: 1 addition & 1 deletion src/R3.Avalonia/AvaloniaDispatcherFrameProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace R3.Avalonia;

// NOTE: idially, not polling, use like the WPF's CompositionTarget.Rendering

public sealed class AvaloniaDispatcherFrameProvider : FrameProvider
public sealed class AvaloniaDispatcherFrameProvider : FrameProvider, IDisposable
{
bool disposed;
long frameCount;
Expand Down
8 changes: 8 additions & 0 deletions src/R3.Unity/Assets/R3.Unity.meta

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

8 changes: 8 additions & 0 deletions src/R3.Unity/Assets/R3.Unity/Editor.meta

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

47 changes: 47 additions & 0 deletions src/R3.Unity/Assets/R3.Unity/Editor/EditorEnableState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using UnityEditor;

namespace R3.Unity.Editor
{
public static class EditorEnableState
{
const string EnableAutoReloadKey = "ObservableTrackerWindow_EnableAutoReloadKey";
const string EnableTrackingKey = "ObservableTrackerWindow_EnableTrackingKey";
const string EnableStackTraceKey = "ObservableTrackerWindow_EnableStackTraceKey";

public static bool EnableAutoReload
{
get
{
return EditorPrefs.GetBool(EnableAutoReloadKey, false);
}
set
{
UnityEditor.EditorPrefs.SetBool(EnableAutoReloadKey, value);
}
}

public static bool EnableTracking
{
get
{
return UnityEditor.EditorPrefs.GetBool(EnableTrackingKey, false);
}
set
{
UnityEditor.EditorPrefs.SetBool(EnableTrackingKey, value);
}
}

public static bool EnableStackTrace
{
get
{
return UnityEditor.EditorPrefs.GetBool(EnableStackTraceKey, false);
}
set
{
UnityEditor.EditorPrefs.SetBool(EnableStackTraceKey, value);
}
}
}
}
11 changes: 11 additions & 0 deletions src/R3.Unity/Assets/R3.Unity/Editor/EditorEnableState.cs.meta

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

173 changes: 173 additions & 0 deletions src/R3.Unity/Assets/R3.Unity/Editor/ObservableTrackerTreeView.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;

namespace R3.Unity.Editor
{
public class ObservableTrackerViewItem : TreeViewItem
{
static Regex removeHref = new Regex("<a href.+>(.+)</a>", RegexOptions.Compiled);

public string Type { get; set; }
public string Elapsed { get; set; }

string position;
public string Position
{
get { return position; }
set
{
position = value;
PositionFirstLine = GetFirstLine(position);
}
}

public string PositionFirstLine { get; private set; }

static string GetFirstLine(string str)
{
var sb = new StringBuilder();
for (int i = 0; i < str.Length; i++)
{
if (str[i] == '\r' || str[i] == '\n')
{
break;
}
sb.Append(str[i]);
}

return removeHref.Replace(sb.ToString(), "$1");
}

public ObservableTrackerViewItem(int id) : base(id)
{

}
}

public class ObservableTrackerTreeView : TreeView
{
const string sortedColumnIndexStateKey = "UniTaskTrackerTreeView_sortedColumnIndex";

public IReadOnlyList<TreeViewItem> CurrentBindingItems;

public ObservableTrackerTreeView()
: this(new TreeViewState(), new MultiColumnHeader(new MultiColumnHeaderState(new[]
{
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("Type"), width = 20},
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("Elapsed"), width = 10},
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("Position")},
})))
{
}

ObservableTrackerTreeView(TreeViewState state, MultiColumnHeader header)
: base(state, header)
{
rowHeight = 20;
showAlternatingRowBackgrounds = true;
showBorder = true;
header.sortingChanged += Header_sortingChanged;

header.ResizeToFit();
Reload();

header.sortedColumnIndex = SessionState.GetInt(sortedColumnIndexStateKey, 1);
}

public void ReloadAndSort()
{
var currentSelected = this.state.selectedIDs;
Reload();
Header_sortingChanged(this.multiColumnHeader);
this.state.selectedIDs = currentSelected;
}

private void Header_sortingChanged(MultiColumnHeader multiColumnHeader)
{
SessionState.SetInt(sortedColumnIndexStateKey, multiColumnHeader.sortedColumnIndex);
var index = multiColumnHeader.sortedColumnIndex;
var ascending = multiColumnHeader.IsSortedAscending(multiColumnHeader.sortedColumnIndex);

var items = rootItem.children.Cast<ObservableTrackerViewItem>();

IOrderedEnumerable<ObservableTrackerViewItem> orderedEnumerable;
switch (index)
{
case 0:
orderedEnumerable = ascending ? items.OrderBy(item => item.Type) : items.OrderByDescending(item => item.Type);
break;
case 1:
orderedEnumerable = ascending ? items.OrderBy(item => double.Parse(item.Elapsed)) : items.OrderByDescending(item => double.Parse(item.Elapsed));
break;
case 2:
orderedEnumerable = ascending ? items.OrderBy(item => item.Position) : items.OrderByDescending(item => item.Position);
break;
default:
throw new ArgumentOutOfRangeException(nameof(index), index, null);
}

CurrentBindingItems = rootItem.children = orderedEnumerable.Cast<TreeViewItem>().ToList();
BuildRows(rootItem);
}

protected override TreeViewItem BuildRoot()
{
var root = new TreeViewItem { depth = -1 };

var children = new List<TreeViewItem>();

var now = DateTime.Now; // tracking state is using local Now.
SubscriptionTracker.ForEachActiveTask(state =>
{
children.Add(new ObservableTrackerViewItem(state.TrackingId) { Type = state.FormattedType, Elapsed = (now - state.AddTime).TotalSeconds.ToString("00.00"), Position = state.StackTrace });
});

CurrentBindingItems = children;
root.children = CurrentBindingItems as List<TreeViewItem>;
return root;
}

protected override bool CanMultiSelect(TreeViewItem item)
{
return false;
}

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

for (var visibleColumnIndex = 0; visibleColumnIndex < args.GetNumVisibleColumns(); visibleColumnIndex++)
{
var rect = args.GetCellRect(visibleColumnIndex);
var columnIndex = args.GetColumn(visibleColumnIndex);

var labelStyle = args.selected ? EditorStyles.whiteLabel : EditorStyles.label;
labelStyle.alignment = TextAnchor.MiddleLeft;
switch (columnIndex)
{
case 0:
EditorGUI.LabelField(rect, item.Type, labelStyle);
break;
case 1:
EditorGUI.LabelField(rect, item.Elapsed, labelStyle);
break;
case 2:
EditorGUI.LabelField(rect, item.PositionFirstLine, labelStyle);
break;
default:
throw new ArgumentOutOfRangeException(nameof(columnIndex), columnIndex, null);
}
}
}
}

}

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

Loading

0 comments on commit b914f50

Please sign in to comment.