use of org.spongepowered.api.data.Key in project SpongeCommon by SpongePowered.
the class DataProviderRegistrator method registerDataStoreDelegatingProvider.
public <H extends DataHolder, K, V extends Value<K>> void registerDataStoreDelegatingProvider(final Key<V> key, final Type typeToken) {
// Create dataprovider for mutable and immutable DataContainerHolders
if (GenericTypeReflector.isSuperType(DataProviderRegistrator.MUTABLE, typeToken)) {
this.asMutable(GenericTypeReflector.erase(typeToken)).create(key).get(holder -> {
final DataContainer dataContainer = ((DataContainerHolder) holder).data$getDataContainer();
return SpongeDataManager.getDatastoreRegistry().getDataStore(key, typeToken).deserialize(dataContainer).get(key).orElse(null);
}).set((holder, v) -> {
final DataContainer dataContainer = ((DataContainerHolder) holder).data$getDataContainer();
final DataManipulator.Mutable manipulator = DataManipulator.mutableOf();
manipulator.set(key, v);
SpongeDataManager.getDatastoreRegistry().getDataStore(key, typeToken).serialize(manipulator, dataContainer);
((DataContainerHolder.Mutable) holder).data$setDataContainer(dataContainer);
});
} else if (GenericTypeReflector.isSuperType(DataProviderRegistrator.IMMUTABLE, typeToken)) {
this.asImmutable((Class<? super H>) GenericTypeReflector.erase(typeToken)).create(key).get(holder -> {
final DataContainer dataContainer = ((DataContainerHolder) holder).data$getDataContainer();
return SpongeDataManager.getDatastoreRegistry().getDataStore(key, typeToken).deserialize(dataContainer).get(key).orElse(null);
}).set((holder, v) -> {
final DataContainer dataContainer = ((DataContainerHolder) holder).data$getDataContainer();
final DataManipulator.Mutable manipulator = DataManipulator.mutableOf();
manipulator.set(key, v);
SpongeDataManager.getDatastoreRegistry().getDataStore(key, typeToken).serialize(manipulator, dataContainer);
return (H) ((DataContainerHolder.Immutable) holder).data$withDataContainer(dataContainer);
});
}
}
use of org.spongepowered.api.data.Key in project SpongeCommon by SpongePowered.
the class DataProviderRegistrator method spongeDataStore.
public void spongeDataStore(final ResourceKey datastoreKey, final int version, final DataContentUpdater[] contentUpdater, final Class dataHolder, final Key<? extends Value<?>>... dataKeys) {
final SpongeDataStoreBuilder builder = ((SpongeDataStoreBuilder) DataStore.builder()).pluginData(datastoreKey, version);
builder.updater(contentUpdater);
builder.holder(dataHolder);
for (Key dataKey : dataKeys) {
builder.key(dataKey, dataKey.key().value());
}
SpongeDataManager.getDatastoreRegistry().register(builder.build(), Arrays.asList(dataKeys));
}
use of org.spongepowered.api.data.Key in project SpongeCommon by SpongePowered.
the class GetValueFilterSourceDelegate method write.
@Override
public Tuple<Integer, Integer> write(final ClassWriter cw, final MethodVisitor mv, final ListenerClassVisitor.DiscoveredMethod method, final int paramIdx, int local, final int[] plocals, final ListenerClassVisitor.ListenerParameter[] params) throws ClassNotFoundException {
final Field targetField;
try {
targetField = this.anno.container().getField(this.anno.value());
} catch (final NoSuchFieldException ex) {
throw new IllegalArgumentException(String.format("Field %s specified by GetValue annotation was not found in container %s", this.anno.value(), this.anno.container()));
}
if (!Key.class.isAssignableFrom(targetField.getType())) {
throw new IllegalArgumentException(String.format("Field %s.%s was not a Key", targetField.getName(), targetField.getType()));
}
final Type paramType = params[paramIdx].type();
final Type eventType = params[0].type();
// key := <container>.<value>
final int keyIdx = local++;
mv.visitFieldInsn(GETSTATIC, Type.getInternalName(this.anno.container()), this.anno.value(), Type.getDescriptor(Key.class));
mv.visitVarInsn(ASTORE, keyIdx);
final Label success = new Label();
final Label failure = new Label();
// for all parameters p' before `param` that inherit from ValueContainer, excluding the event itself
for (int i = paramIdx - 1; i > 0; --i) {
final ListenerClassVisitor.ListenerParameter param = params[i];
if (!ValueContainer.class.isAssignableFrom(method.classByLoader(param.type().getClassName()))) {
continue;
}
// p'
mv.visitVarInsn(ALOAD, plocals[i - 1]);
mv.visitVarInsn(ALOAD, keyIdx);
// x = p'.get(key)
mv.visitMethodInsn(INVOKEINTERFACE, param.type().getInternalName(), "get", GetValueFilterSourceDelegate.VALUE_CONTAINER_GET, true);
// if (x.isPresent()) goto success
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKEVIRTUAL, GetValueFilterSourceDelegate.OPTIONAL.getInternalName(), "isPresent", GetValueFilterSourceDelegate.OPTIONAL_IS_PRESENT, false);
mv.visitJumpInsn(IFNE, success);
// drop the optional from the stack if we're unsuccessful
mv.visitInsn(POP);
}
// since none have been reached yet
// x = locals[1].cause().first(ValueContainer.class)
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEINTERFACE, eventType.getInternalName(), "cause", "()" + GetValueFilterSourceDelegate.CAUSE.getDescriptor(), true);
mv.visitLdcInsn(GetValueFilterSourceDelegate.VALUE_CONTAINER);
mv.visitMethodInsn(INVOKEVIRTUAL, GetValueFilterSourceDelegate.CAUSE.getInternalName(), "first", Type.getMethodDescriptor(GetValueFilterSourceDelegate.OPTIONAL, Type.getType(Class.class)), false);
mv.visitInsn(DUP);
// if (!x.isPresent()) goto failure;
mv.visitMethodInsn(INVOKEVIRTUAL, GetValueFilterSourceDelegate.OPTIONAL.getInternalName(), "isPresent", GetValueFilterSourceDelegate.OPTIONAL_IS_PRESENT, false);
mv.visitJumpInsn(IFEQ, failure);
// event:
// x = x.get().get(key)
mv.visitMethodInsn(INVOKEVIRTUAL, GetValueFilterSourceDelegate.OPTIONAL.getInternalName(), "get", GetValueFilterSourceDelegate.OPTIONAL_GET, false);
// Optional<ValueContainer>
mv.visitVarInsn(ALOAD, keyIdx);
mv.visitMethodInsn(INVOKEINTERFACE, GetValueFilterSourceDelegate.VALUE_CONTAINER.getInternalName(), "get", GetValueFilterSourceDelegate.VALUE_CONTAINER_GET, true);
// if (x.isPresent()) goto success;
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKEVIRTUAL, GetValueFilterSourceDelegate.OPTIONAL.getInternalName(), "isPresent", GetValueFilterSourceDelegate.OPTIONAL_IS_PRESENT, false);
mv.visitJumpInsn(IFNE, success);
mv.visitLabel(failure);
mv.visitInsn(ACONST_NULL);
mv.visitInsn(ARETURN);
mv.visitLabel(success);
// x = x.get()
mv.visitMethodInsn(INVOKEVIRTUAL, GetValueFilterSourceDelegate.OPTIONAL.getInternalName(), "get", GetValueFilterSourceDelegate.OPTIONAL_GET, false);
if (paramType.getSort() < Type.ARRAY) {
GeneratorUtils.visitUnboxingMethod(mv, paramType);
} else {
final Label success2 = new Label();
mv.visitInsn(DUP);
mv.visitTypeInsn(INSTANCEOF, paramType.getInternalName());
mv.visitJumpInsn(IFNE, success2);
mv.visitInsn(ACONST_NULL);
mv.visitInsn(ARETURN);
mv.visitLabel(success2);
}
final int paramLocal = local;
local += paramType.getSize();
mv.visitVarInsn(paramType.getOpcode(ISTORE), paramLocal);
return new Tuple<>(local, paramLocal);
}
use of org.spongepowered.api.data.Key in project SpongeCommon by SpongePowered.
the class HasDataFilterDelegate method write.
@Override
public void write(final ClassWriter cw, final MethodVisitor mv, final ListenerClassVisitor.ListenerParameter param, final int localParam) throws ClassNotFoundException {
if (!ValueContainer.class.isAssignableFrom(param.clazz())) {
throw new IllegalStateException("Annotated type for data filter is not a ValueContainer");
}
final Field targetField;
try {
targetField = this.anno.container().getField(this.anno.value());
} catch (final NoSuchFieldException ex) {
throw new IllegalArgumentException(String.format("Field %s specified by GetValue annotation was not found in container %s", this.anno.value(), this.anno.container()));
}
if (!Key.class.isAssignableFrom(targetField.getType())) {
throw new IllegalArgumentException(String.format("Field %s.%s was not a Key", targetField.getName(), targetField.getType()));
}
mv.visitVarInsn(ALOAD, localParam);
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(ValueContainer.class));
mv.visitFieldInsn(GETSTATIC, Type.getInternalName(this.anno.container()), this.anno.value(), Type.getDescriptor(Key.class));
mv.visitMethodInsn(INVOKEINTERFACE, param.type().getInternalName(), "get", HasDataFilterDelegate.HAS_DESC, true);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Optional", "isPresent", "()Z", false);
final Label success = new Label();
if (this.anno.inverse()) {
mv.visitJumpInsn(IFEQ, success);
} else {
mv.visitJumpInsn(IFNE, success);
}
mv.visitInsn(ACONST_NULL);
mv.visitInsn(ARETURN);
mv.visitLabel(success);
}
use of org.spongepowered.api.data.Key in project SpongeCommon by SpongePowered.
the class SupportsDataFilterDelegate method write.
@Override
public void write(final ClassWriter cw, final MethodVisitor mv, final ListenerClassVisitor.ListenerParameter param, final int localParam) throws ClassNotFoundException {
if (!ValueContainer.class.isAssignableFrom(param.clazz())) {
throw new IllegalStateException("Annotated type for data filter is not a ValueContainer");
}
final Field targetField;
try {
targetField = this.anno.container().getField(this.anno.value());
} catch (final NoSuchFieldException ex) {
throw new IllegalArgumentException(String.format("Field %s specified by GetValue annotation was not found in container %s", this.anno.value(), this.anno.container()));
}
if (!Key.class.isAssignableFrom(targetField.getType())) {
throw new IllegalArgumentException(String.format("Field %s.%s was not a Key", targetField.getName(), targetField.getType()));
}
mv.visitVarInsn(ALOAD, localParam);
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(ValueContainer.class));
mv.visitFieldInsn(GETSTATIC, Type.getInternalName(this.anno.container()), this.anno.value(), Type.getDescriptor(Key.class));
mv.visitMethodInsn(INVOKEINTERFACE, param.type().getInternalName(), "supports", SupportsDataFilterDelegate.SUPPORTS_DESC, true);
final Label success = new Label();
if (this.anno.inverse()) {
mv.visitJumpInsn(IFEQ, success);
} else {
mv.visitJumpInsn(IFNE, success);
}
mv.visitInsn(ACONST_NULL);
mv.visitInsn(ARETURN);
mv.visitLabel(success);
}
Aggregations