basic resource manager implementation

load/save configurations files in user home
This commit is contained in:
Eduardo Bart 2010-11-21 23:19:20 -02:00
parent d121154932
commit b6f1a18beb
7 changed files with 163 additions and 23 deletions

View File

@ -28,6 +28,7 @@
#include <fstream> #include <fstream>
#include <yaml-cpp/yaml.h> #include <yaml-cpp/yaml.h>
#include "resourcemanager.h"
ConfigManager g_config; ConfigManager g_config;
@ -43,11 +44,16 @@ ConfigManager::~ConfigManager()
bool ConfigManager::load(const std::string& fileName) bool ConfigManager::load(const std::string& fileName)
{ {
std::ifstream fin(fileName.c_str()); m_fileName = fileName;
if(!fin.good())
if(!g_resources.fileExists(fileName))
return false; return false;
m_fileName = fileName; std::string fileContents = g_resources.loadTextFile(fileName);
if(fileContents.size() == 0)
return false;
std::istringstream fin(fileContents);
try { try {
YAML::Parser parser(fin); YAML::Parser parser(fin);
@ -71,16 +77,9 @@ bool ConfigManager::load(const std::string& fileName)
void ConfigManager::save() void ConfigManager::save()
{ {
std::ofstream fout(m_fileName.c_str());
if(!fout.good()) {
error("Failed to save configuration file %s", m_fileName.c_str());
return;
}
YAML::Emitter out; YAML::Emitter out;
out << m_confsMap; out << m_confsMap;
g_resources.saveFile(m_fileName, (const unsigned char*)out.c_str(), out.size());
fout << out.c_str();
} }
void ConfigManager::setValue(const std::string &key, const std::string &value) void ConfigManager::setValue(const std::string &key, const std::string &value)

View File

@ -25,12 +25,13 @@
#include "engine.h" #include "engine.h"
#include "const.h" #include "const.h"
#include "logger.h" #include "logger.h"
#include "configmanager.h"
#include "resourcemanager.h"
#include "platform.h"
#include <csignal> #include <csignal>
#include "configmanager.h"
#include "util.h"
// catches terminate signals to exit nicely /// Catches signals so we can exit nicely
void signal_handler(int sig) void signal_handler(int sig)
{ {
switch(sig) { switch(sig) {
@ -48,7 +49,7 @@ void signal_handler(int sig)
} }
} }
/// Default otclient configurations /// Default configurations
void setDefaultConfigs() void setDefaultConfigs()
{ {
g_config.setValue("width", 640); g_config.setValue("width", 640);
@ -62,7 +63,15 @@ int main(int argc, const char *argv[])
signal(SIGINT, signal_handler); signal(SIGINT, signal_handler);
signal(SIGQUIT, signal_handler); signal(SIGQUIT, signal_handler);
// setup resources
g_resources.init(argv[0]);
if(g_resources.setWriteDir(Platform::getAppUserDir()))
g_resources.addToSearchPath(Platform::getAppUserDir());
// before loading configurations set the default ones
setDefaultConfigs(); setDefaultConfigs();
// load configurations
if(!g_config.load("config.yml")) if(!g_config.load("config.yml"))
notice("Could not read configuration file, default configurations will be used."); notice("Could not read configuration file, default configurations will be used.");
@ -73,6 +82,10 @@ int main(int argc, const char *argv[])
g_engine.run(); g_engine.run();
g_engine.terminate(); g_engine.terminate();
// save configurations before exiting
g_config.save(); g_config.save();
// unload resources
g_resources.terminate();
return 0; return 0;
} }

View File

@ -63,6 +63,9 @@ namespace Platform
void setVsync(bool enable = true); void setVsync(bool enable = true);
/// Swap GL buffers /// Swap GL buffers
void swapBuffers(); void swapBuffers();
/// Get the app user directory, the place to save files configurations files
const char *getAppUserDir();
} }
#endif // PLATFORM_H #endif // PLATFORM_H

View File

@ -23,6 +23,9 @@
#include "resourcemanager.h" #include "resourcemanager.h"
#include "logger.h"
#include <physfs.h>
ResourceManager g_resources; ResourceManager g_resources;
@ -35,3 +38,82 @@ ResourceManager::~ResourceManager()
{ {
} }
void ResourceManager::init(const char *argv0)
{
PHYSFS_init(argv0);
}
void ResourceManager::terminate()
{
PHYSFS_deinit();
}
bool ResourceManager::setWriteDir(const std::string& path)
{
bool ret = (bool)PHYSFS_setWriteDir(path.c_str());
if(!ret)
error("Could not set the path %s as write directory, file write will not work.");
return ret;
}
bool ResourceManager::addToSearchPath(const std::string& path, bool insertInFront)
{
if(!PHYSFS_addToSearchPath(path.c_str(), insertInFront ? 0 : 1)) {
error("Error while adding %s to resources search path: %s", PHYSFS_getLastError());
return false;
}
return true;
}
bool ResourceManager::fileExists(const std::string& filePath)
{
return PHYSFS_exists(filePath.c_str());
}
unsigned char *ResourceManager::loadFile(const std::string& fileName, unsigned int *fileSize)
{
PHYSFS_file *file = PHYSFS_openRead(fileName.c_str());
if(!file) {
error("Failed to load file %s: %s", fileName.c_str(), PHYSFS_getLastError());
*fileSize = 0;
return NULL;
}
*fileSize = PHYSFS_fileLength(file);
unsigned char *buffer = new unsigned char[*fileSize];
PHYSFS_read(file, (void*)buffer, 1, *fileSize);
PHYSFS_close(file);
return buffer;
}
std::string ResourceManager::loadTextFile(const std::string& fileName)
{
std::string text;
unsigned int fileSize;
char *buffer = (char *)loadFile(fileName, &fileSize);
if(buffer) {
text.assign(buffer);
delete[] buffer;
}
return text;
}
bool ResourceManager::saveFile(const std::string &fileName, const unsigned char *data, unsigned int size)
{
PHYSFS_file *file = PHYSFS_openWrite(fileName.c_str());
if(!file) {
error("Failed to save file %s: %s", fileName.c_str(), PHYSFS_getLastError());
return false;
}
PHYSFS_write(file, (void*)data, size, 1);
PHYSFS_close(file);
return true;
}
bool ResourceManager::saveTextFile(const std::string &fileName, std::string text)
{
return saveFile(fileName, (const unsigned char*)text.c_str(), text.size());
}

View File

@ -26,7 +26,6 @@
#define RESOURCEMANAGER_H #define RESOURCEMANAGER_H
#include <string> #include <string>
#include <list>
class ResourceManager class ResourceManager
{ {
@ -34,7 +33,36 @@ public:
ResourceManager(); ResourceManager();
~ResourceManager(); ~ResourceManager();
private: void init(const char *argv0);
void terminate();
/// Sets the write directory
bool setWriteDir(const std::string &path);
/// Adds a directory or zip archive to the search path
bool addToSearchPath(const std::string& path, bool insertInFront = true);
/// Checks whether the given file exists in the search path
bool fileExists(const std::string& filePath);
/// Searches for zip files and adds them to the search path
void searchAndAddArchives(const std::string &path,
const std::string &ext,
const bool append);
/** Load a file by allocating a buffer and filling it with the file contents
* where fileSize will be set to the file size.
* The returned buffer must be freed with delete[]. */
unsigned char *loadFile(const std::string &fileName, unsigned int *fileSize);
/// Loads a text file into a std::string
std::string loadTextFile(const std::string &fileName);
/// Save a file into write directory
bool saveFile(const std::string &fileName, const unsigned char *data, unsigned int size);
/// Save a text file into write directory
bool saveTextFile(const std::string &fileName, std::string text);
}; };
extern ResourceManager g_resources; extern ResourceManager g_resources;

View File

@ -43,6 +43,7 @@ inline std::string castToString(const T& x) {
return ss.str(); return ss.str();
} }
/// Convert std:;string to int/float like types
template<typename T> template<typename T>
inline T castFromString(const std::string& s) { inline T castFromString(const std::string& s) {
std::istringstream ss(s); std::istringstream ss(s);

View File

@ -26,18 +26,23 @@
#include "engine.h" #include "engine.h"
#include "input.h" #include "input.h"
#include "logger.h" #include "logger.h"
#include "const.h"
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <time.h> #include <time.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/stat.h>
#include <errno.h>
#include <cstring>
#include <string>
#include <sstream>
#include <algorithm>
#include <map>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <GL/glx.h> #include <GL/glx.h>
#include <physfs.h>
struct X11PlatformPrivate { struct X11PlatformPrivate {
Display *display; Display *display;
@ -719,3 +724,12 @@ int Platform::getWindowHeight()
{ {
return x11.height; return x11.height;
} }
const char *Platform::getAppUserDir()
{
std::stringstream sdir;
sdir << PHYSFS_getUserDir() << "/." << APP_NAME << "/";
if((mkdir(sdir.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) && (errno != EEXIST))
error("Couldn't create directory for saving configuration file. (%s)", sdir.str().c_str());
return sdir.str().c_str();
}