use of org.spongepowered.api.data.value.ValueContainer in project LanternServer by LanternPowered.
the class IValueContainer method matchContents.
/**
* Matches the contents of the two {@link ValueContainer}s.
*
* @param valueContainerA The first value container
* @param valueContainerB The second value container
* @return Whether the contents match
*/
static boolean matchContents(IValueContainer<?> valueContainerA, IValueContainer<?> valueContainerB) {
final boolean additional = valueContainerA instanceof IAdditionalCompositeValueStore;
if (additional != valueContainerB instanceof IAdditionalCompositeValueStore) {
return false;
}
final ValueCollection valueCollectionA = valueContainerA.getValueCollection();
final ValueCollection valueCollectionB = valueContainerB.getValueCollection();
final Collection<Key<?>> keysA = valueCollectionA.getKeys();
final Collection<Key<?>> keysB = valueCollectionB.getKeys();
// The same keys have to be present in both of the containers
if (keysA.size() != keysB.size() || !keysA.containsAll(keysB)) {
return false;
}
for (KeyRegistration<?, ?> registration1 : valueCollectionA.getAll()) {
final KeyRegistration registration2 = (KeyRegistration) valueCollectionB.get((Key) registration1.getKey()).get();
// Get the values from both of the containers and match them
final Object value1 = ((Processor) registration1).getFrom(valueContainerA).orElse(null);
final Object value2 = ((Processor) registration2).getFrom(valueContainerB).orElse(null);
if (!Objects.equals(value1, value2)) {
return false;
}
}
// Match additional containers
if (additional) {
final Map<Class<?>, ValueContainer<?>> mapA = ((IAdditionalCompositeValueStore) valueContainerA).getAdditionalContainers().getMap();
final Map<Class<?>, ValueContainer<?>> mapB = ((IAdditionalCompositeValueStore) valueContainerB).getAdditionalContainers().getMap();
if (mapA.size() != mapB.size() || !mapA.keySet().containsAll(mapB.keySet())) {
return false;
}
for (Map.Entry<Class<?>, ValueContainer<?>> entry : mapA.entrySet()) {
final ValueContainer<?> containerA = entry.getValue();
final ValueContainer<?> containerB = mapB.get(entry.getKey());
if (!Objects.equals(containerA, containerB)) {
return false;
}
}
}
return true;
}
use of org.spongepowered.api.data.value.ValueContainer in project LanternServer by LanternPowered.
the class DataHelper method deserializeRawContainerData.
public static void deserializeRawContainerData(DataView dataView, IValueContainer valueContainer, DataQuery query) throws InvalidDataException {
final List<DataView> dataViews = dataView.getViewList(query).orElse(null);
if (dataViews == null) {
return;
}
if (!(valueContainer instanceof AdditionalContainerHolder)) {
getLogger().warn("{} is not a AdditionalContainerHolder, but data manipulators were found.", valueContainer);
return;
}
final ValueCollection valueCollection = valueContainer.getValueCollection();
final AdditionalContainerCollection<ValueContainer<?>> containers = ((AdditionalContainerHolder) valueContainer).getAdditionalContainers();
final List<DataView> failedData = new ArrayList<>();
final LanternDataManager dataManager = Lantern.getGame().getDataManager();
for (DataView view : dataViews) {
Optional<DataRegistration> optRegistration;
String id;
if (view.contains(DataQueries.MANIPULATOR_ID)) {
id = view.getString(DataQueries.MANIPULATOR_ID).get();
optRegistration = DataManipulatorRegistryModule.get().getById(id);
} else if (view.contains(DATA_CLASS)) {
id = view.getString(DATA_CLASS).get();
optRegistration = dataManager.getLegacyRegistration(id);
} else {
getLogger().warn("Manipulator with missing id.");
continue;
}
final Optional<DataView> manipulatorView = view.getView(DataQueries.MANIPULATOR_DATA);
if (manipulatorView.isPresent()) {
getLogger().warn("Missing manipulator data for id: {}", id);
}
if (optRegistration.isPresent()) {
try {
final Optional<DataManipulator> optManipulator = optRegistration.get().getDataManipulatorBuilder().build(manipulatorView.get());
if (optManipulator.isPresent()) {
containers.offer(optManipulator.get());
}
} catch (InvalidDataException e) {
getLogger().error("Could not deserialize " + id + "! Don't worry though, we'll try to deserialize the rest of the data.", e);
}
} else {
getLogger().warn("Missing DataRegistration for ID: " + id + ". Don't worry, the data will be kept safe.");
failedData.add(view);
}
}
if (!failedData.isEmpty()) {
// Should be safe to cast, at least if nobody touches this key
Element<List<DataView>> holder = valueCollection.getElement(LanternKeys.FAILED_DATA_MANIPULATORS).orElse(null);
if (holder == null) {
holder = valueCollection.register(LanternKeys.FAILED_DATA_MANIPULATORS, null);
}
holder.set(failedData);
}
}
use of org.spongepowered.api.data.value.ValueContainer in project LanternServer by LanternPowered.
the class ICompositeValueStore method offerFastNoEvents.
default boolean offerFastNoEvents(H valueContainer, MergeFunction function) {
if (valueContainer instanceof IDataManipulatorBase) {
// Offer all the default key values as long if they are supported
final Optional<DataManipulatorRegistration> optRegistration = DataManipulatorRegistry.get().getByMutable(((IDataManipulatorBase) valueContainer).getMutableType());
if (optRegistration.isPresent()) {
if (function == MergeFunction.FORCE_NOTHING) {
return true;
} else if (function != MergeFunction.IGNORE_ALL) {
ValueContainer old = DataHelper.create(this, optRegistration.get());
if (valueContainer instanceof IImmutableDataManipulator && old != null) {
old = ((DataManipulator) old).asImmutable();
}
valueContainer = (H) function.merge(old, valueContainer);
}
boolean success = false;
for (ImmutableValue value : valueContainer.getValues()) {
if (offerFast(value)) {
success = true;
break;
}
}
return success;
}
}
if (this instanceof AdditionalContainerHolder) {
final AdditionalContainerCollection<H> containers = ((AdditionalContainerHolder<H>) this).getAdditionalContainers();
final Class key = valueContainer.getClass();
final H old = (H) containers.get(key).orElse(null);
final H merged = function.merge(old, valueContainer);
containers.offer(merged);
return true;
}
return false;
}
use of org.spongepowered.api.data.value.ValueContainer in project LanternServer by LanternPowered.
the class ICompositeValueStore method offerNoEvents.
default DataTransactionResult offerNoEvents(H valueContainer, MergeFunction function) {
if (valueContainer instanceof IDataManipulatorBase) {
// Offer all the default key values as long if they are supported
final Optional<DataManipulatorRegistration> optRegistration = DataManipulatorRegistry.get().getByMutable(((IDataManipulatorBase) valueContainer).getMutableType());
if (optRegistration.isPresent()) {
if (function != MergeFunction.IGNORE_ALL) {
ValueContainer old = DataHelper.create(this, optRegistration.get());
if (valueContainer instanceof IImmutableDataManipulator && old != null) {
old = ((DataManipulator) old).asImmutable();
}
valueContainer = (H) function.merge(old, valueContainer);
}
final DataTransactionResult.Builder builder = DataTransactionResult.builder();
boolean success = false;
for (ImmutableValue value : valueContainer.getValues()) {
final DataTransactionResult result = offerNoEvents(value);
if (result.isSuccessful()) {
builder.success(value);
builder.replace(result.getReplacedData());
success = true;
} else {
builder.reject(value);
}
}
if (success) {
builder.result(DataTransactionResult.Type.SUCCESS);
} else {
builder.result(DataTransactionResult.Type.FAILURE);
}
return builder.build();
}
}
if (this instanceof AdditionalContainerHolder) {
final AdditionalContainerCollection<H> containers = ((AdditionalContainerHolder<H>) this).getAdditionalContainers();
final Class key = valueContainer.getClass();
final H old = (H) containers.get(key).orElse(null);
final H merged = function.merge(old, valueContainer);
containers.offer(merged);
final DataTransactionResult.Builder builder = DataTransactionResult.builder().result(DataTransactionResult.Type.SUCCESS);
builder.success(merged.getValues());
if (old != null) {
builder.replace(old.getValues());
}
return builder.build();
}
return DataTransactionResult.failNoData();
}
Aggregations