diff --git a/include/tags/context.hpp b/include/tags/context.hpp index 424ee9d0..21d6a628 100644 --- a/include/tags/context.hpp +++ b/include/tags/context.hpp @@ -158,8 +158,8 @@ namespace tags { bool has_double_click() const; size_t num_actions() const; + size_t num_unclosed() const; - // TODO provide better interface for adjusting the start positions of actions const std::vector& get_blocks() const; protected: diff --git a/src/tags/context.cpp b/src/tags/context.cpp index ec0873e3..c3046a86 100644 --- a/src/tags/context.cpp +++ b/src/tags/context.cpp @@ -198,6 +198,18 @@ namespace tags { return m_action_blocks.size(); } + size_t action_context::num_unclosed() const { + size_t num = 0; + + for (const auto& a : m_action_blocks) { + if (a.is_open) { + num++; + } + } + + return num; + } + const std::vector& action_context::get_blocks() const { return m_action_blocks; } diff --git a/src/tags/dispatch.cpp b/src/tags/dispatch.cpp index 222df632..66c49ae4 100644 --- a/src/tags/dispatch.cpp +++ b/src/tags/dispatch.cpp @@ -100,14 +100,19 @@ namespace tags { } } + /* + * After rendering, we need to tell the action context about the position + * of the alignment blocks so that it can do intersection tests. + */ for (auto a : {alignment::LEFT, alignment::CENTER, alignment::RIGHT}) { m_action_ctxt.set_alignmnent_start(a, renderer.get_alignment_start(a)); } - // TODO handle unclosed action tags in ctxt - /* if (!m_actions.empty()) { */ - /* throw runtime_error(to_string(m_actions.size()) + " unclosed action block(s)"); */ - /* } */ + auto num_unclosed = m_action_ctxt.num_unclosed(); + + if (num_unclosed != 0) { + throw runtime_error(to_string(num_unclosed) + " unclosed action block(s)"); + } } /** diff --git a/tests/unit_tests/tags/action_context.cpp b/tests/unit_tests/tags/action_context.cpp index a5be8414..7d1bec34 100644 --- a/tests/unit_tests/tags/action_context.cpp +++ b/tests/unit_tests/tags/action_context.cpp @@ -46,6 +46,7 @@ TEST(ActionCtxtTest, closing) { EXPECT_EQ(make_pair(id2, mousebtn::RIGHT), ctxt.action_close(mousebtn::NONE, alignment::CENTER, 1)); EXPECT_EQ(4, ctxt.num_actions()); + EXPECT_EQ(0, ctxt.num_unclosed()); } TEST(ActionCtxtTest, overlapping) { @@ -76,6 +77,7 @@ TEST(ActionCtxtTest, overlapping) { EXPECT_EQ(id3, actions[mousebtn::RIGHT]); EXPECT_EQ(3, ctxt.num_actions()); + EXPECT_EQ(0, ctxt.num_unclosed()); } TEST(ActionCtxtTest, stacking) { @@ -109,6 +111,7 @@ TEST(ActionCtxtTest, stacking) { EXPECT_EQ(id1, ctxt.has_action(mousebtn::LEFT, 7)); EXPECT_EQ(3, ctxt.num_actions()); + EXPECT_EQ(0, ctxt.num_unclosed()); } TEST(ActionCtxtTest, cmd) {