KeyboardManager: a class to manage the polling of a switch-matrix keyboard

Dependents:   KeyboardTest

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers KeyboardState.h Source File

KeyboardState.h

00001 #ifndef KEYBOARD_STATE_H_
00002 #define KEYBOARD_STATE_H_
00003 
00004 #include <vector>
00005 #include <iostream>
00006 
00007 namespace kbd_mgr {
00008 
00009 /**
00010  * @brief A class to hold the state of a keyboard.
00011  * A keyboard is handled as a set of key rows. Each row can have as many keys as there are bits in integers.
00012  * The class maintains an array of integers to handle the number of rows.
00013  * If possible, multiple rows are combined in a single integer to reduce memory footprint.
00014  */
00015 class KeyboardState {
00016 public:
00017     /**
00018      * @brief Constructor for a 0x0 keyboard state.
00019      */
00020     KeyboardState();
00021     
00022     /**
00023      * @brief Constructor for a NxM keyboard state.
00024      * @param numRows       Number of key rows (unlimited)
00025      * @param numKeysPerRow Number of keys per row (limited to the number of bits in an integer).
00026      */
00027     KeyboardState(std::size_t numRows, std::size_t numKeysPerRow);
00028 
00029     std::size_t getNumRows() const { return this->numRows; }
00030     std::size_t getNumKeysPerRow() const { return this->numKeysPerRow; }
00031     std::size_t getNumKeys() const { return this->numRows * this->numKeysPerRow; }
00032     
00033     void clear();
00034     void setRowState(std::size_t row, int rowState);
00035     int getRowState(std::size_t row) const;
00036     bool getKeyState(std::size_t key) const;
00037     
00038     /**
00039      * @brief Executes a XOR between two states.
00040      * @return a state that represents the keys that changed of state.
00041      */
00042     KeyboardState operator^(const KeyboardState &other) const;
00043     
00044     /**
00045      * @brief Executes an AND between two states.
00046      */
00047     KeyboardState operator&(const KeyboardState &mask) const;
00048     
00049     bool operator==(const KeyboardState &other) const;
00050     bool operator!=(const KeyboardState &other) const { return !(*this == other); }
00051     
00052     /**
00053      * @brief Checks if a keyboard state is full of 0.
00054      */
00055     bool empty() const;
00056     
00057     enum KeyPressType {
00058         Idle, SingleKeyPress, MultiKeyPress
00059     };
00060     
00061     /**
00062      * @brief Determines the kind of key press present in the state.
00063      * The keyboard state can represent an idle keyboard, a single key pressed
00064      * or a key combination. This method determines which type of state this is.
00065      * If a single key is represented, the key index can be retrieved.
00066      * @param key   An integer where the single key pressed should be stored.
00067      */
00068     KeyPressType getKeyPressType(int *key = NULL) const;
00069     KeyPressType getKeyPressType(int &key) const { return getKeyPressType(&key); }
00070     
00071     void streamTo(std::ostream &out) const;
00072     
00073 private:
00074     int getRowInfo(std::size_t row, std::size_t &wordIndex, std::size_t &rowShift, int &rowMask) const;
00075 
00076     std::size_t numRows;
00077     std::size_t numKeysPerRow;
00078     int rowMask;
00079     std::size_t numRowsPerWord;
00080     std::size_t numKeysPerWord;
00081     std::size_t numWords;
00082     
00083     typedef std::vector<int> Data;
00084     Data data;
00085 };
00086 
00087 inline std::ostream & operator<<(std::ostream &out, const KeyboardState &s) {
00088     s.streamTo(out);
00089     return out;
00090 }
00091 
00092 } // kbd_mgr
00093 
00094 #endif // KEYBOARD_STATE_H_