Skip to content

Commit

Permalink
Refactor: Refactored away resourcetypeid_t
Browse files Browse the repository at this point in the history
ResourceType is specialised by FileResourceType to add an interpret()
(file instance) method. The file system iterates FileResourceTypes
when attempting to open a file.

Presently this is only used for Wad and Zip, as the other file types
do not yet have compatible interpreter functions.
  • Loading branch information
danij-deng committed Nov 16, 2012
1 parent 5ef4f28 commit 149a12d
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 179 deletions.
4 changes: 2 additions & 2 deletions doomsday/engine/api/resourceclass.h
Expand Up @@ -75,7 +75,7 @@ namespace de
struct ResourceClass
{
public:
typedef QList<resourcetypeid_e> Types;
typedef QList<ResourceType*> Types;

public:
ResourceClass(String _name, String _defaultNamespace)
Expand Down Expand Up @@ -108,7 +108,7 @@ namespace de
* @param rtype Identifier of the resourceType to add.
* @return This instance.
*/
ResourceClass& addResourceType(resourcetypeid_e rtype)
ResourceClass& addResourceType(ResourceType* rtype)
{
searchTypeOrder.push_back(rtype);
return *this;
Expand Down
87 changes: 38 additions & 49 deletions doomsday/engine/api/resourcetype.h
Expand Up @@ -26,65 +26,32 @@
#ifndef LIBDENG_RESOURCETYPE_H
#define LIBDENG_RESOURCETYPE_H

#ifdef __cplusplus
extern "C" {
#endif

/**
* Resource Type identifer attributable to resources (e.g., files).
*
* @ingroup core
*
* @todo Refactor away. These identifiers are no longer needed.
*/
typedef enum resourcetypeid_e {
RT_NONE = 0,
RT_FIRST = 1,
RT_ZIP = RT_FIRST,
RT_WAD,
RT_LMP,
RT_DED,
RT_PNG,
RT_JPG,
RT_TGA,
RT_PCX,
RT_DMD,
RT_MD2,
RT_WAV,
RT_OGG,
RT_MP3,
RT_MOD,
RT_MID,
RT_DEH,
RT_DFN,
RT_LAST_INDEX
} resourcetypeid_t;

#define RESOURCETYPE_COUNT (RT_LAST_INDEX - 1)
#define VALID_RESOURCE_TYPEID(v) ((v) >= RT_FIRST && (v) < RT_LAST_INDEX)

#ifdef __cplusplus
} // extern "C"
#endif

#ifdef __cplusplus
#ifndef DENG2_C_API_ONLY

#include <QStringList>
#include <de/Log>
#include <de/NativePath>
#include <de/String>
#include "filehandle.h"

enum resourceclassid_e;

namespace de
{
struct FileInfo;

/**
* Encapsulates the properties and logics belonging to a logical
* type of resource (e.g., Zip, PNG, WAV, etc...)
*
* @ingroup core
*/
struct ResourceType
class ResourceType
{
public:
typedef de::File1* (*InterpretFunc)(de::FileHandle& hndl, String path, FileInfo const& info);

public:
ResourceType(String _name, resourceclassid_e _defaultClass)
: name_(_name), defaultClass_(_defaultClass)
Expand All @@ -104,12 +71,6 @@ namespace de
return defaultClass_;
}

/// Return the number of known extensions for this type of resource.
int knownExtensionCount() const
{
return knownFileNameExtensions_.count();
}

/**
* Add a new known extension to this resource type. Earlier extensions
* have priority.
Expand Down Expand Up @@ -167,8 +128,9 @@ namespace de
*
* @ingroup core
*/
struct NullResourceType : public ResourceType
class NullResourceType : public ResourceType
{
public:
NullResourceType() : ResourceType("RT_NONE", RC_UNKNOWN)
{}
};
Expand All @@ -178,6 +140,33 @@ namespace de
return !!dynamic_cast<NullResourceType const*>(&rtype);
}

/**
* Base class for all file resource types.
*/
class FileResourceType : public ResourceType
{
public:
FileResourceType(String name, resourceclassid_t rclassId)
: ResourceType(name, rclassId)
{}

/**
* Attempt to interpret a file resource of this type.
*
* @param hndl Handle to the file to be interpreted.
* @param path VFS path to associate with the file.
* @param info File metadata info to attach to the file.
*
* @return The interpreted file; otherwise @c 0.
*/
virtual de::File1* interpret(de::FileHandle& /*hndl*/, String /*path*/, FileInfo const& /*info*/) const = 0;
};

/// @return @c true= @a rtype is a FileResourceType object.
inline bool isFileResourceType(ResourceType const& rtype) {
return !!dynamic_cast<FileResourceType const*>(&rtype);
}

} // namespace de
#endif // DENG2_C_API_ONLY
#endif // __cplusplus
Expand Down
2 changes: 1 addition & 1 deletion doomsday/engine/include/de_platform.h
Expand Up @@ -58,7 +58,7 @@
#define stricmp _stricmp
#define strnicmp _strnicmp
#define open _open
#define close _close
//#define close _close
//#define read _read
//#define write _write
#define access _access
Expand Down
20 changes: 6 additions & 14 deletions doomsday/engine/include/resource/sys_reslocator.h
Expand Up @@ -123,6 +123,8 @@ typedef QList<ResourceNamespace*> ResourceNamespaces;
*/
de::ResourceNamespace* F_ResourceNamespaceByName(de::String name);

de::ResourceTypes const& F_ResourceTypes();

de::ResourceNamespaces const& F_ResourceNamespaces();

/**
Expand All @@ -133,41 +135,31 @@ de::ResourceNamespaces const& F_ResourceNamespaces();
* @param classId Unique identifier of the class.
* @return ResourceClass associated with @a id; otherwise @c 0 (not found).
*/
de::ResourceClass const* F_ResourceClassById(resourceclassid_t classId);
de::ResourceClass* F_ResourceClassById(resourceclassid_t classId);

/**
* Lookup a ResourceClass by symbolic name.
*
* @param name Symbolic name of the class.
* @return ResourceClass associated with @a name; otherwise @c 0 (not found).
*/
de::ResourceClass const& F_ResourceClassByName(de::String name);

/**
* Lookup a ResourceType by id.
*
* @todo Refactor away.
*
* @param typeId Unique identifier of the type.
* @return ResourceType associated with @a id; otherwise @c 0 (not found).
*/
de::ResourceType const* F_ResourceTypeById(resourcetypeid_t typeId);
de::ResourceClass& F_ResourceClassByName(de::String name);

/**
* Lookup a ResourceType by symbolic name.
*
* @param name Symbolic name of the type.
* @return ResourceType associated with @a name. May return a null-object.
*/
de::ResourceType const& F_ResourceTypeByName(de::String name);
de::ResourceType& F_ResourceTypeByName(de::String name);

/**
* Attempts to determine which "type" should be attributed to a resource, solely
* by examining the name (e.g., a file name/path).
*
* @return Type determined for this resource. May return a null-object.
*/
de::ResourceType const& F_GuessResourceTypeFromFileName(de::String name);
de::ResourceType& F_GuessResourceTypeFromFileName(de::String name);

#endif // __cplusplus

Expand Down
1 change: 1 addition & 0 deletions doomsday/engine/src/dd_main.cpp
Expand Up @@ -58,6 +58,7 @@
#include "texture.h"
#include "updater.h"
#include "filesys/wad.h"
#include "resource/sys_reslocator.h"

using namespace de;

Expand Down
53 changes: 12 additions & 41 deletions doomsday/engine/src/filesys/fs_main.cpp
Expand Up @@ -46,6 +46,7 @@
#include "game.h"
#include "lumpindex.h"
#include "resourcenamespace.h"
#include "resource/sys_reslocator.h"

using namespace de;

Expand Down Expand Up @@ -1002,63 +1003,33 @@ int FS1::findAllPaths(String searchPattern, int flags, FS1::PathList& found)
return found.count() - numFoundSoFar;
}

