[Add] I don't want to talk about it.

-- Should be pretty usable now.
This commit is contained in:
Rtch90 2012-09-02 23:57:19 +01:00
parent 48d85b777f
commit f182e6749c
8 changed files with 415 additions and 2 deletions

View File

@ -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 \

View File

@ -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; }

View 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.

View 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.

View 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.

View File

@ -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.

View 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.

View 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.