diff --git a/CHANGELOG.md b/CHANGELOG.md index 67ea4f3173..99246b0843 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ - Added a "C# Editor Output Directory" field to the GDK Tools Configuration. [#1376](https://github.com/spatialos/gdk-for-unity/pull/1376) - This specifies where Editor-only code is generated to. - This defaults to `Assets/Generated/Editor`. +- `EntityId` now implements `IComparable`. [#1375](https://github.com/spatialos/gdk-for-unity/pull/1375) +- The `ComponentDatabase` now exposes a non-generic `GetComponentId(Type type)` static method. [#1379](https://github.com/spatialos/gdk-for-unity/pull/1379) +- Added a new "Worker Inspector" Editor window. [#1375](https://github.com/spatialos/gdk-for-unity/pull/1375) [#1379](https://github.com/spatialos/gdk-for-unity/pull/1379) [#1382](https://github.com/spatialos/gdk-for-unity/pull/1382) + - This window displays worker information like: worker flags, worker ID, and worker type. + - This window also displays the entities that a worker has checked out. + - For each entity checked out, you can view the components on that entity and whether the worker is authoritative over that component. ### Fixed diff --git a/workers/unity/Packages/io.improbable.gdk.core/View/View.cs b/workers/unity/Packages/io.improbable.gdk.core/View/View.cs index 6693302e17..f5822e692d 100644 --- a/workers/unity/Packages/io.improbable.gdk.core/View/View.cs +++ b/workers/unity/Packages/io.improbable.gdk.core/View/View.cs @@ -8,6 +8,8 @@ namespace Improbable.Gdk.Core { public class View { + public IReadOnlyDictionary WorkerFlags => workerFlags; + private readonly Dictionary typeToViewStorage = new Dictionary(); private readonly Dictionary componentIdToViewStorage = new Dictionary(); private readonly List viewStorages = new List(); diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerDetail.uxml b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerDetail.uxml new file mode 100644 index 0000000000..fd8f608bea --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerDetail.uxml @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerDetail.uxml.meta b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerDetail.uxml.meta new file mode 100644 index 0000000000..27de252ede --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerDetail.uxml.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c56100e86a494bb08328385d943ff2c3 +timeCreated: 1591178193 \ No newline at end of file diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow.uss b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow.uss index 74c403acad..ab0c5698fc 100644 --- a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow.uss +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow.uss @@ -1,4 +1,4 @@ -.columns { +#entities { flex-direction: row; flex-grow: 1; } @@ -9,7 +9,7 @@ --unity-item-height: 24; } -.unity-list-view__item { +#entity-list-view .unity-list-view__item { padding-left: 8px; -unity-text-align: middle-left; } @@ -74,6 +74,61 @@ padding-bottom: 4px; } -.is-auth-toggle .unity-label:disabled { - color: white; +#worker-details { + padding: 8px 4px; + border-top-color: rgba(0, 0, 0, 0.20); + border-top-width: 1px; + height: 15%; +} + +#worker-details-container { + flex-direction: row; + flex-grow: 1; +} + +#worker-details-label { + -unity-font-style: bold; + font-size: 18px; + margin-bottom: 8px; +} + +#worker-info { + max-width: 40%; + flex-grow: 1; + padding-left: 4px; +} + +#worker-type .unity-label { + min-width: 100px; +} + +#worker-id .unity-label { + min-width: 100px; +} + +#worker-flags { + max-width: 60%; + flex-grow: 2; + padding-left: 20px; +} + +#worker-flags-list { + margin-top: 6px; + flex-grow: 1; + flex-direction: column; + --unity-item-height: 24; + -unity-text-align: middle-left; +} + +#worker-flags-list .unity-list-view__item { + padding-left: 2px; +} + +.flag-element-container { + flex-direction: row; +} + +.flag-element { + flex-grow: 1; + max-width: 50%; } diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow.uxml b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow.uxml index a9cff97fa0..43ace426ab 100644 --- a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow.uxml +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow.uxml @@ -4,7 +4,8 @@ xmlns:wi="Improbable.Gdk.Debug.WorkerInspector" > - + + diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Dark.uss b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Dark.uss new file mode 100644 index 0000000000..40af681017 --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Dark.uss @@ -0,0 +1,11 @@ +.is-auth-toggle .unity-label:disabled { + color: white; +} + +#worker-info .unity-label:disabled { + color: white; +} + +#worker-flags .unity-label:disabled { + color: white; +} diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Dark.uss.meta b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Dark.uss.meta new file mode 100644 index 0000000000..45a5d22efb --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Dark.uss.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7c1b5753cf484d15b9f53402cb0c48a5 +timeCreated: 1591193738 \ No newline at end of file diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Light.uss b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Light.uss new file mode 100644 index 0000000000..1d3fcf74db --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Light.uss @@ -0,0 +1,11 @@ +.is-auth-toggle .unity-label:disabled { + color: black; +} + +#worker-info .unity-label:disabled { + color: black; +} + +#worker-flags .unity-label:disabled { + color: black; +} diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Light.uss.meta b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Light.uss.meta new file mode 100644 index 0000000000..21f2404494 --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Light.uss.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3db699d437b1426899fc1343a5e00b14 +timeCreated: 1591193747 \ No newline at end of file diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/WorkerDetail.cs b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/WorkerDetail.cs new file mode 100644 index 0000000000..31d6ae13aa --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/WorkerDetail.cs @@ -0,0 +1,112 @@ +using System.Collections.Generic; +using Improbable.Gdk.Core; +using Unity.Entities; +using UnityEditor; +using UnityEngine.UIElements; + +namespace Improbable.Gdk.Debug.WorkerInspector +{ + internal class WorkerDetail : VisualElement + { + private const string FlagKeyName = "key"; + private const string FlagValueName = "value"; + + private readonly TextField workerType; + private readonly TextField workerId; + private readonly ListView workerFlags; + + private readonly List> workerFlagData = new List>(); + + private View view; + + public WorkerDetail() + { + const string uxmlPath = "Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerDetail.uxml"; + var template = AssetDatabase.LoadAssetAtPath(uxmlPath); + template.CloneTree(this); + + workerType = this.Q("worker-type"); + workerType.SetEnabled(false); + + workerId = this.Q("worker-id"); + workerId.SetEnabled(false); + + workerFlags = this.Q("worker-flags-list"); + workerFlags.makeItem = MakeItem; + workerFlags.bindItem = BindElement; + workerFlags.itemsSource = workerFlagData; + workerFlags.SetEnabled(false); + } + + public void SetWorld(World world) + { + if (world == null) + { + workerType.value = ""; + workerId.value = ""; + workerFlagData.Clear(); + workerFlags.Refresh(); + view = null; + return; + } + + var workerSystem = world.GetExistingSystem(); + + workerType.value = workerSystem.WorkerType; + workerId.value = workerSystem.WorkerId; + + view = workerSystem.View; + Update(); + } + + public void Update() + { + if (view == null) + { + return; + } + + workerFlagData.Clear(); + + foreach (var pair in view.WorkerFlags) + { + workerFlagData.Add(pair); + } + + workerFlags.Refresh(); + } + + private static VisualElement MakeItem() + { + var container = new VisualElement(); + container.AddToClassList("flag-element-container"); + + var key = new Label { name = FlagKeyName, }; + + key.AddToClassList("flag-element"); + + var value = new Label { name = FlagValueName }; + + value.AddToClassList("flag-element"); + + container.Add(key); + container.Add(value); + + return container; + } + + private void BindElement(VisualElement element, int index) + { + var key = element.Q