struct FileInterpreter
{
resourcetypeid_t resourceType;
de::File1* (*interpret)(de::FileHandle& hndl, String path, FileInfo const& info);
};

static de::File1* interpretAsZipFile(de::FileHandle& hndl, String path, FileInfo const& info)
{
if(!Zip::recognise(hndl)) return 0;
LOG_VERBOSE("Interpreted \"") << NativePath(path).pretty() << "\" as a Zip (archive)";
return new Zip(hndl, path, info);
}

static de::File1* interpretAsWadFile(de::FileHandle& hndl, String path, FileInfo const& info)
{
if(!Wad::recognise(hndl)) return 0;
LOG_VERBOSE("Interpreted \"") << NativePath(path).pretty() << "\" as a Wad (archive)";
return new Wad(hndl, path, info);
}

de::File1& FS1::interpret(de::FileHandle& hndl, String path, FileInfo const& info)
{
DENG_ASSERT(!path.isEmpty());

static FileInterpreter interpreters[] = {
{ RT_ZIP, interpretAsZipFile },
{ RT_WAD, interpretAsWadFile },
{ RT_NONE, NULL }
};

de::File1* interpretedFile = 0;

// Firstly try interpreter(s) for guessed resource types.
ResourceType const& rtypeGuess = F_GuessResourceTypeFromFileName(path);
if(!isNullResourceType(rtypeGuess))
if(FileResourceType const* fileType = dynamic_cast<FileResourceType const*>(&rtypeGuess))
{
for(FileInterpreter* intper = interpreters; intper->interpret; ++intper)
{
// Not applicable for this resource type?
if(F_ResourceTypeById(intper->resourceType) != &rtypeGuess) continue;

interpretedFile = intper->interpret(hndl, path, info);
if(interpretedFile) break;
}
interpretedFile = fileType->interpret(hndl, path, info);
}

// If not yet interpreted - try each recognisable format in order.
/// @todo Order here should be determined by the resource locator.
if(!interpretedFile)
{
for(FileInterpreter* intper = interpreters; intper->interpret; ++intper)
ResourceTypes const& rtypes = F_ResourceTypes();
DENG2_FOR_EACH_CONST(ResourceTypes, i, rtypes)
{
// Already tried this?
if(F_ResourceTypeById(intper->resourceType) == &rtypeGuess) continue;
if(FileResourceType const* fileType = dynamic_cast<FileResourceType const*>(*i))
{
// Already tried this?
if(fileType == &rtypeGuess) continue;

interpretedFile = intper->interpret(hndl, path, info);
if(interpretedFile) break;
interpretedFile = fileType->interpret(hndl, path, info);
if(interpretedFile) break;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions doomsday/engine/src/filesys/zip.cpp
Expand Up @@ -31,6 +31,7 @@
#include "lumpcache.h"
#include "pathtree.h"
#include "resourcenamespace.h"
#include "sys_reslocator.h"

#include <de/App>
#include <de/ByteOrder>
Expand Down
1 change: 1 addition & 0 deletions doomsday/engine/src/m_misc.c
Expand Up @@ -66,6 +66,7 @@
#define DBITS (FRACBITS-SLOPEBITS)

#if defined(WIN32)
#define close _close
#define read _read
#define write _write
#endif
Expand Down

0 comments on commit 149a12d

Please sign in to comment.