Skip to content

Commit

Permalink
Refactor|Materials|MaterialArchive: Addressed design issue with Mater…
Browse files Browse the repository at this point in the history
…ialArchive population

MaterialArchive no longer assumes knowledge about how a/the Materials
collection generates material ids. Added Materials::populateArchive()
which uses MaterialArchive::addRecord() to fill the archive with
records for it's materials.

Note that de::MaterialArchive's constructor no longer automatically
populates the archive using the global Materials collection. This
logic is now instead implemented by the Doomsday public API function
MaterialArchive_New()
  • Loading branch information
danij-deng committed Jan 22, 2013
1 parent 6e4a191 commit 8399828
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 37 deletions.
40 changes: 28 additions & 12 deletions doomsday/client/include/resource/materialarchive.h
Expand Up @@ -35,6 +35,9 @@ class Material;

namespace de {

/**
* @ingroup resource
*/
class MaterialArchive
{
public:
Expand All @@ -43,12 +46,28 @@ class MaterialArchive

public:
/**
* @param useSegments If @c true, a serialized archive will be preceded by a segment id number.
* @param useSegments If @c true, the serialized archive will be preceded
* by a segment id number.
* @param recordSymbolicMaterials Add records for the symbolic materials
* used to record special references in the serialized archive.
*/
MaterialArchive(int useSegments, bool populate = true);
MaterialArchive(int useSegments, bool recordSymbolicMaterials = true);

~MaterialArchive();

/**
* Returns the number of materials in the archive.
*/
int count() const;

/**
* Returns the number of materials in the archive.
* Same as count()
*/
inline int size() const {
return count();
}

/**
* @return A new (unused) SerialId for the specified material.
*/
Expand All @@ -65,17 +84,14 @@ class MaterialArchive
Material *find(materialarchive_serialid_t serialId, int group) const;

/**
* Returns the number of materials in the archive.
*/
int count() const;

/**
* Returns the number of materials in the archive.
* Same as count()
* Insert the specified @a material into the archive. If this material
* is already present the existing serial ID is returned and the archive
* is unchanged.
*
* @param material The material to be recorded.
* @return Unique SerialId of the recorded material.
*/
inline int size() const {
return count();
}
materialarchive_serialid_t addRecord(Material const &material);

/**
* Serializes the state of the archive using @a writer.
Expand Down
7 changes: 7 additions & 0 deletions doomsday/client/include/resource/materials.h
Expand Up @@ -28,6 +28,7 @@
#include "def_data.h"
#include "uri.hh"
#include "resource/material.h"
#include "resource/materialarchive.h"
#include "resource/materialmanifest.h"
#include "resource/materialscheme.h"
#include "resource/materialvariantspec.h"
Expand Down Expand Up @@ -355,6 +356,12 @@ class Materials
*/
inline int groupCount() const { return allGroups().count(); }

/**
* Record in the archive all materials in the collection.
* @param archive The archive to be populated.
*/
void populateArchive(MaterialArchive &archive) const;

private:
struct Instance;
Instance *d;
Expand Down
45 changes: 20 additions & 25 deletions doomsday/client/src/resource/materialarchive.cpp
@@ -1,7 +1,7 @@
/** @file materialarchive.cpp Material Archive.
*
* @authors Copyright © 2003-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright © 2005-2013 Daniel Swanson <danij@dengine.net>
* @authors Copyright 2003-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright 2005-2013 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
Expand Down Expand Up @@ -137,25 +137,6 @@ struct MaterialArchive::Instance
return records.intern(uri.compose());
}

/**
* Populate the archive using the global Materials list.
*/
void populate()
{
insertRecord(Uri(UNKNOWN_MATERIALNAME, RC_NULL));

/// @todo Assumes knowledge of how material ids are generated.
/// Should be iterated by Materials using a callback function.
uint num = App_Materials().count();
for(uint i = 1; i < num + 1; ++i)
{
MaterialManifest *manifest = App_Materials().toManifest(i);
SerialId id = insertRecord(manifest->composeUri());
records.setUserPointer(id, &manifest->material());
records.setUserValue(id, true);
}
}

void beginSegment(int seg, writer_s &writer)
{
if(!useSegments) return;
Expand Down Expand Up @@ -218,12 +199,13 @@ struct MaterialArchive::Instance
}
};

MaterialArchive::MaterialArchive(int useSegments, bool populate)
MaterialArchive::MaterialArchive(int useSegments, bool recordSymbolicMaterials)
{
d = new Instance(useSegments);
if(populate)
if(recordSymbolicMaterials)
{
d->populate();
// The first material is the special "unknown material".
d->insertRecord(de::Uri(UNKNOWN_MATERIALNAME, RC_NULL));
}
}

Expand Down Expand Up @@ -284,6 +266,14 @@ Material *MaterialArchive::find(materialarchive_serialid_t serialId, int group)
return findRecordMaterial(d->records, serialId);
}

materialarchive_serialid_t MaterialArchive::addRecord(Material const &material)
{
SerialId id = d->insertRecord(material.manifest().composeUri());
d->records.setUserPointer(id, const_cast<Material *>(&material));
d->records.setUserValue(id, true);
return materialarchive_serialid_t(id);
}

int MaterialArchive::count() const
{
return d->records.size();
Expand Down Expand Up @@ -364,7 +354,12 @@ void MaterialArchive::read(reader_s &reader, int forcedVersion)
#undef MaterialArchive_New
MaterialArchive *MaterialArchive_New(int useSegments)
{
return reinterpret_cast<MaterialArchive *>(new de::MaterialArchive(useSegments));
de::MaterialArchive *archive = new de::MaterialArchive(useSegments);

// Populate the archive using the global Materials collection.
App_Materials().populateArchive(*archive);

return reinterpret_cast<MaterialArchive *>(archive);
}

#undef MaterialArchive_NewEmpty
Expand Down
8 changes: 8 additions & 0 deletions doomsday/client/src/resource/materials.cpp
Expand Up @@ -701,6 +701,14 @@ void Materials::resetAllMaterialAnimations()
}
}

void Materials::populateArchive(MaterialArchive &archive) const
{
DENG2_FOR_EACH(MaterialList, i, d->materials)
{
archive.addRecord(**i);
}
}

static void printVariantInfo(Material::Variant &variant, int variantIdx)
{
Con_Printf("Variant #%i: Spec:%p\n", variantIdx, de::dintptr(&variant.spec()));
Expand Down

0 comments on commit 8399828

Please sign in to comment.