|
40 | 40 | import net.minecraft.network.chat.Component; |
41 | 41 | import net.minecraft.resources.ResourceLocation; |
42 | 42 | import net.minecraft.world.item.component.CustomData; |
| 43 | +import org.apache.commons.lang3.mutable.MutableObject; |
43 | 44 | import org.jetbrains.annotations.Nullable; |
44 | 45 |
|
45 | 46 | import java.lang.reflect.Modifier; |
|
48 | 49 | import java.util.HashSet; |
49 | 50 | import java.util.Map; |
50 | 51 | import java.util.Objects; |
| 52 | +import java.util.Optional; |
51 | 53 | import java.util.Set; |
52 | 54 | import java.util.StringJoiner; |
53 | 55 | import java.util.function.BiConsumer; |
@@ -430,56 +432,65 @@ static DataResult<DataComponentPatch> tryPatchOf(Context cx, @Nullable Object o) |
430 | 432 | }; |
431 | 433 | } |
432 | 434 |
|
433 | | - private static void wrapEntry( |
434 | | - Context cx, |
435 | | - Map.Entry<DataComponentType<?>, ?> entry, |
436 | | - @Nullable Consumer<DataComponentType<?>> ifNull, |
437 | | - @SuppressWarnings("rawtypes") BiConsumer<DataComponentType, Object> builder, |
438 | | - BiConsumer<DataComponentType<?>, String> error |
439 | | - ) { |
| 435 | + static <T> DataResult<Optional<T>> tryWrapComponent(Context cx, DataComponentType<T> type, Object value) { |
440 | 436 | var reg = RegistryAccessContainer.of(cx); |
441 | 437 |
|
442 | | - var type = entry.getKey(); |
443 | 438 | var valueType = getTypeInfo(type); |
444 | 439 |
|
445 | | - var value = entry.getValue(); |
446 | | - |
447 | 440 | if (value == null || value instanceof Undefined) { |
448 | | - if (ifNull != null) { |
449 | | - ifNull.accept(type); |
450 | | - } |
451 | | - |
452 | | - return; |
| 441 | + return success(Optional.empty()); |
453 | 442 | } |
454 | 443 |
|
455 | | - EvaluatorException evalError = null; |
| 444 | + var evalError = new MutableObject<EvaluatorException>(); |
456 | 445 |
|
457 | 446 | if (valueType.shouldConvert() && cx.canConvert(value, valueType)) { |
458 | 447 | try { |
459 | 448 | Object converted = cx.jsToJava(value, valueType); |
460 | 449 | if (converted != null) { |
461 | | - builder.accept(type, converted); |
462 | | - return; |
| 450 | + return success(Optional.of(Cast.to(converted))); |
463 | 451 | } |
464 | 452 | } catch (EvaluatorException e) { |
465 | | - evalError = e; |
| 453 | + evalError.setValue(e); |
466 | 454 | } |
467 | 455 | } |
468 | 456 |
|
| 457 | + |
469 | 458 | var codec = type.codec(); |
470 | 459 |
|
471 | 460 | if (codec != null) { |
472 | | - switch (codec.parse(reg.json(), JsonUtils.of(cx, value))) { |
473 | | - case DataResult.Success<?> success -> builder.accept(type, success.value()); |
474 | | - case DataResult.Error<?> err -> error.accept(type, evalError != null |
475 | | - ? "Failed to parse component from type wrappers and codec! Native: %s, Codec: %s".formatted(evalError.details(), err.message()) |
476 | | - : "Failed to parse component from codec: %s!".formatted(err.message())); |
477 | | - } |
| 461 | + //noinspection unchecked |
| 462 | + return (DataResult<Optional<T>>) switch (codec.parse(reg.json(), JsonUtils.of(cx, value))) { |
| 463 | + case DataResult.Success<?> success -> success.map(Optional::of); |
| 464 | + case DataResult.Error<?> error -> error.mapError(err -> evalError.getValue() != null |
| 465 | + ? "Failed to parse component from type wrappers and codec! Native: %s, Codec: %s".formatted(evalError.getValue().details(), err) |
| 466 | + : "Failed to parse component from codec: %s!".formatted(err)); |
| 467 | + }; |
478 | 468 | } else { |
479 | | - error.accept(type, "Component has non-serializable type"); |
| 469 | + return error(() -> "Component has non-serializable type"); |
480 | 470 | } |
481 | 471 | } |
482 | 472 |
|
| 473 | + private static void wrapEntry( |
| 474 | + Context cx, |
| 475 | + Map.Entry<DataComponentType<?>, ?> entry, |
| 476 | + @Nullable Consumer<DataComponentType<?>> ifNull, |
| 477 | + @SuppressWarnings("rawtypes") BiConsumer<DataComponentType, Object> builder, |
| 478 | + BiConsumer<DataComponentType<?>, String> errorBuilder |
| 479 | + ) { |
| 480 | + var type = entry.getKey(); |
| 481 | + var value = entry.getValue(); |
| 482 | + |
| 483 | + tryWrapComponent(cx, type, value) |
| 484 | + .ifSuccess(success -> { |
| 485 | + if (success.isPresent()) { |
| 486 | + builder.accept(type, success.get()); |
| 487 | + } else if (ifNull != null) { |
| 488 | + ifNull.accept(type); |
| 489 | + } |
| 490 | + }) |
| 491 | + .ifError(error -> errorBuilder.accept(type, error.message())); |
| 492 | + } |
| 493 | + |
483 | 494 | private static <B, T> DataResult<T> fnToBuilder(Context cx, Class<B> builderType, BaseFunction fn, Function<B, T> build) { |
484 | 495 | try { |
485 | 496 | B builder = Cast.to(cx.createInterfaceAdapter(TypeInfo.of(builderType), fn)); |
|
0 commit comments