So, as I suggested in my prior blog post, I’ve been working on totally redesigning the Common::Action and Common::Keymap structures.
I’ve been at work on this for a few days now, but because I’m totally redesigning the way they interact with each other, and interface with the rest of the code at large, I’m not done yet, and the code won’t compile until I finish, so I can’t commit it yet.
So, to show what I’ve been working at, I’m posting what I’ve gotten done here.
So far, all the actual rewritten code has been going into the Action struct and related enums.
enum ActionType {
//Emulate a hardware event in the engine
kSingleKeyPressActionType,
kMultiKeyPressType,
kMouseClickType,
kMouseWheelType,
//Interface directly with the VM
kSaveActionType,
kMenuActionType,
kQuitActionType,
kVirtualKeyboardActionType,
kKeyRemapActionType,
kVolumeUpActionType,
kVolumeDownActionType,
//This is the total number of types currently defined in this enum
kActionTypeMax
};
enum ClickType {
kLeftClickType,
kMiddleClickType,
kRightClickType
};
enum KeyType {
//Direction keys
kDirUpKeyType,
kDirDownKeyType,
kDirLeftKeyType,
kDirRightKeyType,
//Keyboard keys
kTextKeyType, //Letters, numbers, symbols, whitespace
kModifierKeyType, //Ctrl, Alt, Shift
//Gamepad buttons
kFaceButtonKeyType, //A, B, C, X, Y, Z, and the like
kShoulderButtonKeyType, //Separated from FaceButtons because they can be used as pseudo-modifier keys.
//System key types
kPauseKeyType, //Start, Pause, etc..
kMenuKeyType, //Select, Escape, etc…
kSystemActionKeyType, //F1-F12, volume sliders, and so forth
//This is the total number of types currently defined in this enum
kKeyTypeMax
};
struct Action {
char id[ACTION_ID_SIZE];
ActionType type;
KeyType preferredKey;
private:
List<Event> _events;
HardwareKey *_mappedKey;
public:
void mapKey (const HardwareKey *key);
void addKeyPressEvent(KeyCode code, byte modifiers) {
KeyState key = KeyState(code);
key.flags = modifiers;
Event keyPress;
keyPress.type = EVENT_KEYDOWN;
keyPress.kbd = key;
_events.push_back(keyPress);
}
void addMouseClickEvent(ClickType t) {
Event mouseClick;
if (t == kLeftClickType)
mouseClick.type = EVENT_LBUTTONDOWN;
else if (t == kRightClickType)
mouseClick.type = EVENT_RBUTTONDOWN;
else
mouseClick.type = EVENT_MBUTTONDOWN;
_events.push_back(mouseClick);
}
template <ActonType t>;
Action<kSingleKeyPressActionType> (char *i, KeyType k, KeyCode c, byte m) {
memcpy(id,i,ACTION_ID_SIZE);
type = t;
preferredKey = k;
addKeyPressEvent(c,m);
}
Action<kMultiKeyPressType> (char *i, KeyType k, List<KeyCode> cs, byte m) {
memcpy(id,i,ACTION_ID_SIZE);
type = t;
preferredKey = k;
List<KeyCode>::iterator it;
for (it = cs.begin(); it != cs.end(); it++) {
KeyCode c = *it;
addKeyPressEvent(c,m);
}
}
Action<kMouseClickType> (char *i, bool l = true, bool m = false, bool r = false) {
memcpy(id,i,ACTION_ID_SIZE);
type = t;
preferredKey = k;
if (l)
addMouseClickEvent(kLeftClickType);
if (m)
addMouseClickEvent(kMiddleClickType);
if (r)
addMouseClickEvent(kRightClickType);
}
Action<kMouseWheelType> (char *i, bool up = false) {
memcpy(id,i,ACTION_ID_SIZE);
Event evt;
if (up)
evt.type = EVENT_WHEELUP;
else
evt.type = EVENT_WHEELDOWN;
_events.push_back(evt);
}
Action (char *i) {
memcpy(id,i,ACTION_ID_SIZE);
type = t;
}
};
There’s more about how this is going to work which is still in my head, but a lot of initialization stuff that was previously done by Action methods is going to be moved into the Keymap, so there will no longer be any need for an Action to know anything about the set that it is in, except to have a HardwareKey pointer provided to it (and even that will only be so that the Keymap can do effective data-management when an action gets remapped.)