Skip to content

Commit

Permalink
Refactor|World|Sector: Implement Sector-linked MapElement iterations …
Browse files Browse the repository at this point in the history
…with C++11 lambdas
  • Loading branch information
danij-deng committed Dec 2, 2014
1 parent db8b439 commit 1dbafbb
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 158 deletions.
91 changes: 42 additions & 49 deletions doomsday/client/include/world/sector.h
Expand Up @@ -21,7 +21,7 @@
#ifndef DENG_WORLD_SECTOR_H
#define DENG_WORLD_SECTOR_H

#include <QList>
#include <functional>
#ifdef __CLIENT__
# include <de/aabox.h>
#endif
Expand Down Expand Up @@ -56,12 +56,6 @@ class Sector : public de::MapElement
/// Notified whenever a light color change occurs.
DENG2_DEFINE_AUDIENCE(LightColorChange, void sectorLightColorChanged(Sector &sector))

/*
* Linked-element lists:
*/
typedef QList<Plane *> Planes;
typedef QList<LineSide *> Sides;

// Plane identifiers:
enum { Floor, Ceiling };

Expand All @@ -76,81 +70,82 @@ class Sector : public de::MapElement
de::Vector3f const &lightColor = de::Vector3f(1, 1, 1));

/**
* Returns the sector plane with the specified @a planeIndex.
* Returns @c true if at least one Plane in the sector is sky-masked.
*
* @see Surface::hasSkyMaskedMaterial()
*/
Plane &plane(int planeIndex);

/// @copydoc plane()
Plane const &plane(int planeIndex) const;

bool hasSkyMaskedPlane() const;

/**
* Returns the floor plane of the sector.
* Returns the total number of planes in/owned by the sector.
*/
inline Plane &floor() { return plane(Floor); }
int planeCount() const;

/// @copydoc floor()
inline Plane const &floor() const { return plane(Floor); }
/**
* Lookup a Plane by it's sector-unique @a planeIndex.
*/
Plane &plane(int planeIndex);
Plane const &plane(int planeIndex) const;

/**
* Returns the ceiling plane of the sector.
* Returns the @em floor Plane of the sector.
*/
inline Plane &ceiling() { return plane(Ceiling); }
inline Plane &floor() { return plane(Floor); }
inline Plane const &floor() const { return plane(Floor); }

/// @copydoc ceiling()
/**
* Returns the @em ceiling Plane of the sector.
*/
inline Plane &ceiling() { return plane(Ceiling); }
inline Plane const &ceiling() const { return plane(Ceiling); }

Plane *addPlane(de::Vector3f const &normal, coord_t height);

/**
* Provides access to the list of planes in/owned by the sector, for efficient
* traversal.
* Add a new Plane to the sector.
*
* @param normal World space normal for the new plane.
* @param height World space Z axis coordinate for the new plane.
*/
Planes const &planes() const;
Plane *addPlane(de::Vector3f const &normal, coord_t height);

/**
* Returns the total number of planes in/owned by the sector.
* Iterate through the Planes of the sector.
*
* @param func Callback to make for each Plane.
*/
inline int planeCount() const { return planes().count(); }
de::LoopResult forAllPlanes(std::function<de::LoopResult (Plane &)> func) const;

/**
* Convenient accessor method for returning the surface of the specified
* plane of the sector.
*/
inline Surface &planeSurface(int planeIndex) { return plane(planeIndex).surface(); }

/// @copydoc planeSurface()
inline Surface &planeSurface(int planeIndex) { return plane(planeIndex).surface(); }
inline Surface const &planeSurface(int planeIndex) const { return plane(planeIndex).surface(); }

/**
* Convenient accessor method for returning the surface of the floor plane
* of the sector.
*/
inline Surface &floorSurface() { return floor().surface(); }

/// @copydoc floorSurface()
inline Surface &floorSurface() { return floor().surface(); }
inline Surface const &floorSurface() const { return floor().surface(); }

/**
* Convenient accessor method for returning the surface of the ceiling plane
* of the sector.
*/
inline Surface &ceilingSurface() { return ceiling().surface(); }

/// @copydoc ceilingSurface()
inline Surface &ceilingSurface() { return ceiling().surface(); }
inline Surface const &ceilingSurface() const { return ceiling().surface(); }

/**
* Provides access to the list of line sides which reference the sector,
* for efficient traversal.
* Returns the total number of Line::Sides which reference the sector.
*/
Sides const &sides() const;
int sideCount() const;

/**
* Returns the total number of line sides which reference the sector.
* Iterate through the Line::Sides of the sector.
*
* @param func Callback to make for each Line::Side.
*/
inline int sideCount() const { return sides().count(); }
de::LoopResult forAllSides(std::function<de::LoopResult (LineSide &)> func) const;

