amulet-core 1.9.19__py3-none-any.whl → 1.9.20__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of amulet-core might be problematic. Click here for more details.
- amulet/__init__.py +27 -27
- amulet/__pyinstaller/__init__.py +2 -2
- amulet/__pyinstaller/hook-amulet.py +4 -4
- amulet/_version.py +21 -21
- amulet/api/__init__.py +2 -2
- amulet/api/abstract_base_entity.py +128 -128
- amulet/api/block.py +630 -630
- amulet/api/block_entity.py +71 -71
- amulet/api/cache.py +107 -107
- amulet/api/chunk/__init__.py +6 -6
- amulet/api/chunk/biomes.py +207 -207
- amulet/api/chunk/block_entity_dict.py +175 -175
- amulet/api/chunk/blocks.py +46 -46
- amulet/api/chunk/chunk.py +389 -389
- amulet/api/chunk/entity_list.py +75 -75
- amulet/api/chunk/status.py +167 -167
- amulet/api/data_types/__init__.py +4 -4
- amulet/api/data_types/generic_types.py +4 -4
- amulet/api/data_types/operation_types.py +16 -16
- amulet/api/data_types/world_types.py +49 -49
- amulet/api/data_types/wrapper_types.py +71 -71
- amulet/api/entity.py +74 -74
- amulet/api/errors.py +119 -119
- amulet/api/history/__init__.py +36 -36
- amulet/api/history/base/__init__.py +3 -3
- amulet/api/history/base/base_history.py +26 -26
- amulet/api/history/base/history_manager.py +63 -63
- amulet/api/history/base/revision_manager.py +73 -73
- amulet/api/history/changeable.py +15 -15
- amulet/api/history/data_types.py +7 -7
- amulet/api/history/history_manager/__init__.py +3 -3
- amulet/api/history/history_manager/container.py +102 -102
- amulet/api/history/history_manager/database.py +279 -279
- amulet/api/history/history_manager/meta.py +93 -93
- amulet/api/history/history_manager/object.py +116 -116
- amulet/api/history/revision_manager/__init__.py +2 -2
- amulet/api/history/revision_manager/disk.py +33 -33
- amulet/api/history/revision_manager/ram.py +12 -12
- amulet/api/item.py +75 -75
- amulet/api/level/__init__.py +4 -4
- amulet/api/level/base_level/__init__.py +1 -1
- amulet/api/level/base_level/base_level.py +1035 -1026
- amulet/api/level/base_level/chunk_manager.py +227 -227
- amulet/api/level/base_level/clone.py +389 -389
- amulet/api/level/base_level/player_manager.py +101 -101
- amulet/api/level/immutable_structure/__init__.py +1 -1
- amulet/api/level/immutable_structure/immutable_structure.py +94 -94
- amulet/api/level/immutable_structure/void_format_wrapper.py +117 -117
- amulet/api/level/structure.py +22 -22
- amulet/api/level/world.py +19 -19
- amulet/api/partial_3d_array/__init__.py +2 -2
- amulet/api/partial_3d_array/base_partial_3d_array.py +263 -263
- amulet/api/partial_3d_array/bounded_partial_3d_array.py +528 -528
- amulet/api/partial_3d_array/data_types.py +15 -15
- amulet/api/partial_3d_array/unbounded_partial_3d_array.py +229 -229
- amulet/api/partial_3d_array/util.py +152 -152
- amulet/api/player.py +65 -65
- amulet/api/registry/__init__.py +2 -2
- amulet/api/registry/base_registry.py +34 -34
- amulet/api/registry/biome_manager.py +153 -153
- amulet/api/registry/block_manager.py +156 -156
- amulet/api/selection/__init__.py +2 -2
- amulet/api/selection/abstract_selection.py +315 -315
- amulet/api/selection/box.py +805 -805
- amulet/api/selection/group.py +488 -488
- amulet/api/structure.py +37 -37
- amulet/api/wrapper/__init__.py +8 -8
- amulet/api/wrapper/chunk/interface.py +441 -441
- amulet/api/wrapper/chunk/translator.py +567 -567
- amulet/api/wrapper/format_wrapper.py +772 -772
- amulet/api/wrapper/structure_format_wrapper.py +116 -116
- amulet/api/wrapper/world_format_wrapper.py +63 -63
- amulet/level/__init__.py +1 -1
- amulet/level/formats/anvil_forge_world.py +40 -40
- amulet/level/formats/anvil_world/__init__.py +3 -3
- amulet/level/formats/anvil_world/_sector_manager.py +291 -384
- amulet/level/formats/anvil_world/data_pack/__init__.py +2 -2
- amulet/level/formats/anvil_world/data_pack/data_pack.py +224 -224
- amulet/level/formats/anvil_world/data_pack/data_pack_manager.py +77 -77
- amulet/level/formats/anvil_world/dimension.py +177 -177
- amulet/level/formats/anvil_world/format.py +769 -769
- amulet/level/formats/anvil_world/region.py +384 -384
- amulet/level/formats/construction/__init__.py +3 -3
- amulet/level/formats/construction/format_wrapper.py +515 -515
- amulet/level/formats/construction/interface.py +134 -134
- amulet/level/formats/construction/section.py +60 -60
- amulet/level/formats/construction/util.py +165 -165
- amulet/level/formats/leveldb_world/__init__.py +3 -3
- amulet/level/formats/leveldb_world/chunk.py +33 -33
- amulet/level/formats/leveldb_world/dimension.py +385 -419
- amulet/level/formats/leveldb_world/format.py +659 -641
- amulet/level/formats/leveldb_world/interface/chunk/__init__.py +36 -36
- amulet/level/formats/leveldb_world/interface/chunk/base_leveldb_interface.py +836 -836
- amulet/level/formats/leveldb_world/interface/chunk/generate_interface.py +31 -31
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_0.py +30 -30
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_1.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_10.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_11.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_12.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_13.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_14.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_15.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_16.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_17.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_18.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_19.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_2.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_20.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_21.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_22.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_23.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_24.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_25.py +24 -24
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_26.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_27.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_28.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_29.py +33 -33
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_3.py +57 -57
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_30.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_31.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_32.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_33.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_34.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_35.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_36.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_37.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_38.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_39.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_4.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_40.py +16 -16
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_5.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_6.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_7.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_8.py +180 -180
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_9.py +18 -18
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_chunk_versions.py +79 -79
- amulet/level/formats/mcstructure/__init__.py +3 -3
- amulet/level/formats/mcstructure/chunk.py +50 -50
- amulet/level/formats/mcstructure/format_wrapper.py +408 -408
- amulet/level/formats/mcstructure/interface.py +175 -175
- amulet/level/formats/schematic/__init__.py +3 -3
- amulet/level/formats/schematic/chunk.py +55 -55
- amulet/level/formats/schematic/data_types.py +4 -4
- amulet/level/formats/schematic/format_wrapper.py +373 -373
- amulet/level/formats/schematic/interface.py +142 -142
- amulet/level/formats/sponge_schem/__init__.py +4 -4
- amulet/level/formats/sponge_schem/chunk.py +62 -62
- amulet/level/formats/sponge_schem/format_wrapper.py +463 -463
- amulet/level/formats/sponge_schem/interface.py +118 -118
- amulet/level/formats/sponge_schem/varint/__init__.py +1 -1
- amulet/level/formats/sponge_schem/varint/varint.py +87 -87
- amulet/level/interfaces/chunk/anvil/anvil_0.py +72 -72
- amulet/level/interfaces/chunk/anvil/anvil_1444.py +336 -336
- amulet/level/interfaces/chunk/anvil/anvil_1466.py +94 -94
- amulet/level/interfaces/chunk/anvil/anvil_1467.py +37 -37
- amulet/level/interfaces/chunk/anvil/anvil_1484.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1503.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1519.py +34 -34
- amulet/level/interfaces/chunk/anvil/anvil_1901.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1908.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1912.py +21 -21
- amulet/level/interfaces/chunk/anvil/anvil_1934.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_2203.py +69 -69
- amulet/level/interfaces/chunk/anvil/anvil_2529.py +19 -19
- amulet/level/interfaces/chunk/anvil/anvil_2681.py +76 -76
- amulet/level/interfaces/chunk/anvil/anvil_2709.py +19 -19
- amulet/level/interfaces/chunk/anvil/anvil_2844.py +267 -267
- amulet/level/interfaces/chunk/anvil/anvil_3463.py +19 -19
- amulet/level/interfaces/chunk/anvil/anvil_na.py +607 -607
- amulet/level/interfaces/chunk/anvil/base_anvil_interface.py +326 -326
- amulet/level/load.py +59 -59
- amulet/level/loader.py +95 -95
- amulet/level/translators/chunk/bedrock/__init__.py +267 -267
- amulet/level/translators/chunk/bedrock/bedrock_nbt_blockstate_translator.py +46 -46
- amulet/level/translators/chunk/bedrock/bedrock_numerical_translator.py +39 -39
- amulet/level/translators/chunk/bedrock/bedrock_psudo_numerical_translator.py +37 -37
- amulet/level/translators/chunk/java/java_1_18_translator.py +40 -40
- amulet/level/translators/chunk/java/java_blockstate_translator.py +94 -94
- amulet/level/translators/chunk/java/java_numerical_translator.py +62 -62
- amulet/libs/leveldb/__init__.py +7 -7
- amulet/operations/__init__.py +5 -5
- amulet/operations/clone.py +18 -18
- amulet/operations/delete_chunk.py +32 -32
- amulet/operations/fill.py +30 -30
- amulet/operations/paste.py +65 -65
- amulet/operations/replace.py +58 -58
- amulet/utils/__init__.py +14 -14
- amulet/utils/format_utils.py +41 -41
- amulet/utils/generator.py +15 -15
- amulet/utils/matrix.py +243 -243
- amulet/utils/numpy_helpers.py +46 -46
- amulet/utils/world_utils.py +349 -349
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/METADATA +97 -97
- amulet_core-1.9.20.dist-info/RECORD +208 -0
- amulet_core-1.9.19.dist-info/RECORD +0 -208
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/WHEEL +0 -0
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/entry_points.txt +0 -0
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/top_level.txt +0 -0
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
from typing import Tuple, Generator
|
|
2
|
-
|
|
3
|
-
from amulet.utils.generator import generator_unpacker
|
|
4
|
-
from amulet.api.history.base.history_manager import HistoryManager
|
|
5
|
-
from .container import ContainerHistoryManager
|
|
6
|
-
|
|
7
|
-
SnapshotType = Tuple[HistoryManager, ...]
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class MetaHistoryManager(ContainerHistoryManager):
|
|
11
|
-
def __init__(self):
|
|
12
|
-
super().__init__()
|
|
13
|
-
self._world_managers = []
|
|
14
|
-
self._non_world_managers = []
|
|
15
|
-
|
|
16
|
-
def _check_snapshot(self, snapshot: SnapshotType):
|
|
17
|
-
assert isinstance(snapshot, tuple) and all(
|
|
18
|
-
isinstance(item, HistoryManager) for item in snapshot
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
def register(self, manager: HistoryManager, is_world_manager: bool):
|
|
22
|
-
"""
|
|
23
|
-
Register a manager to track.
|
|
24
|
-
:param manager: The manager to track
|
|
25
|
-
:param is_world_manager: Is the manager tracking world data
|
|
26
|
-
:return:
|
|
27
|
-
"""
|
|
28
|
-
assert isinstance(
|
|
29
|
-
manager, HistoryManager
|
|
30
|
-
), "manager must be an instance of BaseHistoryManager"
|
|
31
|
-
if is_world_manager:
|
|
32
|
-
self._world_managers.append(manager)
|
|
33
|
-
else:
|
|
34
|
-
self._non_world_managers.append(manager)
|
|
35
|
-
|
|
36
|
-
def _undo(self, snapshot: SnapshotType):
|
|
37
|
-
for item in snapshot:
|
|
38
|
-
item.undo()
|
|
39
|
-
|
|
40
|
-
def _redo(self, snapshot: SnapshotType):
|
|
41
|
-
for item in snapshot:
|
|
42
|
-
item.redo()
|
|
43
|
-
|
|
44
|
-
def _mark_saved(self):
|
|
45
|
-
for manager in self._managers():
|
|
46
|
-
manager.mark_saved()
|
|
47
|
-
|
|
48
|
-
def _managers(
|
|
49
|
-
self, world: bool = True, non_world: bool = True
|
|
50
|
-
) -> Tuple[HistoryManager, ...]:
|
|
51
|
-
return (
|
|
52
|
-
tuple(self._world_managers) * world
|
|
53
|
-
+ tuple(self._non_world_managers) * non_world
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
@property
|
|
57
|
-
def changed(self) -> bool:
|
|
58
|
-
if super().changed:
|
|
59
|
-
return True
|
|
60
|
-
managers = self._managers(True, False)
|
|
61
|
-
for manager in managers:
|
|
62
|
-
if manager.changed:
|
|
63
|
-
return True
|
|
64
|
-
return False
|
|
65
|
-
|
|
66
|
-
def create_undo_point(self, world=True, non_world=True) -> bool:
|
|
67
|
-
return generator_unpacker(self.create_undo_point_iter(world, non_world))
|
|
68
|
-
|
|
69
|
-
def create_undo_point_iter(
|
|
70
|
-
self, world=True, non_world=True
|
|
71
|
-
) -> Generator[float, None, bool]:
|
|
72
|
-
"""Create an undo point.
|
|
73
|
-
|
|
74
|
-
:param world: Should the world based history managers be included
|
|
75
|
-
:param non_world: Should the non-world based history managers be included
|
|
76
|
-
:return:
|
|
77
|
-
"""
|
|
78
|
-
managers = self._managers(world, non_world)
|
|
79
|
-
snapshot = []
|
|
80
|
-
for manager in managers:
|
|
81
|
-
changed = yield from manager.create_undo_point_iter()
|
|
82
|
-
if changed:
|
|
83
|
-
snapshot.append(manager)
|
|
84
|
-
return self._register_snapshot(tuple(snapshot))
|
|
85
|
-
|
|
86
|
-
def restore_last_undo_point(self):
|
|
87
|
-
for manager in self._managers():
|
|
88
|
-
manager.restore_last_undo_point()
|
|
89
|
-
|
|
90
|
-
def purge(self):
|
|
91
|
-
"""Unload all history data. Restore to the state after creation."""
|
|
92
|
-
for manager in self._managers():
|
|
93
|
-
manager.purge()
|
|
1
|
+
from typing import Tuple, Generator
|
|
2
|
+
|
|
3
|
+
from amulet.utils.generator import generator_unpacker
|
|
4
|
+
from amulet.api.history.base.history_manager import HistoryManager
|
|
5
|
+
from .container import ContainerHistoryManager
|
|
6
|
+
|
|
7
|
+
SnapshotType = Tuple[HistoryManager, ...]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MetaHistoryManager(ContainerHistoryManager):
|
|
11
|
+
def __init__(self):
|
|
12
|
+
super().__init__()
|
|
13
|
+
self._world_managers = []
|
|
14
|
+
self._non_world_managers = []
|
|
15
|
+
|
|
16
|
+
def _check_snapshot(self, snapshot: SnapshotType):
|
|
17
|
+
assert isinstance(snapshot, tuple) and all(
|
|
18
|
+
isinstance(item, HistoryManager) for item in snapshot
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
def register(self, manager: HistoryManager, is_world_manager: bool):
|
|
22
|
+
"""
|
|
23
|
+
Register a manager to track.
|
|
24
|
+
:param manager: The manager to track
|
|
25
|
+
:param is_world_manager: Is the manager tracking world data
|
|
26
|
+
:return:
|
|
27
|
+
"""
|
|
28
|
+
assert isinstance(
|
|
29
|
+
manager, HistoryManager
|
|
30
|
+
), "manager must be an instance of BaseHistoryManager"
|
|
31
|
+
if is_world_manager:
|
|
32
|
+
self._world_managers.append(manager)
|
|
33
|
+
else:
|
|
34
|
+
self._non_world_managers.append(manager)
|
|
35
|
+
|
|
36
|
+
def _undo(self, snapshot: SnapshotType):
|
|
37
|
+
for item in snapshot:
|
|
38
|
+
item.undo()
|
|
39
|
+
|
|
40
|
+
def _redo(self, snapshot: SnapshotType):
|
|
41
|
+
for item in snapshot:
|
|
42
|
+
item.redo()
|
|
43
|
+
|
|
44
|
+
def _mark_saved(self):
|
|
45
|
+
for manager in self._managers():
|
|
46
|
+
manager.mark_saved()
|
|
47
|
+
|
|
48
|
+
def _managers(
|
|
49
|
+
self, world: bool = True, non_world: bool = True
|
|
50
|
+
) -> Tuple[HistoryManager, ...]:
|
|
51
|
+
return (
|
|
52
|
+
tuple(self._world_managers) * world
|
|
53
|
+
+ tuple(self._non_world_managers) * non_world
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def changed(self) -> bool:
|
|
58
|
+
if super().changed:
|
|
59
|
+
return True
|
|
60
|
+
managers = self._managers(True, False)
|
|
61
|
+
for manager in managers:
|
|
62
|
+
if manager.changed:
|
|
63
|
+
return True
|
|
64
|
+
return False
|
|
65
|
+
|
|
66
|
+
def create_undo_point(self, world=True, non_world=True) -> bool:
|
|
67
|
+
return generator_unpacker(self.create_undo_point_iter(world, non_world))
|
|
68
|
+
|
|
69
|
+
def create_undo_point_iter(
|
|
70
|
+
self, world=True, non_world=True
|
|
71
|
+
) -> Generator[float, None, bool]:
|
|
72
|
+
"""Create an undo point.
|
|
73
|
+
|
|
74
|
+
:param world: Should the world based history managers be included
|
|
75
|
+
:param non_world: Should the non-world based history managers be included
|
|
76
|
+
:return:
|
|
77
|
+
"""
|
|
78
|
+
managers = self._managers(world, non_world)
|
|
79
|
+
snapshot = []
|
|
80
|
+
for manager in managers:
|
|
81
|
+
changed = yield from manager.create_undo_point_iter()
|
|
82
|
+
if changed:
|
|
83
|
+
snapshot.append(manager)
|
|
84
|
+
return self._register_snapshot(tuple(snapshot))
|
|
85
|
+
|
|
86
|
+
def restore_last_undo_point(self):
|
|
87
|
+
for manager in self._managers():
|
|
88
|
+
manager.restore_last_undo_point()
|
|
89
|
+
|
|
90
|
+
def purge(self):
|
|
91
|
+
"""Unload all history data. Restore to the state after creation."""
|
|
92
|
+
for manager in self._managers():
|
|
93
|
+
manager.purge()
|
|
@@ -1,116 +1,116 @@
|
|
|
1
|
-
from typing import Optional, Any, Generator
|
|
2
|
-
|
|
3
|
-
from amulet.api.history import Changeable
|
|
4
|
-
from ..base import RevisionManager
|
|
5
|
-
from amulet.api.history.base.history_manager import HistoryManager
|
|
6
|
-
from ..revision_manager import RAMRevisionManager
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class ObjectHistoryManager(HistoryManager):
|
|
10
|
-
def __init__(self, original_entry: Changeable):
|
|
11
|
-
super().__init__()
|
|
12
|
-
self._value: Changeable = original_entry
|
|
13
|
-
self._revision_manager = self._create_new_revision_manager(
|
|
14
|
-
self._pack_value(self._value)
|
|
15
|
-
)
|
|
16
|
-
self._snapshots_size: int = 0
|
|
17
|
-
self._snapshot_index: int = -1
|
|
18
|
-
|
|
19
|
-
# the snapshot that was saved or the save branches off from
|
|
20
|
-
self._last_save_snapshot = -1
|
|
21
|
-
self._branch_save_count = 0 # if the user saves, undoes and does a new operation a save branch will be lost
|
|
22
|
-
# This is the number of changes on that branch
|
|
23
|
-
|
|
24
|
-
@property
|
|
25
|
-
def value(self):
|
|
26
|
-
return self._value
|
|
27
|
-
|
|
28
|
-
@staticmethod
|
|
29
|
-
def _create_new_revision_manager(original_entry: Optional[Any]) -> RevisionManager:
|
|
30
|
-
"""Create an RevisionManager as desired and populate it with the original entry."""
|
|
31
|
-
return RAMRevisionManager(original_entry)
|
|
32
|
-
|
|
33
|
-
def _register_snapshot(self):
|
|
34
|
-
if self._last_save_snapshot > self._snapshot_index:
|
|
35
|
-
# if the user has undone changes and made more changes things get a bit messy
|
|
36
|
-
# This fixes the property storing the number of changes since the last save.
|
|
37
|
-
self._branch_save_count += self._last_save_snapshot - self._snapshot_index
|
|
38
|
-
self._last_save_snapshot = self._snapshot_index
|
|
39
|
-
self._snapshot_index += 1
|
|
40
|
-
self._snapshots_size = min(self._snapshots_size, self._snapshot_index) + 1
|
|
41
|
-
|
|
42
|
-
def mark_saved(self):
|
|
43
|
-
"""Let the class know that the current state has been saved."""
|
|
44
|
-
self._last_save_snapshot = self._snapshot_index
|
|
45
|
-
self._branch_save_count = 0
|
|
46
|
-
self._revision_manager.mark_saved()
|
|
47
|
-
|
|
48
|
-
def purge(self):
|
|
49
|
-
"""Unload the cached objects and restore to the starting value."""
|
|
50
|
-
self._revision_manager = self._create_new_revision_manager(
|
|
51
|
-
self._pack_value(self._value)
|
|
52
|
-
)
|
|
53
|
-
self._snapshots_size: int = 0
|
|
54
|
-
self._snapshot_index: int = -1
|
|
55
|
-
self._last_save_snapshot = -1
|
|
56
|
-
self._branch_save_count = 0
|
|
57
|
-
|
|
58
|
-
@property
|
|
59
|
-
def undo_count(self) -> int:
|
|
60
|
-
return self._snapshot_index + 1
|
|
61
|
-
|
|
62
|
-
@property
|
|
63
|
-
def redo_count(self) -> int:
|
|
64
|
-
return self._snapshots_size - (self._snapshot_index + 1)
|
|
65
|
-
|
|
66
|
-
@property
|
|
67
|
-
def unsaved_changes(self) -> int:
|
|
68
|
-
"""The number of changes that have been made since the last save"""
|
|
69
|
-
return (
|
|
70
|
-
abs(self._snapshot_index - self._last_save_snapshot)
|
|
71
|
-
+ self._branch_save_count
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
def undo(self):
|
|
75
|
-
"""Undoes the last set of changes to the object"""
|
|
76
|
-
if self.undo_count > 0:
|
|
77
|
-
self._revision_manager.undo()
|
|
78
|
-
self._unpack()
|
|
79
|
-
self._snapshot_index -= 1
|
|
80
|
-
|
|
81
|
-
def redo(self):
|
|
82
|
-
"""Redoes the last set of changes to the object"""
|
|
83
|
-
if self.redo_count > 0:
|
|
84
|
-
self._snapshot_index += 1
|
|
85
|
-
self._revision_manager.redo()
|
|
86
|
-
self._unpack()
|
|
87
|
-
|
|
88
|
-
@property
|
|
89
|
-
def changed(self) -> bool:
|
|
90
|
-
return bool(self.unsaved_changes)
|
|
91
|
-
|
|
92
|
-
def create_undo_point_iter(self) -> Generator[float, None, bool]:
|
|
93
|
-
yield 1
|
|
94
|
-
if self._value.changed:
|
|
95
|
-
self._value.changed = False
|
|
96
|
-
self._pack()
|
|
97
|
-
self._register_snapshot()
|
|
98
|
-
return True
|
|
99
|
-
else:
|
|
100
|
-
self._unpack()
|
|
101
|
-
return False
|
|
102
|
-
|
|
103
|
-
def restore_last_undo_point(self):
|
|
104
|
-
self._unpack()
|
|
105
|
-
|
|
106
|
-
def _unpack(self):
|
|
107
|
-
self._unpack_value(self._revision_manager.get_current_entry())
|
|
108
|
-
|
|
109
|
-
def _unpack_value(self, value: Optional[Any]):
|
|
110
|
-
self._value = value
|
|
111
|
-
|
|
112
|
-
def _pack(self):
|
|
113
|
-
self._revision_manager.put_new_entry(self._pack_value(self._value))
|
|
114
|
-
|
|
115
|
-
def _pack_value(self, value: Optional[Any]) -> Optional[Any]:
|
|
116
|
-
return value
|
|
1
|
+
from typing import Optional, Any, Generator
|
|
2
|
+
|
|
3
|
+
from amulet.api.history import Changeable
|
|
4
|
+
from ..base import RevisionManager
|
|
5
|
+
from amulet.api.history.base.history_manager import HistoryManager
|
|
6
|
+
from ..revision_manager import RAMRevisionManager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ObjectHistoryManager(HistoryManager):
|
|
10
|
+
def __init__(self, original_entry: Changeable):
|
|
11
|
+
super().__init__()
|
|
12
|
+
self._value: Changeable = original_entry
|
|
13
|
+
self._revision_manager = self._create_new_revision_manager(
|
|
14
|
+
self._pack_value(self._value)
|
|
15
|
+
)
|
|
16
|
+
self._snapshots_size: int = 0
|
|
17
|
+
self._snapshot_index: int = -1
|
|
18
|
+
|
|
19
|
+
# the snapshot that was saved or the save branches off from
|
|
20
|
+
self._last_save_snapshot = -1
|
|
21
|
+
self._branch_save_count = 0 # if the user saves, undoes and does a new operation a save branch will be lost
|
|
22
|
+
# This is the number of changes on that branch
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def value(self):
|
|
26
|
+
return self._value
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def _create_new_revision_manager(original_entry: Optional[Any]) -> RevisionManager:
|
|
30
|
+
"""Create an RevisionManager as desired and populate it with the original entry."""
|
|
31
|
+
return RAMRevisionManager(original_entry)
|
|
32
|
+
|
|
33
|
+
def _register_snapshot(self):
|
|
34
|
+
if self._last_save_snapshot > self._snapshot_index:
|
|
35
|
+
# if the user has undone changes and made more changes things get a bit messy
|
|
36
|
+
# This fixes the property storing the number of changes since the last save.
|
|
37
|
+
self._branch_save_count += self._last_save_snapshot - self._snapshot_index
|
|
38
|
+
self._last_save_snapshot = self._snapshot_index
|
|
39
|
+
self._snapshot_index += 1
|
|
40
|
+
self._snapshots_size = min(self._snapshots_size, self._snapshot_index) + 1
|
|
41
|
+
|
|
42
|
+
def mark_saved(self):
|
|
43
|
+
"""Let the class know that the current state has been saved."""
|
|
44
|
+
self._last_save_snapshot = self._snapshot_index
|
|
45
|
+
self._branch_save_count = 0
|
|
46
|
+
self._revision_manager.mark_saved()
|
|
47
|
+
|
|
48
|
+
def purge(self):
|
|
49
|
+
"""Unload the cached objects and restore to the starting value."""
|
|
50
|
+
self._revision_manager = self._create_new_revision_manager(
|
|
51
|
+
self._pack_value(self._value)
|
|
52
|
+
)
|
|
53
|
+
self._snapshots_size: int = 0
|
|
54
|
+
self._snapshot_index: int = -1
|
|
55
|
+
self._last_save_snapshot = -1
|
|
56
|
+
self._branch_save_count = 0
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def undo_count(self) -> int:
|
|
60
|
+
return self._snapshot_index + 1
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def redo_count(self) -> int:
|
|
64
|
+
return self._snapshots_size - (self._snapshot_index + 1)
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def unsaved_changes(self) -> int:
|
|
68
|
+
"""The number of changes that have been made since the last save"""
|
|
69
|
+
return (
|
|
70
|
+
abs(self._snapshot_index - self._last_save_snapshot)
|
|
71
|
+
+ self._branch_save_count
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def undo(self):
|
|
75
|
+
"""Undoes the last set of changes to the object"""
|
|
76
|
+
if self.undo_count > 0:
|
|
77
|
+
self._revision_manager.undo()
|
|
78
|
+
self._unpack()
|
|
79
|
+
self._snapshot_index -= 1
|
|
80
|
+
|
|
81
|
+
def redo(self):
|
|
82
|
+
"""Redoes the last set of changes to the object"""
|
|
83
|
+
if self.redo_count > 0:
|
|
84
|
+
self._snapshot_index += 1
|
|
85
|
+
self._revision_manager.redo()
|
|
86
|
+
self._unpack()
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def changed(self) -> bool:
|
|
90
|
+
return bool(self.unsaved_changes)
|
|
91
|
+
|
|
92
|
+
def create_undo_point_iter(self) -> Generator[float, None, bool]:
|
|
93
|
+
yield 1
|
|
94
|
+
if self._value.changed:
|
|
95
|
+
self._value.changed = False
|
|
96
|
+
self._pack()
|
|
97
|
+
self._register_snapshot()
|
|
98
|
+
return True
|
|
99
|
+
else:
|
|
100
|
+
self._unpack()
|
|
101
|
+
return False
|
|
102
|
+
|
|
103
|
+
def restore_last_undo_point(self):
|
|
104
|
+
self._unpack()
|
|
105
|
+
|
|
106
|
+
def _unpack(self):
|
|
107
|
+
self._unpack_value(self._revision_manager.get_current_entry())
|
|
108
|
+
|
|
109
|
+
def _unpack_value(self, value: Optional[Any]):
|
|
110
|
+
self._value = value
|
|
111
|
+
|
|
112
|
+
def _pack(self):
|
|
113
|
+
self._revision_manager.put_new_entry(self._pack_value(self._value))
|
|
114
|
+
|
|
115
|
+
def _pack_value(self, value: Optional[Any]) -> Optional[Any]:
|
|
116
|
+
return value
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
from .ram import RAMRevisionManager
|
|
2
|
-
from .disk import DBRevisionManager
|
|
1
|
+
from .ram import RAMRevisionManager
|
|
2
|
+
from .disk import DBRevisionManager
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
from abc import abstractmethod
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
from amulet.api.history.base import RevisionManager
|
|
5
|
-
from ..data_types import EntryType
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class DBRevisionManager(RevisionManager):
|
|
9
|
-
"""A class to hold data about an entries history on disk.
|
|
10
|
-
Revision indexes are still stored in RAM."""
|
|
11
|
-
|
|
12
|
-
__slots__ = ("_prefix",)
|
|
13
|
-
|
|
14
|
-
def __init__(self, prefix: str, initial_state: EntryType):
|
|
15
|
-
self._prefix: str = prefix
|
|
16
|
-
super().__init__(initial_state)
|
|
17
|
-
|
|
18
|
-
def _store_entry(self, entry: EntryType):
|
|
19
|
-
path = f"{self._prefix}/{len(self._revisions)}"
|
|
20
|
-
path = self._serialise(path, entry)
|
|
21
|
-
self._revisions.append(path)
|
|
22
|
-
|
|
23
|
-
@abstractmethod
|
|
24
|
-
def _serialise(self, path: str, entry: EntryType) -> Optional[str]:
|
|
25
|
-
raise NotImplementedError
|
|
26
|
-
|
|
27
|
-
def get_current_entry(self):
|
|
28
|
-
path = self._revisions[self._current_revision_index]
|
|
29
|
-
return self._deserialise(path)
|
|
30
|
-
|
|
31
|
-
@abstractmethod
|
|
32
|
-
def _deserialise(self, path: str) -> EntryType:
|
|
33
|
-
raise NotImplementedError
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from amulet.api.history.base import RevisionManager
|
|
5
|
+
from ..data_types import EntryType
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DBRevisionManager(RevisionManager):
|
|
9
|
+
"""A class to hold data about an entries history on disk.
|
|
10
|
+
Revision indexes are still stored in RAM."""
|
|
11
|
+
|
|
12
|
+
__slots__ = ("_prefix",)
|
|
13
|
+
|
|
14
|
+
def __init__(self, prefix: str, initial_state: EntryType):
|
|
15
|
+
self._prefix: str = prefix
|
|
16
|
+
super().__init__(initial_state)
|
|
17
|
+
|
|
18
|
+
def _store_entry(self, entry: EntryType):
|
|
19
|
+
path = f"{self._prefix}/{len(self._revisions)}"
|
|
20
|
+
path = self._serialise(path, entry)
|
|
21
|
+
self._revisions.append(path)
|
|
22
|
+
|
|
23
|
+
@abstractmethod
|
|
24
|
+
def _serialise(self, path: str, entry: EntryType) -> Optional[str]:
|
|
25
|
+
raise NotImplementedError
|
|
26
|
+
|
|
27
|
+
def get_current_entry(self):
|
|
28
|
+
path = self._revisions[self._current_revision_index]
|
|
29
|
+
return self._deserialise(path)
|
|
30
|
+
|
|
31
|
+
@abstractmethod
|
|
32
|
+
def _deserialise(self, path: str) -> EntryType:
|
|
33
|
+
raise NotImplementedError
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
from amulet.api.history.base import RevisionManager
|
|
2
|
-
from ..data_types import EntryType
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class RAMRevisionManager(RevisionManager):
|
|
6
|
-
"""A class to hold data about an entries history in RAM."""
|
|
7
|
-
|
|
8
|
-
def _store_entry(self, entry: EntryType):
|
|
9
|
-
self._revisions.append(entry)
|
|
10
|
-
|
|
11
|
-
def get_current_entry(self):
|
|
12
|
-
return self._revisions[self._current_revision_index]
|
|
1
|
+
from amulet.api.history.base import RevisionManager
|
|
2
|
+
from ..data_types import EntryType
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class RAMRevisionManager(RevisionManager):
|
|
6
|
+
"""A class to hold data about an entries history in RAM."""
|
|
7
|
+
|
|
8
|
+
def _store_entry(self, entry: EntryType):
|
|
9
|
+
self._revisions.append(entry)
|
|
10
|
+
|
|
11
|
+
def get_current_entry(self):
|
|
12
|
+
return self._revisions[self._current_revision_index]
|
amulet/api/item.py
CHANGED
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
from amulet_nbt import CompoundTag, StringTag
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class Item(CompoundTag):
|
|
5
|
-
"""
|
|
6
|
-
{
|
|
7
|
-
"namespace": StringTag,
|
|
8
|
-
"base_name": StringTag,
|
|
9
|
-
"metadata": CompoundTag
|
|
10
|
-
}
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
def __init__(self, namespace: str, base_name: str, metadata: dict = None):
|
|
14
|
-
super().__init__(
|
|
15
|
-
{
|
|
16
|
-
"namespace": StringTag(namespace),
|
|
17
|
-
"base_name": StringTag(base_name),
|
|
18
|
-
"metadata": CompoundTag(metadata or {}),
|
|
19
|
-
}
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
@property
|
|
23
|
-
def namespace(self) -> str:
|
|
24
|
-
return self.get_string("namespace").py_str
|
|
25
|
-
|
|
26
|
-
@property
|
|
27
|
-
def base_name(self) -> str:
|
|
28
|
-
return self.get_string("base_name").py_str
|
|
29
|
-
|
|
30
|
-
@property
|
|
31
|
-
def metadata(self) -> CompoundTag:
|
|
32
|
-
return self.get_compound("metadata")
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class BlockItem(CompoundTag):
|
|
36
|
-
"""
|
|
37
|
-
{
|
|
38
|
-
"namespace": StringTag,
|
|
39
|
-
"base_name": StringTag,
|
|
40
|
-
"properties": CompoundTag
|
|
41
|
-
"metadata": CompoundTag
|
|
42
|
-
}
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
def __init__(
|
|
46
|
-
self,
|
|
47
|
-
namespace: str,
|
|
48
|
-
base_name: str,
|
|
49
|
-
properties: dict = None,
|
|
50
|
-
metadata: dict = None,
|
|
51
|
-
):
|
|
52
|
-
super().__init__(
|
|
53
|
-
{
|
|
54
|
-
"namespace": StringTag(namespace),
|
|
55
|
-
"base_name": StringTag(base_name),
|
|
56
|
-
"properties": CompoundTag(properties or {}),
|
|
57
|
-
"metadata": CompoundTag(metadata or {}),
|
|
58
|
-
}
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
@property
|
|
62
|
-
def namespace(self) -> str:
|
|
63
|
-
return self.get_string("namespace").py_str
|
|
64
|
-
|
|
65
|
-
@property
|
|
66
|
-
def base_name(self) -> str:
|
|
67
|
-
return self.get_string("base_name").py_str
|
|
68
|
-
|
|
69
|
-
@property
|
|
70
|
-
def properties(self) -> CompoundTag:
|
|
71
|
-
return self.get_compound("properties")
|
|
72
|
-
|
|
73
|
-
@property
|
|
74
|
-
def metadata(self) -> CompoundTag:
|
|
75
|
-
return self.get_compound("metadata")
|
|
1
|
+
from amulet_nbt import CompoundTag, StringTag
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Item(CompoundTag):
|
|
5
|
+
"""
|
|
6
|
+
{
|
|
7
|
+
"namespace": StringTag,
|
|
8
|
+
"base_name": StringTag,
|
|
9
|
+
"metadata": CompoundTag
|
|
10
|
+
}
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, namespace: str, base_name: str, metadata: dict = None):
|
|
14
|
+
super().__init__(
|
|
15
|
+
{
|
|
16
|
+
"namespace": StringTag(namespace),
|
|
17
|
+
"base_name": StringTag(base_name),
|
|
18
|
+
"metadata": CompoundTag(metadata or {}),
|
|
19
|
+
}
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def namespace(self) -> str:
|
|
24
|
+
return self.get_string("namespace").py_str
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def base_name(self) -> str:
|
|
28
|
+
return self.get_string("base_name").py_str
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def metadata(self) -> CompoundTag:
|
|
32
|
+
return self.get_compound("metadata")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class BlockItem(CompoundTag):
|
|
36
|
+
"""
|
|
37
|
+
{
|
|
38
|
+
"namespace": StringTag,
|
|
39
|
+
"base_name": StringTag,
|
|
40
|
+
"properties": CompoundTag
|
|
41
|
+
"metadata": CompoundTag
|
|
42
|
+
}
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
namespace: str,
|
|
48
|
+
base_name: str,
|
|
49
|
+
properties: dict = None,
|
|
50
|
+
metadata: dict = None,
|
|
51
|
+
):
|
|
52
|
+
super().__init__(
|
|
53
|
+
{
|
|
54
|
+
"namespace": StringTag(namespace),
|
|
55
|
+
"base_name": StringTag(base_name),
|
|
56
|
+
"properties": CompoundTag(properties or {}),
|
|
57
|
+
"metadata": CompoundTag(metadata or {}),
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def namespace(self) -> str:
|
|
63
|
+
return self.get_string("namespace").py_str
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def base_name(self) -> str:
|
|
67
|
+
return self.get_string("base_name").py_str
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def properties(self) -> CompoundTag:
|
|
71
|
+
return self.get_compound("properties")
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def metadata(self) -> CompoundTag:
|
|
75
|
+
return self.get_compound("metadata")
|