Day 154: Platform File API

I know that the usage code should guide how the API is defined but I find the need to loop over all hha files twice annoying.

Does the game really need to know the number of asset files up-front?

/Kim

Edited by Kim Jørgensen on Reason: Corrected spelling
OK, I did it! I implemented the platform file API for the SDL port. See this link.

I am using a combination of opendir, readdir, and fnmatch but it ain't pretty. If anybody has a better way of implementing this please let me know.

/Kim

Edited by Kim Jørgensen on
A possibly cleaner way to use Win32 FindFirstFile/FIndNextFile APIs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
WIN32_FIND_DATA FindData;
HANDLE FindHandle = FindFirstFile("*.*", &FindData);
if (FindHandle != INVALID_HANDLE_VALUE)
{
  do {
	
    // Process the file
	
  } while (FindNextFile(FindHandle, &FindData));

  FindClose(FindHandle);
}
Thank you Orso.

Neat, but I am looking for a solution that works on Linux.

/Kim
@Orso: I was thinking of this...

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
    HANDLE Handle;
    WIN32_FIND_DATA FindData;
    BOOL MoreFiles = TRUE;

    for (Handle = FindFirstFile(Pattern, &FindData);
         Handle != INVALID_HANDLE_VALUE && MoreFiles;
         MoreFiles = FindNextFile(Handle, &FindData))
    {
        // Process the file
    }
    FindClose(Handle);


...but I like yours better.

Edited by Mike T on
If you're just looking for a "for" loop, no matter how ugly, you can still do it, it's just awful :) It'd look like this:

1
2
3
4
5
6
7
    WIN32_FIND_DATA FindData;
    for (HANDLE Handle = FindFirstFile(Pattern, &FindData);
         Handle != INVALID_HANDLE_VALUE;
         Handle = FindNextFile(Handle, &FindData) ? Handle : FindClose(Handle), INVALID_FILE_HANDLE)
    {
        // ...
    }


- Casey
Orso's loop is the cleanest. There's no redundancy, and it's easy-to-understand. It's hard to come up with that solution on the first try, but if you keep refactoring (or what Casey refers to as compression-oriented programming), you'll inevitably end up with that solution.
Does anybody have suggestions to make the Linux version of GetAllFilesOfTypeBegin and OpenNextFile cleaner? Right now it is worse than the Win32 version due to the following:

3 method calls are needed (opendir, readdir, fnmatch) vs 2 (FindFirstFileA, FindNextFileA)
The platform layer iterates over all files not just the hha ones
It is necessary to store the wild card in sdl_platform_file_group struct

/Kim
jeez, it would have been nice to know about fnmatch or glob.

I couldn't find something to match a wildcard so I just did my own string processing.

I attached the code in code.txt
@mmozeiko: I will take a look at glob, thank you.

And thank you @people. Now I am feeling less bad about my code :)

/Kim
@people: allocating memory with mmap is not called allocating on heap. Allocating on heap happens with new/malloc. mmap allocates memory from OS. You can call it allocating new virtual memory region or something.
@mmozeiko: Using glob simplified the Linux version a lot. It even eliminated the need to loop over all hha files twice :)

But it came with the expense of allocating space for all the hha filenames up-front.

/Kim
@mmozeiko: so the heap is a c runtime library abstraction that gets it's memory from the OS using (s)brk or mmap, is that right?

@kim: well, it is handmade hero :). I actually considered manually parsing the directory file instead of using "dirent.h" :p
Yes, that is right.