ungroup/ungroup_game

View on GitHub
src/server/rendering/TerminalRenderingController.cpp

Summary

Maintainability
Test Coverage
#include "TerminalRenderingController.hpp"

TerminalRenderingController::TerminalRenderingController(uint32_t tcp_port) :
    m_termboxTextOutputArea(10) {
    // termbox setup
    int ret = tb_init();
    if (ret) {
        fprintf(stderr, "tb_init() failed with error code %d\n", ret);
    }

    m_termboxPlayerTable.addColumn("Player ID");
    m_termboxPlayerTable.addColumn("UPS");
    m_termboxPlayerTable.addColumn("Avg Drift");
    m_termboxPlayerTable.addColumn("Direction");
    m_termboxPlayerTable.addColumn("Joinable");
    m_termboxServerStatsTable.addColumn("Steps per second");
    m_termboxServerStatsTable.addColumn("Updates per second");
    m_termboxServerStatsTable.addColumn("Broadcasts per second");
    m_termboxServerStatsTable.addColumn("Tick");
    m_termboxTextOutputArea.addTitle("Ungroup Server Output");
    m_termboxTextOutputArea.addLine("Listening on TCP Port: " + std::to_string(tcp_port));
}

void TerminalRenderingController::preUpdate() {
    // collect inputs from terminal window
    struct tb_event ev;
    // non-blocking insta-peek of input
    if (tb_peek_event(&ev, 0) > 0) {
        switch (ev.type) {
            case TB_EVENT_KEY:
                switch (ev.key) {
                    case TB_KEY_ESC:
                        if (!m_shutting_down) {
                            tb_shutdown();
                            exit(0);
                        }
                        m_shutting_down = true;
                        break;
                }
                break;
        }
    }
}

void TerminalRenderingController::update() {
    // noop
}

void TerminalRenderingController::postUpdate() {
    // noop
}

void TerminalRenderingController::addWinner(const std::string& winner_player_id) {
    m_termboxTextOutputArea.addLine("We have a winner!");
    m_termboxTextOutputArea.addLine("Congratulations: " + winner_player_id);
}

void TerminalRenderingController::draw(
    std::unordered_map<uint32_t, float> player_ids_to_updates_rates,
    std::unordered_map<uint32_t, float> player_ids_to_avg_tick_drifts,
    float broadcast_game_state_rate, std::vector<PlayerUpdate> player_updates, float game_step_rate,
    float game_update_rate, uint32_t tick) {
    // clear out internal termbox screen buffer
    tb_clear();

    // output area will be half of vertical space
    m_termboxTextOutputArea.setMaxHeight(tb_height() / 2);
    m_termboxTextOutputArea.setLines();

    // server stats will render halfway down the screen
    m_termboxServerStatsTable.setOrigin(0, (tb_height() / 2) + 1);
    m_termboxServerStatsTable.setColHeaders();
    m_termboxServerStatsTable.setCell(std::to_string(game_step_rate), 1, 0);
    m_termboxServerStatsTable.setCell(std::to_string(game_update_rate), 1, 1);
    m_termboxServerStatsTable.setCell(std::to_string(broadcast_game_state_rate), 1, 2);
    m_termboxServerStatsTable.setCell(std::to_string(tick), 1, 3);

    // player table will be on right half of screen
    m_termboxPlayerTable.setOrigin(tb_width() / 2, 0);
    m_termboxPlayerTable.setColHeaders();

    uint32_t curr_row = 1;
    for (auto pu : player_updates) {
        if (pu.is_active) {
            uint32_t curr_col = 0;
            // update player ID column
            auto player_id = std::to_string(pu.player_id);
            m_termboxPlayerTable.setCell(player_id, curr_row, curr_col++);

            // update UPS column
            if (player_ids_to_updates_rates.count(pu.player_id) != 0) {
                float rate = player_ids_to_updates_rates[pu.player_id];
                // ups = updates per sec
                auto ups = std::to_string(rate);
                ups.resize(2);
                m_termboxPlayerTable.setCell(ups, curr_row, curr_col++);
            }

            // update drift column
            if (player_ids_to_avg_tick_drifts.count(pu.player_id) != 0) {
                float rate = player_ids_to_avg_tick_drifts[pu.player_id];
                auto drift = std::to_string(rate);
                drift.resize(2);
                m_termboxPlayerTable.setCell(drift, curr_row, curr_col++);
            }

            // update direction column
            auto x_dir = std::to_string(pu.direction.x);
            x_dir.resize(4);
            auto y_dir = std::to_string(pu.direction.y);
            y_dir.resize(4);
            auto player_dir = x_dir + ", " + y_dir;
            m_termboxPlayerTable.setCell(player_dir, curr_row, curr_col++);

            // update joinable column
            auto joinable = std::to_string(pu.joinable);
            m_termboxPlayerTable.setCell(joinable, curr_row, curr_col);

            curr_row++;
        }
    }
    tb_present();
}