Updated Linux makefile. added <errno.h>, <sys/stat.h>, and <dirent.h> to AssetCache.cpp. Asset system works on Linux now. I also did A Bad Thing and replaced MAX_PATH with 1024. Also, VS allows for some majorly bad template code to be accepted.

master
kts 2015-03-01 02:44:28 -08:00
parent bc831f05b0
commit c5f013d693
4 changed files with 44 additions and 29 deletions

View File

@ -14,7 +14,7 @@ CXXFLAGS+=$(DEBUG) -Wall `sdl2-config --cflags` -c
LDFLAGS+= -Wall -L../../../sdl/$(LIB_DIR) -Wl,-rpath=$(LIB_DIR)/ -lSDL2 -lpthread -Wl,--no-undefined -lm -ldl -pthread -lrt -Wl,-Bstatic -lGLEW -Wl,-Bdynamic -lGL LDFLAGS+= -Wall -L../../../sdl/$(LIB_DIR) -Wl,-rpath=$(LIB_DIR)/ -lSDL2 -lpthread -Wl,--no-undefined -lm -ldl -pthread -lrt -Wl,-Bstatic -lGLEW -Wl,-Bdynamic -lGL
VPATH=../../src VPATH=../../src
BINARY=RtB$(BITS) BINARY=RtB$(BITS)
OBJ=main.o Asset.o AssetManager.o Core.o fio.o checksum.o Log.o Quat.o Mat4.o Vec.o Mesh.o Program.o RenderScene.o RenderSet.o RenderObject.o RenderCamera.o RenderView.o OBJ=main.o Asset.o AssetCache.o AssetManager.o Core.o fio.o checksum.o Log.o Quat.o Mat4.o Vec.o Mesh.o Program.o RenderScene.o RenderSet.o RenderObject.o RenderCamera.o RenderView.o
OBJ_DIR=obj OBJ_DIR=obj
$(BINARY): $(patsubst %,$(OBJ_DIR)/%,$(OBJ)) $(BINARY): $(patsubst %,$(OBJ_DIR)/%,$(OBJ))

View File

