Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

World chunk api rework #83

Merged
merged 10 commits into from
Aug 11, 2020
32 changes: 13 additions & 19 deletions amulet/api/chunk/block_entity_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@
class BlockEntityDict(UserDict):
InputType = Iterable[BlockEntity]

def __init__(self, parent_chunk: "Chunk", block_entities: InputType = ()):
def __init__(self, block_entities: InputType = ()):
super(BlockEntityDict, self).__init__()
for block_entity in block_entities:
self._assert_val(block_entity)
self.data[block_entity.location] = block_entity

self._parent_chunk = weakref.ref(parent_chunk)

def _assert_key(self, key):
assert self._check_key(
key
Expand All @@ -41,19 +39,15 @@ def _assert_val(self, value):
def _check_val(value):
return isinstance(value, BlockEntity)

def _dirty(self):
self._parent_chunk().changed = True

def __repr__(self) -> str:
""" Return repr(self). """
super_repr = (
"".join(f"\n\t{key}:{val}" for key, val in self.data.items()) + "\n"
)
return f"BlockEntityDict({self._parent_chunk().cx},{self._parent_chunk().cz},{super_repr})"
return f"BlockEntityDict({super_repr})"

def clear(self) -> None:
""" Remove all items from list. """
self._dirty()
self.data.clear()

def keys(self) -> Generator[Coordinate, None, None]:
Expand All @@ -74,7 +68,6 @@ def copy(self) -> "BlockEntityDict":
def insert(self, block_entity: BlockEntity) -> None:
""" Insert block_entity at its coordinates. """
self._assert_val(block_entity)
self._dirty()
self.data[block_entity.location] = block_entity

def pop(self, coordinate: Coordinate) -> BlockEntity:
Expand All @@ -85,36 +78,37 @@ def pop(self, coordinate: Coordinate) -> BlockEntity:
"""
self._assert_key(coordinate)
if coordinate in self.data:
self._dirty()
return self.data.pop(coordinate)
raise IndexError

def __delitem__(self, coordinate: Coordinate) -> None:
""" Delete self[key]. """
self._assert_key(coordinate)
self._dirty()
super().__delitem__(coordinate)

def __setitem__(self, coordinate: Coordinate, block_entity: BlockEntity) -> None:
""" Set self[key] to value. """
def _check_block_entity(
self, coordinate: Coordinate, block_entity: BlockEntity
) -> BlockEntity:
self._assert_key(coordinate)
self._assert_val(block_entity)
self._dirty()
self.data[coordinate] = block_entity
if coordinate != block_entity.location:
block_entity = block_entity.new_at_location(*coordinate)
return block_entity

def __setitem__(self, coordinate: Coordinate, block_entity: BlockEntity) -> None:
""" Set self[key] to value. """
self.data[coordinate] = self._check_block_entity(coordinate, block_entity)

def setdefault(
self, coordinate: Coordinate, block_entity: BlockEntity
) -> BlockEntity:
self._assert_key(coordinate)
self._assert_val(block_entity)
self._dirty()
block_entity = self._check_block_entity(coordinate, block_entity)
return self.data.setdefault(coordinate, block_entity)

def popitem(self):
raise NotImplementedError

def update(self, block_entities: InputType) -> None:
self._dirty()
for block_entity in block_entities:
self._assert_val(block_entity)
self.data[block_entity.location] = block_entity
33 changes: 26 additions & 7 deletions amulet/api/chunk/chunk.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pickle
import gzip

from amulet.api.block import Block
from amulet.api.registry import BlockManager
from amulet.api.registry.biome_manager import BiomeManager
from amulet.api.chunk import Biomes, Blocks, Status, BlockEntityDict, EntityList
Expand All @@ -30,8 +31,8 @@ def __init__(self, cx: int, cz: int):
self.__block_palette = BlockManager()
self.__biome_palette = BiomeManager()
self._biomes = None
self._entities = EntityList(self)
self._block_entities = BlockEntityDict(self)
self._entities = EntityList()
self._block_entities = BlockEntityDict()
self._status = Status(self)
self.misc = {} # all entries that are not important enough to get an attribute

Expand Down Expand Up @@ -119,6 +120,27 @@ def blocks(self) -> Blocks:
def blocks(self, value: Optional[Union[Dict[int, numpy.ndarray], Blocks]]):
self._blocks = Blocks(value)

def get_block(self, dx: int, y: int, dz: int) -> Block:
"""
Get the universal Block object at the given location within the chunk.
:param dx: The x coordinate within the chunk. 0 is the bottom edge, 15 is the top edge
:param y: The y coordinate within the chunk. This can be any integer.
:param dz: The z coordinate within the chunk. 0 is the bottom edge, 15 is the top edge
:return: The universal Block object representation of the block at that location
"""
return self.block_palette[self.blocks[dx, y, dz]]

def set_block(self, dx: int, y: int, dz: int, block: Block):
"""
Get the universal Block object at the given location within the chunk.
:param dx: The x coordinate within the chunk. 0 is the bottom edge, 15 is the top edge
:param y: The y coordinate within the chunk. This can be any integer.
:param dz: The z coordinate within the chunk. 0 is the bottom edge, 15 is the top edge
:param block: The universal Block object to set at the given location
:return:
"""
self.blocks[dx, y, dz] = self.block_palette.get_add_block(block)

@property
def _block_palette(self) -> BlockManager:
"""The block block_palette for the chunk.
Expand Down Expand Up @@ -180,7 +202,6 @@ def biomes(self, value: numpy.ndarray):
numpy.issubdtype(
value.dtype, numpy.integer
), "dtype must be an unsigned integer"
self.changed = True
self._biomes = Biomes(self, value)

@property
Expand Down Expand Up @@ -240,8 +261,7 @@ def entities(self, value: Iterable[Entity]):
:return:
"""
if self._entities != value:
self.changed = True
self._entities = EntityList(self, value)
self._entities = EntityList(value)

@property
def block_entities(self) -> BlockEntityDict:
Expand All @@ -259,8 +279,7 @@ def block_entities(self, value: BlockEntityDict.InputType):
:return:
"""
if self._block_entities != value:
self.changed = True
self._block_entities = BlockEntityDict(self, value)
self._block_entities = BlockEntityDict(value)

@property
def status(self) -> Status:
Expand Down
92 changes: 0 additions & 92 deletions amulet/api/chunk/chunk_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,95 +16,3 @@ def __array_finalize__(self, obj):
if obj is None:
return
self._parent_chunk = getattr(obj, "_parent_chunk", None)

def _dirty(self):
self._parent_chunk().changed = True

def byteswap(self, inplace=False):
if inplace:
self._dirty()
numpy.ndarray.byteswap(self, inplace)

def fill(self, value):
self._dirty()
numpy.ndarray.fill(self, value)

def itemset(self, *args):
self._dirty()
numpy.ndarray.itemset(*args)

def partition(self, kth, axis=-1, kind="introselect", order=None):
self._dirty()
numpy.ndarray.partition(self, kth, axis, kind, order)

def put(self, indices, values, mode="raise"):
self._dirty()
numpy.ndarray.put(self, indices, values, mode)

def resize(self, *new_shape, refcheck=True):
self._dirty()
numpy.ndarray.resize(self, *new_shape, refcheck=refcheck)

def sort(self, axis=-1, kind="quicksort", order=None):
self._dirty()
numpy.ndarray.sort(self, axis, kind, order)

def squeeze(self, axis=None):
self._dirty()
numpy.ndarray.squeeze(self, axis)

def __iadd__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__iadd__(self, *args, **kwargs)

def __iand__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__iand__(self, *args, **kwargs)

def __ifloordiv__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__ifloordiv__(self, *args, **kwargs)

def __ilshift__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__ilshift__(self, *args, **kwargs)

def __imatmul__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__imatmul__(self, *args, **kwargs)

def __imod__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__imod__(self, *args, **kwargs)

def __imul__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__imul__(self, *args, **kwargs)

def __ior__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__ior__(self, *args, **kwargs)

def __ipow__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__ipow__(self, *args, **kwargs)

def __irshift__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__irshift__(self, *args, **kwargs)

def __isub__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__isub__(self, *args, **kwargs)

def __itruediv__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__itruediv__(self, *args, **kwargs)

def __ixor__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__ixor__(self, *args, **kwargs)

def __setitem__(self, *args, **kwargs):
self._dirty()
numpy.ndarray.__setitem__(self, *args, **kwargs)
Loading