Generalized regionset wrapper objects so they can be chained
This commit is contained in:
@@ -365,8 +365,11 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
||||
if rset == None: # indicates no such dimension was found:
|
||||
logging.error("Sorry, you requested dimension '%s' for %s, but I couldn't find it", render['dimension'], render_name)
|
||||
return 1
|
||||
|
||||
# If this is to be a rotated regionset, wrap it in a RotatedRegionSet
|
||||
# object
|
||||
if (render['northdirection'] > 0):
|
||||
rset = rset.rotate(render['northdirection'])
|
||||
rset = world.RotatedRegionSet(rset, render['northdirection'])
|
||||
logging.debug("Using RegionSet %r", rset)
|
||||
|
||||
# create our TileSet from this RegionSet
|
||||
|
||||
@@ -36,10 +36,10 @@ class BiomeDataDoesntExist(Exception):
|
||||
pass
|
||||
|
||||
def log_other_exceptions(func):
|
||||
"""A decorator that prints out any errors that are not
|
||||
ChunkDoesntExist or BiomeDataDoesntExist errors. This decorates
|
||||
get_chunk because the C code is likely to swallow exceptions, so
|
||||
this will at least make them visible.
|
||||
"""A decorator that prints out any errors that are not ChunkDoesntExist or
|
||||
BiomeDataDoesntExist errors. This should decorate any functions or methods
|
||||
called by the C code, such as get_chunk(), because the C code is likely to
|
||||
swallow exceptions. This will at least make them visible.
|
||||
|
||||
"""
|
||||
functools.wraps(func)
|
||||
@@ -265,7 +265,6 @@ class RegionSet(object):
|
||||
raise Exception("Woah, what kind of dimension is this! %r" % self.regiondir)
|
||||
|
||||
# this is decorated with cache.lru_cache in __init__(). Be aware!
|
||||
@log_other_exceptions
|
||||
def _get_biome_data_for_region(self, regionx, regionz):
|
||||
"""Get the block of biome data for an entire region. Biome
|
||||
data is in the format output by Minecraft Biome Extractor:
|
||||
@@ -366,9 +365,6 @@ class RegionSet(object):
|
||||
return chunk_data
|
||||
|
||||
|
||||
def rotate(self, north_direction):
|
||||
return RotatedRegionSet(self.regiondir, north_direction)
|
||||
|
||||
def iterate_chunks(self):
|
||||
"""Returns an iterator over all chunk metadata in this world. Iterates
|
||||
over tuples of integers (x,z,mtime) for each chunk. Other chunk data
|
||||
@@ -419,6 +415,33 @@ class RegionSet(object):
|
||||
x = int(p[1])
|
||||
y = int(p[2])
|
||||
yield (x, y, path)
|
||||
|
||||
class RegionSetWrapper(object):
|
||||
"""This is the base class for all "wrappers" of RegionSet objects. A
|
||||
wrapper is an object that acts similarly to a subclass: some methods are
|
||||
overridden and functionality is changed, others may not be. The difference
|
||||
here is that these wrappers may wrap each other, forming chains.
|
||||
|
||||
In fact, subclasses of this object may act exactly as if they've subclassed
|
||||
the original RegionSet object, except the first parameter of the
|
||||
constructor is a regionset object, not a regiondir.
|
||||
|
||||
This class must implement the full public interface of RegionSet objects
|
||||
|
||||
"""
|
||||
def __init__(self, rsetobj):
|
||||
self._r = rsetobj
|
||||
|
||||
def get_type(self):
|
||||
return self._r.get_type()
|
||||
def get_biome_data(self, x, z):
|
||||
return self._r.get_biome_data(x,z)
|
||||
def get_chunk(self, x, z):
|
||||
return self._r.get_chunk(x,z)
|
||||
def iterate_chunks(self):
|
||||
return self._r.iterate_chunks()
|
||||
def get_chunk_mtime(self, x, z):
|
||||
return self._r.get_chunk_mtime(x,z)
|
||||
|
||||
# see RegionSet.rotate. These values are chosen so that they can be
|
||||
# passed directly to rot90; this means that they're the number of
|
||||
@@ -428,7 +451,7 @@ UPPER_RIGHT = 1 ## - Return the world such that north is down the +X axis (rotat
|
||||
LOWER_RIGHT = 2 ## - Return the world such that north is down the +Z axis (rotate 180 degrees)
|
||||
LOWER_LEFT = 3 ## - Return the world such that north is down the -X axis (rotate 90 degrees clockwise)
|
||||
|
||||
class RotatedRegionSet(RegionSet):
|
||||
class RotatedRegionSet(RegionSetWrapper):
|
||||
"""A regionset, only rotated such that north points in the given direction
|
||||
|
||||
"""
|
||||
@@ -440,32 +463,33 @@ class RotatedRegionSet(RegionSet):
|
||||
_ROTATE_180 = lambda x,z: (-x,-z)
|
||||
|
||||
# These take rotated coords and translate into un-rotated coords
|
||||
_unrotation_funcs = {
|
||||
0: _NO_ROTATION,
|
||||
1: _ROTATE_COUNTERCLOCKWISE,
|
||||
2: _ROTATE_180,
|
||||
3: _ROTATE_CLOCKWISE,
|
||||
}
|
||||
_unrotation_funcs = [
|
||||
_NO_ROTATION,
|
||||
_ROTATE_COUNTERCLOCKWISE,
|
||||
_ROTATE_180,
|
||||
_ROTATE_CLOCKWISE,
|
||||
]
|
||||
|
||||
# These translate un-rotated coordinates into rotated coordinates
|
||||
_rotation_funcs = {
|
||||
0: _NO_ROTATION,
|
||||
1: _ROTATE_CLOCKWISE,
|
||||
2: _ROTATE_180,
|
||||
3: _ROTATE_COUNTERCLOCKWISE,
|
||||
}
|
||||
_rotation_funcs = [
|
||||
_NO_ROTATION,
|
||||
_ROTATE_CLOCKWISE,
|
||||
_ROTATE_180,
|
||||
_ROTATE_COUNTERCLOCKWISE,
|
||||
]
|
||||
|
||||
def __init__(self, regiondir, north_dir):
|
||||
def __init__(self, rsetobj, north_dir):
|
||||
self.north_dir = north_dir
|
||||
self.unrotate = self._unrotation_funcs[north_dir]
|
||||
self.rotate = self._rotation_funcs[north_dir]
|
||||
|
||||
super(RotatedRegionSet, self).__init__(regiondir)
|
||||
super(RotatedRegionSet, self).__init__(rsetobj)
|
||||
|
||||
|
||||
# Re-initialize upon unpickling
|
||||
# Re-initialize upon unpickling. This is needed because we store a couple
|
||||
# lambda functions as instance variables
|
||||
def __getstate__(self):
|
||||
return (self.regiondir, self.north_dir)
|
||||
return (self._r, self.north_dir)
|
||||
def __setstate__(self, args):
|
||||
self.__init__(args[0], args[1])
|
||||
|
||||
@@ -476,7 +500,7 @@ class RotatedRegionSet(RegionSet):
|
||||
|
||||
def get_chunk(self, x, z):
|
||||
x,z = self.unrotate(x,z)
|
||||
chunk_data = super(RotatedRegionSet, self).get_chunk(x,z)
|
||||
chunk_data = dict(super(RotatedRegionSet, self).get_chunk(x,z))
|
||||
chunk_data['Blocks'] = numpy.rot90(chunk_data['Blocks'], self.north_dir)
|
||||
chunk_data['Data'] = numpy.rot90(chunk_data['Data'], self.north_dir)
|
||||
chunk_data['SkyLight'] = numpy.rot90(chunk_data['SkyLight'], self.north_dir)
|
||||
|
||||
Reference in New Issue
Block a user