Dynamic Evaluations in a Key Listener
public class KeyUpper {
Func<Key, bool> _evaluate;
public void RegisterEvaluator(Func<Key, bool> evaluate){
_evaluate = evaluate;
}
public void KeyUp(object sender, KeyEventArgs e){
if (_evaluate(e.KeyCode))
SomeResponse();
}
public void SomeResponse(){
// ...
}
}
This Lambda Should Await on Each Line
keyUpper.RegisterEvaluator(key =>
{
if (key == Key.A)
if (key == Key.W)
if (key == Key.A)
return true;
}
);
- i.e. client code would provide a series of evaluations on the same
keyargument with the expectation that each line of evaluation would be awaited so that SomeResponse() would be invoked after a sequence of keyup events of 1:A 2:W 3:A - obviously at the moment that will never happen because the method is run until the end and
key == Key.Wwill never be true - it may not be possible, but is there a way to make the method invocation automagically return from the next line if it evaluates to false but return to it until that line evaluates to true, following that through to the line after that, and to the line after that until the end of the method?
- i.e. might there be a simple way to provide awaitable lambda expressions of this kind?
If asynchronicity is not a requirement and you are fine with having one thread that almost always waits, you could do it by giving the lambda some blocking way to access the key. For example:
RegisterEvaluatorwould then spin up a new thread that calls the lambda in a loop, passing it a method that accesses the key, blocking if no key is available at the moment, for example usingBlockingCollection<Key>.If you think doing it this way is wasteful (it is), and you can use async-await, just make the lambda
asyncand change the passed in method to one that is asynchronous too:Implementation of the latter version (using
BlockBuffer<Key>) could look like this:Now, I’m not sure how exactly do you want to handle matching the keys, but I think it’s not like this. For example, this sample code would match the sequence of keys
BAW, but notAAW.Another option would be not using
Func<Task<Key>>, but your custom awaitable that can be awaited multiple times and gives one key each time you do that:But I think doing it this way is more confusing and harder to do.