A number of existing behaviours that are being proposed are agnostic to the kind of Input that they are coming from. When you are receiving a chat message, you don't necessarily need to know where it is from, so long as you can get the message, and reply to it.
Likewise, creators of plugins should not need to be aware of every possible InputEvent abstraction that they could use. The common solution to this would be Protocol. However as we have a marker base class that we use for registering interests, the type system does not like the simple construction of these Protocols.
This is solved by adding custom MetaClasses to override issubclass() and isinstance(). This allows the Protocols to always be considered subclasses of InputEvent, and at the same time specific InputEvents being instances of the protocols if they have the appropriate members.
A number of existing behaviours that are being proposed are agnostic to the kind of Input that they are coming from. When you are receiving a chat message, you don't necessarily need to know where it is from, so long as you can get the message, and reply to it.
Likewise, creators of plugins should not need to be aware of every possible InputEvent abstraction that they could use. The common solution to this would be Protocol. However as we have a marker base class that we use for registering interests, the type system does not like the simple construction of these Protocols.
This is solved by adding custom MetaClasses to override issubclass() and isinstance(). This allows the Protocols to always be considered subclasses of InputEvent, and at the same time specific InputEvents being instances of the protocols if they have the appropriate members.