#pragma once #include #include #include #include #include #include namespace boo { class IWindow; enum class EModifierKey; enum class ESpecialKey; struct IGraphicsCommandQueue; } // namespace boo namespace hecl { class CVarManager; class CVar; struct SConsoleCommand { enum class ECommandFlags { Normal = 0, Cheat = (1 << 0), Developer = (1 << 1) }; std::string m_displayName; std::string m_helpString; std::string m_usage; std::function&)> m_func; ECommandFlags m_flags; }; ENABLE_BITWISE_ENUM(SConsoleCommand::ECommandFlags) class Console { friend class LogVisorAdapter; struct LogVisorAdapter : logvisor::ILogger { Console* m_con; LogVisorAdapter(Console* con) : logvisor::ILogger(log_typeid(LogVisorAdapter)), m_con(con) {} ~LogVisorAdapter() override = default; void report(const char* modName, logvisor::Level severity, fmt::string_view format, fmt::format_args args) override; void report(const char* modName, logvisor::Level severity, fmt::wstring_view format, fmt::wformat_args args) override; void reportSource(const char* modName, logvisor::Level severity, const char* file, unsigned linenum, fmt::string_view format, fmt::format_args args) override; void reportSource(const char* modName, logvisor::Level severity, const char* file, unsigned linenum, fmt::wstring_view format, fmt::wformat_args args) override; }; public: static Console* m_instance; enum class Level { Info, /**< Non-error informative message */ Warning, /**< Non-error warning message */ Error, /**< Recoverable error message */ Fatal /**< Non-recoverable error message (Kept for compatibility with logvisor) */ }; enum class State { Closed, Closing, Opened, Opening }; private: CVarManager* m_cvarMgr = nullptr; boo::IWindow* m_window = nullptr; std::unordered_map m_commands; std::vector> m_log; int m_logOffset = 0; std::string m_commandString; std::vector m_commandHistory; int m_cursorPosition = -1; int m_currentCommand = -1; size_t m_maxLines = 0; bool m_overwrite : 1; bool m_cursorAtEnd : 1; State m_state = State::Closed; CVar* m_conSpeed; CVar* m_conHeight; float m_cachedConSpeed; float m_cachedConHeight; bool m_showCursor = true; float m_cursorTime = 0.f; public: Console(CVarManager*); void registerCommand(std::string_view name, std::string_view helpText, std::string_view usage, std::function&)>&& func, SConsoleCommand::ECommandFlags cmdFlags = SConsoleCommand::ECommandFlags::Normal); void unregisterCommand(std::string_view name); void executeString(const std::string& strToExec); void help(Console* con, const std::vector& args); void listCommands(Console* con, const std::vector& args); bool commandExists(std::string_view cmd) const; void vreport(Level level, fmt::string_view format, fmt::format_args args); template > void report(Level level, const S& format, Args&&... args) { vreport(level, fmt::to_string_view(format), fmt::basic_format_args>( fmt::make_args_checked(format, args...))); } void init(boo::IWindow* ctx); void proc(); void draw(boo::IGraphicsCommandQueue* gfxQ); void handleCharCode(unsigned long chr, boo::EModifierKey mod, bool repeat); void handleSpecialKeyDown(boo::ESpecialKey sp, boo::EModifierKey mod, bool repeat); void handleSpecialKeyUp(boo::ESpecialKey sp, boo::EModifierKey mod); void dumpLog(); static Console* instance(); static void RegisterLogger(Console* con); bool isOpen() const { return m_state == State::Opened; } }; } // namespace hecl