Skip to content

Commit

Permalink
CHANGE: Move text input to separate interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rene Damm committed Oct 3, 2018
1 parent d0a92ca commit 1b045d4
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 77 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using UnityEngine.Experimental.Input.LowLevel;

namespace UnityEngine.Experimental.Input
{
/// <summary>
/// Interface for <see cref="InputDevice">devices</see> that can receive text input events.
/// </summary>
/// <seealso cref="TextEvent"/>
/// <seealso cref="IMECompositionEvent"/>
public interface ITextInputReceiver
{
/// <summary>
/// A single, fully-formed Unicode character has been typed on the device.
/// </summary>
/// <param name="character">Character that was typed. Note that in case the character is part of
/// a surrogate pair, this method is called first with the low surrogate and then with the
/// high surrogate character.</param>
void OnTextInput(char character);

/// <summary>
/// Called when an IME composition is in-progress or finished.
/// </summary>
/// <param name="compositionString">The current composition string.</param>
/// <seealso cref="IMECompositionEvent"/>
/// <seealso cref="Keyboard.onIMECompositionChange"/>
/// <remarks>
/// The method will be repeatedly called with the current string while composition is in progress.
/// Once composition finishes, the method will be called one more time with a blank composition
/// string.
/// </remarks>
void OnIMECompositionChanged(IMECompositionString compositionString);
}
}

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

Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace UnityEngine.Experimental.Input
/// a device at the root. Devices cannot occur inside of hierarchies.
///
/// Unlike other controls, usages of InputDevices are allowed to be changed on the fly
/// without requiring a change to the device layout (<see cref="InputSystem.SetUsage"/>).
/// without requiring a change to the device layout (<see cref="InputSystem.SetDeviceUsage(InputDevice,string)"/>).
/// </remarks>
public class InputDevice : InputControl
{
Expand Down Expand Up @@ -265,19 +265,6 @@ public virtual void MakeCurrent()
{
}

////REVIEW: should this receive a timestamp, too?
/// <summary>
/// Invoked when the device receive a <see cref="LowLevel.TextEvent">text input event</see>.
/// </summary>
/// <param name="character"></param>
public virtual void OnTextInput(char character)
{
}

public virtual void OnIMEStringEvent(IMEComposition imeComposition)
{
}

/// <summary>
/// Called by the system when the configuration of the device has changed.
/// </summary>
Expand Down
12 changes: 6 additions & 6 deletions Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ public enum Key
/// <see cref="KeyControl.altDisplayName"/>.
/// </remarks>
[InputControlLayout(stateType = typeof(KeyboardState))]
public class Keyboard : InputDevice
public class Keyboard : InputDevice, ITextInputReceiver
{
public const int KeyCount = (int)Key.OEM5;

Expand All @@ -347,7 +347,7 @@ public class Keyboard : InputDevice
///
/// See <see cref="Keyboard.imeEnabled"/> for turning IME on/off
/// </remarks>
public event Action<IMEComposition> onIMECompositionChange
public event Action<IMECompositionString> onIMECompositionChange
{
add { m_ImeCompositionListeners.Append(value); }
remove { m_ImeCompositionListeners.Remove(value); }
Expand Down Expand Up @@ -897,24 +897,24 @@ protected override void RefreshConfiguration()
keyboardLayout = command.ReadLayoutName();
}

public override void OnTextInput(char character)
public void OnTextInput(char character)
{
for (var i = 0; i < m_TextInputListeners.length; ++i)
m_TextInputListeners[i](character);
}

public override void OnIMEStringEvent(IMEComposition composition)
public void OnIMECompositionChanged(IMECompositionString compositionString)
{
if (m_ImeCompositionListeners.length > 0)
{
for (var i = 0; i < m_ImeCompositionListeners.length; ++i)
m_ImeCompositionListeners[i](composition);
m_ImeCompositionListeners[i](compositionString);
}
}

internal InlinedArray<Action<char>> m_TextInputListeners;
private string m_KeyboardLayoutName;

internal InlinedArray<Action<IMEComposition>> m_ImeCompositionListeners;
internal InlinedArray<Action<IMECompositionString>> m_ImeCompositionListeners;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine.Experimental.Input.LowLevel;
using UnityEngine.Experimental.Input.Utilities;

namespace UnityEngine.Experimental.Input.LowLevel
Expand All @@ -11,7 +12,7 @@ namespace UnityEngine.Experimental.Input.LowLevel
/// This event contains the entire current string to date, and once a new composition is submitted will send a blank string event.
/// </summary>
[StructLayout(LayoutKind.Explicit, Size = InputEvent.kBaseEventSize + sizeof(int) + (sizeof(char) * kIMECharBufferSize))]
public unsafe struct IMECompositionEvent : IInputEventTypeInfo
public struct IMECompositionEvent : IInputEventTypeInfo
{
// These needs to match the native ImeCompositionStringInputEventData settings
public const int kIMECharBufferSize = 64;
Expand All @@ -21,7 +22,7 @@ public unsafe struct IMECompositionEvent : IInputEventTypeInfo
public InputEvent baseEvent;

[FieldOffset(InputEvent.kBaseEventSize)]
public IMEComposition composition;
public IMECompositionString compositionString;

public FourCC GetTypeStatic()
{
Expand All @@ -32,32 +33,76 @@ public FourCC GetTypeStatic()

namespace UnityEngine.Experimental.Input
{
[StructLayout(LayoutKind.Explicit, Size = sizeof(int) + (sizeof(char) * LowLevel.IMECompositionEvent.kIMECharBufferSize))]
public unsafe struct IMEComposition : IEnumerable<char>
[StructLayout(LayoutKind.Explicit, Size = sizeof(int) + sizeof(char) * IMECompositionEvent.kIMECharBufferSize)]
public unsafe struct IMECompositionString : IEnumerable<char>
{
internal unsafe struct Enumerator : IEnumerator<char>
public int Count
{
get
{
return size;
}
}

public char this[int index]
{
get
{
if (index >= Count || index < 0)
throw new ArgumentOutOfRangeException("index");

fixed(char* ptr = buffer)
{
return *(ptr + index);
}
}
}

[FieldOffset(0)]
internal int size;

[FieldOffset(sizeof(int))]
internal fixed char buffer[IMECompositionEvent.kIMECharBufferSize];

public override string ToString()
{
fixed(char* ptr = buffer)
return new string(ptr);
}

public IEnumerator<char> GetEnumerator()
{
return new Enumerator(this);
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

internal struct Enumerator : IEnumerator<char>
{
IMEComposition m_Composition;
IMECompositionString m_CompositionString;
char m_CurrentCharacter;
int m_CurrentIndex;

public Enumerator(IMEComposition composition)
public Enumerator(IMECompositionString compositionString)
{
m_Composition = composition;
m_CompositionString = compositionString;
m_CurrentCharacter = '\0';
m_CurrentIndex = -1;
}

public bool MoveNext()
{
int size = m_Composition.Count;
var size = m_CompositionString.Count;

m_CurrentIndex++;

if (m_CurrentIndex == size)
return false;

fixed(char* ptr = m_Composition.buffer)
fixed(char* ptr = m_CompositionString.buffer)
{
m_CurrentCharacter = *(ptr + m_CurrentIndex);
}
Expand Down Expand Up @@ -87,49 +132,5 @@ object IEnumerator.Current
get { return Current; }
}
}

public int Count
{
get
{
return size;
}
}

public unsafe char this[int index]
{
get
{
if (index >= Count || index < 0)
throw new IndexOutOfRangeException();

fixed(char* ptr = buffer)
{
return *(ptr + index);
}
}
}

[FieldOffset(0)]
int size;

[FieldOffset(sizeof(int))]
fixed char buffer[LowLevel.IMECompositionEvent.kIMECharBufferSize];

public override string ToString()
{
fixed(char* ptr = buffer)
return new string(ptr);
}

public IEnumerator<char> GetEnumerator()
{
return new Enumerator(this);
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
22 changes: 19 additions & 3 deletions Packages/com.unity.inputsystem/InputSystem/InputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2211,15 +2211,31 @@ internal unsafe void OnUpdate(InputUpdateType updateType, int eventCount, IntPtr
break;

case TextEvent.Type:
{
var textEventPtr = (TextEvent*)currentEventPtr;
////TODO: handle UTF-32 to UTF-16 conversion properly
device.OnTextInput((char)textEventPtr->character);
var textInputReceiver = device as ITextInputReceiver;
if (textInputReceiver != null)
{
var ch = (char)textEventPtr->character;
textInputReceiver.OnTextInput(ch);
if (char.IsSurrogate(ch))
{
// Get high-surrogate char of pair.
ch = (char)(textEventPtr->character >> 16);
textInputReceiver.OnTextInput(ch);
}
}
break;
}

case IMECompositionEvent.Type:
{
var imeEventPtr = (IMECompositionEvent*)currentEventPtr;
device.OnIMEStringEvent(imeEventPtr->composition);
var textInputReceiver = device as ITextInputReceiver;
if (textInputReceiver != null)
textInputReceiver.OnIMECompositionChanged(imeEventPtr->compositionString);
break;
}

case DeviceRemoveEvent.Type:
RemoveDevice(device);
Expand Down

0 comments on commit 1b045d4

Please sign in to comment.