Page 1 of 1

[fixed] Problem With Folder Archives

Posted: Wed Jul 08, 2009 12:57 pm
by kkrizka
Hi There,

I'm using IFileSystem::addFolderFileArchive() in my code to add a folder that contains all my media. Then I use the standard ways to access mesh files and textures. That worked pretty well until a few days ago, when there were some changes in Irrlicht-SVN (I'm using trunk) to the file system classes. Then it stopped working.

The first thing I did was change to IFileSystem::addFileArchive("media/",true,true,EFAT_FOLDER), which I understand is now the recommended way. That did not fix my problem.

I've created a simple test application from 01.HelloWorld example by adding "../../media" as a folder archive and removing the path to the sydney mesh. It fails to load too. Also the addFileArchive("../../media/") call returns false, which I understand means it failed.

Here is the patch against the latest svn trunk to the HelloWorld example:

Code: Select all

Index: examples/01.HelloWorld/main.cpp
===================================================================
--- examples/01.HelloWorld/main.cpp	(revision 2450)
+++ examples/01.HelloWorld/main.cpp	(working copy)
@@ -144,6 +144,7 @@
 	IVideoDriver* driver = device->getVideoDriver();
 	ISceneManager* smgr = device->getSceneManager();
 	IGUIEnvironment* guienv = device->getGUIEnvironment();
+	IFileSystem* fs = device->getFileSystem();
 
 	/*
 	We add a hello world label to the window, using the GUI environment.
@@ -165,7 +166,8 @@
 	other supported file format. By the way, that cool Quake 2 model
 	called sydney was modelled by Brian Collins.
 	*/
-	IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2");
+	printf("Adding ../../media: %d\n",fs->addFileArchive("../../media/",true,true,EFAT_FOLDER));
+	IAnimatedMesh* mesh = smgr->getMesh("sydney.md2");
 	if (!mesh)
 	{
 		device->drop();
Am I doing something wrong or is this a bug with the new IFileSystem code?

Posted: Wed Jul 08, 2009 1:22 pm
by kkrizka
I've found something. In CFileSystem::addFileArchive(), when I specify a known type of EFAT_FOLDER, then it goes to this:

Code: Select all

		io::IReadFile* file = 0; 

		for (i = 0; i < ArchiveLoader.size(); ++i)
		{
			if (ArchiveLoader[i]->getType() == archiveType)
			{
				// attempt to open file
				if (!file)
					file = createAndOpenFile(filename);

				// is the file open?
				if (file)
				{
				  printf("OPEN\n");
					// attempt to open archive
					file->seek(0);
					if (ArchiveLoader[i]->isALoadableFileFormat(file))
					{
						file->seek(0);
						archive = ArchiveLoader[i]->createArchive(file, ignoreCase, ignorePaths);
						if (archive)
							break;
					}
				}
				else
				{
					// couldn't open file
					break;
				}
			}
		}
Now the code find the correct loader for EFAT_FOLDER: CArchiveLoaderMount. However CArchiveLoaderMount::isALoadableFileFormat(io::IReadFile* file) is hardcoded to return false. So no archive is ever created for folders.

But, the EFAT_UNKNOWN code uses CArchiveLoaderMount::isALoadableFileFormat(string filename), which is implemented and works.

I'm assuming you just did not have time to implement CArchiveLoaderMount::isALoadableFileFormat(io::IReadFile* file) (and CArchiveLoaderMount::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths)) yet. Is that right?

Posted: Wed Jul 08, 2009 1:30 pm
by bitplane
oops sorry, I broke that! I'll commit a fix shortly, thanks for the report :)

edit: fixed in revision 2453

Posted: Wed Jul 08, 2009 2:08 pm
by kkrizka
Yup yup, everything seems to work now. (y)