X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=vrfileman;a=blobdiff_plain;f=src%2Ffs.cc;h=b65db45ce096ea359281076c745087bc3a1c2786;hp=c85040a0347c0fb7995e8d326b076aadf25f8219;hb=dfbd5842ef2f270e7d83507c4ba7bed005eea780;hpb=c5daeff5edca4efa63ef7ae10722c047ab120be0 diff --git a/src/fs.cc b/src/fs.cc index c85040a..b65db45 100644 --- a/src/fs.cc +++ b/src/fs.cc @@ -1,7 +1,12 @@ #include #include #include +#include +#include +#include #include +#include +#include #include "fs.h" #include "icon.h" #include "gmath/gmath.h" @@ -10,6 +15,10 @@ static IconRenderer *iconrend; +static std::map node_cache; +static FSNode *cur_node; +static int start_child; + bool init_fs() { iconrend = new ShapesIcons; @@ -17,83 +26,158 @@ bool init_fs() return false; } + cur_node = get_fsnode(0); + cur_node->expand(); return true; } void cleanup_fs() { + std::map::iterator it = node_cache.begin(); + while(it != node_cache.end()) { + FSNode *node = it++->second; + delete node; + } + node_cache.clear(); delete iconrend; } -void draw_fs() +static Vec3 icon_pos(int row, int col, int ncols, float row_spacing, float radius) { - FSNode test; - test.type = FSNODE_DIR; + float angle = 2.0 * M_PI * (float)col / (float)ncols; + float x = sin(angle) * radius; + float z = -cos(angle) * radius; + float y = (float)row * row_spacing; + return Vec3(x, y, z); +} - Mat4 xform; - xform.rotate(time_sec, 0, 0); - xform.rotate(0, 0, time_sec * 0.5); - xform.translate(0, 2, -5); +void draw_fs() +{ + static const int ncols = 8; + static const float row_spacing = 2.0; + static const float radius = 5; - glPushMatrix(); - glMultMatrixf(xform[0]); + Mat4 base_xform; + base_xform.rotate(time_sec, 0, 0); + base_xform.rotate(0, 0, time_sec * 0.5); + base_xform.translate(0, 2, 0); glUseProgram(0); glDisable(GL_TEXTURE_2D); - iconrend->draw(&test); - glPopMatrix(); + int first = start_child % ncols; + int nchildren = (int)cur_node->children.size(); + int col = 0, row = 0; + + for(int i=0; idraw(cur_node->children[idx]); + glPopMatrix(); + + if(++col >= ncols) { + col = 0; + ++row; + } + } } -// ---- FSNode implementation ---- -FSNode::FSNode() +FSNode *get_fsnode(const char *path) { - type = FSNODE_UNKNOWN; - abs_path = name = suffix = 0; + char *abspath = make_abs_path(path); + + FSNode *node = node_cache[abspath]; + if(!node) { + node = new FSNode; + node->path = path; + + struct stat st; + if(stat(node->path, &st) == -1) { + fprintf(stderr, "failed to stat: %s\n", node->path.get_path()); + delete node; + return 0; + } + node->size = st.st_size; + + switch(st.st_mode & S_IFMT) { + case S_IFREG: + node->type = FSTYPE_FILE; + break; + + case S_IFDIR: + node->type = FSTYPE_DIR; + break; + + case S_IFBLK: + case S_IFCHR: + node->type = FSTYPE_DEV; + break; + + default: + node->type = FSTYPE_UNKNOWN; + } + node_cache[abspath] = node; + } + + return node; } -FSNode::~FSNode() +FSNode *get_fsnode(const char *dir, const char *name) { - if(abs_path) { - delete [] abs_path; + if(!dir) { + return get_fsnode(name); + } + if(!name || *name == '/') { + return 0; } + + int len = strlen(dir) + 1 + strlen(name); + char *buf = new char[len + 1]; + sprintf(buf, "%s/%s", dir, name); + FSNode *res = get_fsnode(buf); + delete [] buf; + return res; } -void FSNode::set_path(const char *s) +// ---- FSNode implementation ---- +FSNode::FSNode() { - int len = strlen(s); - if(!len) return; + type = FSTYPE_UNKNOWN; + size = 0; + parent = 0; +} - delete [] abs_path; +bool FSNode::expand() +{ + if(type != FSTYPE_DIR) { + return false; + } - const char *slash = s + len - 1; - while(slash > s && *slash != '/') { - --slash; + DIR *dir = opendir(path); + if(!dir) { + fprintf(stderr, "failed to open dir: %s: %s\n", path.get_path(), strerror(errno)); + return false; } - if(name == s) { // no slashes found - char buf[1024]; - if(!getcwd(buf, sizeof buf)) { - abort(); - } - int dirlen = strlen(buf); - abs_path = new char[len + dirlen + 2]; - sprintf(abs_path, "%s/%s", buf, s); + struct dirent *dent; + while((dent = readdir(dir))) { + if(strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) { + continue; + } - name = abs_path + dirlen + 1; - suffix = abs_path + len + dirlen - 1; - } else { - abs_path = new char[len + 1]; - memcpy(abs_path, s, len + 1); + FSNode *node = get_fsnode(path, dent->d_name); + if(!node) continue; - name = abs_path + (slash - s); - suffix = abs_path + len - 1; + children.push_back(node); } + printf("expanded %d children\n", (int)children.size()); - while(suffix > name && *suffix != '.') { - --suffix; - } - if(suffix == name) { - suffix = 0; - } + parent = get_fsnode(path.get_parent()); + return true; }