Maze / Library /PackageCache /com.unity.inputsystem@1.6.1 /InputSystem /Events /IMECompositionEvent.cs
| using System; | |
| using System.Collections; | |
| using System.Collections.Generic; | |
| using System.Runtime.InteropServices; | |
| using UnityEngine.InputSystem.Utilities; | |
| namespace UnityEngine.InputSystem.LowLevel | |
| { | |
| /// <summary> | |
| /// A specialized event that contains the current IME Composition string, if IME is enabled and active. | |
| /// This event contains the entire current string to date, and once a new composition is submitted will send a blank string event. | |
| /// </summary> | |
| [] | |
| public struct IMECompositionEvent : IInputEventTypeInfo | |
| { | |
| // These needs to match the native ImeCompositionStringInputEventData settings | |
| internal const int kIMECharBufferSize = 64; | |
| public const int Type = 0x494D4553; | |
| [] | |
| public InputEvent baseEvent; | |
| [] | |
| public IMECompositionString compositionString; | |
| public FourCC typeStatic => Type; | |
| public static IMECompositionEvent Create(int deviceId, string compositionString, double time) | |
| { | |
| var inputEvent = new IMECompositionEvent(); | |
| inputEvent.baseEvent = new InputEvent(Type, InputEvent.kBaseEventSize + sizeof(int) + (sizeof(char) * kIMECharBufferSize), deviceId, time); | |
| inputEvent.compositionString = new IMECompositionString(compositionString); | |
| return inputEvent; | |
| } | |
| } | |
| /// <summary> | |
| /// A struct representing an string of characters generated by an IME for text input. | |
| /// </summary> | |
| /// <remarks> | |
| /// This is the internal representation of character strings in the event stream. It is exposed to user content through the | |
| /// <see cref="ITextInputReceiver.OnIMECompositionChanged"/> method. It can easily be converted to a normal C# string using | |
| /// <see cref="ToString"/>, but is exposed as the raw struct to avoid allocating memory by default. | |
| /// </remarks> | |
| [] | |
| public unsafe struct IMECompositionString : IEnumerable<char> | |
| { | |
| internal struct Enumerator : IEnumerator<char> | |
| { | |
| IMECompositionString m_CompositionString; | |
| char m_CurrentCharacter; | |
| int m_CurrentIndex; | |
| public Enumerator(IMECompositionString compositionString) | |
| { | |
| m_CompositionString = compositionString; | |
| m_CurrentCharacter = '\0'; | |
| m_CurrentIndex = -1; | |
| } | |
| public bool MoveNext() | |
| { | |
| int size = m_CompositionString.Count; | |
| m_CurrentIndex++; | |
| if (m_CurrentIndex == size) | |
| return false; | |
| fixed(char* ptr = m_CompositionString.buffer) | |
| { | |
| m_CurrentCharacter = *(ptr + m_CurrentIndex); | |
| } | |
| return true; | |
| } | |
| public void Reset() | |
| { | |
| m_CurrentIndex = -1; | |
| } | |
| public void Dispose() | |
| { | |
| } | |
| public char Current => m_CurrentCharacter; | |
| object IEnumerator.Current => Current; | |
| } | |
| public int Count => size; | |
| public char this[int index] | |
| { | |
| get | |
| { | |
| if (index >= Count || index < 0) | |
| throw new ArgumentOutOfRangeException(nameof(index)); | |
| fixed(char* ptr = buffer) | |
| { | |
| return *(ptr + index); | |
| } | |
| } | |
| } | |
| [] | |
| int size; | |
| [] | |
| fixed char buffer[IMECompositionEvent.kIMECharBufferSize]; | |
| public IMECompositionString(string characters) | |
| { | |
| if (string.IsNullOrEmpty(characters)) | |
| { | |
| size = 0; | |
| return; | |
| } | |
| Debug.Assert(characters.Length < IMECompositionEvent.kIMECharBufferSize); | |
| size = characters.Length; | |
| for (var i = 0; i < size; i++) | |
| buffer[i] = characters[i]; | |
| } | |
| public override string ToString() | |
| { | |
| fixed(char* ptr = buffer) | |
| { | |
| return new string(ptr, 0, size); | |
| } | |
| } | |
| public IEnumerator<char> GetEnumerator() | |
| { | |
| return new Enumerator(this); | |
| } | |
| IEnumerator IEnumerable.GetEnumerator() | |
| { | |
| return GetEnumerator(); | |
| } | |
| } | |
| } | |