Eliminated memory allocations in Keyboard events

This commit is contained in:
Stefanos A 2013-12-09 23:44:51 +01:00
parent 537a2f7b89
commit 128d96994b

View file

@ -59,6 +59,16 @@ namespace OpenTK.Platform.SDL2
Icon icon; Icon icon;
string window_title; string window_title;
// Used in KeyPress event to decode SDL UTF8 text strings
// to .Net UTF16 strings
char[] DecodeTextBuffer = new char[32];
// Argument for KeyPress event (allocated once to avoid runtime allocations)
readonly KeyPressEventArgs keypress_args = new KeyPressEventArgs('\0');
// Argument for KeyDown and KeyUp events (allocated once to avoid runtime allocations)
readonly KeyboardKeyEventArgs key_args = new KeyboardKeyEventArgs();
readonly IInputDriver input_driver = new Sdl2InputDriver(); readonly IInputDriver input_driver = new Sdl2InputDriver();
readonly EventFilter EventFilterDelegate_GCUnsafe = FilterEvents; readonly EventFilter EventFilterDelegate_GCUnsafe = FilterEvents;
@ -226,39 +236,49 @@ namespace OpenTK.Platform.SDL2
{ {
bool key_pressed = ev.Key.State == State.Pressed; bool key_pressed = ev.Key.State == State.Pressed;
var key = ev.Key.Keysym; var key = ev.Key.Keysym;
var args = new KeyboardKeyEventArgs() window.key_args.Key = TranslateKey(key.Scancode);
{ window.key_args.ScanCode = (uint)key.Scancode;
Key = TranslateKey(key.Scancode),
ScanCode = (uint)key.Scancode
};
if (key_pressed) if (key_pressed)
window.KeyDown(window, args); {
window.KeyDown(window, window.key_args);
}
else else
window.KeyUp(window, args); {
window.KeyUp(window, window.key_args);
}
//window.keyboard.SetKey(TranslateKey(key.scancode), (uint)key.scancode, key_pressed); //window.keyboard.SetKey(TranslateKey(key.scancode), (uint)key.scancode, key_pressed);
} }
static unsafe void ProcessTextInputEvent(Sdl2NativeWindow window, TextInputEvent ev) static unsafe void ProcessTextInputEvent(Sdl2NativeWindow window, TextInputEvent ev)
{ {
var keyPress = window.KeyPress; // Calculate the length of the typed text string
if (keyPress != null) int length;
for (length = 0; length < TextInputEvent.TextSize && ev.Text[length] != '\0'; length++)
;
// Make sure we have enough space to decode this string
int decoded_length = Encoding.UTF8.GetCharCount(ev.Text, length);
if (window.DecodeTextBuffer.Length < decoded_length)
{ {
var length = 0; Array.Resize(
byte* pText = ev.Text; ref window.DecodeTextBuffer,
while (*pText != 0) 2 * Math.Max(decoded_length, window.DecodeTextBuffer.Length));
{
length++;
pText++;
} }
using (var stream = new System.IO.UnmanagedMemoryStream(ev.Text, length))
using (var reader = new System.IO.StreamReader(stream, Encoding.UTF8)) // Decode the string from UTF8 to .Net UTF16
fixed (char* pBuffer = window.DecodeTextBuffer)
{ {
var text = reader.ReadToEnd(); decoded_length = System.Text.Encoding.UTF8.GetChars(
foreach (var c in text) ev.Text,
length,
pBuffer,
window.DecodeTextBuffer.Length);
}
for (int i = 0; i < decoded_length; i++)
{ {
keyPress(window, new KeyPressEventArgs(c)); window.keypress_args.KeyChar = window.DecodeTextBuffer[i];
} window.KeyPress(window, window.keypress_args);
}
} }
} }