From e141ca44e1bc2eb62ffd9c79b35ee44dc4a6654d Mon Sep 17 00:00:00 2001 From: ShockedPlot7560 Date: Wed, 7 Jun 2023 14:35:58 +0200 Subject: [PATCH 1/4] implement unregister functions in CraftingManager --- src/crafting/CraftingManager.php | 80 +++++++++++++++++++++++++++ src/crafting/FurnaceRecipeManager.php | 12 ++++ 2 files changed, 92 insertions(+) diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 74bc2ba1022..911174ddbbd 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -29,6 +29,8 @@ use pocketmine\utils\BinaryStream; use pocketmine\utils\DestructorCallbackTrait; use pocketmine\utils\ObjectSet; +use function array_search; +use function count; use function usort; class CraftingManager{ @@ -205,6 +207,34 @@ public function registerShapedRecipe(ShapedRecipe $recipe) : void{ } } + public function unregisterShapedRecipe(ShapedRecipe $recipe) : void{ + $edited = false; + $hash = self::hashOutputs($recipe->getResults()); + + foreach($this->shapedRecipes[$hash] ?? [] as $i => $r){ + if($r === $recipe){ + unset($this->shapedRecipes[$hash][$i]); + if(count($this->shapedRecipes[$hash]) === 0){ + unset($this->shapedRecipes[$hash]); + $edited = true; + } + break; + } + } + + $index = array_search($recipe, $this->craftingRecipeIndex, true); + if($index !== false){ + unset($this->craftingRecipeIndex[$index]); + $edited = true; + } + + if($edited){ + foreach($this->recipeRegisteredCallbacks as $callback){ + $callback(); + } + } + } + public function registerShapelessRecipe(ShapelessRecipe $recipe) : void{ $this->shapelessRecipes[self::hashOutputs($recipe->getResults())][] = $recipe; $this->craftingRecipeIndex[] = $recipe; @@ -214,6 +244,34 @@ public function registerShapelessRecipe(ShapelessRecipe $recipe) : void{ } } + public function unregisterShapelessRecipe(ShapelessRecipe $recipe) : void{ + $edited = false; + $hash = self::hashOutputs($recipe->getResults()); + + foreach($this->shapelessRecipes[$hash] ?? [] as $i => $r){ + if($r === $recipe){ + unset($this->shapelessRecipes[$hash][$i]); + if(count($this->shapelessRecipes[$hash]) === 0){ + unset($this->shapelessRecipes[$hash]); + $edited = true; + } + break; + } + } + + $index = array_search($recipe, $this->craftingRecipeIndex, true); + if($index !== false){ + unset($this->craftingRecipeIndex[$index]); + $edited = true; + } + + if($edited){ + foreach($this->recipeRegisteredCallbacks as $callback){ + $callback(); + } + } + } + public function registerPotionTypeRecipe(PotionTypeRecipe $recipe) : void{ $this->potionTypeRecipes[] = $recipe; @@ -222,6 +280,17 @@ public function registerPotionTypeRecipe(PotionTypeRecipe $recipe) : void{ } } + public function unregisterPotionTypeRecipe(PotionTypeRecipe $recipe) : void{ + $recipeIndex = array_search($recipe, $this->potionTypeRecipes, true); + if($recipeIndex !== false){ + unset($this->potionTypeRecipes[$recipeIndex]); + + foreach($this->recipeRegisteredCallbacks as $callback){ + $callback(); + } + } + } + public function registerPotionContainerChangeRecipe(PotionContainerChangeRecipe $recipe) : void{ $this->potionContainerChangeRecipes[] = $recipe; @@ -230,6 +299,17 @@ public function registerPotionContainerChangeRecipe(PotionContainerChangeRecipe } } + public function unregisterPotionContainerChangeRecipe(PotionContainerChangeRecipe $recipe) : void{ + $recipeIndex = array_search($recipe, $this->potionContainerChangeRecipes, true); + if($recipeIndex !== false){ + unset($this->potionContainerChangeRecipes[$recipeIndex]); + + foreach($this->recipeRegisteredCallbacks as $callback){ + $callback(); + } + } + } + /** * @param Item[] $outputs */ diff --git a/src/crafting/FurnaceRecipeManager.php b/src/crafting/FurnaceRecipeManager.php index d13465b44a7..38bd25a4850 100644 --- a/src/crafting/FurnaceRecipeManager.php +++ b/src/crafting/FurnaceRecipeManager.php @@ -25,6 +25,7 @@ use pocketmine\item\Item; use pocketmine\utils\ObjectSet; +use function array_search; final class FurnaceRecipeManager{ /** @var FurnaceRecipe[] */ @@ -64,6 +65,17 @@ public function register(FurnaceRecipe $recipe) : void{ } } + public function unregister(FurnaceRecipe $recipe) : void{ + $index = array_search($recipe, $this->furnaceRecipes, true); + if($index !== false){ + unset($this->furnaceRecipes[$index]); + + foreach($this->recipeRegisteredCallbacks as $callback){ + $callback($recipe); + } + } + } + public function match(Item $input) : ?FurnaceRecipe{ $index = $input->getStateId(); $simpleRecipe = $this->lookupCache[$index] ?? null; From 59b0d73c20aff3fcc3a1df3586f846d90ebb348e Mon Sep 17 00:00:00 2001 From: ShockedPlot7560 Date: Wed, 7 Jun 2023 18:29:43 +0200 Subject: [PATCH 2/4] use specific observer for recipe deregistration --- src/crafting/CraftingManager.php | 16 ++++++++++++---- src/network/mcpe/cache/CraftingDataCache.php | 3 +++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 911174ddbbd..45405ed8312 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -80,12 +80,17 @@ class CraftingManager{ /** @phpstan-var ObjectSet<\Closure() : void> */ private ObjectSet $recipeRegisteredCallbacks; + /** @phpstan-var ObjectSet<\Closure() : void> */ + private ObjectSet $recipeUnregisteredCallbacks; + public function __construct(){ $this->recipeRegisteredCallbacks = new ObjectSet(); foreach(FurnaceType::getAll() as $furnaceType){ $this->furnaceRecipeManagers[$furnaceType->id()] = new FurnaceRecipeManager(); } + $this->recipeUnregisteredCallbacks = new ObjectSet(); + $recipeRegisteredCallbacks = $this->recipeRegisteredCallbacks; foreach($this->furnaceRecipeManagers as $furnaceRecipeManager){ $furnaceRecipeManager->getRecipeRegisteredCallbacks()->add(static function(FurnaceRecipe $recipe) use ($recipeRegisteredCallbacks) : void{ @@ -99,6 +104,9 @@ public function __construct(){ /** @phpstan-return ObjectSet<\Closure() : void> */ public function getRecipeRegisteredCallbacks() : ObjectSet{ return $this->recipeRegisteredCallbacks; } + /** @phpstan-return ObjectSet<\Closure() : void> */ + public function getRecipeUnregisteredCallbacks() : ObjectSet{ return $this->recipeUnregisteredCallbacks; } + /** * Function used to arrange Shapeless Recipe ingredient lists into a consistent order. */ @@ -229,7 +237,7 @@ public function unregisterShapedRecipe(ShapedRecipe $recipe) : void{ } if($edited){ - foreach($this->recipeRegisteredCallbacks as $callback){ + foreach($this->recipeUnregisteredCallbacks as $callback){ $callback(); } } @@ -266,7 +274,7 @@ public function unregisterShapelessRecipe(ShapelessRecipe $recipe) : void{ } if($edited){ - foreach($this->recipeRegisteredCallbacks as $callback){ + foreach($this->recipeUnregisteredCallbacks as $callback){ $callback(); } } @@ -285,7 +293,7 @@ public function unregisterPotionTypeRecipe(PotionTypeRecipe $recipe) : void{ if($recipeIndex !== false){ unset($this->potionTypeRecipes[$recipeIndex]); - foreach($this->recipeRegisteredCallbacks as $callback){ + foreach($this->recipeUnregisteredCallbacks as $callback){ $callback(); } } @@ -304,7 +312,7 @@ public function unregisterPotionContainerChangeRecipe(PotionContainerChangeRecip if($recipeIndex !== false){ unset($this->potionContainerChangeRecipes[$recipeIndex]); - foreach($this->recipeRegisteredCallbacks as $callback){ + foreach($this->recipeUnregisteredCallbacks as $callback){ $callback(); } } diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index e6ac6167b5d..35b20c74aa0 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -68,6 +68,9 @@ public function getCache(CraftingManager $manager) : CraftingDataPacket{ $manager->getRecipeRegisteredCallbacks()->add(function() use ($id) : void{ unset($this->caches[$id]); }); + $manager->getRecipeUnregisteredCallbacks()->add(function() use ($id) : void{ + unset($this->caches[$id]); + }); $this->caches[$id] = $this->buildCraftingDataCache($manager); } return $this->caches[$id]; From c9fee5a8a9edb3f633793a3e7ccd3129f4917aac Mon Sep 17 00:00:00 2001 From: ShockedPlot7560 Date: Wed, 7 Jun 2023 18:33:17 +0200 Subject: [PATCH 3/4] use specific observer for FurnaceRecipe deregistering --- src/crafting/CraftingManager.php | 6 ++++++ src/crafting/FurnaceRecipeManager.php | 13 ++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 45405ed8312..4632c295c03 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -92,12 +92,18 @@ public function __construct(){ $this->recipeUnregisteredCallbacks = new ObjectSet(); $recipeRegisteredCallbacks = $this->recipeRegisteredCallbacks; + $recipeUnregisteredCallbacks = $this->recipeUnregisteredCallbacks; foreach($this->furnaceRecipeManagers as $furnaceRecipeManager){ $furnaceRecipeManager->getRecipeRegisteredCallbacks()->add(static function(FurnaceRecipe $recipe) use ($recipeRegisteredCallbacks) : void{ foreach($recipeRegisteredCallbacks as $callback){ $callback(); } }); + $furnaceRecipeManager->getRecipeUnregisteredCallbacks()->add(static function(FurnaceRecipe $recipe) use ($recipeUnregisteredCallbacks) : void{ + foreach($recipeUnregisteredCallbacks as $callback){ + $callback(); + } + }); } } diff --git a/src/crafting/FurnaceRecipeManager.php b/src/crafting/FurnaceRecipeManager.php index 38bd25a4850..fd09763b332 100644 --- a/src/crafting/FurnaceRecipeManager.php +++ b/src/crafting/FurnaceRecipeManager.php @@ -40,8 +40,12 @@ final class FurnaceRecipeManager{ /** @phpstan-var ObjectSet<\Closure(FurnaceRecipe) : void> */ private ObjectSet $recipeRegisteredCallbacks; + /** @phpstan-return ObjectSet<\Closure(FurnaceRecipe) : void> */ + private ObjectSet $recipeUnregisteredCallbacks; + public function __construct(){ $this->recipeRegisteredCallbacks = new ObjectSet(); + $this->recipeUnregisteredCallbacks = new ObjectSet(); } /** @@ -51,6 +55,13 @@ public function getRecipeRegisteredCallbacks() : ObjectSet{ return $this->recipeRegisteredCallbacks; } + /** + * @phpstan-return ObjectSet<\Closure(FurnaceRecipe) : void> + */ + public function getRecipeUnregisteredCallbacks() : ObjectSet{ + return $this->recipeUnregisteredCallbacks; + } + /** * @return FurnaceRecipe[] */ @@ -70,7 +81,7 @@ public function unregister(FurnaceRecipe $recipe) : void{ if($index !== false){ unset($this->furnaceRecipes[$index]); - foreach($this->recipeRegisteredCallbacks as $callback){ + foreach($this->recipeUnregisteredCallbacks as $callback){ $callback($recipe); } } From 4690f7e7a5ff761a79d83c4ed59818501a96f65a Mon Sep 17 00:00:00 2001 From: ShockedPlot7560 Date: Wed, 7 Jun 2023 18:37:26 +0200 Subject: [PATCH 4/4] fix PHPstan + function placement --- src/crafting/CraftingManager.php | 4 ++-- src/crafting/FurnaceRecipeManager.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 4632c295c03..55e6f2f41d9 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -85,12 +85,12 @@ class CraftingManager{ public function __construct(){ $this->recipeRegisteredCallbacks = new ObjectSet(); + $this->recipeUnregisteredCallbacks = new ObjectSet(); + foreach(FurnaceType::getAll() as $furnaceType){ $this->furnaceRecipeManagers[$furnaceType->id()] = new FurnaceRecipeManager(); } - $this->recipeUnregisteredCallbacks = new ObjectSet(); - $recipeRegisteredCallbacks = $this->recipeRegisteredCallbacks; $recipeUnregisteredCallbacks = $this->recipeUnregisteredCallbacks; foreach($this->furnaceRecipeManagers as $furnaceRecipeManager){ diff --git a/src/crafting/FurnaceRecipeManager.php b/src/crafting/FurnaceRecipeManager.php index fd09763b332..72fbf252632 100644 --- a/src/crafting/FurnaceRecipeManager.php +++ b/src/crafting/FurnaceRecipeManager.php @@ -40,7 +40,7 @@ final class FurnaceRecipeManager{ /** @phpstan-var ObjectSet<\Closure(FurnaceRecipe) : void> */ private ObjectSet $recipeRegisteredCallbacks; - /** @phpstan-return ObjectSet<\Closure(FurnaceRecipe) : void> */ + /** @phpstan-var ObjectSet<\Closure(FurnaceRecipe) : void> */ private ObjectSet $recipeUnregisteredCallbacks; public function __construct(){