/**
* (Re)Build the side list for the sector.
Expand All @@ -171,9 +166,7 @@ class Sector : public de::MapElement
* sector are linked to this, forming a chain which can be traversed using
* the 'next' pointer of the emitter's thinker_t.
*/
SoundEmitter &soundEmitter();

/// @copydoc soundEmitter()
SoundEmitter &soundEmitter();
SoundEmitter const &soundEmitter() const;

/**
Expand Down Expand Up @@ -230,19 +223,19 @@ class Sector : public de::MapElement
/**
* Unlink the mobj from the list of mobjs "in" the sector.
*
* @param mobj Mobj to be unlinked.
* @param mob Mobj to be unlinked.
*/
void unlink(struct mobj_s *mobj);
void unlink(struct mobj_s *mob);

/**
* Link the mobj to the head of the list of mobjs "in" the sector. Note that
* mobjs in this list may not actually be inside the sector. This is because
* the sector is determined by interpreting the BSP leaf as a half-space and
* not a closed convex subspace (@ref de::Map::link()).
*
* @param mobj Mobj to be linked.
* @param mob Mobj to be linked.
*/
void link(struct mobj_s *mobj);
void link(struct mobj_s *mob);

/**
* Returns the @em validCount of the sector. Used by some legacy iteration
Expand Down Expand Up @@ -285,4 +278,4 @@ class Sector : public de::MapElement
DENG2_PRIVATE(d)
};

#endif // DENG_WORLD_SECTOR_H
#endif // DENG_WORLD_SECTOR_H
7 changes: 4 additions & 3 deletions doomsday/client/src/dd_main.cpp
Expand Up @@ -3325,10 +3325,11 @@ DENG_EXTERN_C void R_SetupMap(int mode, int flags)
/// @todo Refactor away.
map.forAllSectors([] (Sector &sector)
{
for(LineSide *side : sector.sides())
sector.forAllSides([] (LineSide &side)
{
side->fixMissingMaterials();
}
side.fixMissingMaterials();
return LoopContinue;
});
return LoopContinue;
});
#endif
Expand Down
19 changes: 10 additions & 9 deletions doomsday/client/src/render/rend_main.cpp
Expand Up @@ -4802,25 +4802,26 @@ static void drawSoundEmitters(Map &map)
});
}

if(devSoundEmitters & (SOF_SECTOR|SOF_PLANE))
if(devSoundEmitters & (SOF_SECTOR | SOF_PLANE))
{
map.forAllSectors([] (Sector &sec)
map.forAllSectors([] (Sector &sector)
{
if(devSoundEmitters & SOF_PLANE)
{
for(Plane *plane : sec.planes())
sector.forAllPlanes([] (Plane &plane)
{
drawSoundEmitter(plane->soundEmitter(),
drawSoundEmitter(plane.soundEmitter(),
String("Sector #%1 (pln:%2)")
.arg(sec.indexInMap())
.arg(plane->indexInSector()));
}
.arg(plane.sector().indexInMap())
.arg(plane.indexInSector()));
return LoopContinue;
});
}

if(devSoundEmitters & SOF_SECTOR)
{
drawSoundEmitter(sec.soundEmitter(),
String("Sector #%1").arg(sec.indexInMap()));
drawSoundEmitter(sector.soundEmitter(),
String("Sector #%1").arg(sector.indexInMap()));
}
return LoopContinue;
});
Expand Down
11 changes: 7 additions & 4 deletions doomsday/client/src/resource/resourcesystem.cpp
Expand Up @@ -3974,12 +3974,15 @@ void ResourceSystem::cacheForCurrentMap()
{
// Skip sectors with no line sides as their planes will never be drawn.
if(sector.sideCount())
for(Plane *plane : sector.planes())
{
if(plane->surface().hasMaterial())
sector.forAllPlanes([this, &spec] (Plane &plane)
{
cache(plane->surface().material(), spec);
}
if(plane.surface().hasMaterial())
{
cache(plane.surface().material(), spec);
}
return LoopContinue;
});
}
return LoopContinue;
});
Expand Down
16 changes: 6 additions & 10 deletions doomsday/client/src/world/api_map.cpp
Expand Up @@ -396,20 +396,16 @@ int P_Iteratep(void *elPtr, uint prop, int (*callback) (void *p, void *ctx), voi
switch(prop)
{
case DMU_LINE:
for(LineSide *side : sector.sides())
return sector.forAllSides([&callback, &context] (LineSide &side)
{
if(int result = callback(&side->line(), context))
return result;
}
return false; // Continue iteration
return callback(&side.line(), context);
});

case DMU_PLANE:
for(Plane *plane : sector.planes())
return sector.forAllPlanes([&callback, &context] (Plane &plane)
{
if(int result = callback(plane, context))
return result;
}
return false; // Continue iteration
return callback(&plane, context);
});

default:
throw Error("P_Iteratep", QString("Property %1 unknown/not vector").arg(DMU_Str(prop)));
Expand Down

0 comments on commit 1dbafbb

Please sign in to comment.