amulet-core 2.0a7__cp312-cp312-win_amd64.whl → 2.0.1.0.1297307203.19.43.34808.0a0__cp312-cp312-win_amd64.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/core/__init__.py +36 -0
- amulet/core/__pyinstaller/hook-amulet.core.py +4 -0
- amulet/core/_amulet_core.cp312-win_amd64.pyd +0 -0
- amulet/core/_amulet_core.pyi +7 -0
- amulet/{_version.py → core/_version.py} +3 -3
- amulet/core/amulet_core.dll +0 -0
- amulet/core/amulet_core.lib +0 -0
- amulet/core/amulet_coreConfig.cmake +18 -0
- amulet/{biome.pyi → core/biome/__init__.pyi} +3 -3
- amulet/core/biome/biome.hpp +53 -0
- amulet/{block.pyi → core/block/__init__.pyi} +25 -26
- amulet/core/block/block.hpp +156 -0
- amulet/{block_entity.pyi → core/block_entity/__init__.pyi} +7 -7
- amulet/core/block_entity/block_entity.hpp +84 -0
- amulet/{errors.py → core/chunk/__init__.pyi} +37 -33
- amulet/core/chunk/chunk.hpp +126 -0
- amulet/core/chunk/component/__init__.pyi +18 -0
- amulet/core/chunk/component/biome_3d_component.hpp +96 -0
- amulet/core/chunk/component/block_component.hpp +101 -0
- amulet/core/chunk/component/block_component.pyi +28 -0
- amulet/core/chunk/component/block_entity_component.hpp +119 -0
- amulet/core/chunk/component/section_array_map.hpp +129 -0
- amulet/{chunk_components.pyi → core/chunk/component/section_array_map.pyi} +4 -24
- amulet/core/dll.hpp +21 -0
- amulet/core/entity/__init__.pyi +105 -0
- amulet/core/entity/entity.hpp +100 -0
- amulet/{palette → core/palette}/__init__.pyi +2 -2
- amulet/core/palette/biome_palette.hpp +65 -0
- amulet/{palette → core/palette}/biome_palette.pyi +8 -8
- amulet/core/palette/block_palette.hpp +71 -0
- amulet/{palette → core/palette}/block_palette.pyi +12 -10
- amulet/core/selection/__init__.pyi +8 -0
- amulet/core/selection/box.hpp +86 -0
- amulet/core/selection/box.pyi +215 -0
- amulet/core/selection/group.hpp +80 -0
- amulet/core/selection/group.pyi +213 -0
- amulet/{version.pyi → core/version/__init__.pyi} +58 -10
- amulet/core/version/version.hpp +204 -0
- {amulet_core-2.0a7.dist-info → amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info}/METADATA +25 -20
- amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info/RECORD +45 -0
- {amulet_core-2.0a7.dist-info → amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info}/WHEEL +1 -1
- amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info/entry_points.txt +2 -0
- amulet/__init__.cp312-win_amd64.pyd +0 -0
- amulet/__init__.py.cpp +0 -43
- amulet/__init__.pyi +0 -28
- amulet/__pyinstaller/hook-amulet.py +0 -4
- amulet/_init.py +0 -26
- amulet/biome.cpp +0 -36
- amulet/biome.hpp +0 -43
- amulet/biome.py.cpp +0 -122
- amulet/block.cpp +0 -435
- amulet/block.hpp +0 -119
- amulet/block.py.cpp +0 -377
- amulet/block_entity.cpp +0 -12
- amulet/block_entity.hpp +0 -56
- amulet/block_entity.py.cpp +0 -115
- amulet/chunk.cpp +0 -16
- amulet/chunk.hpp +0 -99
- amulet/chunk.py.cpp +0 -80
- amulet/chunk.pyi +0 -28
- amulet/chunk_components/biome_3d_component.cpp +0 -5
- amulet/chunk_components/biome_3d_component.hpp +0 -79
- amulet/chunk_components/block_component.cpp +0 -41
- amulet/chunk_components/block_component.hpp +0 -88
- amulet/chunk_components/block_entity_component.cpp +0 -5
- amulet/chunk_components/block_entity_component.hpp +0 -147
- amulet/chunk_components/section_array_map.cpp +0 -129
- amulet/chunk_components/section_array_map.hpp +0 -147
- amulet/collections/eq.py.hpp +0 -37
- amulet/collections/hash.py.hpp +0 -27
- amulet/collections/holder.py.hpp +0 -37
- amulet/collections/iterator.py.hpp +0 -80
- amulet/collections/mapping.py.hpp +0 -199
- amulet/collections/mutable_mapping.py.hpp +0 -226
- amulet/collections/sequence.py.hpp +0 -163
- amulet/collections.pyi +0 -40
- amulet/data_types.py +0 -29
- amulet/entity.py +0 -182
- amulet/game/__init__.py +0 -7
- amulet/game/_game.py +0 -152
- amulet/game/_universal/__init__.py +0 -1
- amulet/game/_universal/_biome.py +0 -17
- amulet/game/_universal/_block.py +0 -47
- amulet/game/_universal/_version.py +0 -68
- amulet/game/abc/__init__.py +0 -22
- amulet/game/abc/_block_specification.py +0 -150
- amulet/game/abc/biome.py +0 -213
- amulet/game/abc/block.py +0 -331
- amulet/game/abc/game_version_container.py +0 -25
- amulet/game/abc/json_interface.py +0 -27
- amulet/game/abc/version.py +0 -44
- amulet/game/bedrock/__init__.py +0 -1
- amulet/game/bedrock/_biome.py +0 -35
- amulet/game/bedrock/_block.py +0 -42
- amulet/game/bedrock/_version.py +0 -165
- amulet/game/java/__init__.py +0 -2
- amulet/game/java/_biome.py +0 -35
- amulet/game/java/_block.py +0 -60
- amulet/game/java/_version.py +0 -176
- amulet/game/translate/__init__.py +0 -12
- amulet/game/translate/_functions/__init__.py +0 -15
- amulet/game/translate/_functions/_code_functions/__init__.py +0 -0
- amulet/game/translate/_functions/_code_functions/_text.py +0 -553
- amulet/game/translate/_functions/_code_functions/banner_pattern.py +0 -67
- amulet/game/translate/_functions/_code_functions/bedrock_chest_connection.py +0 -152
- amulet/game/translate/_functions/_code_functions/bedrock_moving_block_pos.py +0 -88
- amulet/game/translate/_functions/_code_functions/bedrock_sign.py +0 -152
- amulet/game/translate/_functions/_code_functions/bedrock_skull_rotation.py +0 -16
- amulet/game/translate/_functions/_code_functions/custom_name.py +0 -146
- amulet/game/translate/_functions/_frozen.py +0 -66
- amulet/game/translate/_functions/_state.py +0 -54
- amulet/game/translate/_functions/_typing.py +0 -98
- amulet/game/translate/_functions/abc.py +0 -123
- amulet/game/translate/_functions/carry_nbt.py +0 -160
- amulet/game/translate/_functions/carry_properties.py +0 -80
- amulet/game/translate/_functions/code.py +0 -143
- amulet/game/translate/_functions/map_block_name.py +0 -66
- amulet/game/translate/_functions/map_nbt.py +0 -111
- amulet/game/translate/_functions/map_properties.py +0 -93
- amulet/game/translate/_functions/multiblock.py +0 -112
- amulet/game/translate/_functions/new_block.py +0 -42
- amulet/game/translate/_functions/new_entity.py +0 -43
- amulet/game/translate/_functions/new_nbt.py +0 -206
- amulet/game/translate/_functions/new_properties.py +0 -64
- amulet/game/translate/_functions/sequence.py +0 -51
- amulet/game/translate/_functions/walk_input_nbt.py +0 -331
- amulet/game/translate/_translator.py +0 -433
- amulet/img/__init__.py +0 -10
- amulet/img/missing_no.png +0 -0
- amulet/img/missing_pack.png +0 -0
- amulet/img/missing_world.png +0 -0
- amulet/io/binary_reader.hpp +0 -45
- amulet/io/binary_writer.hpp +0 -30
- amulet/item.py +0 -75
- amulet/level/__init__.pyi +0 -23
- amulet/level/_load.py +0 -100
- amulet/level/abc/__init__.py +0 -12
- amulet/level/abc/_chunk_handle.py +0 -335
- amulet/level/abc/_dimension.py +0 -86
- amulet/level/abc/_history/__init__.py +0 -1
- amulet/level/abc/_history/_cache.py +0 -224
- amulet/level/abc/_history/_history_manager.py +0 -291
- amulet/level/abc/_level/__init__.py +0 -5
- amulet/level/abc/_level/_compactable_level.py +0 -10
- amulet/level/abc/_level/_creatable_level.py +0 -28
- amulet/level/abc/_level/_disk_level.py +0 -17
- amulet/level/abc/_level/_level.py +0 -449
- amulet/level/abc/_level/_loadable_level.py +0 -42
- amulet/level/abc/_player_storage.py +0 -7
- amulet/level/abc/_raw_level.py +0 -187
- amulet/level/abc/_registry.py +0 -40
- amulet/level/java/__init__.pyi +0 -16
- amulet/level/java/_chunk_handle.py +0 -17
- amulet/level/java/_dimension.py +0 -20
- amulet/level/java/_level.py +0 -184
- amulet/level/java/_raw/__init__.pyi +0 -15
- amulet/level/java/_raw/_chunk.pyi +0 -23
- amulet/level/java/_raw/_constant.py +0 -9
- amulet/level/java/_raw/_data_pack/__init__.py +0 -2
- amulet/level/java/_raw/_data_pack/data_pack.py +0 -241
- amulet/level/java/_raw/_data_pack/data_pack_manager.py +0 -77
- amulet/level/java/_raw/_dimension.py +0 -86
- amulet/level/java/_raw/_level.py +0 -507
- amulet/level/java/_raw/_typing.py +0 -3
- amulet/level/java/_raw/java_chunk_decode.cpp +0 -531
- amulet/level/java/_raw/java_chunk_decode.hpp +0 -23
- amulet/level/java/_raw/java_chunk_encode.cpp +0 -25
- amulet/level/java/_raw/java_chunk_encode.hpp +0 -23
- amulet/level/java/anvil/__init__.py +0 -2
- amulet/level/java/anvil/_dimension.py +0 -170
- amulet/level/java/anvil/_region.py +0 -421
- amulet/level/java/anvil/_sector_manager.py +0 -223
- amulet/level/java/chunk.pyi +0 -81
- amulet/level/java/chunk_/_chunk.py +0 -260
- amulet/level/java/chunk_/components/inhabited_time.py +0 -12
- amulet/level/java/chunk_/components/last_update.py +0 -12
- amulet/level/java/chunk_/components/legacy_version.py +0 -12
- amulet/level/java/chunk_/components/light_populated.py +0 -12
- amulet/level/java/chunk_/components/named_height_2d.py +0 -37
- amulet/level/java/chunk_/components/status.py +0 -11
- amulet/level/java/chunk_/components/terrain_populated.py +0 -12
- amulet/level/java/chunk_components/data_version_component.cpp +0 -32
- amulet/level/java/chunk_components/data_version_component.hpp +0 -31
- amulet/level/java/chunk_components/java_raw_chunk_component.cpp +0 -56
- amulet/level/java/chunk_components/java_raw_chunk_component.hpp +0 -45
- amulet/level/java/chunk_components.pyi +0 -22
- amulet/level/java/java_chunk.cpp +0 -170
- amulet/level/java/java_chunk.hpp +0 -141
- amulet/level/java/long_array.hpp +0 -175
- amulet/level/java/long_array.pyi +0 -39
- amulet/level/temporary_level/__init__.py +0 -1
- amulet/level/temporary_level/_level.py +0 -16
- amulet/mesh/__init__.py +0 -0
- amulet/mesh/block/__init__.py +0 -1
- amulet/mesh/block/block_mesh.py +0 -369
- amulet/mesh/block/cube.py +0 -149
- amulet/mesh/block/missing_block.py +0 -20
- amulet/mesh/util.py +0 -17
- amulet/palette/biome_palette.hpp +0 -85
- amulet/palette/block_palette.cpp +0 -32
- amulet/palette/block_palette.hpp +0 -93
- amulet/player.py +0 -62
- amulet/pybind11/collections.hpp +0 -118
- amulet/pybind11/numpy.hpp +0 -26
- amulet/pybind11/py_module.hpp +0 -34
- amulet/pybind11/type_hints.hpp +0 -51
- amulet/pybind11/types.hpp +0 -25
- amulet/pybind11/typing.hpp +0 -7
- amulet/resource_pack/__init__.py +0 -62
- amulet/resource_pack/abc/__init__.py +0 -2
- amulet/resource_pack/abc/resource_pack.py +0 -38
- amulet/resource_pack/abc/resource_pack_manager.py +0 -87
- amulet/resource_pack/bedrock/__init__.py +0 -2
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/pack_icon.png +0 -0
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/grass_carried.png +0 -0
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/grass_side_carried.png +0 -0
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/water.png +0 -0
- amulet/resource_pack/bedrock/blockshapes/__init__.py +0 -31
- amulet/resource_pack/bedrock/blockshapes/air.py +0 -35
- amulet/resource_pack/bedrock/blockshapes/base_blockshape.py +0 -29
- amulet/resource_pack/bedrock/blockshapes/bubble_column.py +0 -29
- amulet/resource_pack/bedrock/blockshapes/cake.py +0 -46
- amulet/resource_pack/bedrock/blockshapes/chest.py +0 -54
- amulet/resource_pack/bedrock/blockshapes/comparator.py +0 -51
- amulet/resource_pack/bedrock/blockshapes/cross_texture.py +0 -186
- amulet/resource_pack/bedrock/blockshapes/cross_texture0.py +0 -17
- amulet/resource_pack/bedrock/blockshapes/cross_texture_green.py +0 -16
- amulet/resource_pack/bedrock/blockshapes/cube.py +0 -38
- amulet/resource_pack/bedrock/blockshapes/default.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door.py +0 -38
- amulet/resource_pack/bedrock/blockshapes/door1.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door2.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door3.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door4.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door5.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door6.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/double_plant.py +0 -40
- amulet/resource_pack/bedrock/blockshapes/enchanting_table.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/farmland.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/fence.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/flat.py +0 -55
- amulet/resource_pack/bedrock/blockshapes/flat_wall.py +0 -55
- amulet/resource_pack/bedrock/blockshapes/furnace.py +0 -44
- amulet/resource_pack/bedrock/blockshapes/furnace_lit.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/green_cube.py +0 -39
- amulet/resource_pack/bedrock/blockshapes/ladder.py +0 -36
- amulet/resource_pack/bedrock/blockshapes/lilypad.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/partial_block.py +0 -57
- amulet/resource_pack/bedrock/blockshapes/piston.py +0 -44
- amulet/resource_pack/bedrock/blockshapes/piston_arm.py +0 -72
- amulet/resource_pack/bedrock/blockshapes/portal_frame.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/pressure_plate.py +0 -29
- amulet/resource_pack/bedrock/blockshapes/pumpkin.py +0 -36
- amulet/resource_pack/bedrock/blockshapes/pumpkin_carved.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/pumpkin_lit.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/red_dust.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/repeater.py +0 -53
- amulet/resource_pack/bedrock/blockshapes/slab.py +0 -33
- amulet/resource_pack/bedrock/blockshapes/slab_double.py +0 -15
- amulet/resource_pack/bedrock/blockshapes/tree.py +0 -41
- amulet/resource_pack/bedrock/blockshapes/turtle_egg.py +0 -15
- amulet/resource_pack/bedrock/blockshapes/vine.py +0 -52
- amulet/resource_pack/bedrock/blockshapes/wall.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/water.py +0 -38
- amulet/resource_pack/bedrock/download_resources.py +0 -147
- amulet/resource_pack/bedrock/resource_pack.py +0 -40
- amulet/resource_pack/bedrock/resource_pack_manager.py +0 -361
- amulet/resource_pack/bedrock/sort_blockshapes.py +0 -15
- amulet/resource_pack/java/__init__.py +0 -2
- amulet/resource_pack/java/download_resources.py +0 -212
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_black.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_blue.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_brown.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_cyan.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_gray.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_green.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_blue.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_gray.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_lime.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_magenta.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_orange.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_pink.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_purple.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_red.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_white.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_yellow.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/barrier.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/end_portal.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/grass.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/structure_void.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/pack.png +0 -0
- amulet/resource_pack/java/resource_pack.py +0 -44
- amulet/resource_pack/java/resource_pack_manager.py +0 -551
- amulet/resource_pack/unknown_resource_pack.py +0 -10
- amulet/selection/__init__.py +0 -2
- amulet/selection/abstract_selection.py +0 -342
- amulet/selection/box.py +0 -852
- amulet/selection/group.py +0 -481
- amulet/utils/__init__.pyi +0 -23
- amulet/utils/call_spec/__init__.py +0 -24
- amulet/utils/call_spec/_call_spec.py +0 -257
- amulet/utils/comment_json.py +0 -188
- amulet/utils/format_utils.py +0 -41
- amulet/utils/generator.py +0 -18
- amulet/utils/matrix.py +0 -243
- amulet/utils/numpy.hpp +0 -36
- amulet/utils/numpy.pyi +0 -11
- amulet/utils/numpy_helpers.py +0 -19
- amulet/utils/shareable_lock.py +0 -335
- amulet/utils/signal/__init__.py +0 -10
- amulet/utils/signal/_signal.py +0 -228
- amulet/utils/task_manager.py +0 -235
- amulet/utils/typed_property.py +0 -111
- amulet/utils/weakref.py +0 -70
- amulet/utils/world_utils.py +0 -102
- amulet/version.cpp +0 -136
- amulet/version.hpp +0 -142
- amulet/version.py.cpp +0 -281
- amulet_core-2.0a7.dist-info/RECORD +0 -295
- amulet_core-2.0a7.dist-info/entry_points.txt +0 -2
- /amulet/{__pyinstaller → core/__pyinstaller}/__init__.py +0 -0
- /amulet/{py.typed → core/py.typed} +0 -0
- {amulet_core-2.0a7.dist-info → amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info}/top_level.txt +0 -0
amulet/utils/matrix.py
DELETED
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
from typing import Literal
|
|
2
|
-
import math
|
|
3
|
-
import numpy
|
|
4
|
-
from amulet.data_types import FloatTriplet, PointCoordinates
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def scale_matrix(sx: float, sy: float, sz: float) -> numpy.ndarray:
|
|
8
|
-
"""
|
|
9
|
-
Create a scale matrix from the inputs specified
|
|
10
|
-
|
|
11
|
-
:param sx: The scale in the x axis
|
|
12
|
-
:param sy: The scale in the y axis
|
|
13
|
-
:param sz: The scale in the z axis
|
|
14
|
-
:return: The 4x4 scale matrix
|
|
15
|
-
"""
|
|
16
|
-
return numpy.array(
|
|
17
|
-
[[sx, 0, 0, 0], [0, sy, 0, 0], [0, 0, sz, 0], [0, 0, 0, 1]], dtype=numpy.float64
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def displacement_matrix(x: float, y: float, z: float) -> numpy.ndarray:
|
|
22
|
-
"""
|
|
23
|
-
Create a displacement matrix from the inputs specified
|
|
24
|
-
|
|
25
|
-
:param x: The displacement in the x axis
|
|
26
|
-
:param y: The displacement in the y axis
|
|
27
|
-
:param z: The displacement in the z axis
|
|
28
|
-
:return: The 4x4 displacement matrix
|
|
29
|
-
"""
|
|
30
|
-
return numpy.array(
|
|
31
|
-
[[1, 0, 0, x], [0, 1, 0, y], [0, 0, 1, z], [0, 0, 0, 1]], dtype=numpy.float64
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def _rotation_matrix(*angles: float, order: str) -> numpy.ndarray:
|
|
36
|
-
"""
|
|
37
|
-
Create a rotation matrix from the inputs specified
|
|
38
|
-
|
|
39
|
-
:param angles: The angles in radians
|
|
40
|
-
:param order: The order the angles are specified. Transforms will be applied in this order.
|
|
41
|
-
:return: The 4x4 rotation matrix
|
|
42
|
-
"""
|
|
43
|
-
assert isinstance(order, str) and len(order) == len(
|
|
44
|
-
angles
|
|
45
|
-
), "Order must be a string of the same length as angles."
|
|
46
|
-
mat = numpy.identity(4, dtype=numpy.float64)
|
|
47
|
-
|
|
48
|
-
for angle, axis in zip(angles, order):
|
|
49
|
-
if angle:
|
|
50
|
-
c = math.cos(angle)
|
|
51
|
-
s = math.sin(angle)
|
|
52
|
-
if axis == "x":
|
|
53
|
-
mat = numpy.matmul(
|
|
54
|
-
numpy.array(
|
|
55
|
-
[[1, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, 1]],
|
|
56
|
-
dtype=numpy.float64,
|
|
57
|
-
),
|
|
58
|
-
mat,
|
|
59
|
-
)
|
|
60
|
-
elif axis == "y":
|
|
61
|
-
mat = numpy.matmul(
|
|
62
|
-
numpy.array(
|
|
63
|
-
[[c, 0, s, 0], [0, 1, 0, 0], [-s, 0, c, 0], [0, 0, 0, 1]],
|
|
64
|
-
dtype=numpy.float64,
|
|
65
|
-
),
|
|
66
|
-
mat,
|
|
67
|
-
)
|
|
68
|
-
elif axis == "z":
|
|
69
|
-
mat = numpy.matmul(
|
|
70
|
-
numpy.array(
|
|
71
|
-
[[c, -s, 0, 0], [s, c, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]],
|
|
72
|
-
dtype=numpy.float64,
|
|
73
|
-
),
|
|
74
|
-
mat,
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
return mat
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def rotation_matrix_x(rx: float) -> numpy.ndarray:
|
|
81
|
-
"""
|
|
82
|
-
Create a rotation matrix in the x axis
|
|
83
|
-
|
|
84
|
-
:param rx: The angle in radians
|
|
85
|
-
:return: The 4x4 rotation matrix
|
|
86
|
-
"""
|
|
87
|
-
return _rotation_matrix(rx, order="x")
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def rotation_matrix_y(ry: float) -> numpy.ndarray:
|
|
91
|
-
"""
|
|
92
|
-
Create a rotation matrix in the x axis
|
|
93
|
-
|
|
94
|
-
:param ry: The angle in radians
|
|
95
|
-
:return: The 4x4 rotation matrix
|
|
96
|
-
"""
|
|
97
|
-
return _rotation_matrix(ry, order="y")
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def rotation_matrix_z(rz: float) -> numpy.ndarray:
|
|
101
|
-
"""
|
|
102
|
-
Create a rotation matrix in the x axis
|
|
103
|
-
|
|
104
|
-
:param rz: The angle in radians
|
|
105
|
-
:return: The 4x4 rotation matrix
|
|
106
|
-
"""
|
|
107
|
-
return _rotation_matrix(rz, order="z")
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def rotation_matrix_xy(rx: float, ry: float) -> numpy.ndarray:
|
|
111
|
-
"""
|
|
112
|
-
Create a rotation matrix from the inputs specified
|
|
113
|
-
|
|
114
|
-
:param rx: The rotation in radians in the x axis
|
|
115
|
-
:param ry: The rotation in radians in the y axis
|
|
116
|
-
:return: The 4x4 rotation matrix
|
|
117
|
-
"""
|
|
118
|
-
return _rotation_matrix(rx, ry, order="xy")
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def rotation_matrix_yx(ry: float, rx: float) -> numpy.ndarray:
|
|
122
|
-
"""
|
|
123
|
-
Create a rotation matrix from the inputs specified
|
|
124
|
-
|
|
125
|
-
:param rx: The rotation in radians in the x axis
|
|
126
|
-
:param ry: The rotation in radians in the y axis
|
|
127
|
-
:return: The 4x4 rotation matrix
|
|
128
|
-
"""
|
|
129
|
-
return _rotation_matrix(ry, rx, order="yx")
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
def rotation_matrix_xyz(x: float, y: float, z: float) -> numpy.ndarray:
|
|
133
|
-
"""
|
|
134
|
-
Create a rotation matrix from the inputs specified
|
|
135
|
-
|
|
136
|
-
:param x: The rotation in radians in the x axis
|
|
137
|
-
:param y: The rotation in radians in the y axis
|
|
138
|
-
:param z: The rotation in radians in the z axis
|
|
139
|
-
:return: The 4x4 rotation matrix
|
|
140
|
-
"""
|
|
141
|
-
return _rotation_matrix(x, y, z, order="xyz")
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def transform_matrix(
|
|
145
|
-
scale: FloatTriplet,
|
|
146
|
-
rotation: FloatTriplet,
|
|
147
|
-
displacement: PointCoordinates,
|
|
148
|
-
order: Literal["xyz", "xzy", "yxz", "yzx", "zxy", "zyx"] = "xyz",
|
|
149
|
-
) -> numpy.ndarray:
|
|
150
|
-
"""Create a 4x4 transformation matrix from the scale, rotation and displacement specified.
|
|
151
|
-
|
|
152
|
-
:param scale: The scale in the x, y and z axis
|
|
153
|
-
:param rotation: The rotation in the x, y and z axis in radians. (axis can be changed using `order`)
|
|
154
|
-
:param displacement: The displacement in the x, y and z axis
|
|
155
|
-
:param order: The order to apply the rotations in.
|
|
156
|
-
:return: The 4x4 transformation matrix of combined scale, rotation and displacement
|
|
157
|
-
"""
|
|
158
|
-
scale_transform = scale_matrix(*scale)
|
|
159
|
-
rotation_transform = _rotation_matrix(*rotation, order=order)
|
|
160
|
-
displacement_transform = displacement_matrix(*displacement)
|
|
161
|
-
return numpy.matmul( # type: ignore
|
|
162
|
-
displacement_transform,
|
|
163
|
-
numpy.matmul(rotation_transform, scale_transform),
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
def inverse_transform_matrix(
|
|
168
|
-
scale: FloatTriplet,
|
|
169
|
-
rotation: FloatTriplet,
|
|
170
|
-
displacement: PointCoordinates,
|
|
171
|
-
order: Literal["xyz", "xzy", "yxz", "yzx", "zxy", "zyx"] = "xyz",
|
|
172
|
-
) -> numpy.ndarray:
|
|
173
|
-
"""Create the inverse of the 4x4 transformation matrix from the scale, rotation and displacement specified.
|
|
174
|
-
This should be the inverse of transform_matrix
|
|
175
|
-
|
|
176
|
-
:param scale: The scale in the x, y and z axis
|
|
177
|
-
:param rotation: The rotation in the x, y and z axis (axis can be changed using `order`)
|
|
178
|
-
:param displacement: The displacement in the x, y and z axis
|
|
179
|
-
:param order: The order to apply the rotations in.
|
|
180
|
-
:return: The 4x4 transformation matrix of combined scale, rotation and displacement
|
|
181
|
-
"""
|
|
182
|
-
scale_transform = scale_matrix(*1 / numpy.asarray(scale))
|
|
183
|
-
ra, rb, rc = -numpy.asarray(rotation)
|
|
184
|
-
rotation_transform = _rotation_matrix(
|
|
185
|
-
rc, rb, ra, order="".join(list(reversed(order)))
|
|
186
|
-
)
|
|
187
|
-
displacement_transform = displacement_matrix(*-numpy.asarray(displacement))
|
|
188
|
-
return numpy.matmul( # type: ignore
|
|
189
|
-
scale_transform,
|
|
190
|
-
numpy.matmul(rotation_transform, displacement_transform),
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
def decompose_transformation_matrix(
|
|
195
|
-
matrix: numpy.ndarray,
|
|
196
|
-
) -> tuple[
|
|
197
|
-
tuple[float, float, float], tuple[float, float, float], tuple[float, float, float]
|
|
198
|
-
]:
|
|
199
|
-
"""
|
|
200
|
-
Decompose a 4x4 transformation matrix into scale, rotation and displacement tuples.
|
|
201
|
-
|
|
202
|
-
:param matrix: The matrix to decompose.
|
|
203
|
-
:return: The scale, rotation and displacement.
|
|
204
|
-
"""
|
|
205
|
-
assert isinstance(matrix, numpy.ndarray), "Matrix must be an ndarray"
|
|
206
|
-
assert matrix.shape == (4, 4), "Expected a 4x4 numpy array"
|
|
207
|
-
# https://gist.github.com/Aerilius/0cbc46271c163746717902b36bea8fd4
|
|
208
|
-
# 0 4 8 12
|
|
209
|
-
# 1 5 9 13
|
|
210
|
-
# 2 6 10 14
|
|
211
|
-
# 3 7 11 15
|
|
212
|
-
matrix = matrix.copy() # just in case
|
|
213
|
-
displacement = tuple(matrix[:3, 3].tolist())
|
|
214
|
-
matrix[:3, 3] = 0
|
|
215
|
-
scale_np = numpy.linalg.norm(matrix[:3, :3], axis=0) * matrix[3, 3]
|
|
216
|
-
scale = tuple(scale_np.tolist())
|
|
217
|
-
matrix[:3, :3] = matrix[:3, :3] / scale_np
|
|
218
|
-
|
|
219
|
-
matrix[3, 3] = 1
|
|
220
|
-
|
|
221
|
-
if (
|
|
222
|
-
numpy.dot(
|
|
223
|
-
numpy.cross(
|
|
224
|
-
matrix[:3, 0],
|
|
225
|
-
matrix[:3, 1],
|
|
226
|
-
),
|
|
227
|
-
matrix[:3, 2],
|
|
228
|
-
)
|
|
229
|
-
< 0
|
|
230
|
-
):
|
|
231
|
-
scale = (-scale[0], scale[1], scale[2])
|
|
232
|
-
matrix[:3, 0] *= -1
|
|
233
|
-
|
|
234
|
-
rotation = (
|
|
235
|
-
math.atan2(matrix[2, 1], matrix[2, 2]),
|
|
236
|
-
math.atan2(
|
|
237
|
-
-matrix[2, 0],
|
|
238
|
-
(matrix[2, 1] ** 2 + matrix[2, 2] ** 2) ** 0.5,
|
|
239
|
-
),
|
|
240
|
-
math.atan2(matrix[1, 0], matrix[0, 0]),
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
return scale, rotation, displacement
|
amulet/utils/numpy.hpp
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include <cstdint>
|
|
4
|
-
#include <vector>
|
|
5
|
-
#include <utility>
|
|
6
|
-
#include <span>
|
|
7
|
-
#include <unordered_map>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
namespace Amulet {
|
|
11
|
-
// dtypeT can be any numerical type.
|
|
12
|
-
// inverseT must be large enough to store the length of arr.
|
|
13
|
-
template <typename dtypeT, typename inverseT>
|
|
14
|
-
void unique_inverse(const std::span<dtypeT> arr, std::vector<dtypeT>& unique, std::span<inverseT>& inverse){
|
|
15
|
-
if (arr.size() != inverse.size()){
|
|
16
|
-
throw std::invalid_argument("arr and inverse must have the same size.");
|
|
17
|
-
}
|
|
18
|
-
if (unique.size()){
|
|
19
|
-
throw std::invalid_argument("unique must be empty.");
|
|
20
|
-
}
|
|
21
|
-
// Map from found values to their index in unique
|
|
22
|
-
std::unordered_map<dtypeT, inverseT> value_to_index;
|
|
23
|
-
|
|
24
|
-
for (inverseT i = 0; i < arr.size(); i++){
|
|
25
|
-
dtypeT value = arr[i];
|
|
26
|
-
auto it = value_to_index.find(value);
|
|
27
|
-
if (it == value_to_index.end()){
|
|
28
|
-
inverse[i] = unique.size();
|
|
29
|
-
value_to_index[value] = unique.size();
|
|
30
|
-
unique.push_back(value);
|
|
31
|
-
} else {
|
|
32
|
-
inverse[i] = it->second;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
amulet/utils/numpy.pyi
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import numpy
|
|
4
|
-
import numpy.typing
|
|
5
|
-
import typing_extensions
|
|
6
|
-
|
|
7
|
-
__all__ = ["unique_inverse"]
|
|
8
|
-
|
|
9
|
-
def unique_inverse(
|
|
10
|
-
array: typing_extensions.Buffer,
|
|
11
|
-
) -> tuple[numpy.typing.NDArray[numpy.uint32], numpy.typing.NDArray[numpy.uint32]]: ...
|
amulet/utils/numpy_helpers.py
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from typing import TypeVar
|
|
2
|
-
from collections.abc import Collection
|
|
3
|
-
import numpy
|
|
4
|
-
|
|
5
|
-
T = TypeVar("T")
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def brute_sort_objects_no_hash(data: Collection[T]) -> tuple[list[T], numpy.ndarray]:
|
|
9
|
-
unique: list[T] = []
|
|
10
|
-
inverse = numpy.zeros(dtype=numpy.uint32, shape=len(data))
|
|
11
|
-
for i, d in enumerate(data):
|
|
12
|
-
try:
|
|
13
|
-
index = unique.index(d)
|
|
14
|
-
except ValueError:
|
|
15
|
-
index = len(unique)
|
|
16
|
-
unique.append(d)
|
|
17
|
-
inverse[i] = index
|
|
18
|
-
|
|
19
|
-
return unique, numpy.array(inverse)
|
amulet/utils/shareable_lock.py
DELETED
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
from typing import Callable, Iterator
|
|
2
|
-
from threading import Lock, Condition, get_ident
|
|
3
|
-
from contextlib import contextmanager
|
|
4
|
-
import time
|
|
5
|
-
import logging
|
|
6
|
-
|
|
7
|
-
from .task_manager import AbstractCancelManager, VoidCancelManager, TaskCancelled
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
log = logging.getLogger(__name__)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class LockNotAcquired(TaskCancelled):
|
|
14
|
-
"""An exception raised if the lock was not acquired."""
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class ShareableRLock:
|
|
18
|
-
"""
|
|
19
|
-
This is a custom lock implementation that can be acquired in
|
|
20
|
-
1) unique mode.
|
|
21
|
-
- This is the normal mode where only this thread can use the resource.
|
|
22
|
-
- All other acquires block until this releases it.
|
|
23
|
-
2) shared mode.
|
|
24
|
-
- This allows multiple threads to acquire the resource at the same time.
|
|
25
|
-
- This is useful if multiple threads want to read a resource but not write to it.
|
|
26
|
-
- If the resource is locked in unique mode this will block
|
|
27
|
-
- Once locked in shared mode it
|
|
28
|
-
|
|
29
|
-
"""
|
|
30
|
-
|
|
31
|
-
_state_lock: Lock
|
|
32
|
-
_state_condition: Condition
|
|
33
|
-
_blocking_threads: dict[
|
|
34
|
-
int, tuple[bool, bool]
|
|
35
|
-
] # dict[thread_id, tuple[is_serial, is_blocking]]
|
|
36
|
-
_unique_thread: int | None
|
|
37
|
-
_unique_r_count: int
|
|
38
|
-
_shared_threads: dict[
|
|
39
|
-
int, int
|
|
40
|
-
] # Map from thread id to the number of times it has been acquired in shared mode.
|
|
41
|
-
|
|
42
|
-
def __init__(self) -> None:
|
|
43
|
-
self._state_lock = Lock()
|
|
44
|
-
self._state_condition = Condition(self._state_lock)
|
|
45
|
-
self._blocking_threads = {}
|
|
46
|
-
self._unique_thread = None
|
|
47
|
-
self._unique_r_count = 0
|
|
48
|
-
self._shared_threads = {}
|
|
49
|
-
|
|
50
|
-
def _wait(
|
|
51
|
-
self,
|
|
52
|
-
exit_condition: Callable[[], bool],
|
|
53
|
-
blocking: bool = True,
|
|
54
|
-
timeout: float = -1,
|
|
55
|
-
task_manager: AbstractCancelManager = VoidCancelManager(),
|
|
56
|
-
) -> bool:
|
|
57
|
-
"""Wait until a condition is False.
|
|
58
|
-
|
|
59
|
-
:param exit_condition: The condition to check.
|
|
60
|
-
:param blocking: Should this block until the lock can be acquired. Default is True.
|
|
61
|
-
If false and the lock cannot be acquired on the first try, this returns False.
|
|
62
|
-
:param timeout: Maximum amount of time to block for. Has no effect is blocking is False. Default is forever.
|
|
63
|
-
:param task_manager: A custom object through which acquiring can be cancelled.
|
|
64
|
-
This effectively manually triggers timeout.
|
|
65
|
-
This is useful for GUIs so that the user can cancel an operation that may otherwise block for a while.
|
|
66
|
-
:return: True if the lock was acquired, otherwise False.
|
|
67
|
-
"""
|
|
68
|
-
if task_manager.is_cancel_requested():
|
|
69
|
-
return False
|
|
70
|
-
|
|
71
|
-
if exit_condition():
|
|
72
|
-
# We don't need to wait
|
|
73
|
-
return True
|
|
74
|
-
|
|
75
|
-
if not blocking:
|
|
76
|
-
# Need to wait but told not to
|
|
77
|
-
return False
|
|
78
|
-
|
|
79
|
-
if timeout == -1:
|
|
80
|
-
# wait with no timeout
|
|
81
|
-
while not exit_condition():
|
|
82
|
-
if task_manager.is_cancel_requested():
|
|
83
|
-
return False
|
|
84
|
-
self._state_condition.wait()
|
|
85
|
-
return True
|
|
86
|
-
|
|
87
|
-
else:
|
|
88
|
-
# Wait with a timeout
|
|
89
|
-
end_time = time.time() + timeout
|
|
90
|
-
while not exit_condition():
|
|
91
|
-
if task_manager.is_cancel_requested():
|
|
92
|
-
return False
|
|
93
|
-
wait_time = end_time - time.time()
|
|
94
|
-
if wait_time > 0:
|
|
95
|
-
self._state_condition.wait(wait_time)
|
|
96
|
-
else:
|
|
97
|
-
return False
|
|
98
|
-
return True
|
|
99
|
-
|
|
100
|
-
def acquire_unique(
|
|
101
|
-
self,
|
|
102
|
-
blocking: bool = True,
|
|
103
|
-
timeout: float = -1,
|
|
104
|
-
task_manager: AbstractCancelManager = VoidCancelManager(),
|
|
105
|
-
) -> bool:
|
|
106
|
-
"""
|
|
107
|
-
Only use this if you know what you are doing. Consider using :meth:`unique` instead
|
|
108
|
-
Acquire the lock in unique mode. This is equivalent to threading.RLock.acquire
|
|
109
|
-
With improper use this can lead to a deadlock.
|
|
110
|
-
:param blocking: Should this block until the lock can be acquired. Default is True.
|
|
111
|
-
If false and the lock cannot be acquired on the first try, this returns False.
|
|
112
|
-
:param timeout: Maximum amount of time to block for. Has no effect is blocking is False. Default is forever.
|
|
113
|
-
:param task_manager: A custom object through which acquiring can be cancelled.
|
|
114
|
-
This effectively manually triggers timeout.
|
|
115
|
-
This is useful for GUIs so that the user can cancel an operation that may otherwise block for a while.
|
|
116
|
-
:return: True if the lock was acquired otherwise False.
|
|
117
|
-
"""
|
|
118
|
-
with self._state_lock:
|
|
119
|
-
ident = get_ident()
|
|
120
|
-
if (
|
|
121
|
-
ident in self._shared_threads
|
|
122
|
-
and blocking
|
|
123
|
-
and timeout == -1
|
|
124
|
-
and any(
|
|
125
|
-
self._blocking_threads[thread_id][1]
|
|
126
|
-
for thread_id in self._blocking_threads
|
|
127
|
-
if thread_id in self._shared_threads
|
|
128
|
-
)
|
|
129
|
-
):
|
|
130
|
-
logging.warning("Possible deadlock")
|
|
131
|
-
|
|
132
|
-
def on_cancel() -> None:
|
|
133
|
-
with self._state_lock:
|
|
134
|
-
self._state_condition.notify_all()
|
|
135
|
-
|
|
136
|
-
task_manager.register_on_cancel(on_cancel)
|
|
137
|
-
|
|
138
|
-
self._blocking_threads[ident] = (
|
|
139
|
-
True,
|
|
140
|
-
blocking
|
|
141
|
-
and timeout == -1
|
|
142
|
-
and isinstance(task_manager, VoidCancelManager),
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
def exit_condition() -> bool:
|
|
146
|
-
# The thread was the first to join
|
|
147
|
-
# The lock is not locked or is locked by this thread
|
|
148
|
-
can_exit = (
|
|
149
|
-
next(iter(self._blocking_threads)) == ident
|
|
150
|
-
and self._unique_thread in (None, ident)
|
|
151
|
-
and self._shared_threads.keys() in (set(), {ident})
|
|
152
|
-
)
|
|
153
|
-
if can_exit:
|
|
154
|
-
self._blocking_threads.pop(ident)
|
|
155
|
-
return can_exit
|
|
156
|
-
|
|
157
|
-
locked = self._wait(
|
|
158
|
-
exit_condition,
|
|
159
|
-
blocking,
|
|
160
|
-
timeout,
|
|
161
|
-
task_manager,
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
task_manager.unregister_on_cancel(on_cancel)
|
|
165
|
-
|
|
166
|
-
if locked:
|
|
167
|
-
# Lock it
|
|
168
|
-
self._unique_thread = ident
|
|
169
|
-
self._unique_r_count += 1
|
|
170
|
-
return True
|
|
171
|
-
else:
|
|
172
|
-
self._blocking_threads.pop(ident)
|
|
173
|
-
return False
|
|
174
|
-
|
|
175
|
-
def release_unique(self) -> None:
|
|
176
|
-
"""
|
|
177
|
-
Only use this if you know what you are doing. Consider using :meth:`unique` instead
|
|
178
|
-
Release the unique hold on the lock. This must be called by the same thread that acquired it.
|
|
179
|
-
This must be called exactly the same number of times as :meth:`acquire_unique` was called.
|
|
180
|
-
"""
|
|
181
|
-
with self._state_lock:
|
|
182
|
-
if self._unique_thread != get_ident():
|
|
183
|
-
raise RuntimeError("Lock released by a thread that does not own it.")
|
|
184
|
-
|
|
185
|
-
self._unique_r_count -= 1
|
|
186
|
-
if self._unique_r_count == 0:
|
|
187
|
-
self._unique_thread = None
|
|
188
|
-
# Let another thread continue
|
|
189
|
-
self._state_condition.notify_all()
|
|
190
|
-
|
|
191
|
-
def acquire_shared(
|
|
192
|
-
self,
|
|
193
|
-
blocking: bool = True,
|
|
194
|
-
timeout: float = -1,
|
|
195
|
-
task_manager: AbstractCancelManager = VoidCancelManager(),
|
|
196
|
-
) -> bool:
|
|
197
|
-
"""
|
|
198
|
-
Only use this if you know what you are doing. Consider using :meth:`shared` instead
|
|
199
|
-
Acquire the lock in shared mode.
|
|
200
|
-
:param blocking: Should this block until the lock can be acquired. Default is True.
|
|
201
|
-
If false and the lock cannot be acquired on the first try, this returns False.
|
|
202
|
-
:param timeout: Maximum amount of time to block for. Has no effect is blocking is False. Default is forever.
|
|
203
|
-
:param task_manager: A custom object through which acquiring can be cancelled.
|
|
204
|
-
This effectively manually triggers timeout.
|
|
205
|
-
This is useful for GUIs so that the user can cancel an operation that may otherwise block for a while.
|
|
206
|
-
:return: True if the lock was acquired otherwise False.
|
|
207
|
-
"""
|
|
208
|
-
with self._state_lock:
|
|
209
|
-
ident = get_ident()
|
|
210
|
-
|
|
211
|
-
def exit_condition() -> bool:
|
|
212
|
-
if self._unique_thread == ident or ident in self._shared_threads:
|
|
213
|
-
# Lock is already acquired by this thread
|
|
214
|
-
self._blocking_threads.pop(ident)
|
|
215
|
-
return True
|
|
216
|
-
elif self._unique_thread is None:
|
|
217
|
-
# Is it not locked in unique mode
|
|
218
|
-
for thread_id, (is_serial, _) in self._blocking_threads.items():
|
|
219
|
-
if is_serial:
|
|
220
|
-
return False
|
|
221
|
-
elif thread_id == ident:
|
|
222
|
-
self._blocking_threads.pop(ident)
|
|
223
|
-
return True
|
|
224
|
-
return False
|
|
225
|
-
|
|
226
|
-
def on_cancel() -> None:
|
|
227
|
-
with self._state_lock:
|
|
228
|
-
self._state_condition.notify_all()
|
|
229
|
-
|
|
230
|
-
task_manager.register_on_cancel(on_cancel)
|
|
231
|
-
|
|
232
|
-
self._blocking_threads[ident] = (False, False)
|
|
233
|
-
|
|
234
|
-
locked = self._wait(exit_condition, blocking, timeout, task_manager)
|
|
235
|
-
|
|
236
|
-
task_manager.unregister_on_cancel(on_cancel)
|
|
237
|
-
|
|
238
|
-
if locked:
|
|
239
|
-
# Not unique locked or unique locked by the current thread
|
|
240
|
-
self._shared_threads.setdefault(ident, 0)
|
|
241
|
-
self._shared_threads[ident] += 1
|
|
242
|
-
return True
|
|
243
|
-
else:
|
|
244
|
-
self._blocking_threads.pop(ident)
|
|
245
|
-
return False
|
|
246
|
-
|
|
247
|
-
def release_shared(self) -> None:
|
|
248
|
-
"""
|
|
249
|
-
Only use this if you know what you are doing. Consider using :meth:`shared` instead
|
|
250
|
-
Release the shared hold on the lock. This must be called by the same thread that acquired it.
|
|
251
|
-
This must be called exactly the same number of times as :meth:`acquire_shared` was called.
|
|
252
|
-
"""
|
|
253
|
-
with self._state_lock:
|
|
254
|
-
ident = get_ident()
|
|
255
|
-
if ident not in self._shared_threads:
|
|
256
|
-
raise RuntimeError("Lock released by a thread that does not own it.")
|
|
257
|
-
|
|
258
|
-
self._shared_threads[ident] -= 1
|
|
259
|
-
if self._shared_threads[ident] == 0:
|
|
260
|
-
self._shared_threads.pop(ident)
|
|
261
|
-
self._state_condition.notify_all()
|
|
262
|
-
|
|
263
|
-
@contextmanager
|
|
264
|
-
def unique(
|
|
265
|
-
self,
|
|
266
|
-
blocking: bool = True,
|
|
267
|
-
timeout: float = -1,
|
|
268
|
-
task_manager: AbstractCancelManager = VoidCancelManager(),
|
|
269
|
-
) -> Iterator[None]:
|
|
270
|
-
"""
|
|
271
|
-
Acquire the lock in unique mode.
|
|
272
|
-
This is used as follows
|
|
273
|
-
|
|
274
|
-
>>> lock: ShareableRLock
|
|
275
|
-
>>> with lock.unique():
|
|
276
|
-
>>> # code with lock acquired
|
|
277
|
-
>>> # the lock will automatically be released here
|
|
278
|
-
|
|
279
|
-
This will block while all other threads using the resource finish
|
|
280
|
-
and once acquired block all other threads until the lock is released.
|
|
281
|
-
|
|
282
|
-
:param blocking: Should this block until the lock can be acquired. Default is True.
|
|
283
|
-
If false and the lock cannot be acquired on the first try, this returns False.
|
|
284
|
-
:param timeout: Maximum amount of time to block for. Has no effect is blocking is False. Default is forever.
|
|
285
|
-
:param task_manager: A custom object through which acquiring can be cancelled.
|
|
286
|
-
This effectively manually triggers timeout.
|
|
287
|
-
This is useful for GUIs so that the user can cancel an operation that may otherwise block for a while.
|
|
288
|
-
:return: None
|
|
289
|
-
:raises: LockNotAcquired if the lock could not be acquired.
|
|
290
|
-
"""
|
|
291
|
-
if not self.acquire_unique(blocking, timeout, task_manager):
|
|
292
|
-
raise LockNotAcquired
|
|
293
|
-
try:
|
|
294
|
-
yield
|
|
295
|
-
finally:
|
|
296
|
-
self.release_unique()
|
|
297
|
-
|
|
298
|
-
@contextmanager
|
|
299
|
-
def shared(
|
|
300
|
-
self,
|
|
301
|
-
blocking: bool = True,
|
|
302
|
-
timeout: float = -1,
|
|
303
|
-
task_manager: AbstractCancelManager = VoidCancelManager(),
|
|
304
|
-
) -> Iterator[None]:
|
|
305
|
-
"""
|
|
306
|
-
Acquire the lock in shared mode.
|
|
307
|
-
This is used as follows
|
|
308
|
-
|
|
309
|
-
>>> lock: ShareableRLock
|
|
310
|
-
>>> with lock.shared():
|
|
311
|
-
>>> # code with lock acquired
|
|
312
|
-
>>> # the lock will automatically be released here
|
|
313
|
-
|
|
314
|
-
If the lock is acquired by a different thread in unique mode then this will block until it is finished.
|
|
315
|
-
If the lock is acquired in unique mode by this thread or by otherthreads in shared mode then this will acquire
|
|
316
|
-
the lock.
|
|
317
|
-
|
|
318
|
-
If another thread wants to acquire the lock in unique mode it will block until all threads have finished in
|
|
319
|
-
shared mode.
|
|
320
|
-
|
|
321
|
-
:param blocking: Should this block until the lock can be acquired. Default is True.
|
|
322
|
-
If false and the lock cannot be acquired on the first try, this returns False.
|
|
323
|
-
:param timeout: Maximum amount of time to block for. Has no effect is blocking is False. Default is forever.
|
|
324
|
-
:param task_manager: A custom object through which acquiring can be cancelled.
|
|
325
|
-
This effectively manually triggers timeout.
|
|
326
|
-
This is useful for GUIs so that the user can cancel an operation that may otherwise block for a while.
|
|
327
|
-
:return: None
|
|
328
|
-
:raises: LockNotAcquired if the lock could not be acquired.
|
|
329
|
-
"""
|
|
330
|
-
if not self.acquire_shared(blocking, timeout, task_manager):
|
|
331
|
-
raise LockNotAcquired
|
|
332
|
-
try:
|
|
333
|
-
yield
|
|
334
|
-
finally:
|
|
335
|
-
self.release_shared()
|
amulet/utils/signal/__init__.py
DELETED