@ -3,9 +3,13 @@
#include "checksum.hpp" #include "checksum.hpp"
#include "fio.hpp" #include "fio.hpp"
#include <stdio.h> #include <stdio.h>
#include <errno.h>
#if _WIN32 #if _WIN32
#include <Windows.h> #include <Windows.h>
#include <Strsafe.h> #include <Strsafe.h>
#else
#include <sys/stat.h>
#include <dirent.h>
#endif #endif
/* ======== Construction and Destruction ======== */ /* ======== Construction and Destruction ======== */
@ -50,7 +54,7 @@ int AssetCache::fromFile(const char *cache_file) {
asset->data_checksum = fsum; asset->data_checksum = fsum;
asset->data_length = fsize; asset->data_length = fsize;
assets->set(fpath, asset); assets->set(fpath, asset);
LOG(LOG_DEBUG) << "opened " << fpath << " " << fsum; LOG(LOG_DEBUG) << "opened " << fpath << " " << fsum << " " << fsize;
} }
return 0; return 0;
} }
@ -59,11 +63,11 @@ This function will first attempt to load the .CACHE file contained in the given
If not, the function will traverse the full hierarchy of the given directory and populate the cache accordingly. If not, the function will traverse the full hierarchy of the given directory and populate the cache accordingly.
*/ */
int AssetCache::fromDir(const char *dir) { int AssetCache::fromDir(const char *dir) {
char cachepath[MAX_PATH]; char cachepath[1024];
#ifndef _WIN32 #ifndef _WIN32
sprintf(cachepath, "%s/.CACHE", dir); sprintf(cachepath, "%s/.CACHE", dir);
#else #else
sprintf_s(cachepath, MAX_PATH, "%s/.CACHE", dir); sprintf_s(cachepath, 1024, "%s/.CACHE", dir);
#endif #endif
if (fromFile(cachepath) != 0) { if (fromFile(cachepath) != 0) {
LOG(LOG_INFO) << FUNC_NAME << ": " << cachepath << " does not exist"; LOG(LOG_INFO) << FUNC_NAME << ": " << cachepath << " does not exist";
@ -89,10 +93,10 @@ int AssetCache::traverseDir_r(const char *dir) {
#if _WIN32 #if _WIN32
WIN32_FIND_DATA ffd; WIN32_FIND_DATA ffd;
HANDLE h_find = INVALID_HANDLE_VALUE; HANDLE h_find = INVALID_HANDLE_VALUE;
char wdir[MAX_PATH]; char wdir[1024];
StringCbCopyN(wdir, MAX_PATH, dir, dir_len); StringCbCopyN(wdir, 1024, dir, dir_len);
StringCbCatN(wdir, MAX_PATH, "/*", 2); StringCbCatN(wdir, 1024, "/*", 2);
if ((h_find = FindFirstFile(wdir, &ffd)) == INVALID_HANDLE_VALUE) { if ((h_find = FindFirstFile(wdir, &ffd)) == INVALID_HANDLE_VALUE) {
LOG(LOG_ERROR) << FUNC_NAME << " " << wdir << " FindFirstFile error " << GetLastError(); LOG(LOG_ERROR) << FUNC_NAME << " " << wdir << " FindFirstFile error " << GetLastError();
@ -100,10 +104,10 @@ int AssetCache::traverseDir_r(const char *dir) {
} }
do { do {
if (strcmp(ffd.cFileName, "..") == 0 || strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, ".CACHE") == 0) continue; if (strcmp(ffd.cFileName, "..") == 0 || strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, ".CACHE") == 0) continue;
char fpath[MAX_PATH]; char fpath[1024];
StringCbCopyN(fpath, MAX_PATH, dir, dir_len); StringCbCopyN(fpath, 1024, dir, dir_len);
StringCbCatN(fpath, MAX_PATH, "/", 2); StringCbCatN(fpath, 1024, "/", 2);
StringCbCatN(fpath, MAX_PATH, ffd.cFileName, strlen(ffd.cFileName)+1); StringCbCatN(fpath, 1024, ffd.cFileName, strlen(ffd.cFileName)+1);
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
traverseDir_r(fpath); traverseDir_r(fpath);
} else { } else {
@ -130,28 +134,38 @@ int AssetCache::traverseDir_r(const char *dir) {
struct dirent **files; struct dirent **files;
struct stat file_stat; struct stat file_stat;
int n, i; int n, i;
char udir[MAX_PATH]; char udir[1024];
char filepath[MAX_PATH]; char fpath[1024];
Asset *asset;
n = scandir(dir, &files, NULL, alphasort); n = scandir(dir, &files, NULL, alphasort);
if (n < 0) { if (n < 0) {
LOG(LOG_INFO) << FUNC_NAME << ": No files in dir " << dir; LOG(LOG_INFO) << FUNC_NAME << ": No files in dir " << dir;
return 2; return 2;
} }
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
snprintf(filepath, "%s/%s", dir, files[i]->dname); snprintf(fpath, 1024, "%s/%s", dir, files[i]->d_name);
stat(filepath, &file_stat); stat(fpath, &file_stat);
switch(file_stat.st_mode & S_IFMT) { switch(file_stat.st_mode & S_IFMT) {
case S_IFDIR: case S_IFDIR:
traverseDir_r(filepath); if (strcmp(files[i]->d_name, "..") == 0 || strcmp(files[i]->d_name, ".") == 0) continue;
traverseDir_r(fpath);
break; break;
case S_IFREG: case S_IFREG:
Asset *asset = assets->get(fpath); if (strcmp(files[i]->d_name, ".CACHE") == 0) continue;
if (asset == NULL) { asset = assets->get(fpath);
if (asset != NULL) {
if (file_stat.st_size != asset->data_length) {
LOG(LOG_DEBUG) << " file " << fpath << " changed from " << asset->data_length << " to " << file_stat.st_size;
asset->data_length = file_stat.st_size;
// TODO: recalculate checksum?
}
} else {
asset = new Asset(); asset = new Asset();
asset->filename.assign(fpath); asset->filename.assign(fpath);
asset->data_length = files[i]->d_off;
assets->set(fpath, asset);
} }
asset->flags &= ~Asset::IS_NULL; asset->flags &= ~Asset::IS_NULL;
assets->set(fpath, asset);
break; break;
case S_IFLNK: case S_IFLNK:
// TODO: travelDir_r if dir? // TODO: travelDir_r if dir?
@ -233,4 +247,4 @@ This function attempts to create a new Asset using some provided data
*/ */
Asset* AssetCache::createAsset(const char *filename, const char *data, size_t data_len) { Asset* AssetCache::createAsset(const char *filename, const char *data, size_t data_len) {
return NULL; return NULL;
} }

View File

@ -17,6 +17,7 @@ Following this, the USER AssetCache is loaded, and are:
#include "Log.hpp" #include "Log.hpp"
#include "fio.hpp" #include "fio.hpp"
#include "checksum.hpp" #include "checksum.hpp"
#include <stdexcept> // for std::out_of_range
AssetManager::AssetManager() { AssetManager::AssetManager() {
null_asset.filename = "NULL"; null_asset.filename = "NULL";
@ -66,4 +67,4 @@ Asset* AssetManager::loadFile(const char *filename) {
int AssetManager::addCache(AssetCache *cache) { int AssetManager::addCache(AssetCache *cache) {
caches.push_back(cache); caches.push_back(cache);
return 0; return 0;
} }

View File

@ -53,7 +53,7 @@ template<class T> class HashTable {
// resize should _only_ be called when the HashTable has _no_ data! // resize should _only_ be called when the HashTable has _no_ data!
void resize(int hash_size) { void resize(int hash_size) {
size = hash_size; size = hash_size;
table = (HashEntry**)realloc(table, sizeof(HashEntry*)*size); table = (HashEntry<T>**)realloc(table, sizeof(HashEntry<T>*)*size);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
table[i] = NULL; table[i] = NULL;
} }
@ -159,7 +159,7 @@ template<class T> class HashTable {
} }
return iter->data; return iter->data;
}*/ }*/
template <class T> T operator[](char* key) { T operator[](char* key) {
int key_hash = 0; int key_hash = 0;
int key_len = strlen(key); int key_len = strlen(key);
// get our key hash // get our key hash
@ -169,7 +169,7 @@ template<class T> class HashTable {
// limit it to our HashTable's size // limit it to our HashTable's size
key_hash = key_hash % size; key_hash = key_hash % size;
// find our hash if it exists // find our hash if it exists
HashEntry *entry = table[key_hash]; HashEntry<T> *entry = table[key_hash];
while (entry != NULL) { while (entry != NULL) {
if (strcmp(entry->key, key) == 0) { if (strcmp(entry->key, key) == 0) {
return entry->data; return entry->data;
@ -179,7 +179,7 @@ template<class T> class HashTable {
// doesn't exist, return the user's null value // doesn't exist, return the user's null value
return null; return null;
} }
template <class T> T& operator[](char *key) const { T& operator[](char *key) const {
int key_hash = 0; int key_hash = 0;
int key_len = strlen(key); int key_len = strlen(key);
// get our key hash // get our key hash
@ -189,9 +189,9 @@ template<class T> class HashTable {
// limit it to our HashTable's size // limit it to our HashTable's size
key_hash = key_hash % size; key_hash = key_hash % size;
// find our hash if it exists // find our hash if it exists
HashEntry *last_entry, *entry = table[key_hash]; HashEntry<T> *last_entry, *entry = table[key_hash];
if (entry == NULL) { if (entry == NULL) {
table[key_hash] = new HashEntry(key, null); table[key_hash] = new HashEntry<T>(key, null);
return entry->data; return entry->data;
} }
while (entry->next != NULL) { while (entry->next != NULL) {
@ -201,7 +201,7 @@ template<class T> class HashTable {
last_entry = entry; last_entry = entry;
entry = entry->next; entry = entry->next;
} }
entry->next = new HashEntry(key, null); entry->next = new HashEntry<T>(key, null);
return entry->next; return entry->next;
} }
HashEntry<T> *iterate() { HashEntry<T> *iterate() {
@ -230,4 +230,4 @@ template<class T> class HashTable {
HashEntry<T> *iter; HashEntry<T> *iter;
HashEntry<T> *last_iter; HashEntry<T> *last_iter;
}; };
#endif #endif