← source index

src/Commands.h

98 lines  ·  2.9 K  ·  cpp
#pragma once
#include "../Include.h"
#include "../Helper.h"
#include "OrderBook.h"
#include "Log.h"
#include "WebSocket.h"
#include "OrderEntryItem.h"
#include <ncurses.h>
#include <chrono>

#include <nlohmann/json.hpp>
#include <boost/algorithm/string.hpp>

enum class CommandInstructions : uint8_t
{
    HELP,
    CONNECT,
    SHOW,
    SET_DEPTH,
    QUIT,

    __NONE__,
    __LAST__
};

class Commands
{
public:
    Commands();

    std::tuple<bool, std::string, std::string, std::vector<std::string>, std::string> parseCommand(const std::string&, bool isFromCmd = false);
    std::tuple<LogStatus, std::string, CommandInstructions> runCommand(const std::string&, const std::vector<std::string>&, const std::string&);

private:
    void connectionHandler(const std::vector<std::string>&);
    void geminiMarketDataFeedHandler(std::vector<std::string>, int);
    void geminiMarketDataFeedHandlerSubscription(std::vector<std::string>, int);

private:
    WINDOW* mOrderBookDisplay;
    WINDOW* mAppCmdDisplay;
    WINDOW* mOutputDisplay;

    struct DisplayData
    {
        //Setting up reference display sizes
        int wWinMax = 140;
        int hWinMax = 25;
        int hOrdBook = hWinMax * 0.8;
        int wOrdBook = wWinMax;
        int hAppCmd = 3;
        int wAppCmd = wWinMax;
        int hOutput = hWinMax;
        int wOutput = wWinMax;

        int yOrdBook = 0;
        int xOrdBook = 0;
        int yAppCmd = hOrdBook;
        int xAppCmd = 0;
        int yOutput = yAppCmd + hAppCmd;
        int xOutput = 0;
        
        unsigned int displayClockTriggerDelay = 400;
        uint8_t maxDisplayCmdInput = 80;
        uint8_t maxCommandHistory = 50;
        uint8_t maxSubsCount = 6;
        uint8_t currentSubsCount = 0;
        uint8_t maxSubsCountPerRow = 3;
        uint8_t orderBookDepth = 5;
    } mDisplayData;

    Helper::LRUCache mLRUCache;
    WebSocket mWebSock;
    int mActiveWebSocId;

    //Aligning to avoid false sharing
    alignas(CACHE_LINE_SYS_SIZE) std::atomic<bool> mIsThreadRunning;
    alignas(CACHE_LINE_SYS_SIZE) std::atomic<bool> mIsAppRunning;
    alignas(CACHE_LINE_SYS_SIZE) std::atomic<int> mMsgCountPerSec;
    std::atomic<long long> mMsgCountTotal;
    std::atomic<long long> mWriterTime; //long long is already 64 bits
    std::atomic<long long> mMaxWriterMs;
    std::atomic<long long> mAvgWriterMs;
    std::atomic<long long> mAvgCounter;
    std::atomic<bool> mDisableReaderThread;
#if defined ENABLE_ATOMIC_WAITFREE
    Helper::WaitFreeSPSCQueue<OrderEntryItem> mSPSCQueue;
#endif

    std::map<std::string, CommandInstructions> mComMap;
    std::list<std::string> mCommandHistory;
    std::vector<std::pair<std::vector<std::string>, std::string>> mComLookup{(uint8_t) CommandInstructions::__LAST__ - 1};

    Log& mLog = Log::getInstance();

    std::unordered_map<std::string, std::shared_ptr<OrderBook>> mOrderBookMap;
    std::mutex mOrderBookMapMtx;
};