@@ -59,11 +59,9 @@ public final class RegistryRecipes extends RegistrySimple<CustomRecipe<?>> {
5959
6060 private final Map <String , List <CustomRecipe <?>>> BY_NAMESPACE = new HashMap <>();
6161 private final Map <String , List <CustomRecipe <?>>> BY_GROUP = new HashMap <>();
62- private final Map <StackReference , List <CustomRecipe <?>>> BY_RESULT = new HashMap <>();
6362 private final Map <Class <?>, List <CustomRecipe <?>>> BY_CLASS_TYPE = new HashMap <>();
6463 private final Map <RecipeType <?>, List <CustomRecipe <?>>> BY_RECIPE_TYPE = new HashMap <>();
6564 private final Map <RecipeType .Container <?>, List <CustomRecipe <?>>> BY_RECIPE_TYPE_CONTAINER = new HashMap <>();
66- private final Map <String , Map <String , List <CustomRecipe <?>>>> BY_NAMESPACE_AND_FOLDER = new HashMap <>();
6765 private final Map <String , Map <String , List <CustomRecipe <?>>>> BY_NAMESPACE_AND_DIR = new HashMap <>();
6866 private final Set <String > NAMESPACES = new HashSet <>();
6967 private final Map <String , List <String >> FOLDERS = new HashMap <>();
@@ -78,12 +76,27 @@ public boolean has(NamespacedKey namespacedKey) {
7876 return this .map .containsKey (namespacedKey );
7977 }
8078
79+ public void removeAll (NamespacedKey ... keys ) {
80+ for (NamespacedKey key : keys ) {
81+ removeNoUpdate (key );
82+ }
83+ updateCache (namespacedKey );
84+ }
85+
8186 public void remove (NamespacedKey namespacedKey ) {
87+ removeNoUpdate (namespacedKey );
88+ updateCache (namespacedKey );
89+ }
90+
91+ private void removeNoUpdate (NamespacedKey namespacedKey ) {
8292 if (get (namespacedKey ) instanceof ICustomVanillaRecipe ) {
8393 removeBukkitRecipe (namespacedKey );
8494 }
8595 this .map .remove (namespacedKey );
86- clearCache (namespacedKey );
96+ }
97+
98+ public void updateCache () {
99+ updateCache (new NamespacedKey [0 ]);
87100 }
88101
89102 /**
@@ -93,27 +106,53 @@ public void remove(NamespacedKey namespacedKey) {
93106 * Of course, you could check if the specific caches must be cleared, but that would be at the cost of register/remove performance.<br>
94107 * (Most servers have a fixed set of recipes that they use and don't frequently change in production... well at least they shouldn't)
95108 *
96- * @param key The key of the recipe that caused the reset.
109+ * @param keys The key of the recipe that caused the reset.
97110 */
98- private void clearCache (NamespacedKey key ) {
99- BY_NAMESPACE .remove (key .getNamespace ());
111+ private void updateCache (NamespacedKey ... keys ) {
112+ for (NamespacedKey key : keys ) {
113+ BY_NAMESPACE .remove (key .getNamespace ());
114+ FOLDERS .remove (key .getNamespace ());
115+ BY_NAMESPACE_AND_DIR .remove (key .getNamespace ());
116+ }
100117 BY_GROUP .clear ();
101118 NAMESPACES .clear ();
102- FOLDERS .remove (key .getNamespace ());
103119 GROUPS .clear ();
104- BY_RESULT .clear ();
105120 BY_CLASS_TYPE .clear ();
106121 BY_RECIPE_TYPE .clear ();
122+ for (RecipeType <? extends CustomRecipe <?>> type : RecipeType .values ()) {
123+ BY_RECIPE_TYPE .put (type , values ().stream ().filter (type ::isInstance ).toList ());
124+ }
107125 BY_RECIPE_TYPE_CONTAINER .clear ();
108- BY_NAMESPACE_AND_FOLDER .remove (key .getNamespace ());
109- BY_NAMESPACE_AND_DIR .remove (key .getNamespace ());
126+ for (RecipeType .Container <? extends CustomRecipe <?>> container : RecipeType .Container .values ()) {
127+ BY_RECIPE_TYPE_CONTAINER .put (container , values ().stream ().filter (container ::isInstance ).toList ());
128+ }
129+ }
130+
131+ public synchronized void bulkRegister (List <CustomRecipe <?>> recipes ) {
132+ var keys = new NamespacedKey [recipes .size ()];
133+ for (int i = 0 ; i < recipes .size (); i ++) {
134+ var recipe = recipes .get (i );
135+ registerNoUpdate (recipe .getNamespacedKey (), recipe );
136+ keys [i ] = recipe .getNamespacedKey ();
137+ }
138+ updateCache (keys );
110139 }
111140
112141 @ Override
113142 public synchronized void register (NamespacedKey namespacedKey , CustomRecipe <?> value ) {
143+ registerNoUpdate (namespacedKey , value );
144+ updateCache (namespacedKey );
145+ }
146+
147+ @ Override
148+ public void register (CustomRecipe <?> value ) {
149+ this .register (value .getNamespacedKey (), value );
150+ }
151+
152+ public void registerNoUpdate (NamespacedKey namespacedKey , CustomRecipe <?> value ) {
114153 Preconditions .checkArgument (namespacedKey != null , "Invalid NamespacedKey! The namespaced key cannot be null!" );
115154 Preconditions .checkArgument (!namespacedKey .getNamespace ().equalsIgnoreCase ("minecraft" ), "Invalid NamespacedKey! Cannot register recipe under minecraft namespace!" );
116- remove (namespacedKey );
155+ removeNoUpdate (namespacedKey );
117156 super .register (namespacedKey , value );
118157 if (value instanceof ICustomVanillaRecipe <?> vanillaRecipe && !value .isDisabled ()) {
119158 Bukkit .getScheduler ().runTask (customCrafting , () -> {
@@ -134,12 +173,6 @@ public synchronized void register(NamespacedKey namespacedKey, CustomRecipe<?> v
134173 }
135174 });
136175 }
137- clearCache (namespacedKey );
138- }
139-
140- @ Override
141- public void register (CustomRecipe <?> value ) {
142- this .register (value .getNamespacedKey (), value );
143176 }
144177
145178 /**
@@ -395,14 +428,20 @@ public List<CustomRecipe<?>> get(String namespace) {
395428 return BY_NAMESPACE .computeIfAbsent (namespace , s -> entrySet ().stream ().filter (entry -> entry .getKey ().getNamespace ().equalsIgnoreCase (s )).map (Map .Entry ::getValue ).collect (Collectors .toList ()));
396429 }
397430
431+ /**
432+ * @deprecated Not used anywhere and fundamentally flawed. Do not use!
433+ */
434+ @ Deprecated (forRemoval = true )
398435 public List <CustomRecipe <?>> get (CustomItem result ) {
399- return BY_RESULT .computeIfAbsent (
400- result .hasNamespacedKey () ? new StackReference (WolfyUtilCore .getInstance (), new WolfyUtilsStackIdentifier (result .getNamespacedKey ()), result .getWeight (), result .getAmount (), result .getItemStack ()) : result .stackReference (),
401- item -> values ().stream ().filter (recipe -> recipe .getResult ().choices ().contains (item )).collect (Collectors .toList ()));
436+ return get (result .hasNamespacedKey () ? new StackReference (WolfyUtilCore .getInstance (), new WolfyUtilsStackIdentifier (result .getNamespacedKey ()), result .getWeight (), result .getAmount (), result .getItemStack ()) : result .stackReference ());
402437 }
403438
439+ /**
440+ * @deprecated Not used anywhere and fundamentally flawed. Do not use!
441+ */
442+ @ Deprecated (forRemoval = true )
404443 public List <CustomRecipe <?>> get (StackReference reference ) {
405- return BY_RESULT . computeIfAbsent ( reference , reference1 -> values ().stream ().filter (recipe -> recipe .getResult ().choices ().contains (reference1 )).collect (Collectors .toList () ));
444+ return values ().stream ().filter (recipe -> recipe .getResult ().choices ().contains (reference )).collect (Collectors .toList ());
406445 }
407446
408447 @ SuppressWarnings ("unchecked" )
@@ -417,7 +456,7 @@ public <T extends CustomRecipe<?>> List<T> get(Class<T> type) {
417456 */
418457 @ SuppressWarnings ("unchecked" )
419458 public <T extends CustomRecipe <?>> List <T > get (RecipeType <T > type ) {
420- return (List <T >) BY_RECIPE_TYPE .computeIfAbsent (type , recipeType -> values (). stream (). filter ( recipeType :: isInstance ). map ( recipeType :: cast ). collect ( Collectors . toList () ));
459+ return (List <T >) BY_RECIPE_TYPE .getOrDefault (type , Collections . emptyList ( ));
421460 }
422461
423462 /**
@@ -427,7 +466,7 @@ public <T extends CustomRecipe<?>> List<T> get(RecipeType<T> type) {
427466 */
428467 @ SuppressWarnings ("unchecked" )
429468 public <T extends CustomRecipe <?>> List <T > get (RecipeType .Container <T > type ) {
430- return (List <T >) BY_RECIPE_TYPE_CONTAINER .computeIfAbsent (type , container -> values (). stream (). filter ( container :: isInstance ). map ( container :: cast ). collect ( Collectors . toList () ));
469+ return (List <T >) BY_RECIPE_TYPE_CONTAINER .getOrDefault (type , Collections . emptyList ( ));
431470 }
432471
433472 @ SafeVarargs
0 commit comments