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:
|
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)
|
logging.error("Sorry, you requested dimension '%s' for %s, but I couldn't find it", render['dimension'], render_name)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
# If this is to be a rotated regionset, wrap it in a RotatedRegionSet
|
||||||
|
# object
|
||||||
if (render['northdirection'] > 0):
|
if (render['northdirection'] > 0):
|
||||||
rset = rset.rotate(render['northdirection'])
|
rset = world.RotatedRegionSet(rset, render['northdirection'])
|
||||||
logging.debug("Using RegionSet %r", rset)
|
logging.debug("Using RegionSet %r", rset)
|
||||||
|
|
||||||
# create our TileSet from this RegionSet
|
# create our TileSet from this RegionSet
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ class BiomeDataDoesntExist(Exception):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def log_other_exceptions(func):
|
def log_other_exceptions(func):
|
||||||
"""A decorator that prints out any errors that are not
|
"""A decorator that prints out any errors that are not ChunkDoesntExist or
|
||||||
ChunkDoesntExist or BiomeDataDoesntExist errors. This decorates
|
BiomeDataDoesntExist errors. This should decorate any functions or methods
|
||||||
get_chunk because the C code is likely to swallow exceptions, so
|
called by the C code, such as get_chunk(), because the C code is likely to
|
||||||
this will at least make them visible.
|
swallow exceptions. This will at least make them visible.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
functools.wraps(func)
|
functools.wraps(func)
|
||||||
@@ -265,7 +265,6 @@ class RegionSet(object):
|
|||||||
raise Exception("Woah, what kind of dimension is this! %r" % self.regiondir)
|
raise Exception("Woah, what kind of dimension is this! %r" % self.regiondir)
|
||||||
|
|
||||||
# this is decorated with cache.lru_cache in __init__(). Be aware!
|
# this is decorated with cache.lru_cache in __init__(). Be aware!
|
||||||
@log_other_exceptions
|
|
||||||
def _get_biome_data_for_region(self, regionx, regionz):
|
def _get_biome_data_for_region(self, regionx, regionz):
|
||||||
"""Get the block of biome data for an entire region. Biome
|
"""Get the block of biome data for an entire region. Biome
|
||||||
data is in the format output by Minecraft Biome Extractor:
|
data is in the format output by Minecraft Biome Extractor:
|
||||||
@@ -366,9 +365,6 @@ class RegionSet(object):
|
|||||||
return chunk_data
|
return chunk_data
|
||||||
|
|
||||||
|
|
||||||
def rotate(self, north_direction):
|
|
||||||
return RotatedRegionSet(self.regiondir, north_direction)
|
|
||||||
|
|
||||||
def iterate_chunks(self):
|
def iterate_chunks(self):
|
||||||
"""Returns an iterator over all chunk metadata in this world. Iterates
|
"""Returns an iterator over all chunk metadata in this world. Iterates
|
||||||
over tuples of integers (x,z,mtime) for each chunk. Other chunk data
|
over tuples of integers (x,z,mtime) for each chunk. Other chunk data
|
||||||
@@ -419,6 +415,33 @@ class RegionSet(object):
|
|||||||
x = int(p[1])
|
x = int(p[1])
|
||||||
y = int(p[2])
|
y = int(p[2])
|
||||||
yield (x, y, path)
|
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
|
# see RegionSet.rotate. These values are chosen so that they can be
|
||||||
# passed directly to rot90; this means that they're the number of
|
# 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_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)
|
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
|
"""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)
|
_ROTATE_180 = lambda x,z: (-x,-z)
|
||||||
|
|
||||||
# These take rotated coords and translate into un-rotated coords
|
# These take rotated coords and translate into un-rotated coords
|
||||||
_unrotation_funcs = {
|
_unrotation_funcs = [
|
||||||
0: _NO_ROTATION,
|
_NO_ROTATION,
|
||||||
1: _ROTATE_COUNTERCLOCKWISE,
|
_ROTATE_COUNTERCLOCKWISE,
|
||||||
2: _ROTATE_180,
|
_ROTATE_180,
|
||||||
3: _ROTATE_CLOCKWISE,
|
_ROTATE_CLOCKWISE,
|
||||||
}
|
]
|
||||||
|
|
||||||
# These translate un-rotated coordinates into rotated coordinates
|
# These translate un-rotated coordinates into rotated coordinates
|
||||||
_rotation_funcs = {
|
_rotation_funcs = [
|
||||||
0: _NO_ROTATION,
|
_NO_ROTATION,
|
||||||
1: _ROTATE_CLOCKWISE,
|
_ROTATE_CLOCKWISE,
|
||||||
2: _ROTATE_180,
|
_ROTATE_180,
|
||||||
3: _ROTATE_COUNTERCLOCKWISE,
|
_ROTATE_COUNTERCLOCKWISE,
|
||||||
}
|
]
|
||||||
|
|
||||||
def __init__(self, regiondir, north_dir):
|
def __init__(self, rsetobj, north_dir):
|
||||||
self.north_dir = north_dir
|
self.north_dir = north_dir
|
||||||
self.unrotate = self._unrotation_funcs[north_dir]
|
self.unrotate = self._unrotation_funcs[north_dir]
|
||||||
self.rotate = self._rotation_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):
|
def __getstate__(self):
|
||||||
return (self.regiondir, self.north_dir)
|
return (self._r, self.north_dir)
|
||||||
def __setstate__(self, args):
|
def __setstate__(self, args):
|
||||||
self.__init__(args[0], args[1])
|
self.__init__(args[0], args[1])
|
||||||
|
|
||||||
@@ -476,7 +500,7 @@ class RotatedRegionSet(RegionSet):
|
|||||||
|
|
||||||
def get_chunk(self, x, z):
|
def get_chunk(self, x, z):
|
||||||
x,z = self.unrotate(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['Blocks'] = numpy.rot90(chunk_data['Blocks'], self.north_dir)
|
||||||
chunk_data['Data'] = numpy.rot90(chunk_data['Data'], 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)
|
chunk_data['SkyLight'] = numpy.rot90(chunk_data['SkyLight'], self.north_dir)
|
||||||
|
|||||||
Reference in New Issue
Block a user