From The Mana World

LlubNek

TODO

  • Apply signal/slot based input system to TMW client.
Why?
It allows several different events to trigger the same action.
Adding new actions is fairly simple: create a member function with no parameters which performs the action, register the action with the event system (something like event_dispatch.registerAction("name", class_instance, &Class::member);, where class_instance is an instance of Class and Class is a subclass of the slot container class).
What would this look like?
Default view
You are presented with a hierarchal list with each action listed, followed immediately by that actions bindings. To add a new binding for an action select it or one of it's existing bindings, click add and trigger whatever event you want to associate with it. To remove a binding, select it and click remove. If you click remove with an action selected, all bindings for that action are removed.
Advanced view
You would have a set of bindings which you can add to or delete from. When adding a member, you would be presented with a list of actions, a list of triggers (button/key press, button/key release, joystick axis goes positive, joystick axis goes negative, mouse/joystick axis increase, mouse/joystick axis decrease, joystick axis returns to 0), and a list of modifiers (shift, ctrl, etc.). You would select one action and one trigger and whatever modifiers and click OK/Add/whatever.
Considerations:
Signal / slot mechanism introduces some additional overhead, however, this is unlikely to be noticeable in a user input system. Nobody types that fast.
Events from SDL should first be sent to GUI, then any unhandled events should be passed to input system. Not the other way around. However, modifier states will need to be monitored even for GUI handled events.
It may be advantageous to define a condition system instead of simple modifiers, so that action A is triggered only when condition B is true and event C occurs. So for example, to attack if lshift+A is pressed, but only if lctrl is not pressed use something like this: if ConditionAnd(left_shift_button_down, ConditionNot(left_ctrl_button_down)) casts to bool as true and KeyPressEvent[SDLK_a] is triggered, call player.attack_target();.