Clean up InputHandler_SextetStream (#1985)
Before, this ended up calling a virtual method in the constructor, which C++ does not allow, and I got weird crashes. This removes a lot of unused code and gets rid of unnecessary abstractions.
This commit is contained in:
@@ -33,22 +33,44 @@ namespace
|
||||
{
|
||||
class LineReader
|
||||
{
|
||||
protected:
|
||||
private:
|
||||
// The buffer size isn't critical; the RString will simply be
|
||||
// extended until the line is done.
|
||||
static const size_t BUFFER_SIZE = 64;
|
||||
char buffer[BUFFER_SIZE];
|
||||
std::FILE * file;
|
||||
int timeout_ms;
|
||||
|
||||
public:
|
||||
LineReader()
|
||||
LineReader(const RString& filename)
|
||||
{
|
||||
timeout_ms = DEFAULT_TIMEOUT_MS;
|
||||
|
||||
LOG->Info("Starting InputHandler_SextetStreamFromFile from std::FILE with filename '%s'",
|
||||
filename.c_str());
|
||||
file = std::fopen(filename.c_str(), "rb");
|
||||
|
||||
if(file == nullptr) {
|
||||
LOG->Warn("Error opening file '%s' for input (cstdio): %s", filename.c_str(),
|
||||
std::strerror(errno));
|
||||
}
|
||||
else {
|
||||
LOG->Info("File opened");
|
||||
// Disable buffering on the file
|
||||
std::setbuf(file, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~LineReader()
|
||||
~LineReader()
|
||||
{
|
||||
if(file != nullptr) {
|
||||
std::fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool IsValid()
|
||||
bool IsValid()
|
||||
{
|
||||
return false;
|
||||
return file != nullptr;
|
||||
}
|
||||
|
||||
// Ideally, this method should return if timeout_ms passes
|
||||
@@ -74,7 +96,26 @@ namespace
|
||||
// false (line undefined) if there is an error or EOF condition,
|
||||
// true (line = next line from stream) if a whole line is available,
|
||||
// true (line = "") if no error but still waiting for next line.
|
||||
virtual bool ReadLine(RString& line) = 0;
|
||||
bool ReadLine(RString& line)
|
||||
{
|
||||
bool afterFirst = false;
|
||||
size_t len;
|
||||
|
||||
line = "";
|
||||
|
||||
if(file != nullptr) {
|
||||
while(fgets(buffer, BUFFER_SIZE, file) != nullptr) {
|
||||
afterFirst = true;
|
||||
line += buffer;
|
||||
len = line.length();
|
||||
if(len > 0 && line[len - 1] == 0xA) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return afterFirst;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -82,6 +123,7 @@ class InputHandler_SextetStream::Impl
|
||||
{
|
||||
private:
|
||||
InputHandler_SextetStream * handler;
|
||||
RString filename;
|
||||
|
||||
protected:
|
||||
void ButtonPressed(const DeviceInput& di)
|
||||
@@ -94,12 +136,6 @@ class InputHandler_SextetStream::Impl
|
||||
RageThread inputThread;
|
||||
bool continueInputThread;
|
||||
|
||||
// Construct and return the LineReader that makes sense for this
|
||||
// object. getLineReader() calls this; if the returned object claims
|
||||
// it is valid, it is returned. Otherwise, it is destroyed and nullptr
|
||||
// is returned.
|
||||
virtual LineReader * getUnvalidatedLineReader() = 0;
|
||||
|
||||
inline void clearStateBuffer()
|
||||
{
|
||||
memset(stateBuffer, 0, STATE_BUFFER_SIZE);
|
||||
@@ -114,30 +150,29 @@ class InputHandler_SextetStream::Impl
|
||||
|
||||
LineReader * getLineReader()
|
||||
{
|
||||
LineReader * linereader = getUnvalidatedLineReader();
|
||||
if(linereader != nullptr) {
|
||||
if(!linereader->IsValid()) {
|
||||
delete linereader;
|
||||
linereader = nullptr;
|
||||
}
|
||||
LineReader * linereader = new LineReader(filename);
|
||||
if(!linereader->IsValid()) {
|
||||
delete linereader;
|
||||
linereader = nullptr;
|
||||
}
|
||||
return linereader;
|
||||
}
|
||||
|
||||
public:
|
||||
Impl(InputHandler_SextetStream * _this)
|
||||
Impl(InputHandler_SextetStream * _this, const RString& filename)
|
||||
{
|
||||
LOG->Info("Number of button states supported by current InputHandler_SextetStream: %u",
|
||||
(unsigned)BUTTON_COUNT);
|
||||
continueInputThread = false;
|
||||
timeout_ms = DEFAULT_TIMEOUT_MS;
|
||||
|
||||
this->filename = filename;
|
||||
handler = _this;
|
||||
clearStateBuffer();
|
||||
createThread();
|
||||
}
|
||||
|
||||
virtual ~Impl()
|
||||
~Impl()
|
||||
{
|
||||
if(inputThread.IsCreated()) {
|
||||
continueInputThread = false;
|
||||
@@ -145,7 +180,7 @@ class InputHandler_SextetStream::Impl
|
||||
}
|
||||
}
|
||||
|
||||
virtual void GetDevicesAndDescriptions(vector<InputDeviceInfo>& vDevicesOut)
|
||||
void GetDevicesAndDescriptions(vector<InputDeviceInfo>& vDevicesOut)
|
||||
{
|
||||
vDevicesOut.push_back(InputDeviceInfo(FIRST_DEVICE, "SextetStream"));
|
||||
}
|
||||
@@ -287,137 +322,9 @@ REGISTER_INPUT_HANDLER_CLASS (SextetStreamFromFile);
|
||||
#endif
|
||||
static Preference<RString> g_sSextetStreamInputFilename("SextetStreamInputFilename", DEFAULT_INPUT_FILENAME);
|
||||
|
||||
namespace
|
||||
{
|
||||
class StdCFileLineReader: public LineReader
|
||||
{
|
||||
private:
|
||||
// The buffer size isn't critical; the RString will simply be
|
||||
// extended until the line is done.
|
||||
static const size_t BUFFER_SIZE = 64;
|
||||
char buffer[BUFFER_SIZE];
|
||||
protected:
|
||||
std::FILE * file;
|
||||
|
||||
public:
|
||||
StdCFileLineReader(std::FILE * file)
|
||||
{
|
||||
LOG->Info("Starting InputHandler_SextetStreamFromFile from open std::FILE");
|
||||
this->file = file;
|
||||
}
|
||||
|
||||
StdCFileLineReader(const RString& filename)
|
||||
{
|
||||
LOG->Info("Starting InputHandler_SextetStreamFromFile from std::FILE with filename '%s'",
|
||||
filename.c_str());
|
||||
file = std::fopen(filename.c_str(), "rb");
|
||||
|
||||
if(file == nullptr) {
|
||||
LOG->Warn("Error opening file '%s' for input (cstdio): %s", filename.c_str(),
|
||||
std::strerror(errno));
|
||||
}
|
||||
else {
|
||||
LOG->Info("File opened");
|
||||
// Disable buffering on the file
|
||||
std::setbuf(file, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
~StdCFileLineReader()
|
||||
{
|
||||
if(file != nullptr) {
|
||||
std::fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool IsValid()
|
||||
{
|
||||
return file != nullptr;
|
||||
}
|
||||
|
||||
virtual bool ReadLine(RString& line)
|
||||
{
|
||||
bool afterFirst = false;
|
||||
size_t len;
|
||||
|
||||
line = "";
|
||||
|
||||
if(file != nullptr) {
|
||||
while(fgets(buffer, BUFFER_SIZE, file) != nullptr) {
|
||||
afterFirst = true;
|
||||
line += buffer;
|
||||
len = line.length();
|
||||
if(len > 0 && line[len - 1] == 0xA) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return afterFirst;
|
||||
}
|
||||
};
|
||||
|
||||
class StdCFileHandleImpl: public InputHandler_SextetStream::Impl
|
||||
{
|
||||
protected:
|
||||
std::FILE * file;
|
||||
|
||||
public:
|
||||
StdCFileHandleImpl(InputHandler_SextetStreamFromFile * handler, std::FILE * file) :
|
||||
InputHandler_SextetStream::Impl(handler)
|
||||
{
|
||||
this->file = file;
|
||||
}
|
||||
|
||||
virtual LineReader * getUnvalidatedLineReader()
|
||||
{
|
||||
return new StdCFileLineReader(this->file);
|
||||
}
|
||||
|
||||
virtual ~StdCFileHandleImpl()
|
||||
{
|
||||
// line reader dtor will close file for us
|
||||
}
|
||||
};
|
||||
|
||||
class StdCFileNameImpl: public InputHandler_SextetStream::Impl
|
||||
{
|
||||
protected:
|
||||
RString filename;
|
||||
|
||||
public:
|
||||
StdCFileNameImpl(InputHandler_SextetStreamFromFile * handler, const RString& filename) :
|
||||
InputHandler_SextetStream::Impl(handler)
|
||||
{
|
||||
this->filename = filename;
|
||||
}
|
||||
|
||||
virtual LineReader * getUnvalidatedLineReader()
|
||||
{
|
||||
return new StdCFileLineReader(filename);
|
||||
}
|
||||
|
||||
virtual ~StdCFileNameImpl()
|
||||
{
|
||||
// Nothing to destroy
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
InputHandler_SextetStreamFromFile::InputHandler_SextetStreamFromFile(FILE * file)
|
||||
{
|
||||
_impl = new StdCFileHandleImpl(this, file);
|
||||
}
|
||||
|
||||
InputHandler_SextetStreamFromFile::InputHandler_SextetStreamFromFile(const RString& filename)
|
||||
{
|
||||
_impl = new StdCFileNameImpl(this, filename);
|
||||
}
|
||||
|
||||
InputHandler_SextetStreamFromFile::InputHandler_SextetStreamFromFile()
|
||||
{
|
||||
_impl = new StdCFileNameImpl(this, g_sSextetStreamInputFilename);
|
||||
_impl = new Impl(this, g_sSextetStreamInputFilename);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -8,9 +8,8 @@ class InputHandler_SextetStream: public InputHandler
|
||||
{
|
||||
public:
|
||||
InputHandler_SextetStream();
|
||||
virtual ~InputHandler_SextetStream();
|
||||
//virtual void Update();
|
||||
virtual void GetDevicesAndDescriptions(vector<InputDeviceInfo>& vDevicesOut);
|
||||
~InputHandler_SextetStream();
|
||||
void GetDevicesAndDescriptions(vector<InputDeviceInfo>& vDevicesOut);
|
||||
|
||||
public:
|
||||
class Impl;
|
||||
@@ -36,12 +35,6 @@ public:
|
||||
// couldn't get RageFile to work here, possibly because I haven't
|
||||
// determined how to disable buffering on an input file.)
|
||||
InputHandler_SextetStreamFromFile();
|
||||
InputHandler_SextetStreamFromFile(const RString& filename);
|
||||
|
||||
// The file object passed here must already be open and buffering should
|
||||
// be disabled. The file object will be closed in the destructor.
|
||||
InputHandler_SextetStreamFromFile(std::FILE * file);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user