Skip to content

Commit b7c2694

Browse files
RogPodgekeveleigh
andauthored
Cherry-picking global input source for speech for 2.7 (#9892)
* Introduced the concept of a global input source and enabled it with speech (#9770) * introduced the concept of a global input source and made the speech provider use a global input source * Update Assets/MRTK/Providers/Windows/WindowsSpeechInputProvider.cs Co-authored-by: Kurtis <[email protected]> * Update Assets/MRTK/Core/Providers/BaseGlobalInputSource.cs Co-authored-by: Kurtis <[email protected]> * removed redundant code, undid public signature changes * added unit tests for the global input source * added test case where the focus listener uses the events after recieving them Co-authored-by: Kurtis <[email protected]> * initialize global input source variable (#9889) Co-authored-by: Kurtis <[email protected]>
1 parent ca134f0 commit b7c2694

File tree

9 files changed

+358
-3
lines changed

9 files changed

+358
-3
lines changed

Assets/MRTK/Core/Interfaces/InputSystem/IMixedRealityInputSystem.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ public interface IMixedRealityInputSystem : IMixedRealityEventSystem
132132

133133
IMixedRealityInputSource RequestNewGenericInputSource(string name, IMixedRealityPointer[] pointers = null, InputSourceType sourceType = InputSourceType.Other);
134134

135+
BaseGlobalInputSource RequestNewGlobalInputSource(string name, IMixedRealityFocusProvider focusProvider = null, InputSourceType sourceType = InputSourceType.Other);
136+
135137
/// <summary>
136138
/// Raise the event that the Input Source was detected.
137139
/// </summary>

Assets/MRTK/Core/Interfaces/InputSystem/IMixedRealityPointer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public interface IMixedRealityPointer : IEqualityComparer
4848
bool IsInteractionEnabled { get; }
4949

5050
/// <summary>
51-
/// Controls whether the pointer dispatches input..
51+
/// Controls whether the pointer dispatches input.
5252
/// </summary>
5353
bool IsActive { get; set; }
5454

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
using System.Collections;
6+
using System.Linq;
7+
8+
namespace Microsoft.MixedReality.Toolkit.Input
9+
{
10+
/// <summary>
11+
/// Base class for input sources whose pointers are all active pointers in the scene.
12+
/// </summary>
13+
/// <remarks>
14+
/// <para>This base class is intended to represent input sources which raise events to all active pointers found by the FocusProvider in a scene.</para>
15+
/// </remarks>
16+
public class BaseGlobalInputSource : IMixedRealityInputSource, IDisposable
17+
{
18+
/// <summary>
19+
/// Constructor.
20+
/// </summary>
21+
public BaseGlobalInputSource(string name, IMixedRealityFocusProvider focusProvider, InputSourceType sourceType = InputSourceType.Other)
22+
{
23+
SourceId = (CoreServices.InputSystem != null) ? CoreServices.InputSystem.GenerateNewSourceId() : 0;
24+
SourceName = name;
25+
FocusProvider = focusProvider;
26+
SourceType = sourceType;
27+
28+
UpdateActivePointers();
29+
}
30+
31+
/// <inheritdoc />
32+
public uint SourceId { get; }
33+
34+
/// <inheritdoc />
35+
public string SourceName { get; }
36+
37+
/// <inheritdoc />
38+
public virtual IMixedRealityPointer[] Pointers { get; set; }
39+
40+
/// <inheritdoc />
41+
public InputSourceType SourceType { get; set; }
42+
43+
private IMixedRealityFocusProvider FocusProvider;
44+
45+
public void UpdateActivePointers()
46+
{
47+
Pointers = FocusProvider.GetPointers<IMixedRealityPointer>().Where(x => x.IsActive).ToArray();
48+
}
49+
50+
#region IEquality Implementation
51+
52+
public static bool Equals(IMixedRealityInputSource left, IMixedRealityInputSource right)
53+
{
54+
return left.Equals(right);
55+
}
56+
57+
/// <inheritdoc />
58+
bool IEqualityComparer.Equals(object left, object right)
59+
{
60+
return left.Equals(right);
61+
}
62+
63+
public override bool Equals(object obj)
64+
{
65+
if (ReferenceEquals(null, obj)) { return false; }
66+
if (ReferenceEquals(this, obj)) { return true; }
67+
if (obj.GetType() != GetType()) { return false; }
68+
69+
return Equals((IMixedRealityInputSource)obj);
70+
}
71+
72+
private bool Equals(IMixedRealityInputSource other)
73+
{
74+
return other != null && SourceId == other.SourceId && string.Equals(SourceName, other.SourceName);
75+
}
76+
77+
/// <inheritdoc />
78+
int IEqualityComparer.GetHashCode(object obj)
79+
{
80+
return obj.GetHashCode();
81+
}
82+
83+
public override int GetHashCode()
84+
{
85+
unchecked
86+
{
87+
int hashCode = 0;
88+
hashCode = (hashCode * 397) ^ (int)SourceId;
89+
hashCode = (hashCode * 397) ^ (SourceName != null ? SourceName.GetHashCode() : 0);
90+
return hashCode;
91+
}
92+
}
93+
94+
/// <summary>
95+
/// Dispose.
96+
/// </summary>
97+
public virtual void Dispose() { }
98+
99+
#endregion IEquality Implementation
100+
}
101+
}

Assets/MRTK/Core/Providers/BaseGlobalInputSource.cs.meta

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

Assets/MRTK/Providers/Windows/WindowsSpeechInputProvider.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,18 @@ public WindowsSpeechInputProvider(
6161
/// <summary>
6262
/// The Input Source for Windows Speech Input.
6363
/// </summary>
64-
public IMixedRealityInputSource InputSource = null;
64+
public IMixedRealityInputSource InputSource => globalInputSource;
6565

6666
/// <summary>
6767
/// The minimum confidence level for the recognizer to fire an event.
6868
/// </summary>
6969
public RecognitionConfidenceLevel RecognitionConfidenceLevel { get; set; }
7070

71+
/// <summary>
72+
/// The global input source used by the the speech input provider to raise events.
73+
/// </summary>
74+
private BaseGlobalInputSource globalInputSource = null;
75+
7176
/// <inheritdoc />
7277
public bool IsRecognitionActive =>
7378
#if UNITY_STANDALONE_WIN || UNITY_WSA || UNITY_EDITOR_WIN
@@ -152,7 +157,7 @@ private void InitializeKeywordRecognizer()
152157
return;
153158
}
154159

155-
InputSource = Service?.RequestNewGenericInputSource("Windows Speech Input Source", sourceType: InputSourceType.Voice);
160+
globalInputSource = Service?.RequestNewGlobalInputSource("Windows Speech Input Source", sourceType: InputSourceType.Voice);
156161

157162
var newKeywords = new string[Commands.Length];
158163

@@ -243,6 +248,8 @@ private void OnPhraseRecognized(ConfidenceLevel confidence, TimeSpan phraseDurat
243248
{
244249
if (Commands[i].LocalizedKeyword == text)
245250
{
251+
globalInputSource.UpdateActivePointers();
252+
246253
Service?.RaiseSpeechCommandRecognized(InputSource, (RecognitionConfidenceLevel)confidence, phraseDuration, phraseStartTime, Commands[i]);
247254
break;
248255
}

Assets/MRTK/Services/InputSystem/MixedRealityInputSystem.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,14 @@ public IMixedRealityInputSource RequestNewGenericInputSource(string name, IMixed
874874
return new BaseGenericInputSource(name, pointers, sourceType);
875875
}
876876

877+
/// <inheritdoc />
878+
public BaseGlobalInputSource RequestNewGlobalInputSource(string name, IMixedRealityFocusProvider focusProvider = null, InputSourceType sourceType = InputSourceType.Other)
879+
{
880+
var inputSourceFocusProvider = focusProvider.IsNull() ? FocusProvider : focusProvider;
881+
return new BaseGlobalInputSource(name, inputSourceFocusProvider, sourceType);
882+
}
883+
884+
877885
#region Input Source State Events
878886

879887
private static readonly ProfilerMarker RaiseSourceDetectedPerfMarker = new ProfilerMarker("[MRTK] MixedRealityInputSystem.RaiseSourceDetected");
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using Microsoft.MixedReality.Toolkit.Input;
5+
using Microsoft.MixedReality.Toolkit.Utilities;
6+
using System;
7+
using System.Collections.Generic;
8+
using UnityEngine;
9+
10+
namespace Microsoft.MixedReality.Toolkit.Tests
11+
{
12+
// For InputSystemGlobalListener
13+
#pragma warning disable 0618
14+
[AddComponentMenu("Scripts/MRTK/Tests/TestInputFocusListener")]
15+
internal class TestInputFocusListener : MonoBehaviour, IMixedRealityFocusHandler, IMixedRealityPointerHandler, IMixedRealitySpeechHandler
16+
{
17+
// Parameters, which are set by child classes
18+
public bool useEventDataOnReception = false;
19+
20+
// Values changed by class to validate event receiving
21+
public int pointerDownCount = 0;
22+
public int pointerDraggedCount = 0;
23+
public int pointerUpCount = 0;
24+
public int pointerClickedCount = 0;
25+
26+
public int focusGainedCount = 0;
27+
public int focusLostCount = 0;
28+
public List<string> speechCommandsReceived = new List<string>();
29+
30+
protected void Start()
31+
{
32+
pointerDownCount = 0;
33+
pointerDraggedCount = 0;
34+
pointerUpCount = 0;
35+
pointerClickedCount = 0;
36+
37+
focusGainedCount = 0;
38+
focusLostCount = 0;
39+
speechCommandsReceived = new List<string>();
40+
}
41+
42+
public void OnPointerDown(MixedRealityPointerEventData eventData)
43+
{
44+
pointerDownCount++;
45+
46+
if (useEventDataOnReception)
47+
{
48+
eventData.Use();
49+
}
50+
}
51+
52+
public void OnPointerDragged(MixedRealityPointerEventData eventData)
53+
{
54+
pointerDraggedCount++;
55+
56+
if (useEventDataOnReception)
57+
{
58+
eventData.Use();
59+
}
60+
}
61+
62+
public void OnPointerUp(MixedRealityPointerEventData eventData)
63+
{
64+
pointerUpCount++;
65+
66+
if (useEventDataOnReception)
67+
{
68+
eventData.Use();
69+
}
70+
}
71+
72+
public virtual void OnPointerClicked(MixedRealityPointerEventData eventData)
73+
{
74+
pointerClickedCount++;
75+
76+
if (useEventDataOnReception)
77+
{
78+
eventData.Use();
79+
}
80+
}
81+
82+
public void OnSpeechKeywordRecognized(SpeechEventData eventData)
83+
{
84+
speechCommandsReceived.Add(eventData.Command.Keyword);
85+
86+
if(useEventDataOnReception)
87+
{
88+
eventData.Use();
89+
}
90+
}
91+
92+
public void OnFocusEnter(FocusEventData eventData)
93+
{
94+
focusGainedCount++;
95+
96+
if (useEventDataOnReception)
97+
{
98+
eventData.Use();
99+
}
100+
}
101+
102+
public void OnFocusExit(FocusEventData eventData)
103+
{
104+
focusLostCount++;
105+
106+
if (useEventDataOnReception)
107+
{
108+
eventData.Use();
109+
}
110+
}
111+
}
112+
#pragma warning restore 0618
113+
}

Assets/MRTK/Tests/PlayModeTests/Components/TestInputFocusListener.cs.meta

Lines changed: 11 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)