Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
bmalrat committed Dec 4, 2024
1 parent cd53351 commit aacee0a
Show file tree
Hide file tree
Showing 5 changed files with 598 additions and 83 deletions.
6 changes: 6 additions & 0 deletions Assets/Tests/InputSystem/CorePerformanceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,14 @@ public void Performance_ReadEveryKey()

Measure.Method(() =>
{
int keyIndex = 0;
foreach (var key in keyboard.allKeys)
{
if (++keyIndex == (int) KeyEx.IMESelected) // Skip IMESelected as it's not a real key.
continue;
key.ReadValue();

}
})
.MeasurementCount(100)
.WarmupCount(5)
Expand Down
2 changes: 1 addition & 1 deletion Assets/Tests/InputSystem/CoreTests_Devices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2674,7 +2674,7 @@ public void Devices_AnyKeyOnKeyboard_DoesNotReactToIMESelected()
{
var keyboard = InputSystem.AddDevice<Keyboard>();

InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.IMESelected));
InputSystem.QueueStateEvent(keyboard, new KeyboardState(IMESelected: true));
InputSystem.Update();

Assert.That(keyboard.anyKey.isPressed, Is.False);
Expand Down
189 changes: 177 additions & 12 deletions Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ public unsafe struct KeyboardState : IInputStateTypeInfo
/// <seealso cref="InputStateBlock.format"/>
public static FourCC Format => new FourCC('K', 'E', 'Y', 'S');

private const int kSizeInBits = Keyboard.KeyCount;
private const int kSizeInBits = Keyboard.KeyCount + 1; // +1 for IMESelected.
internal const int kSizeInBytes = (kSizeInBits + 7) / 8;

[InputControl(name = "anyKey", displayName = "Any Key", layout = "AnyKey", sizeInBits = kSizeInBits - 1, synthetic = true)] // Exclude IMESelected.
[InputControl(name = "anyKey", displayName = "Any Key", layout = "AnyKey", offset = 1, sizeInBits = (int)Key.F24, synthetic = true)]
[InputControl(name = "escape", displayName = "Escape", layout = "Key", usages = new[] {"Back", "Cancel"}, bit = (int)Key.Escape)]
[InputControl(name = "space", displayName = "Space", layout = "Key", bit = (int)Key.Space)]
[InputControl(name = "enter", displayName = "Enter", layout = "Key", usage = "Submit", bit = (int)Key.Enter)]
Expand Down Expand Up @@ -155,17 +155,42 @@ public unsafe struct KeyboardState : IInputStateTypeInfo
[InputControl(name = "OEM3", layout = "Key", bit = (int)Key.OEM3)]
[InputControl(name = "OEM4", layout = "Key", bit = (int)Key.OEM4)]
[InputControl(name = "OEM5", layout = "Key", bit = (int)Key.OEM5)]
[InputControl(name = "IMESelected", layout = "Button", bit = (int)Key.IMESelected, synthetic = true)]
[InputControl(name = "f13", displayName = "F13", layout = "Key", bit = (int)Key.F13)]
[InputControl(name = "f14", displayName = "F14", layout = "Key", bit = (int)Key.F14)]
[InputControl(name = "f15", displayName = "F15", layout = "Key", bit = (int)Key.F15)]
[InputControl(name = "f16", displayName = "F16", layout = "Key", bit = (int)Key.F16)]
[InputControl(name = "f17", displayName = "F17", layout = "Key", bit = (int)Key.F17)]
[InputControl(name = "f18", displayName = "F18", layout = "Key", bit = (int)Key.F18)]
[InputControl(name = "f19", displayName = "F19", layout = "Key", bit = (int)Key.F19)]
[InputControl(name = "f20", displayName = "F20", layout = "Key", bit = (int)Key.F20)]
[InputControl(name = "f21", displayName = "F21", layout = "Key", bit = (int)Key.F21)]
[InputControl(name = "f22", displayName = "F22", layout = "Key", bit = (int)Key.F22)]
[InputControl(name = "f23", displayName = "F23", layout = "Key", bit = (int)Key.F23)]
[InputControl(name = "f24", displayName = "F24", layout = "Key", bit = (int)Key.F24)]
[InputControl(name = "IMESelected", layout = "Button", bit = (int)KeyEx.RemapedIMESelected, synthetic = true)] // Use the last bit to hold IME selected state.
public fixed byte keys[kSizeInBytes];

