Downloading assets
by Simon Waite · in Torque Game Engine · 07/07/2004 (1:00 pm) · 2 replies
I'm posting this knowing little about the asset download routines.
I am assuming the following - based on behaviours seen downloading maps in the
tribes series.
Test case:
set up dedicated server starting starter.fps
set up client with the data directory renamed or removed.
start client.
scan, select and join the appropriate server
This is a good time to attach a remote debugger to the client if you're running
a debug build.
Watch as the data dirctory gets sent out.
... rather slowly - assume that it's rate limited to 4KByte/s or thereabouts ?
Assuming all went well you'll have no problems - your data directory will be
populated correctly, and you're wandering around the map killing the NPC.
Heres where the problems come in. (I've not repeated this test as it's taken a
few hours already - and thus fallen out of the bounds of realistic use for my
purposes - and it's not even finished yet :-)
Partial file appears to cause 'ResourceManager->getCreateFunction' to return null
Error displayed:
Fatal: (f:\projects\p101\torque\engine\core\resmanager.cc @ 723)
ResourceObject::construct: NULL resource create function.
this happened to be on the "thatch" texture - which turns out to be a jpg
the file thatch.jpg was there which was 83K and an extensionless file which
was a partial download at 19K.
Solution:
Removal of the file 19K "thatch" file fixed the problem.
Code:
resmanager.cc (line 723 is the assert)
This looks great, if the debug build encounters a problem it'll give you an
option to jump into the debugger and you can poke about to see what the problem is.
What is not so great is that:
ResourceManager->getCreateFunction() returns null (more on this later.)
No errorchecking is done for the null case, therefore the null pointer is called.
I propose that NULL is returned, with an appropriate log entry, so that the
error can be caught further up the callstack. It should then complain about not
being able to load the texture. (perhaps allowing the .jpg extension to load?)
IMHO this is preferable behaviour to crashing out.
I am assuming the following - based on behaviours seen downloading maps in the
tribes series.
Test case:
set up dedicated server starting starter.fps
set up client with the data directory renamed or removed.
start client.
scan, select and join the appropriate server
This is a good time to attach a remote debugger to the client if you're running
a debug build.
Watch as the data dirctory gets sent out.
... rather slowly - assume that it's rate limited to 4KByte/s or thereabouts ?
Assuming all went well you'll have no problems - your data directory will be
populated correctly, and you're wandering around the map killing the NPC.
Heres where the problems come in. (I've not repeated this test as it's taken a
few hours already - and thus fallen out of the bounds of realistic use for my
purposes - and it's not even finished yet :-)
Partial file appears to cause 'ResourceManager->getCreateFunction' to return null
Error displayed:
Fatal: (f:\projects\p101\torque\engine\core\resmanager.cc @ 723)
ResourceObject::construct: NULL resource create function.
this happened to be on the "thatch" texture - which turns out to be a jpg
the file thatch.jpg was there which was 83K and an extensionless file which
was a partial download at 19K.
Solution:
Removal of the file 19K "thatch" file fixed the problem.
Code:
resmanager.cc (line 723 is the assert)
RESOURCE_CREATE_FN createFunction = ResourceManager->getCreateFunction (obj->name);
AssertFatal (createFunction,
"ResourceObject::construct: NULL resource create function.");
ResourceInstance *ret = createFunction (*stream);
if(ret)
ret->mSourceResource = obj;
closeStream (stream);
return ret;This looks great, if the debug build encounters a problem it'll give you an
option to jump into the debugger and you can poke about to see what the problem is.
What is not so great is that:
ResourceManager->getCreateFunction() returns null (more on this later.)
No errorchecking is done for the null case, therefore the null pointer is called.
I propose that NULL is returned, with an appropriate log entry, so that the
error can be caught further up the callstack. It should then complain about not
being able to load the texture. (perhaps allowing the .jpg extension to load?)
IMHO this is preferable behaviour to crashing out.
About the author
#2
07/07/2004 (3:30 pm)
The download functionality is really in a very exciting state, as you've found out. It's not very robust, mostly because it all seems to happen magically in the background. I think the first step should be to provide a GUI showing what is downloading, where, and how fast. In the process you'll probably end up fixing all sorts of interesting problems in the engine, and maybe even finding a few ways to speed things up (my current favorite solution is allowing downloads to happen off of a 3rd party web server, so as not to clobber the game server).
Torque Owner Simon Waite
RESOURCE_CREATE_FN ResManager::getCreateFunction (const char *name) { const char * s = dStrrchr (name, '.'); if (!s) return (NULL); RegisteredExtension * itr = registeredList; while (itr) { if (dStricmp (s, itr->mExtension) == 0) return (itr->mCreateFn); itr = itr->next; } return (NULL); }Nice simple readable code. (no excuse for lack of comments tho!)
It is clear to me that this function returns NULL upon an error,
therefore should be errortrapped by code in the calling function
rather than only using an assert.
Other errors appear to crop up when (assumption) when interiors
haven't been downloaded correctly and throw the following assert:
Fatal: (f:\projects\p101\torque\engine\interior\interiorlmmanager.cc @ 209)
InteriorLMManager::removeInstance: invalid instance handle
bool InteriorLMManager::loadBaseLightmaps(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle) { AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::loadBaseLightmaps: invalid interior handle"); AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::loadBaseLightmaps: invalid instance handle");(the last assert is the one that gets thrown)
I'm not sure why there is lightmap generation on an interior if there has been
the (assumed) error of incomplete download.
Despite my disappointment with the robustness of this code, I'm still interested in
downloading assets despite these bugs, looks like I'll have to dig further into the
codebase to see why the downloads are terminating unexpectedly.
(edit: spelling)