Skip to content

Commit ffe17ee

Browse files
committed
Optimize Theming hot paths: O(1) hash cache in Theme, delegate caching in BaseThemeBinder, Zero-GC dynamic listeners in ThemeDataSource, and add comprehensive test suite
1 parent 00eb1f8 commit ffe17ee

13 files changed

Lines changed: 473 additions & 18 deletions

File tree

‎org.mixedrealitytoolkit.theming/AssemblyInfo.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
[assembly: AssemblyCopyright("Copyright (c) Mixed Reality Toolkit Contributors")]
99

1010
[assembly: InternalsVisibleTo("MixedReality.Toolkit.Theming.Editor")]
11+
[assembly: InternalsVisibleTo("MixedReality.Toolkit.Theming.Editor.Tests")]
12+
[assembly: InternalsVisibleTo("MixedReality.Toolkit.Theming.Runtime.Tests")]
1113

1214
// The AssemblyVersion attribute is checked-in and is recommended not to be changed often.
1315
// https://docs.microsoft.com/troubleshoot/visualstudio/general/assembly-version-assembly-file-version

‎org.mixedrealitytoolkit.theming/Binders/BaseThemeBinder.cs‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,22 @@ protected void OnThemeChanged(ChangeEvent<Theme> changeEvent)
4848
Apply(value);
4949
}
5050

51+
private UnityEngine.Events.UnityAction<ChangeEvent<Theme>> cachedOnThemeChanged;
52+
5153
void IBinder.Subscribe(ThemeDataSource themeDataSource)
5254
{
5355
if (themeDataSource != null)
5456
{
55-
themeDataSource.AddListener(OnThemeChanged);
57+
cachedOnThemeChanged ??= OnThemeChanged;
58+
themeDataSource.AddListener(cachedOnThemeChanged);
5659
}
5760
}
5861

5962
void IBinder.Unsubscribe(ThemeDataSource themeDataSource)
6063
{
61-
if (themeDataSource != null)
64+
if (themeDataSource != null && cachedOnThemeChanged != null)
6265
{
63-
themeDataSource.RemoveListener(OnThemeChanged);
66+
themeDataSource.RemoveListener(cachedOnThemeChanged);
6467
}
6568
}
6669
}

‎org.mixedrealitytoolkit.theming/CHANGELOG.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
99
* Added serializable theme item data types for booleans. [PR #1130](https://github.com/MixedRealityToolkit/MixedRealityToolkit-Unity/pull/1130)
1010
* Added built-in binders for skybox materials and behaviour enabled states. [PR #1130](https://github.com/MixedRealityToolkit/MixedRealityToolkit-Unity/pull/1130)
1111
* Added edit mode tests for validating custom theming types and their dependencies. [PR #1133](https://github.com/MixedRealityToolkit/MixedRealityToolkit-Unity/pull/1133)
12+
* Added runtime performance benchmark and regression tests for theming hot paths. [PR #1133](https://github.com/MixedRealityToolkit/MixedRealityToolkit-Unity/pull/1133)
13+
14+
### Changed
15+
16+
* Optimized `Theme.TryGetItemData<T>` from an $O(N)$ linear list scan to an $O(1)$ hash table lookup with automatic cache invalidation on deserialization, inspector modifications, and enable events. [PR #1133](https://github.com/MixedRealityToolkit/MixedRealityToolkit-Unity/pull/1133)
17+
* Optimized `BaseThemeBinder` by caching `UnityAction<ChangeEvent<Theme>>` delegates, eliminating heap allocations during repeated subscribe/unsubscribe cycles. [PR #1133](https://github.com/MixedRealityToolkit/MixedRealityToolkit-Unity/pull/1133)
18+
* Optimized `ThemeDataSource` to route programmatic subscribers through a Zero-GC dynamic listener list, avoiding delegate allocations while preserving inspector `UnityEvent` invocations. [PR #1133](https://github.com/MixedRealityToolkit/MixedRealityToolkit-Unity/pull/1133)
1219

1320
## [1.0.0-pre.1] - 2026-05-20
1421

‎org.mixedrealitytoolkit.theming/Tests/Runtime.meta‎

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "MixedReality.Toolkit.Theming.Runtime.Tests",
3+
"rootNamespace": "MixedReality.Toolkit.Theming.Tests.Runtime",
4+
"references": [
5+
"MixedReality.Toolkit.Core",
6+
"MixedReality.Toolkit.Core.TestUtilities",
7+
"MixedReality.Toolkit.Theming",
8+
"MixedReality.Toolkit.UXCore",
9+
"MixedReality.Toolkit.UXCore.Theming",
10+
"UnityEngine.TestRunner",
11+
"UnityEditor.TestRunner",
12+
"Unity.TextMeshPro"
13+
],
14+
"includePlatforms": [],
15+
"excludePlatforms": [],
16+
"allowUnsafeCode": false,
17+
"overrideReferences": true,
18+
"precompiledReferences": [
19+
"nunit.framework.dll"
20+
],
21+
"autoReferenced": false,
22+
"defineConstraints": [
23+
"UNITY_INCLUDE_TESTS"
24+
],
25+
"versionDefines": [],
26+
"noEngineReferences": false
27+
}

‎org.mixedrealitytoolkit.theming/Tests/Runtime/MRTK.Theming.RuntimeTests.asmdef.meta‎

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)