PocketMine-MP 5.33.2 git-636b96a9a5c35292f076e2f2e9c5723611d28d7b
Loading...
Searching...
No Matches
BlockStateToObjectDeserializer.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\data\bedrock\block\convert;
25
36use function array_key_exists;
37use function count;
38
40
45 private array $deserializeFuncs = [];
46
51 private array $simpleCache = [];
52
53 public function deserialize(BlockStateData $stateData) : int{
54 if(count($stateData->getStates()) === 0){
55 //if a block has zero properties, we can keep a map of string ID -> internal blockstate ID
56 return $this->simpleCache[$stateData->getName()] ??= $this->deserializeToStateId($stateData);
57 }
58
59 //we can't cache blocks that have properties - go ahead and deserialize the slow way
60 return $this->deserializeToStateId($stateData);
61 }
62
63 private function deserializeToStateId(BlockStateData $stateData) : int{
64 $stateId = $this->deserializeBlock($stateData)->getStateId();
65 //plugin devs seem to keep missing this and causing core crashes, so we need to verify this at the earliest
66 //available opportunity
67 if(!RuntimeBlockStateRegistry::getInstance()->hasStateId($stateId)){
68 throw new \LogicException("State ID $stateId returned by deserializer for " . $stateData->getName() . " is not registered in RuntimeBlockStateRegistry");
69 }
70 return $stateId;
71 }
72
74 public function map(string $id, \Closure $c) : void{
75 $this->deserializeFuncs[$id] = $c;
76 $this->simpleCache = [];
77 }
78
85 public function getDeserializerForId(string $id) : ?\Closure{
86 return $this->deserializeFuncs[$id] ?? null;
87 }
88
93 public function mapSimple(string $id, \Closure $getBlock) : void{
94 $this->map($id, $getBlock);
95 }
96
101 public function mapSlab(string $singleId, string $doubleId, \Closure $getBlock) : void{
102 $this->map($singleId, fn(Reader $in) => Helper::decodeSingleSlab($getBlock($in), $in));
103 $this->map($doubleId, fn(Reader $in) => Helper::decodeDoubleSlab($getBlock($in), $in));
104 }
105
110 public function mapStairs(string $id, \Closure $getBlock) : void{
111 $this->map($id, fn(Reader $in) : Stair => Helper::decodeStairs($getBlock(), $in));
112 }
113
118 public function mapLog(string $unstrippedId, string $strippedId, \Closure $getBlock) : void{
119 $this->map($unstrippedId, fn(Reader $in) => Helper::decodeLog($getBlock(), false, $in));
120 $this->map($strippedId, fn(Reader $in) => Helper::decodeLog($getBlock(), true, $in));
121 }
122
124 public function deserializeBlock(BlockStateData $blockStateData) : Block{
125 $id = $blockStateData->getName();
126 if(!array_key_exists($id, $this->deserializeFuncs)){
127 throw new UnsupportedBlockStateException("Unknown block ID \"$id\"");
128 }
129 $reader = new Reader($blockStateData);
130 $block = $this->deserializeFuncs[$id]($reader);
131 $reader->checkUnreadProperties();
132 return $block;
133 }
134}
mapLog(string $unstrippedId, string $strippedId, \Closure $getBlock)