use of org.terasology.reflection.TypeInfo in project Terasology by MovingBlocks.
the class SubtypeLayoutBuilder method populate.
@Override
protected void populate(Binding<T> binding, ColumnLayout layout, ColumnLayout mainLayout) {
ColumnLayout widgetContainer = new ColumnLayout();
Binding<TypeInfo<T>> editingType = new NotifyingBinding<TypeInfo<T>>(baseType) {
@Override
protected void onSet() {
widgetContainer.removeAllWidgets();
TypeWidgetBuilder<T> builder = SubtypeLayoutBuilder.this.library.getBuilder(get()).orElse(baseTypeWidgetBuilder);
if (builder == null) {
LOGGER.error("Could not find widget for type {}, editing as base type {}", get(), baseType);
return;
}
widgetContainer.addWidget(builder.build(binding));
}
};
if (binding.get() != null && !editingType.get().getRawType().equals(binding.get().getClass())) {
Type actual = ReflectionUtil.parameterizeandResolveRawType(baseType.getType(), binding.get().getClass());
TypeInfo<T> actualType = (TypeInfo<T>) TypeInfo.of(actual);
if (!allowedSubtypes.contains(actualType)) {
Optional<TypeInfo<T>> closestMatch = allowedSubtypes.stream().filter(subtype -> subtype.getRawType().isAssignableFrom(actualType.getRawType())).findFirst();
// closestMatch is always present since editingType is guaranteed to be a subtype of T
assert closestMatch.isPresent();
editingType.set(closestMatch.get());
} else {
editingType.set(actualType);
}
}
UIDropdownScrollable<TypeInfo<T>> typeSelection = new UIDropdownScrollable<>();
typeSelection.setOptions(allowedSubtypes);
typeSelection.bindSelection(editingType);
typeSelection.setOptionRenderer(new StringTextRenderer<TypeInfo<T>>() {
@Override
public String getString(TypeInfo<T> value) {
return getTypeName(value);
}
});
// TODO: Translate
typeSelection.setTooltip("Select the type for the new object");
layout.addWidget(typeSelection);
layout.addWidget(widgetContainer);
}
use of org.terasology.reflection.TypeInfo in project Terasology by MovingBlocks.
the class ReflectionUtil method getComponentType.
/**
* Returns the {@link TypeInfo} describing the component type of an array of the given type.
*
* @param type The {@link TypeInfo} describing the type of the array.
* @param <C> The component type of the array.
*/
@SuppressWarnings("unchecked")
public static <C> TypeInfo<C> getComponentType(TypeInfo<C[]> type) {
if (type.getType() instanceof GenericArrayType) {
GenericArrayType arrayType = (GenericArrayType) type.getType();
Type componentType = arrayType.getGenericComponentType();
Type resolvedComponentType = resolveType(arrayType, componentType);
return (TypeInfo<C>) TypeInfo.of(resolvedComponentType);
}
return TypeInfo.of((Class<C>) type.getRawType().getComponentType());
}
use of org.terasology.reflection.TypeInfo in project Terasology by MovingBlocks.
the class TypeHandlerLibrary method getTypeHandler.
/**
* Retrieves the {@link TypeHandler} for the specified type, if available.
* <p>
* Each {@link TypeHandlerFactory} added to this {@link TypeHandlerLibrary} is requested to generate a {@link
* TypeHandler} for the given type. Most recently added factories are requested first, hence a {@link
* TypeHandlerFactory} can override one that was added before it.
*
* @param type The {@link TypeInfo} describing the type for which to retrieve the {@link TypeHandler}.
* @param <T> The type for which to retrieve the {@link TypeHandler}.
* @return The {@link TypeHandler} for the specified type, if available.
*/
@SuppressWarnings("unchecked")
public <T> Optional<TypeHandler<T>> getTypeHandler(TypeInfo<T> type) {
TypeHandlerContext context = new TypeHandlerContext(this, sandbox);
if (typeHandlerCache.containsKey(type)) {
return Optional.of((TypeHandler<T>) typeHandlerCache.get(type));
}
Map<TypeInfo<?>, FutureTypeHandler<?>> futures = futureTypeHandlers.get();
boolean cleanupFutureTypeHandlers = false;
if (futures == null) {
cleanupFutureTypeHandlers = true;
futures = new HashMap<>();
futureTypeHandlers.set(futures);
}
FutureTypeHandler<T> future = (FutureTypeHandler<T>) futures.get(type);
if (future != null) {
return Optional.of(future);
}
try {
future = new FutureTypeHandler<>();
futures.put(type, future);
// TODO: Explore reversing typeHandlerFactories itself before building object
for (int i = typeHandlerFactories.size() - 1; i >= 0; i--) {
TypeHandlerFactory typeHandlerFactory = typeHandlerFactories.get(i);
Optional<TypeHandler<T>> typeHandler = typeHandlerFactory.create(type, context);
if (typeHandler.isPresent()) {
TypeHandler<T> handler = typeHandler.get();
if (!sandbox.isValidTypeHandlerDeclaration(type, handler)) {
continue;
}
typeHandlerCache.put(type, handler);
future.typeHandler = handler;
return Optional.of(handler);
}
}
return Optional.empty();
} finally {
futures.remove(type);
if (cleanupFutureTypeHandlers) {
futureTypeHandlers.remove();
}
}
}
use of org.terasology.reflection.TypeInfo in project Terasology by MovingBlocks.
the class ConstructorLibrary method getCollectionCopyConstructor.
public static <E> CollectionCopyConstructor<? extends Collection<E>, E> getCollectionCopyConstructor(TypeInfo<? extends Collection<E>> typeInfo) {
Class<? extends Collection<E>> rawType = typeInfo.getRawType();
Type type = typeInfo.getType();
if (Multiset.class.isAssignableFrom(rawType)) {
if (ImmutableMultiset.class.isAssignableFrom(rawType)) {
return ImmutableMultiset::copyOf;
}
return HashMultiset::create;
}
if (SortedSet.class.isAssignableFrom(rawType)) {
if (ImmutableSortedSet.class.isAssignableFrom(rawType)) {
return ImmutableSortedSet::copyOf;
}
return TreeSet::new;
}
if (EnumSet.class.isAssignableFrom(rawType)) {
return (items) -> {
if (!(type instanceof ParameterizedType)) {
throw new IllegalArgumentException("Invalid EnumSet type: " + type.toString());
}
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
if (!(elementType instanceof Class)) {
throw new IllegalArgumentException("Invalid EnumSet type: " + type.toString());
}
return EnumSet.copyOf((Collection) items);
};
}
if (Set.class.isAssignableFrom(rawType)) {
if (ImmutableSet.class.isAssignableFrom(rawType)) {
return ImmutableSet::copyOf;
}
return LinkedHashSet::new;
}
if (Queue.class.isAssignableFrom(rawType)) {
return ArrayDeque::new;
}
if (ImmutableList.class.isAssignableFrom(rawType)) {
return ImmutableList::copyOf;
}
return ArrayList::new;
}
Aggregations