#pragma once #include "Data/Literals/Literals.h" class GameInputSystem; class InputSession { public: InputSession(GameInputSystem* InSystem) : InputSystem(InSystem) {} InputSession(InputSession&& Other) noexcept : InputSystem(Other.InputSystem) {} ~InputSession(); template InputSession& operator>>(T& RHS); explicit operator bool() const; private: GameInputSystem* InputSystem; }; class GameInputSystem { public: GameInputSystem() : bFailed(false) {} ~GameInputSystem() = default; bool IsFailed() const { return bFailed; } void ApplyFail() { bFailed = true; } void Reset() { bFailed = false; } void ClearBuffer() { std::cin.ignore(std::numeric_limits::max(), '\n'); std::cin.clear(); } template InputSession operator>>(T& RHS) { InputSession session(this); session >> RHS; return session; } template GameInputSystem& operator<<(const T& RHS) { std::cout << RHS; return *this; } private: bool bFailed; }; inline InputSession::~InputSession() { InputSystem->ClearBuffer(); } inline InputSession::operator bool() const { return !InputSystem->IsFailed(); } template InputSession& InputSession::operator>>(T& RHS) { if (InputSystem->IsFailed()) return *this; std::cin >> RHS; if (std::cin.fail()) { std::cout << Game::Common::ErrorInput << "\n"; InputSystem->ClearBuffer(); InputSystem->ApplyFail(); } return *this; }