[Add] I don't want to talk about it.
-- Should be pretty usable now.
This commit is contained in:
parent
48d85b777f
commit
f182e6749c
@ -43,6 +43,8 @@ HEADERS += ../src/Actor/Player.h \
|
|||||||
../src/System/Filesystem/IFileList.h \
|
../src/System/Filesystem/IFileList.h \
|
||||||
../src/System/Filesystem/IFilePackage.h \
|
../src/System/Filesystem/IFilePackage.h \
|
||||||
../src/System/Filesystem/FileList.h \
|
../src/System/Filesystem/FileList.h \
|
||||||
|
../src/System/Filesystem/InputFileStream.h \
|
||||||
|
../src/System/Filesystem/FilePackageManager.h \
|
||||||
../src/Texture/Texture.h \
|
../src/Texture/Texture.h \
|
||||||
../src/Sound/Music.h \
|
../src/Sound/Music.h \
|
||||||
../src/TMXParser/base64.h \
|
../src/TMXParser/base64.h \
|
||||||
@ -95,6 +97,8 @@ SOURCES += ../src/Actor/Player.cpp \
|
|||||||
../src/System/Debug.cpp \
|
../src/System/Debug.cpp \
|
||||||
../src/System/Filesystem/InputStream.cpp \
|
../src/System/Filesystem/InputStream.cpp \
|
||||||
../src/System/Filesystem/FileList.cpp \
|
../src/System/Filesystem/FileList.cpp \
|
||||||
|
../src/System/Filesystem/InputFileStream.cpp \
|
||||||
|
../src/System/Filesystem/FilePackageManager.cpp \
|
||||||
../src/Texture/Texture.cpp \
|
../src/Texture/Texture.cpp \
|
||||||
../src/Sound/Music.cpp \
|
../src/Sound/Music.cpp \
|
||||||
../src/Actor/NPC.cpp \
|
../src/Actor/NPC.cpp \
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
namespace saracraft {
|
namespace saracraft {
|
||||||
namespace filesystem {
|
namespace filesystem {
|
||||||
|
|
||||||
struct EmptyBuffer: public IINputStreamBuffer {
|
struct EmptyBuffer: public IInputStreamBuffer {
|
||||||
unsigned char PopByte(void) { return 0; }
|
unsigned char PopByte(void) { return 0; }
|
||||||
bool IsEof(void) const { return true; }
|
bool IsEof(void) const { return true; }
|
||||||
int GetSize(void) const { return 0; }
|
int GetSize(void) const { return 0; }
|
||||||
|
119
src/System/Filesystem/FileInputStream.cpp
Normal file
119
src/System/Filesystem/FileInputStream.cpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
#include <fstream>
|
||||||
|
#include "../Debug.h"
|
||||||
|
#include "InputFileStream.h"
|
||||||
|
|
||||||
|
namespace saracraft {
|
||||||
|
namespace filesystem {
|
||||||
|
|
||||||
|
struct InputFileStreamBufferData {
|
||||||
|
FILE* fp;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
InputFileStreamBufferData(const std::string filename) : fp(0), size(0) {
|
||||||
|
fp = fopen(filename.c_str(), "rb");
|
||||||
|
|
||||||
|
#ifdef __UNIX__
|
||||||
|
// Another ugly as hell case sensitive hack.
|
||||||
|
// if anyone finds a nice way to handle this. Please implement it. -- Allanis
|
||||||
|
if(!fp) {
|
||||||
|
std::string filename = filename;
|
||||||
|
for(unsigned int i = 0; i < filename.size(); i++) {
|
||||||
|
if(isupper(filename[i]))
|
||||||
|
filename[i] = tolower(filename[i]);
|
||||||
|
else if(filename[i] == '\\')
|
||||||
|
filename[i] = '/';
|
||||||
|
}
|
||||||
|
fp = fopen(filename.c_str(), "rb");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(fp) {
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
size = ftell(fp);
|
||||||
|
fseek(fp, 0, SEEK_SET);
|
||||||
|
}
|
||||||
|
if(!size)
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
~InputFileStreamBufferData(void) {
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Close(void) {
|
||||||
|
if(fp) {
|
||||||
|
fclose(fp);
|
||||||
|
fp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
InputFileStreamBuffer::~InputFileStreamBuffer(void) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char InputFileStreamBuffer::PopByte(void) {
|
||||||
|
char byte = 0;
|
||||||
|
if(_data->fp) {
|
||||||
|
int input = fgetc(_data->fp);
|
||||||
|
if(input == EOF)
|
||||||
|
_data->Close();
|
||||||
|
else
|
||||||
|
byte = (char)input;
|
||||||
|
}
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputFileStreamBuffer::IsEof(void) const {
|
||||||
|
if(!_data->fp)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int InputFileStreamBuffer::GetSize(void) const {
|
||||||
|
if(!_data->fp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// This could cause maybe about a 2GB limimitation to file size
|
||||||
|
// by casting to int. Feel free to FIXME.
|
||||||
|
// -- Allanis
|
||||||
|
return int(_data->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputFileStreamBuffer::PopBytes(char* buffer, int bytes) {
|
||||||
|
if(!_data->fp) {
|
||||||
|
for(int i = 0; i < bytes; ++i)
|
||||||
|
buffer[i] = 0;
|
||||||
|
} else {
|
||||||
|
//_data->stream.read(buffer, bytes);
|
||||||
|
if(fread(buffer, 1, bytes, _data->fp) != (unsigned)bytes)
|
||||||
|
_data->Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK: ffs. This is needed to get some sense into the input stream error reporting.
|
||||||
|
//bool input_file_stream_no_nonexisting_error_message = false;
|
||||||
|
|
||||||
|
//void SetInputStreamErrorReporting(bool logNonExisting) {
|
||||||
|
// input_file_stream_no_nonexisting_error_message = !logNonExisting;
|
||||||
|
//}
|
||||||
|
|
||||||
|
InputStream CreateInputFileStream(const std::string& filename) {
|
||||||
|
|
||||||
|
InputStream inputStream;
|
||||||
|
boost::shared_ptr<InputFileStreamBuffer> inputBuffer(new InputBuffer(filename));
|
||||||
|
// Eh.. No.
|
||||||
|
// TODO: Would need a seperate error check, eof is not the same as the file does not exist..
|
||||||
|
// This would just spam error messages. We don't want that.
|
||||||
|
/*if(!inputBuffer->IsEof()) {
|
||||||
|
if(!input_file_stream_no_nonexisting_error_message) {
|
||||||
|
Debug->logger("CreateInputFileStream - File \"%s\"does not exist or is zero length.", filename.c_str());
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
inputStream.SetBuffer(inputBuffer);
|
||||||
|
return inputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Namespace filesystem.
|
||||||
|
} // Namespace saracraft.
|
||||||
|
|
106
src/System/Filesystem/FilePackageManager.cpp
Normal file
106
src/System/Filesystem/FilePackageManager.cpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#include <map>
|
||||||
|
#include "../Debug.h"
|
||||||
|
#include "FilePackageManager.h"
|
||||||
|
#include "EmptyBuffer.h"
|
||||||
|
#include "FileList.h"
|
||||||
|
|
||||||
|
// HACK: This is not a good dependancy for error reporting.
|
||||||
|
// We are going to use it anyway though.
|
||||||
|
#include "InputFileStream.h"
|
||||||
|
|
||||||
|
namespace saracraft {
|
||||||
|
namespace filesystem {
|
||||||
|
namespace {
|
||||||
|
typedef std::multimap<int, boost::shared_ptr<IFilePackage> > PackageMap;
|
||||||
|
FilePackageManager instance;
|
||||||
|
FilePackageManager* instancePtr = 0;
|
||||||
|
} // Unamed namespace.
|
||||||
|
|
||||||
|
struct FilePackageManagerData {
|
||||||
|
PackageMap packages;
|
||||||
|
bool logNonExisting;
|
||||||
|
|
||||||
|
FilePackageManagerData(void) : logNonExisting(true) {}
|
||||||
|
|
||||||
|
InputStream GetFile(std::string filename) {
|
||||||
|
for(unsigned int i = 0; i < filename.size(); ++i) {
|
||||||
|
if(filename[i] == '\\')
|
||||||
|
filename[i] = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
for(PackageMap::reverse_iterator it = packages.rbegin(); it != packages.rend(); ++it) {
|
||||||
|
InputStream result = it->second->GetFile(filename);
|
||||||
|
if(!result.IsEof())
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a bit of a hack.
|
||||||
|
// Fix all data to use only lowercase letters if you
|
||||||
|
// want it to work right. But you know me and upercase characters. --Allanis
|
||||||
|
for(unsigned int i = 0; i < filename.size(); ++i) {
|
||||||
|
// Not found try again in lowercase..
|
||||||
|
if(isupper(filename[i]))
|
||||||
|
filename[i] = tolower(filename[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing has been found.
|
||||||
|
if(logNonExisting) {
|
||||||
|
Debug::logger->message("FilePackageManager::GetFile - File: \"%s\" does not exist or is zero in length!", filename.c_str());
|
||||||
|
}
|
||||||
|
InputStream inputStream;
|
||||||
|
boost::shared_ptr<EmptyBuffer> inputBuffer(new EmptyBuffer());
|
||||||
|
|
||||||
|
inputStream.SetBuffer(inputBuffer);
|
||||||
|
return inputStream;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
FilePackageManager::FilePackageManager(void) {
|
||||||
|
boost::scoped_ptr<FilePackageManagerData> tempData(new FilePackageManagerData());
|
||||||
|
_data.swap(tempData);
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePackageManager::~FilePackageManager(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilePackageManager::AddPackage(boost::shared_ptr<IFilePackage> filePackage, int priority) {
|
||||||
|
std::pair<int, boost::shared_ptr<IFilePackage> > value(priority, filePackage);
|
||||||
|
_data->packages.insert(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<IFileList> FilePackageManager::FindFiles(const std::string& dir, const std::string& extension, bool caseSensitive) {
|
||||||
|
boost::shared_ptr<IFileList> result(new FileList());
|
||||||
|
result->SetCaseSensitivity(caseSensitive);
|
||||||
|
|
||||||
|
for(PackageMap::iterator it = _data->packages.begin(); it != _data->packages.end(); ++it)
|
||||||
|
it->second->FindFiles(dir, extension, *result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream FilePackageManager::GetFile(const std::string& filename) {
|
||||||
|
return _data->GetFile(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilePackageManager::SetInputStreamErrorReporting(bool logNonExisting) {
|
||||||
|
// HACK: This goes directly to the input file stream...
|
||||||
|
_data->logNonExisting = logNonExisting;
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePackageManager& FilePackageManager::GetInstance(void) {
|
||||||
|
if(!instancePtr)
|
||||||
|
instancePtr = &instance;
|
||||||
|
return *instancePtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilePackageManager::SetInstancePtr(FilePackageManager* newInstance) {
|
||||||
|
assert(newInstance);
|
||||||
|
instancePtr = newInstance;
|
||||||
|
|
||||||
|
//FilePackageManager& oldInstance = GetInstance();
|
||||||
|
//oldInstance._data->packages = newInstance->_data->packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Namespace filesystem.
|
||||||
|
} // Namespace saracraft.
|
||||||
|
|
32
src/System/Filesystem/FilePackageManager.h
Normal file
32
src/System/Filesystem/FilePackageManager.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#include "IFilePackage.h"
|
||||||
|
|
||||||
|
namespace saracraft {
|
||||||
|
namespace filesystem {
|
||||||
|
|
||||||
|
class IFileList;
|
||||||
|
struct FilePackageManagerData;
|
||||||
|
|
||||||
|
class FilePackageManager {
|
||||||
|
boost::scoped_ptr<FilePackageManagerData> _data;
|
||||||
|
public:
|
||||||
|
FilePackageManager(void);
|
||||||
|
~FilePackageManager(void);
|
||||||
|
|
||||||
|
void AddPackage(boost::shared_ptr<IFilePackage> filePackae, int priority);
|
||||||
|
boost::shared_ptr<IFileList> FindFiles(const std::string& dir, const std::string& extension, bool caseSensitive = false);
|
||||||
|
InputStream GetFile(const std::string& filename);
|
||||||
|
|
||||||
|
void SetInputStreamErrorReporting(bool logNonExisting);
|
||||||
|
|
||||||
|
static FilePackageManager& GetInstance(void);
|
||||||
|
static void SetInstancePtr(FilePackageManager* instance);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // Namespace filesystem.
|
||||||
|
} // Namespace saracraft.
|
||||||
|
|
@ -10,7 +10,7 @@ public:
|
|||||||
virtual ~IFilePackage(void) {}
|
virtual ~IFilePackage(void) {}
|
||||||
|
|
||||||
virtual void FindFiles(const std::string& dir, const std::string& extension, IFileList& result) = 0;
|
virtual void FindFiles(const std::string& dir, const std::string& extension, IFileList& result) = 0;
|
||||||
virtual InputStream getFile(const std::string& filename) = 0;
|
virtual InputStream GetFile(const std::string& filename) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Namespace filesystem.
|
} // Namespace filesystem.
|
||||||
|
122
src/System/Filesystem/InputFileStream.cpp
Normal file
122
src/System/Filesystem/InputFileStream.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include <fstream>
|
||||||
|
#include "../Debug.h"
|
||||||
|
#include "InputFileStream.h"
|
||||||
|
|
||||||
|
namespace saracraft {
|
||||||
|
namespace filesystem {
|
||||||
|
|
||||||
|
struct InputFileStreamBufferData {
|
||||||
|
FILE* fp;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
InputFileStreamBufferData(const std::string filename) : fp(0), size(0) {
|
||||||
|
fp = fopen(filename.c_str(), "rb");
|
||||||
|
|
||||||
|
#ifdef __UNIX__
|
||||||
|
// Another ugly as hell case sensitive hack.
|
||||||
|
// if anyone finds a nice way to handle this. Please implement it. -- Allanis
|
||||||
|
if(!fp) {
|
||||||
|
std::string filename = filename;
|
||||||
|
for(unsigned int i = 0; i < filename.size(); i++) {
|
||||||
|
if(isupper(filename[i]))
|
||||||
|
filename[i] = tolower(filename[i]);
|
||||||
|
else if(filename[i] == '\\')
|
||||||
|
filename[i] = '/';
|
||||||
|
}
|
||||||
|
fp = fopen(filename.c_str(), "rb");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(fp) {
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
size = ftell(fp);
|
||||||
|
fseek(fp, 0, SEEK_SET);
|
||||||
|
}
|
||||||
|
if(!size)
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
~InputFileStreamBufferData(void) {
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Close(void) {
|
||||||
|
if(fp) {
|
||||||
|
fclose(fp);
|
||||||
|
fp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
InputFileStreamBuffer::~InputFileStreamBuffer(void) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char InputFileStreamBuffer::PopByte(void) {
|
||||||
|
char byte = 0;
|
||||||
|
if(_data->fp) {
|
||||||
|
int input = fgetc(_data->fp);
|
||||||
|
if(input == EOF)
|
||||||
|
_data->Close();
|
||||||
|
else
|
||||||
|
byte = (char)input;
|
||||||
|
}
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputFileStreamBuffer::IsEof(void) const {
|
||||||
|
if(!_data->fp)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int InputFileStreamBuffer::GetSize(void) const {
|
||||||
|
if(!_data->fp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// This could cause maybe about a 2GB limimitation to file size
|
||||||
|
// by casting to int. Feel free to FIXME.
|
||||||
|
// -- Allanis
|
||||||
|
return int(_data->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputFileStreamBuffer::PopBytes(char* buffer, int bytes) {
|
||||||
|
if(!_data->fp) {
|
||||||
|
for(int i = 0; i < bytes; ++i)
|
||||||
|
buffer[i] = 0;
|
||||||
|
} else {
|
||||||
|
//_data->stream.read(buffer, bytes);
|
||||||
|
if(fread(buffer, 1, bytes, _data->fp) != (unsigned)bytes)
|
||||||
|
_data->Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK: ffs. This is needed to get some sense into the input stream error reporting.
|
||||||
|
//bool input_file_stream_no_nonexisting_error_message = false;
|
||||||
|
|
||||||
|
//void SetInputStreamErrorReporting(bool logNonExisting) {
|
||||||
|
// input_file_stream_no_nonexisting_error_message = !logNonExisting;
|
||||||
|
//}
|
||||||
|
|
||||||
|
InputStream CreateInputFileStream(const std::string& filename) {
|
||||||
|
|
||||||
|
// This whole method is pissing me off!!!!!!!!!!
|
||||||
|
//There..
|
||||||
|
|
||||||
|
//InputStream inputStream;
|
||||||
|
//boost::shared_ptr<InputFileStreamBuffer> inputBuffer(new InputFileStreamBuffer(filename));
|
||||||
|
// Eh.. No.
|
||||||
|
// TODO: Would need a seperate error check, eof is not the same as the file does not exist..
|
||||||
|
// This would just spam error messages. We don't want that.
|
||||||
|
/*if(!inputBuffer->IsEof()) {
|
||||||
|
if(!input_file_stream_no_nonexisting_error_message) {
|
||||||
|
Debug->logger("CreateInputFileStream - File \"%s\"does not exist or is zero length.", filename.c_str());
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
//inputStream.SetBuffer(inputBuffer);
|
||||||
|
//return inputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Namespace filesystem.
|
||||||
|
} // Namespace saracraft.
|
||||||
|
|
30
src/System/Filesystem/InputFileStream.h
Normal file
30
src/System/Filesystem/InputFileStream.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// I forgot some code..
|
||||||
|
#pragma once
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
#include "InputStream.h"
|
||||||
|
|
||||||
|
namespace saracraft {
|
||||||
|
namespace filesystem {
|
||||||
|
|
||||||
|
struct InputFileStreamBufferData;
|
||||||
|
|
||||||
|
class InputFileStreamBuffer: public IInputStreamBuffer {
|
||||||
|
boost::scoped_ptr<InputFileStreamBufferData> _data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
InputFileStreamBuffer(const std::string& filename);
|
||||||
|
~InputFileStreamBuffer(void);
|
||||||
|
|
||||||
|
unsigned char PopByte(void);
|
||||||
|
bool IsEof(void) const;
|
||||||
|
int GetSize(void) const;
|
||||||
|
|
||||||
|
void PopBytes(char* buffer, int bytes);
|
||||||
|
};
|
||||||
|
|
||||||
|
InputStream CreateInputFileStream(const std::string& filename);
|
||||||
|
void SetInputStreamErrorReporting(bool logNonExisting);
|
||||||
|
|
||||||
|
} // Namespace filesystem.
|
||||||
|
} // Namespace saracraft.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user