public KeyboardState(params Key[] pressedKeys)
// will be the default in new editor [InputControl(name = "IMESelected", layout = "Button", bit = 0, sizeInBits = 1, synthetic = true)]
//public byte modifiers;

public KeyboardState(params Key[] pressedKeys) : this(false, pressedKeys)
{

}

public KeyboardState(bool IMESelected, params Key[] pressedKeys)
{
if (pressedKeys == null)
throw new ArgumentNullException(nameof(pressedKeys));

fixed(byte* keysPtr = keys)
fixed (byte* keysPtr = keys)
{
UnsafeUtility.MemClear(keysPtr, kSizeInBytes);

if (IMESelected)
{
MemoryHelpers.WriteSingleBit(keysPtr, (uint)KeyEx.IMESelected, true);
}

for (var i = 0; i < pressedKeys.Length; ++i)
MemoryHelpers.WriteSingleBit(keysPtr, (uint)pressedKeys[i], true);
}
Expand All @@ -177,6 +202,14 @@ public void Set(Key key, bool state)
MemoryHelpers.WriteSingleBit(keysPtr, (uint)key, state);
}

internal bool Get(Key key)
{
fixed (byte* keysPtr = keys)
{
return MemoryHelpers.ReadSingleBit(keysPtr, (uint)key);
}
}

public void Press(Key key)
{
Set(key, true);
Expand Down Expand Up @@ -842,9 +875,86 @@ public enum Key
/// </summary>
OEM5,

////FIXME: This should never have been a Key but rather just an extra button or state on keyboard
// Not exactly a key, but binary data sent by the Keyboard to say if IME is being used.
IMESelected
/// <summary>
/// Don't use this. This is a dummy key that is only used internally to represent the IME selected state.
/// Will be removed in the future.
/// </summary>
[Obsolete("Don't use this. This is a dummy key that is only used internally to represent the IME selected state. Will be removed in the future.", true)]
IMESelected,

/// <summary>
/// The <see cref="Keyboard.f13Key"/>.
/// </summary>
F13,

/// <summary>
/// The <see cref="Keyboard.f14Key"/>.
/// </summary>
F14,

/// <summary>
/// The <see cref="Keyboard.f15Key"/>.
/// </summary>
F15,

/// <summary>
/// The <see cref="Keyboard.f16Key"/>.
/// </summary>
F16,

/// <summary>
/// The <see cref="Keyboard.f17Key"/>.
/// </summary>
F17,

/// <summary>
/// The <see cref="Keyboard.f18Key"/>.
/// </summary>
F18,

/// <summary>
/// The <see cref="Keyboard.f19Key"/>.
/// </summary>
F19,

/// <summary>
/// The <see cref="Keyboard.f20Key"/>.
/// </summary>
F20,

/// <summary>
/// The <see cref="Keyboard.f21Key"/>.
/// </summary>
F21,

/// <summary>
/// The <see cref="Keyboard.f22Key"/>.
/// </summary>
F22,

/// <summary>
/// The <see cref="Keyboard.f23Key"/>.
/// </summary>
F23,

/// <summary>
/// The <see cref="Keyboard.f24Key"/>.
/// </summary>
F24,

/// <summary>
/// Don't use this. This is a dummy key that is only used internally to represent the IME selected state.
/// Will be removed in the future.
/// FIXME: This should never have been a Key but rather just an extra button or state on keyboard
/// Not exactly a key, but binary data sent by the Keyboard to say if IME is being used.
/// </summary>
//InternalForIMESelected = 127,
}

internal static class KeyEx
{
internal const Key IMESelected = (Key)111; //IMESelected value
internal const Key RemapedIMESelected = (Key)127; //IMESelected value
}

