use of org.spongepowered.api.util.Tuple in project SpongeCommon by SpongePowered.
the class SpongeGameRegistry method preRegistryInit.
public void preRegistryInit() {
CommonModuleRegistry.getInstance().registerDefaultModules();
final DirectedGraph<Class<? extends RegistryModule>> graph = new DirectedGraph<>();
for (RegistryModule module : this.registryModules) {
this.classMap.put(module.getClass(), module);
addToGraph(module, graph);
}
// Now we need ot do the catalog ones
for (CatalogRegistryModule<?> module : this.catalogRegistryMap.values()) {
this.classMap.put(module.getClass(), module);
addToGraph(module, graph);
}
try {
this.orderedModules.addAll(TopologicalOrder.createOrderedLoad(graph));
} catch (CyclicGraphException e) {
StringBuilder msg = new StringBuilder();
msg.append("Registry module dependencies are cyclical!\n");
msg.append("Dependency loops are:\n");
for (DataNode<?>[] cycle : e.getCycles()) {
msg.append("[");
for (DataNode<?> node : cycle) {
msg.append(node.getData().toString()).append(" ");
}
msg.append("]\n");
}
SpongeImpl.getLogger().fatal(msg.toString());
throw new RuntimeException("Registry modules dependencies error.");
}
registerModulePhase();
SpongeVillagerRegistry.registerVanillaTrades();
DataRegistrar.setupSerialization();
final List<Tuple<Class<? extends CatalogType>, CatalogRegistryModule<?>>> modules = new ArrayList<>();
for (Map.Entry<Class<? extends CatalogType>, CatalogRegistryModule<?>> entry : this.catalogRegistryMap.entrySet()) {
modules.add(new Tuple<>(entry.getKey(), entry.getValue()));
}
modules.sort(Comparator.comparing(tuple -> tuple.getFirst().getSimpleName()));
if (PRINT_CATALOG_TYPES) {
// Lol... this gets spammy really fast.... Probably at some point should be put to file.
final PrettyPrinter printer = new PrettyPrinter(100).add("Printing all Catalogs and their ID's").centre().hr().addWrapped("This is a test to print out all registered catalogs during initialization for their mapping, id's, and objects themselves.");
for (Tuple<Class<? extends CatalogType>, CatalogRegistryModule<?>> module : modules) {
printer.add(" %s : %s", "CatalogType", module.getFirst().getSimpleName());
final Collection<? extends CatalogType> all = module.getSecond().getAll();
final List<CatalogType> catalogTypes = new ArrayList<>(all);
catalogTypes.sort(Comparator.comparing(CatalogType::getId));
for (CatalogType catalogType : catalogTypes) {
printer.add(" -%s", catalogType.getId());
}
printer.hr();
}
printer.trace(System.err, SpongeImpl.getLogger(), Level.DEBUG);
}
}
use of org.spongepowered.api.util.Tuple in project SpongeCommon by SpongePowered.
the class MixinChunk method getIntersectingEntities.
private void getIntersectingEntities(Collection<Entity> entities, Vector3d start, Vector3d direction, double distance, java.util.function.Predicate<EntityHit> filter, Set<EntityHit> intersections) {
// Check each entity in the list
for (Entity entity : entities) {
final org.spongepowered.api.entity.Entity spongeEntity = (org.spongepowered.api.entity.Entity) entity;
final Optional<AABB> box = spongeEntity.getBoundingBox();
// Can't intersect if the entity doesn't have a bounding box
if (!box.isPresent()) {
continue;
}
// Ignore entities that didn't intersect
final Optional<Tuple<Vector3d, Vector3d>> optionalIntersection = box.get().intersects(start, direction);
if (!optionalIntersection.isPresent()) {
continue;
}
// Check that the entity isn't too far away
final Tuple<Vector3d, Vector3d> intersection = optionalIntersection.get();
final double distanceSquared = intersection.getFirst().sub(start).lengthSquared();
if (distanceSquared > distance * distance) {
continue;
}
// Now test the filter on the entity and intersection
final EntityHit hit = new EntityHit(spongeEntity, intersection.getFirst(), intersection.getSecond(), Math.sqrt(distanceSquared));
if (!filter.test(hit)) {
continue;
}
// If everything passes we have an intersection!
intersections.add(hit);
// If the entity has part, recurse on these
final Entity[] parts = entity.getParts();
if (parts != null && parts.length > 0) {
getIntersectingEntities(Arrays.asList(parts), start, direction, distance, filter, intersections);
}
}
}
use of org.spongepowered.api.util.Tuple in project LanternServer by LanternPowered.
the class FilterGenerator method generateClass.
byte[] generateClass(String name, Method method) {
name = name.replace('.', '/');
final Parameter[] params = method.getParameters();
final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
MethodVisitor mv;
cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, name, null, "java/lang/Object", new String[] { Type.getInternalName(EventFilter.class) });
SubtypeFilterDelegate sfilter = null;
final List<FilterDelegate> additional = new ArrayList<>();
boolean cancellation = false;
for (Annotation anno : method.getAnnotations()) {
Object obj = filterFromAnnotation(anno.annotationType());
if (obj == null) {
continue;
}
if (obj instanceof SubtypeFilter) {
if (sfilter != null) {
throw new IllegalStateException("Cannot have both @Include and @Exclude annotations present at once");
}
sfilter = ((SubtypeFilter) obj).getDelegate(anno);
} else if (obj instanceof EventTypeFilter) {
final EventTypeFilter etf = (EventTypeFilter) obj;
additional.add(etf.getDelegate(anno));
if (etf == EventTypeFilter.CANCELLATION) {
cancellation = true;
}
}
}
if (!cancellation && Cancellable.class.isAssignableFrom(method.getParameterTypes()[0])) {
additional.add(new CancellationEventFilterDelegate(Tristate.FALSE));
}
if (sfilter != null) {
sfilter.createFields(cw);
}
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
if (sfilter != null) {
sfilter.writeCtor(name, cw, mv);
}
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "filter", "(" + Type.getDescriptor(Event.class) + ")[Ljava/lang/Object;", null, null);
mv.visitCode();
// index of the next available local variable
int local = 2;
if (sfilter != null) {
local = sfilter.write(name, cw, mv, method, local);
}
for (FilterDelegate eventFilter : additional) {
local = eventFilter.write(name, cw, mv, method, local);
}
// local var indices of the parameters values
final int[] plocals = new int[params.length - 1];
for (int i = 1; i < params.length; i++) {
final Parameter param = params[i];
ParameterFilterSourceDelegate source = null;
final List<ParameterFilterDelegate> paramFilters = new ArrayList<>();
for (Annotation anno : param.getAnnotations()) {
Object obj = filterFromAnnotation(anno.annotationType());
if (obj == null) {
continue;
}
if (obj instanceof ParameterSource) {
if (source != null) {
throw new IllegalStateException("Cannot have multiple parameter filter source annotations (for " + param.getName() + ")");
}
source = ((ParameterSource) obj).getDelegate(anno);
} else if (obj instanceof ParameterFilter) {
paramFilters.add(((ParameterFilter) obj).getDelegate(anno));
}
}
if (source == null) {
throw new IllegalStateException("Cannot have additional parameters filters without a source (for " + param.getName() + ")");
}
if (source instanceof AllCauseFilterSourceDelegate && !paramFilters.isEmpty()) {
// TODO until better handling for filtering arrays is added
throw new IllegalStateException("Cannot have additional parameters filters without an array source (for " + param.getName() + ")");
}
final Tuple<Integer, Integer> localState = source.write(cw, mv, method, param, local);
local = localState.getFirst();
plocals[i - 1] = localState.getSecond();
for (ParameterFilterDelegate paramFilter : paramFilters) {
paramFilter.write(cw, mv, method, param, plocals[i - 1]);
}
}
// create the return array
if (params.length == 1) {
mv.visitInsn(ICONST_1);
} else {
mv.visitIntInsn(BIPUSH, params.length);
}
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
// load the event into the array
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ALOAD, 1);
mv.visitInsn(AASTORE);
// load all the params into the array
for (int i = 1; i < params.length; i++) {
mv.visitInsn(DUP);
mv.visitIntInsn(BIPUSH, i);
Type paramType = Type.getType(params[i].getType());
mv.visitVarInsn(paramType.getOpcode(ILOAD), plocals[i - 1]);
GeneratorUtils.visitBoxingMethod(mv, paramType);
mv.visitInsn(AASTORE);
}
mv.visitInsn(ARETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
cw.visitEnd();
final byte[] data = cw.toByteArray();
if (FILTER_DEBUG) {
final Path outDir = Paths.get(".sponge.debug.out");
final Path outFile = outDir.resolve(name + ".class");
if (!Files.exists(outFile.getParent())) {
try {
Files.createDirectories(outFile.getParent());
} catch (IOException e) {
Lantern.getLogger().warn("Unable to create the filter debug directory.", e);
}
}
try (final OutputStream out = Files.newOutputStream(outFile)) {
out.write(data);
} catch (IOException e) {
Lantern.getLogger().warn("Unable to create the filter debug class.", e);
}
}
return data;
}
use of org.spongepowered.api.util.Tuple in project LanternServer by LanternPowered.
the class GetterFilterSourceDelegate method write.
@Override
public Tuple<Integer, Integer> write(ClassWriter cw, MethodVisitor mv, Method method, Parameter param, int local) {
Class<?> targetType = param.getType();
Class<?> eventClass = method.getParameterTypes()[0];
String targetMethod = this.anno.value();
Method targetMethodObj;
try {
targetMethodObj = eventClass.getMethod(targetMethod);
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException(String.format("Method %s specified by getter annotation was not found in type %s", targetMethod, eventClass.getName()));
}
if (targetMethodObj.getParameterCount() != 0) {
throw new IllegalArgumentException("Method " + targetMethodObj.toGenericString() + " specified by getter annotation has non-zero parameter count");
}
if (!targetMethodObj.getReturnType().equals(Optional.class) && !targetMethodObj.getReturnType().isAssignableFrom(targetType)) {
throw new IllegalArgumentException("Method " + targetMethodObj.toGenericString() + " does not return the correct type. Expected: " + targetType.getName() + " Found: " + targetMethodObj.getReturnType().getName());
}
Type returnType = Type.getReturnType(targetMethodObj);
Class<?> declaringClass = targetMethodObj.getDeclaringClass();
mv.visitVarInsn(ALOAD, 1);
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(declaringClass));
int op = declaringClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL;
mv.visitMethodInsn(op, Type.getInternalName(declaringClass), targetMethod, "()" + returnType.getDescriptor(), declaringClass.isInterface());
int paramLocal = local++;
mv.visitVarInsn(returnType.getOpcode(ISTORE), paramLocal);
if (!targetMethodObj.getReturnType().isPrimitive()) {
Label failure = new Label();
Label success = new Label();
if (Optional.class.equals(targetMethodObj.getReturnType()) && !Optional.class.equals(targetType)) {
// Unwrap the optional
mv.visitVarInsn(ALOAD, paramLocal);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Optional", "isPresent", "()Z", false);
mv.visitJumpInsn(IFEQ, failure);
mv.visitVarInsn(ALOAD, paramLocal);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Optional", "get", "()Ljava/lang/Object;", false);
mv.visitInsn(DUP);
mv.visitVarInsn(ASTORE, paramLocal);
} else {
mv.visitVarInsn(returnType.getOpcode(ILOAD), paramLocal);
}
mv.visitTypeInsn(INSTANCEOF, Type.getInternalName(targetType));
mv.visitJumpInsn(IFNE, success);
mv.visitLabel(failure);
mv.visitInsn(ACONST_NULL);
mv.visitInsn(ARETURN);
mv.visitLabel(success);
}
return new Tuple<>(local, paramLocal);
}
use of org.spongepowered.api.util.Tuple in project LanternServer by LanternPowered.
the class LanternEntity method damage.
@Override
public boolean damage(double damage, DamageSource damageSource) {
checkNotNull(damageSource, "damageSource");
final Optional<Double> optHealth = get(Keys.HEALTH);
if (!optHealth.isPresent()) {
// entities without health, instantly destroying them.
if (damageSource.getType() == DamageTypes.VOID) {
remove(RemoveState.DESTROYED);
return true;
}
return false;
}
// Always throw the event. Plugins may want to override
// default checking behavior.
boolean cancelled = false;
// if the player is in creative mode
if (!damageSource.doesAffectCreative() && get(Keys.GAME_MODE).orElse(null) == GameModes.CREATIVE) {
cancelled = true;
}
final List<Tuple<DamageFunction, Consumer<DamageEntityEvent>>> damageFunctions = new ArrayList<>();
// Only collect damage modifiers if the event isn't cancelled
if (!cancelled) {
collectDamageFunctions(damageFunctions);
}
// TODO: Damage modifiers, etc.
final CauseStack causeStack = CauseStack.current();
try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
frame.pushCause(damageSource);
frame.addContext(EventContextKeys.DAMAGE_TYPE, damageSource.getType());
final DamageEntityEvent event = SpongeEventFactory.createDamageEntityEvent(frame.getCurrentCause(), damageFunctions.stream().map(Tuple::getFirst).collect(Collectors.toList()), this, damage);
event.setCancelled(cancelled);
Sponge.getEventManager().post(event);
if (event.isCancelled()) {
return false;
}
damageFunctions.forEach(tuple -> tuple.getSecond().accept(event));
damage = event.getFinalDamage();
if (damage > 0) {
offer(Keys.HEALTH, Math.max(optHealth.get() - damage, 0));
}
final double exhaustion = damageSource.getExhaustion();
getValue(Keys.EXHAUSTION).ifPresent(value -> offer(Keys.EXHAUSTION, Math.min(value.getMaxValue(), value.get() + exhaustion)));
}
triggerEvent(DamagedEntityEvent.of());
return true;
}
Aggregations