Prototype Keyboard Wrapper or Getting all the collections out of Text Related stuff.

Ok so i have tinkered with doing this to varying degrees of success before but this time i think i have a pretty decent class worked out. This replaces text input and the keyboard class by wrapping the keyboard, though it still can be used with this. This is also a good workaround for anyone who ever finds themselves think i kinda want to call GetKeysPressed which returns a array with potentially ugly de-allocation side effects.

The main reason i did this was because registering and un-registering repeatedly via delegates and callbacks in the context of buttons or really anything were you do it repeatedly causes garbage de-allocations.
I also think it feels somewhat awkward to have a event based textinput and a polled keyboard.

Ideologically. The wrapper alters the idea of subscribing and un-subscribing into one of registering and then enabling or disabling notifications. So that you simply don’t have to un-register and cause a de-allocation, in order to stop receiving event callbacks you simply tell the class to disable my callbacks.

The class has callbacks for TextInput and ControlKeysPressed and a bool for use in update in order to check when no keys are pressed at all. The text input mirrors monogames current version with some minor differences which i could do in this context.
The way it works can be seen in the application visually via holding different key combinations.

Technically, since most of the time delegates keep weak references (hope i have that term right) around anyways till the delegate goes out of scope i believe this is a valid context for a game.So we are keeping a strong reference on purpose in this case between the sender and reciever.

So far the class works and i posted a DesktopGL test project up on Github if anyone would like to try it. If you do throw some feedback. The project also has my wrapper for stringbuilder a framerate class that also shows garbage and a timer as seen in the below image.

.
No garbage keyboard input wrapper Github Project
.

This test project also has a Visual Keyboard image for the test to show what is happening in real time.

This is the working first version of the completed class.

.

The one cavet is that if you hold a key and exceed the stringbuilder capacity you will end up with a round of garbage. Also you can actually force spritebatch to make garbage however that is on monogames side and is actually part of the design which is as intended and a non issue. I tested that with a swapping buffer which negated that garbage.

The below snippet is how it is initially set up in game1 load.

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            // pull in textures.
            dotTexture = CreateTextureDot(GraphicsDevice);
            Asset.LoadFrom_Content(Content);
            Asset.font_MgGenFont.DefaultCharacter = '?';

            frameRate = new MgFrameRate();
            frameRate.LoadSetUp(this, graphics, spriteBatch, true, false, 60, true);

            // initialize text input and key command input. 
            // this class process multiple key combinations up to 3.
            KeysAndTextInput.Initialize();

            // example, this is done once.
            KeysAndTextInput.AddMethodsToRaiseOnKeyBoardActivity(OnTextInput, OnKeyCommandsInput, this);
            // disable or enable like so prevents garbage collections from occuring.
            KeysAndTextInput.EnableKeyCommandsInput(this);
            KeysAndTextInput.EnableTextInput(this);

            // to visually test and see the above class in practical use.
            // don't have to save the refernce this is a static instance.
            new VisualKeyboardDisplay();
            // record characters.
            VisualKeyboardDisplay.RecordTypedCharacters = true;
            VisualKeyboardDisplay.DisplayRecordedTypedCharacters = true;
            VisualKeyboardDisplay.DisplayKeypressText = true;
        }

Edited for typos.

1 Like