diff options
author | Bardur Arantsson <bardur@scientician.net> | 2019-02-15 19:20:25 +0100 |
---|---|---|
committer | Bardur Arantsson <bardur@scientician.net> | 2019-02-15 19:20:25 +0100 |
commit | 3e64546c68c7b64606451b0fb35a3c95fb1dae3b (patch) | |
tree | 0959cef6a5c1147ec34eecf25ffba9bc77d7451e | |
parent | 144413a1cff8ba073e87c8120bfd2d7692c987b6 (diff) |
Extract key queue logic out of struct term
-rw-r--r-- | src/z-term.cc | 159 |
1 files changed, 126 insertions, 33 deletions
diff --git a/src/z-term.cc b/src/z-term.cc index 73c63396..459430c3 100644 --- a/src/z-term.cc +++ b/src/z-term.cc @@ -358,6 +358,109 @@ public: }; +/* + * Overflow signal + */ +enum class push_result { + OK, + OVERFLOW, +}; + + +static errr push_result_to_errr(push_result r) +{ + switch (r) + { + case push_result::OK: + return 0; + case push_result::OVERFLOW: + return 1; + } +} + + +/* + * Low-level key queue handling. + */ +struct key_queue { + +private: + u16b m_head = 0; + u16b m_tail = 0; + std::vector<char> m_queue; + +public: + explicit key_queue(int k) + : m_queue(k) + { + } + + void clear() + { + m_head = 0; + m_tail = 0; + } + + void push_back(char c) + { + /* Store the char, advance the queue */ + m_queue[m_head++] = c; + + /* Circular queue, handle wrap */ + if (m_head == m_queue.size()) + { + m_head = 0; + } + } + + push_result push_front(char k) + { + /* Hack -- Overflow may induce circular queue */ + if (m_tail == 0) + { + m_tail = m_queue.size(); + } + + /* Back up, Store the char */ + m_queue[--m_tail] = k; + + /* Success (unless overflow) */ + if (m_head != m_tail) + { + return push_result::OK; + } + else + { + return push_result::OVERFLOW; + } + } + + char back() const + { + assert(!empty()); + return m_queue[m_tail]; + } + + char pop_back() + { + auto ch = back(); + + if (++m_tail == m_queue.size()) + { + m_tail = 0; + } + + return ch; + } + + bool empty() const + { + return m_head == m_tail; + } + +}; + + /* * An actual "term" structure @@ -429,10 +532,7 @@ struct term bool icky_corner = false; bool soft_cursor = false; - u16b key_head = 0; - u16b key_tail = 0; - u16b key_size; - std::vector<char> key_queue; + key_queue m_key_queue; byte wid; byte hgt; @@ -460,8 +560,7 @@ struct term */ term(int w, int h, int k, void *data_) : data(data_) - , key_size(k) - , key_queue(key_size) + , m_key_queue(k) , wid(w) , hgt(h) , x1(h) @@ -1484,7 +1583,7 @@ void Term_flush() Term_xtra(TERM_XTRA_FLUSH, 0); /* Forget all keypresses */ - Term->key_head = Term->key_tail = 0; + Term->m_key_queue.clear(); } @@ -1497,11 +1596,8 @@ void Term_keypress(int k) /* Ignore non-keys */ if (!k) return; - /* Store the char, advance the queue */ - Term->key_queue[Term->key_head++] = k; - - /* Circular queue, handle wrap */ - if (Term->key_head == Term->key_size) Term->key_head = 0; + /* Push */ + Term->m_key_queue.push_back(k); } @@ -1513,23 +1609,11 @@ errr Term_key_push(int k) /* Hack -- Refuse to enqueue non-keys */ if (!k) return ( -1); - /* Hack -- Overflow may induce circular queue */ - if (Term->key_tail == 0) Term->key_tail = Term->key_size; - - /* Back up, Store the char */ - Term->key_queue[--Term->key_tail] = k; - - /* Success (unless overflow) */ - if (Term->key_head != Term->key_tail) return (0); - - /* Problem */ - return (1); + /* Push */ + return push_result_to_errr(Term->m_key_queue.push_front(k)); } - - - /* * Check for a pending keypress on the key queue. * @@ -1542,6 +1626,8 @@ errr Term_key_push(int k) */ errr Term_inkey(char *ch, bool_ wait, bool_ take) { + auto &key_queue = Term->m_key_queue; + /* Assume no key */ (*ch) = '\0'; @@ -1552,7 +1638,7 @@ errr Term_inkey(char *ch, bool_ wait, bool_ take) if (wait) { /* Process pending events while necessary */ - while (Term->key_head == Term->key_tail) + while (key_queue.empty()) { /* Process events (wait for one) */ Term_xtra(TERM_XTRA_EVENT, TRUE); @@ -1563,7 +1649,7 @@ errr Term_inkey(char *ch, bool_ wait, bool_ take) else { /* Process pending events if necessary */ - if (Term->key_head == Term->key_tail) + if (key_queue.empty()) { /* Process events (do not wait) */ Term_xtra(TERM_XTRA_EVENT, FALSE); @@ -1571,13 +1657,20 @@ errr Term_inkey(char *ch, bool_ wait, bool_ take) } /* No keys are ready */ - if (Term->key_head == Term->key_tail) return (1); + if (key_queue.empty()) + { + return (1); + } /* Extract the next keypress */ - (*ch) = Term->key_queue[Term->key_tail]; - - /* If requested, advance the queue, wrap around if necessary */ - if (take && (++Term->key_tail == Term->key_size)) Term->key_tail = 0; + if (take) + { + *ch = key_queue.pop_back(); + } + else + { + *ch = key_queue.back(); + } /* Success */ return (0); |