ProjectTextRPG/TextRPG/Source/Core/Subsystems/GameInputSystem.h

80 lines
1.4 KiB
C++

#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 <typename T>
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<std::streamsize>::max(), '\n');
std::cin.clear();
}
template <typename T>
InputSession operator>>(T& RHS)
{
InputSession session(this);
session >> RHS;
return session;
}
template <typename T>
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 <typename T>
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;
}