/// <summary>
Expand Down Expand Up @@ -877,14 +987,15 @@ public enum Key
/// keyboard has certain keys or not.
/// </remarks>
[InputControlLayout(stateType = typeof(KeyboardState), isGenericTypeOfDevice = true)]
public class Keyboard : InputDevice, ITextInputReceiver
public class Keyboard : InputDevice, ITextInputReceiver, IEventPreProcessor
{
/// <summary>
/// Total number of key controls on a keyboard, i.e. the number of controls
/// in <see cref="allKeys"/>.
/// </summary>
/// <value>Total number of key controls.</value>
public const int KeyCount = (int)Key.OEM5;
public const int KeyCount = (int)Key.F24 - 1; // without IMESelected
// without IMESelected

/// <summary>
/// Event that is fired for every single character entered on the keyboard.
Expand Down Expand Up @@ -1862,6 +1973,7 @@ public string keyboardLayout
/// <value>Control representing the F12 key.</value>
public KeyControl f12Key => this[Key.F12];


/// <summary>
/// First additional key on the keyboard.
/// </summary>
Expand Down Expand Up @@ -2149,17 +2261,32 @@ protected override void FinishSetup()
"oem3",
"oem4",
"oem5",
null, // IMESelected
"f13",
"f14",
"f15",
"f16",
"f17",
"f18",
"f19",
"f20",
"f21",
"f22",
"f23",
"f24",
};
m_Keys = new KeyControl[keyStrings.Length];
for (var i = 0; i < keyStrings.Length; ++i)
{
if (string.IsNullOrEmpty(keyStrings[i]))
continue;
m_Keys[i] = GetChildControl<KeyControl>(keyStrings[i]);

////REVIEW: Ideally, we'd have a way to do this through layouts; this way nested key controls could work, too,
//// and it just seems somewhat dirty to jam the data into the control here
m_Keys[i].keyCode = (Key)(i + 1);
}
Debug.Assert(keyStrings[(int)Key.OEM5 - 1] == "oem5",
Debug.Assert(keyStrings[(int)Key.F24 - 1] == "f24",
"keyString array layout doe not match Key enum layout");
anyKey = GetChildControl<AnyKeyControl>("anyKey");
shiftKey = GetChildControl<ButtonControl>("shift");
Expand Down Expand Up @@ -2228,6 +2355,44 @@ public void OnIMECompositionChanged(IMECompositionString compositionString)
}
}

public unsafe bool PreProcessEvent(InputEventPtr currentEventPtr)
{
if (currentEventPtr.type == StateEvent.Type)
{
var stateEvent = StateEvent.FromUnchecked(currentEventPtr);
if (stateEvent->stateFormat == KeyboardState.Format)
{
var keyboardState = ((KeyboardState*)(stateEvent->stateData));
if(keyboardState->Get(KeyEx.IMESelected))
{
keyboardState->Set(KeyEx.IMESelected, false);
keyboardState->Set(KeyEx.RemapedIMESelected, true);
}

//stateEvent->stateSizeInBytes = KeyboardState.kSizeInBytes;

//keyboardState->
//if (stateEvent->)
//var imeSelected = ((KeyboardState*)(stateEvent))->Get(Key.InternalForIMESelected);

//((KeyboardState*)(stateEvent))->Set(Key.IMESelected, ((KeyboardState*)(stateEvent))->Get(Key.DiscardedIMESelected));
////((KeyboardState*)(stateEvent))->keys[]
//if (stateEvent->stateSizeInBytes != KeyboardState.kSizeInBytes)
//{
// //imeSelected
// ((KeyboardState*)(stateEvent))->Set(Key.IMESelected, ((KeyboardState*)(stateEvent))->Get(Key.DiscardedIMESelected));
// ((KeyboardState*)(stateEvent))->Set(Key.DiscardedIMESelected, false);
// Debug.Log($"FastKeyboard: StateEvent size mismatch {stateEvent->stateSizeInBytes} {KeyboardState.kSizeInBytes}");
//}

}


}

return true;
}

private InlinedArray<Action<char>> m_TextInputListeners;
private string m_KeyboardLayoutName;
private KeyControl[] m_Keys;
Expand Down
Loading

0 comments on commit aacee0a

Please sign in to comment.