diff --git a/src/main/java/org/spongepowered/common/data/holder/SpongeMutableDataHolder.java b/src/main/java/org/spongepowered/common/data/holder/SpongeMutableDataHolder.java index c4fa8a33472..3423e86d85a 100644 --- a/src/main/java/org/spongepowered/common/data/holder/SpongeMutableDataHolder.java +++ b/src/main/java/org/spongepowered/common/data/holder/SpongeMutableDataHolder.java @@ -37,6 +37,7 @@ import org.spongepowered.api.data.value.Value; import org.spongepowered.api.data.value.ValueContainer; import org.spongepowered.common.data.key.SpongeKey; +import org.spongepowered.common.data.provider.GenericMutableDataProvider; import org.spongepowered.common.util.DataUtil; import java.util.Collection; @@ -89,6 +90,9 @@ default DataTransactionResult offerSingle(Key>, Collection> key0 = (SpongeKey>, Collection>) key; return this.impl$applyTransaction(key0, (p, m) -> { + if (p instanceof GenericMutableDataProvider) { + return ((GenericMutableDataProvider)p).offerSingle(m, element); + } final Collection collection = p.get(m) .map(DataUtil::ensureMutable) .orElseGet(key0.getDefaultValueSupplier()); diff --git a/src/main/java/org/spongepowered/common/data/provider/DataProviderRegistrator.java b/src/main/java/org/spongepowered/common/data/provider/DataProviderRegistrator.java index c1d471545fa..2ca674f5454 100644 --- a/src/main/java/org/spongepowered/common/data/provider/DataProviderRegistrator.java +++ b/src/main/java/org/spongepowered/common/data/provider/DataProviderRegistrator.java @@ -41,6 +41,7 @@ import org.spongepowered.api.data.persistence.DataContentUpdater; import org.spongepowered.api.data.persistence.DataStore; import org.spongepowered.api.data.persistence.DataView; +import org.spongepowered.api.data.value.CollectionValue; import org.spongepowered.api.data.value.Value; import org.spongepowered.api.registry.DefaultedRegistryReference; import org.spongepowered.api.util.OptBool; @@ -54,6 +55,7 @@ import java.lang.reflect.Type; import java.util.Arrays; +import java.util.Collection; import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.BiFunction; @@ -205,6 +207,13 @@ protected > MutableRegistrator register(final MutableRe this.registrationBuilder.dataKey(provider.key()).provider(provider); return this; } + + @SuppressWarnings({"unchecked", "UnstableApiUsage"}) + protected , L> MutableRegistrator register(final MutableCollectionRegistration registration) { + final DataProvider provider = registration.build(this.target); + this.registrationBuilder.dataKey(provider.key()).provider(provider); + return this; + } } public static final class ImmutableRegistrator extends DataProviderRegistrator { @@ -400,6 +409,15 @@ protected boolean supports(final H dataHolder) { } return super.supports(dataHolder); } + + @Override + public DataTransactionResult offerSingle(final DataHolder.Mutable dataHolder, final TE element) { + if (registration instanceof MutableCollectionRegistration haha && haha.single != null) { + ((BiConsumer)haha.single).accept((H) dataHolder, element); + return DataTransactionResult.successNoData(); + } + return DataTransactionResult.failNoData(); + } }; @@ -426,6 +444,12 @@ public MutableRegistration create(final Key> key return registration; } + public , V extends Collection, VE> MutableCollectionRegistration createCollection(final Key key) { + final MutableCollectionRegistration registration = new MutableCollectionRegistration(this.registrator, key); + this.registrator.register(registration); + return registration; + } + /** * Creates a new {@link MutableRegistrator} * @return The registrator @@ -443,6 +467,33 @@ public ImmutableRegistrator asImmutable(final Class target) { } } + public static final class MutableCollectionRegistration extends MutableRegistrationBase> { + + private final MutableRegistrator registrator; + + @Nullable BiConsumer single; + + private MutableCollectionRegistration(final MutableRegistrator registrator, final Key> key) { + super(key); + this.registrator = registrator; + } + + public MutableRegistration create(final DefaultedRegistryReference>> suppliedKey) { + return this.create(suppliedKey.get()); + } + + public MutableRegistration create(final Key> key) { + final MutableRegistration registration = new MutableRegistration<>(this.registrator, key); + this.registrator.register(registration); + return registration; + } + + public MutableCollectionRegistration single(BiConsumer single) { + this.single = single; + return this; + } + } + @SuppressWarnings("unchecked") private static class ImmutableRegistrationBase> { private final Key> key; diff --git a/src/main/java/org/spongepowered/common/data/provider/GenericMutableDataProviderBase.java b/src/main/java/org/spongepowered/common/data/provider/GenericMutableDataProviderBase.java index 28108fdb833..b2426f2f2ea 100644 --- a/src/main/java/org/spongepowered/common/data/provider/GenericMutableDataProviderBase.java +++ b/src/main/java/org/spongepowered/common/data/provider/GenericMutableDataProviderBase.java @@ -235,4 +235,8 @@ public final DataTransactionResult remove(final DataHolder.Mutable dataHolder) { } return this.deleteAndGetResult((H) dataHolder); } + + public DataTransactionResult offerSingle(final DataHolder.Mutable dataHolder, final TE element) { + return DataTransactionResult.failNoData(); + } } diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/LivingData.java b/src/main/java/org/spongepowered/common/data/provider/entity/LivingData.java index da6619568b5..34bcc151b35 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/LivingData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/LivingData.java @@ -156,7 +156,7 @@ public static void register(final DataProviderRegistrator registrator) { .create(Keys.MAX_HEALTH) .get(h -> (double) h.getMaxHealth()) .set((h, v) -> h.getAttribute(Attributes.MAX_HEALTH).setBaseValue(v)) - .create(Keys.POTION_EFFECTS) + .createCollection(Keys.POTION_EFFECTS) .get(h -> { final Collection effects = h.getActiveEffects(); return PotionEffectUtil.copyAsPotionEffects(effects); @@ -167,6 +167,9 @@ public static void register(final DataProviderRegistrator registrator) { h.addEffect(PotionEffectUtil.copyAsEffectInstance(effect)); } }) + .single((h, v) -> { + h.addEffect(PotionEffectUtil.copyAsEffectInstance(v)); + }) .create(Keys.SCALE) .get(h -> (double) h.getScale()) .create(Keys.STUCK_ARROWS)