From f8da5c8318613fa165b9c2230a8c55f141967884 Mon Sep 17 00:00:00 2001 From: Jan-Willem Harmannij Date: Sat, 28 Sep 2024 21:08:38 +0200 Subject: [PATCH] Set trailing flag parameters as varargs (fixes #140) --- .../javagi/generators/CallableGenerator.java | 103 ++------------- .../javagi/generators/ClosureGenerator.java | 6 +- .../generators/ConstructorGenerator.java | 5 +- .../javagi/generators/MethodGenerator.java | 2 +- .../javagi/generators/NamespaceGenerator.java | 6 +- .../generators/RegisteredTypeGenerator.java | 18 +-- .../javagi/generators/SignalGenerator.java | 2 +- .../generators/TypedValueGenerator.java | 15 +-- .../github/jwharm/javagi/gir/Parameter.java | 4 + .../jwharm/javagi/test/gio/FileTest.java | 3 +- .../github/jwharm/javagi/base/GLibLogger.java | 62 +++++++++- .../github/jwharm/javagi/interop/Interop.java | 21 +++- .../jwharm/javagi/gobject/JavaClosure.java | 16 +-- .../jwharm/javagi/gobject/ValueUtil.java | 15 +-- .../javagi/gobject/types/Overrides.java | 49 +++----- .../javagi/gobject/types/Properties.java | 53 +++----- .../jwharm/javagi/gobject/types/Types.java | 117 +++++++----------- .../javagi/test/gobject/ClosureTest.java | 7 +- .../javagi/gtk/types/TemplateTypes.java | 30 ++--- .../github/jwharm/javagi/gtk/types/Types.java | 21 ++-- .../javagi/gtk/util/BuilderJavaScope.java | 27 ++-- 21 files changed, 232 insertions(+), 350 deletions(-) diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/CallableGenerator.java b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/CallableGenerator.java index 0a5a6f88..305dc3e0 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/CallableGenerator.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/CallableGenerator.java @@ -26,13 +26,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.lang.model.element.Modifier; import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.MemorySegment; import java.lang.foreign.ValueLayout; import java.util.*; import static io.github.jwharm.javagi.util.Conversions.getValueLayout; +import static io.github.jwharm.javagi.util.Conversions.toJavaIdentifier; import static java.util.function.Predicate.not; import static java.util.stream.Collectors.joining; @@ -97,8 +97,7 @@ String generateValueLayout(AnyType anyType) { } void generateMethodParameters(MethodSpec.Builder builder, - boolean generic, - boolean setOfBitfield) { + boolean generic) { if (callable.parameters() == null) return; @@ -111,9 +110,19 @@ void generateMethodParameters(MethodSpec.Builder builder, if (p.varargs()) { builder.addParameter(Object[].class, "varargs"); builder.varargs(true); + } else if ((! (callable instanceof Callback)) + && (! (callable instanceof Signal)) + && (! p.isOutParameter()) + && p.isBitfield() + && p.isLastParameter()) { + // Change trailing flags parameter into varargs + var name = toJavaIdentifier(p.name()); + var type = p.anyType().typeName(); + builder.addParameter(ArrayTypeName.of(type), name); + builder.varargs(true); } else { var generator = new TypedValueGenerator(p); - var type = generator.getType(setOfBitfield); + var type = generator.getType(); if (generic && type.equals(ClassNames.GOBJECT)) type = ClassNames.GENERIC_T; @@ -222,90 +231,4 @@ boolean varargs() { return params != null && params.parameters().stream().anyMatch(Parameter::varargs); } - - public MethodSpec generateBitfieldOverload() { - // Check if this is a (named) constructor - boolean ctor = callable instanceof Constructor; - boolean namedCtor = ctor && (!callable.name().equals("new")); - - boolean generic = MethodGenerator.isGeneric(callable); - - // Method name - String name = ctor - ? ConstructorGenerator.getName((Constructor) callable, false) - : MethodGenerator.getName(callable); - - MethodSpec.Builder builder; - if (ctor && (!namedCtor)) - builder = MethodSpec.constructorBuilder(); - else - builder = MethodSpec.methodBuilder(name); - - // Javadoc - if (callable.infoElements().doc() != null) { - String doc = new DocGenerator(callable.infoElements().doc()).generate(); - if (callable instanceof Multiplatform mp && mp.doPlatformCheck()) - builder.addException(ClassNames.UNSUPPORTED_PLATFORM_EXCEPTION) - .addJavadoc(doc, ClassNames.UNSUPPORTED_PLATFORM_EXCEPTION); - else - builder.addJavadoc(doc); - } - - // Deprecated annotation - if (callable.callableAttrs().deprecated()) - builder.addAnnotation(Deprecated.class); - - // Modifiers - builder.addModifiers(Modifier.PUBLIC); - if (callable instanceof Function || namedCtor) - builder.addModifiers(Modifier.STATIC); - else if (callable.parent() instanceof Interface) - builder.addModifiers(Modifier.DEFAULT); - - // Return type - var returnValue = callable.returnValue(); - if (generic && returnValue.anyType().typeName().equals(ClassNames.GOBJECT)) - builder.returns(ClassNames.GENERIC_T); - else if ((!ctor) || namedCtor) - builder.returns(new TypedValueGenerator(returnValue).getType()); - - // Parameters - generateMethodParameters(builder, generic, false); - - // Exception - if (callable.callableAttrs().throws_()) - builder.addException(ClassNames.GERROR_EXCEPTION); - - // Call the overloaded method - PartialStatement stmt = PartialStatement.of(""); - if (ctor && (!namedCtor)) - stmt.add("this"); - else - stmt.add((returnValue.anyType().isVoid() ? "" : "return ") + name); - - // Set parameters - StringJoiner params = new StringJoiner(",$W", "(", ");\n"); - for (Parameter p : callable.parameters().parameters()) { - if (p.isUserDataParameter() - || p.isDestroyNotifyParameter() - || p.isArrayLengthParameter()) - continue; - - TypedValueGenerator gen = new TypedValueGenerator(p); - - if (p.isBitfield()) { - if (p.isOutParameter()) - params.add(gen.getName() + " == null ? null : new $out:T($enumSet:T.of(" + gen.getName() + ".get()))"); - else - params.add("$enumSet:T.of(" + gen.getName() + ")"); - } else { - params.add(gen.getName()); - } - } - stmt.add(params.toString(), - "out", ClassNames.OUT, - "enumSet", EnumSet.class); - builder.addNamedCode(stmt.format(), stmt.arguments()); - return builder.build(); - } } diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/ClosureGenerator.java b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/ClosureGenerator.java index 7c0ce78c..2ad20110 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/ClosureGenerator.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/ClosureGenerator.java @@ -37,6 +37,7 @@ import java.lang.invoke.MethodHandles; import java.lang.reflect.InvocationTargetException; import java.util.List; +import java.util.Set; import static io.github.jwharm.javagi.util.Conversions.*; import static java.util.Comparator.comparing; @@ -93,7 +94,7 @@ MethodSpec generateRunMethod() { if (closure.throws_()) run.addException(ClassNames.GERROR_EXCEPTION); - generator.generateMethodParameters(run, false, true); + generator.generateMethodParameters(run, false); return run.build(); } @@ -231,9 +232,10 @@ && getCarrierTypeName(returnValue.anyType(), false).equals(TypeName.get(MemorySe if (methodToInvoke.endsWith("invoke")) { upcall.nextControlFlow("catch ($T ite)", InvocationTargetException.class); - upcall.addStatement("$T.log($T.LOG_DOMAIN, $T.LEVEL_WARNING, ite.getCause().toString() + $S + $L)", + upcall.addStatement("$T.log($T.LOG_DOMAIN, $T.of($T.LEVEL_WARNING), ite.getCause().toString() + $S + $L)", ClassNames.GLIB, ClassNames.CONSTANTS, + Set.class, ClassNames.LOG_LEVEL_FLAGS, " in ", methodName); diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/ConstructorGenerator.java b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/ConstructorGenerator.java index 761a932f..de459485 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/ConstructorGenerator.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/ConstructorGenerator.java @@ -95,7 +95,7 @@ private MethodSpec constructor() { builder.addAnnotation(Deprecated.class); // Parameters - new CallableGenerator(ctor).generateMethodParameters(builder, false, true); + new CallableGenerator(ctor).generateMethodParameters(builder, false); // Exception if (ctor.callableAttrs().throws_()) @@ -147,8 +147,7 @@ private MethodSpec namedConstructor() { builder.addAnnotation(Deprecated.class); // Parameters - new CallableGenerator(ctor) - .generateMethodParameters(builder, false, true); + new CallableGenerator(ctor).generateMethodParameters(builder, false); // Exception if (ctor.callableAttrs().throws_()) diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/MethodGenerator.java b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/MethodGenerator.java index e1952d17..6beae306 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/MethodGenerator.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/MethodGenerator.java @@ -144,7 +144,7 @@ else if (func instanceof Constructor) builder.returns(new TypedValueGenerator(returnValue).getType()); // Parameters - generator.generateMethodParameters(builder, generic, true); + generator.generateMethodParameters(builder, generic); // Exception if (func.callableAttrs().throws_()) diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/NamespaceGenerator.java b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/NamespaceGenerator.java index 32d93a84..2feb11b5 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/NamespaceGenerator.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/NamespaceGenerator.java @@ -60,12 +60,8 @@ public TypeSpec generateGlobalsClass() { } for (Function f : ns.functions()) { - if (!f.skip()) { + if (!f.skip()) builder.addMethod(new MethodGenerator(f).generate()); - if (f.hasBitfieldParameters()) - builder.addMethod(new CallableGenerator(f) - .generateBitfieldOverload()); - } } if (hasDowncallHandles()) diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/RegisteredTypeGenerator.java b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/RegisteredTypeGenerator.java index f8f32523..76eab11e 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/RegisteredTypeGenerator.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/RegisteredTypeGenerator.java @@ -75,34 +75,22 @@ protected MethodSpec getTypeMethod() { protected void addFunctions(TypeSpec.Builder builder) { for (Function f : filter(rt.children(), Function.class)) { - if (!f.skip()) { + if (!f.skip()) builder.addMethod(new MethodGenerator(f).generate()); - if (f.hasBitfieldParameters()) - builder.addMethod(new CallableGenerator(f) - .generateBitfieldOverload()); - } } } protected void addConstructors(TypeSpec.Builder builder) { for (Constructor c : filter(rt.children(), Constructor.class)) { - if (!c.skip()) { + if (!c.skip()) builder.addMethods(new ConstructorGenerator(c).generate()); - if (c.hasBitfieldParameters()) - builder.addMethod(new CallableGenerator(c) - .generateBitfieldOverload()); - } } } protected void addMethods(TypeSpec.Builder builder) { for (Method m : filter(rt.children(), Method.class)) { - if (!m.skip()) { + if (!m.skip()) builder.addMethod(new MethodGenerator(m).generate()); - if (m.hasBitfieldParameters()) - builder.addMethod(new CallableGenerator(m) - .generateBitfieldOverload()); - } } } diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/SignalGenerator.java b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/SignalGenerator.java index 50170b2a..9804ab8b 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/SignalGenerator.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/SignalGenerator.java @@ -145,7 +145,7 @@ public MethodSpec generateEmitMethod() { .build()); // Add method parameters - generator.generateMethodParameters(builder, false, true); + generator.generateMethodParameters(builder, false); // Arena for memory allocations builder.beginControlFlow("try ($1T _arena = $1T.ofConfined())", diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/TypedValueGenerator.java b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/TypedValueGenerator.java index 346dfeff..c66b08f8 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/TypedValueGenerator.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/TypedValueGenerator.java @@ -84,28 +84,23 @@ String doFree() { } TypeName getType() { - return getType(true); - } - - TypeName getType(boolean setOfBitfield) { if (type != null && type.isActuallyAnArray()) - return ArrayTypeName.of(getType(type, setOfBitfield)); + return ArrayTypeName.of(getType(type)); if (v instanceof Field f && f.callback() != null) return f.parent().typeName().nestedClass( toJavaSimpleType(f.name() + "_callback", f.namespace())); try { - return getType(v.anyType(), setOfBitfield); + return getType(v.anyType()); } catch (NullPointerException npe) { throw new NoSuchElementException("Cannot find " + type); } } - private TypeName getType(AnyType anyType, boolean setOfBitfield) { - // Wrap Bitfield return value into a Set<> + private TypeName getType(AnyType anyType) { TypeName typeName = anyType.typeName(); - typeName = (setOfBitfield && v.isBitfield()) + typeName = (v.isBitfield()) ? ParameterizedTypeName.get(ClassName.get(Set.class), typeName) : typeName; @@ -662,7 +657,7 @@ FieldSpec generateConstantDeclaration() { final String value = ((Constant) v).value(); try { var builder = FieldSpec.builder( - getType(true), + getType(), toJavaConstant(v.name()), Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL ); diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/gir/Parameter.java b/buildSrc/src/main/java/io/github/jwharm/javagi/gir/Parameter.java index 5230a410..4ef4e5b0 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/gir/Parameter.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/gir/Parameter.java @@ -120,6 +120,10 @@ public boolean allocatesMemory() { && target instanceof Alias a && a.type().isPrimitive(); } + public boolean isLastParameter() { + return this == parent().parameters().getLast(); + } + public boolean nullable() { return "1".equals(attr("nullable")) || "1".equals(attr("allow-none")) diff --git a/modules/gio/src/test/java/io/github/jwharm/javagi/test/gio/FileTest.java b/modules/gio/src/test/java/io/github/jwharm/javagi/test/gio/FileTest.java index 97a65f8e..40ea4380 100644 --- a/modules/gio/src/test/java/io/github/jwharm/javagi/test/gio/FileTest.java +++ b/modules/gio/src/test/java/io/github/jwharm/javagi/test/gio/FileTest.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Path; +import java.util.Set; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; @@ -54,7 +55,7 @@ public void createFile() { // write to file input = "test string"; - try (var stream = file.create(FileCreateFlags.REPLACE_DESTINATION, null)) { + try (var stream = file.create(Set.of(FileCreateFlags.REPLACE_DESTINATION), null)) { stream.write(input.getBytes(StandardCharsets.UTF_8), null); } diff --git a/modules/glib/src/main/java/io/github/jwharm/javagi/base/GLibLogger.java b/modules/glib/src/main/java/io/github/jwharm/javagi/base/GLibLogger.java index 677b97e8..f62401e4 100644 --- a/modules/glib/src/main/java/io/github/jwharm/javagi/base/GLibLogger.java +++ b/modules/glib/src/main/java/io/github/jwharm/javagi/base/GLibLogger.java @@ -23,6 +23,9 @@ import org.gnome.glib.GLib; import org.gnome.glib.LogLevelFlags; +import java.util.EnumSet; +import java.util.Set; + /** * Utility class to call {@link GLib#log} for debug purposes. */ @@ -31,6 +34,12 @@ public final class GLibLogger { // Prevent instantiation private GLibLogger() {} + private static final Set DEBUG = EnumSet.of(LogLevelFlags.LEVEL_DEBUG); + private static final Set INFO = EnumSet.of(LogLevelFlags.LEVEL_INFO); + private static final Set WARNING = EnumSet.of(LogLevelFlags.LEVEL_WARNING); + private static final Set CRITICAL = EnumSet.of(LogLevelFlags.LEVEL_CRITICAL); + private static final Set ERROR = EnumSet.of(LogLevelFlags.LEVEL_ERROR); + /** * Call {@link GLib#log} with log domain "java-gi" and level * {@link LogLevelFlags#LEVEL_DEBUG}. @@ -40,9 +49,54 @@ private GLibLogger() {} * @param varargs the parameters to insert into the format string */ public static void debug(String message, Object... varargs) { - GLib.log(Constants.LOG_DOMAIN, - LogLevelFlags.LEVEL_DEBUG, - message, - varargs); + GLib.log(Constants.LOG_DOMAIN, DEBUG, message, varargs); + } + + /** + * Call {@link GLib#log} with log domain "java-gi" and level + * {@link LogLevelFlags#LEVEL_INFO}. + * + * @param message the message format. See the {@code printf()} + * documentation + * @param varargs the parameters to insert into the format string + */ + public static void info(String message, Object... varargs) { + GLib.log(Constants.LOG_DOMAIN, INFO, message, varargs); + } + + /** + * Call {@link GLib#log} with log domain "java-gi" and level + * {@link LogLevelFlags#LEVEL_WARNING}. + * + * @param message the message format. See the {@code printf()} + * documentation + * @param varargs the parameters to insert into the format string + */ + public static void warn(String message, Object... varargs) { + GLib.log(Constants.LOG_DOMAIN, WARNING, message, varargs); + } + + /** + * Call {@link GLib#log} with log domain "java-gi" and level + * {@link LogLevelFlags#LEVEL_CRITICAL}. + * + * @param message the message format. See the {@code printf()} + * documentation + * @param varargs the parameters to insert into the format string + */ + public static void critical(String message, Object... varargs) { + GLib.log(Constants.LOG_DOMAIN, CRITICAL, message, varargs); + } + + /** + * Call {@link GLib#log} with log domain "java-gi" and level + * {@link LogLevelFlags#LEVEL_ERROR}. + * + * @param message the message format. See the {@code printf()} + * documentation + * @param varargs the parameters to insert into the format string + */ + public static void error(String message, Object... varargs) { + GLib.log(Constants.LOG_DOMAIN, ERROR, message, varargs); } } diff --git a/modules/glib/src/main/java/io/github/jwharm/javagi/interop/Interop.java b/modules/glib/src/main/java/io/github/jwharm/javagi/interop/Interop.java index e170c0b0..5f6303af 100644 --- a/modules/glib/src/main/java/io/github/jwharm/javagi/interop/Interop.java +++ b/modules/glib/src/main/java/io/github/jwharm/javagi/interop/Interop.java @@ -1102,8 +1102,25 @@ EnumSet intToEnumSet(Class cls, public static & Enumeration> int enumSetToInt(Set set) { int bitfield = 0; - for (T element : set) - bitfield |= element.getValue(); + if (set != null) + for (T element : set) + bitfield |= element.getValue(); + return bitfield; + } + + /** + * Create a bitfield from the provided array of enums + * + * @param an enum implementing the Java-GI Enumeration interface + * @param values the array of enums + * @return the resulting bitfield + */ + public static & Enumeration> + int enumSetToInt(T[] values) { + int bitfield = 0; + if (values != null) + for (T element : values) + bitfield |= element.getValue(); return bitfield; } diff --git a/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/JavaClosure.java b/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/JavaClosure.java index 4d53b795..53f61cf0 100644 --- a/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/JavaClosure.java +++ b/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/JavaClosure.java @@ -25,14 +25,10 @@ import java.lang.reflect.Modifier; import java.util.function.BooleanSupplier; -import io.github.jwharm.javagi.interop.MemoryCleaner; -import org.gnome.glib.GLib; -import org.gnome.glib.LogLevelFlags; +import io.github.jwharm.javagi.base.GLibLogger; import org.gnome.gobject.Closure; import org.gnome.gobject.Value; -import static io.github.jwharm.javagi.Constants.LOG_DOMAIN; - /** * An implementation of {@link Closure} that can be used with Java callbacks. * In most cases, the callback will be invoked using reflection. For two common @@ -155,19 +151,13 @@ public JavaClosure(Object instance, Method method) { // Convert the returned Object to a GValue ValueUtil.objectToValue(result, returnValue); } catch (InvocationTargetException e) { - GLib.log( - LOG_DOMAIN, - LogLevelFlags.LEVEL_CRITICAL, - "JavaClosure: Exception in method %s in class %s: %s\n", + GLibLogger.critical("JavaClosure: Exception in method %s in class %s: %s\n", method.getName(), instance == null ? "null" : instance.getClass().getName(), e.getCause().toString() ); } catch (Exception e) { - GLib.log( - LOG_DOMAIN, - LogLevelFlags.LEVEL_CRITICAL, - "JavaClosure: Cannot invoke method %s in class %s: %s\n", + GLibLogger.critical("JavaClosure: Cannot invoke method %s in class %s: %s\n", method == null ? "null" : method.getName(), instance == null ? "null" : instance.getClass().getName(), e.toString() diff --git a/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/ValueUtil.java b/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/ValueUtil.java index aee15475..47777fe5 100644 --- a/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/ValueUtil.java +++ b/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/ValueUtil.java @@ -22,14 +22,12 @@ import java.lang.foreign.MemorySegment; import java.lang.reflect.Method; -import org.gnome.glib.GLib; -import org.gnome.glib.LogLevelFlags; +import io.github.jwharm.javagi.base.GLibLogger; import org.gnome.glib.Type; import org.gnome.gobject.*; import io.github.jwharm.javagi.base.Enumeration; -import static io.github.jwharm.javagi.Constants.LOG_DOMAIN; import static io.github.jwharm.javagi.gobject.types.Types.*; import static org.gnome.gobject.GObjects.gtypeGetType; import static org.gnome.gobject.GObjects.typeIsA; @@ -142,14 +140,9 @@ public static boolean objectToValue(Object src, Value dest) { dest.setBoxed((MemorySegment) src); } } catch (Exception e) { - GLib.log( - LOG_DOMAIN, - LogLevelFlags.LEVEL_CRITICAL, - "ValueUtil: Cannot set Object with Class %s to GValue with GType %s: %s\n", - src.getClass().getSimpleName(), - GObjects.typeName(type), - e.toString() - ); + GLibLogger.critical("ValueUtil: Cannot set Object with Class %s to GValue with GType %s: %s\n", + src.getClass().getSimpleName(), GObjects.typeName(type), + e.toString()); return false; } diff --git a/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/types/Overrides.java b/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/types/Overrides.java index 05bc4d21..cd7650bf 100644 --- a/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/types/Overrides.java +++ b/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/types/Overrides.java @@ -19,11 +19,10 @@ package io.github.jwharm.javagi.gobject.types; +import io.github.jwharm.javagi.base.GLibLogger; import io.github.jwharm.javagi.base.Proxy; import io.github.jwharm.javagi.interop.Interop; import io.github.jwharm.javagi.interop.InteropException; -import org.gnome.glib.GLib; -import org.gnome.glib.LogLevelFlags; import org.gnome.glib.Type; import org.gnome.gobject.GObject; import org.gnome.gobject.GObjects; @@ -37,8 +36,6 @@ import java.util.List; import java.util.function.Consumer; -import static io.github.jwharm.javagi.Constants.LOG_DOMAIN; - /** * Helper class to register method overrides in a new GType. */ @@ -141,21 +138,14 @@ Consumer overrideClassMethods(Class cls) { for (Method method : methods) { String name = getOverrideName(method); try { - Method overrider = gclass.getClass() - .getMethod(name, Arena.class, Method.class); + Method overrider = gclass.getClass().getMethod(name, Arena.class, Method.class); overrider.invoke(gclass, Arena.global(), method); } catch (InvocationTargetException ite) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot override method %s in class %s: %s\n", - method.getName(), - cls.getName(), - ite.getTargetException().toString()); + GLibLogger.critical("Cannot override method %s in class %s: %s\n", + method.getName(), cls.getName(), ite.getTargetException().toString()); } catch (Exception e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot override method %s in class %s: %s\n", - method.getName(), - cls.getName(), - e.toString()); + GLibLogger.critical("Cannot override method %s in class %s: %s\n", + method.getName(), cls.getName(), e.toString()); } } }; @@ -204,14 +194,12 @@ Consumer overrideInterfaceMethods(Class cls, Class iface) { // Lookup the memory address constructor for the TypeInterface Class typeStruct = Types.getTypeInterface(iface); if (typeStruct == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot find TypeInterface class for interface %s\n", iface); + GLibLogger.critical("Cannot find TypeInterface class for interface %s\n", iface); return null; } var constructor = Types.getAddressConstructor(typeStruct); if (constructor == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot find constructor in TypeInterface %s\n", typeStruct); + GLibLogger.critical("Cannot find constructor in TypeInterface %s\n", typeStruct); return null; } @@ -242,22 +230,15 @@ Consumer overrideInterfaceMethods(Class cls, Class iface) { try { // upcast to the actual type TI ifaceInstance = constructor.apply(giface.handle()); - Method overrider = typeStruct.getMethod( - name, Arena.class, Method.class); + Method overrider = typeStruct.getMethod(name, Arena.class, Method.class); overrider.invoke(ifaceInstance, Arena.global(), method); } catch (InvocationTargetException ite) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot override method %s from interface %s in class %s: %s\n", - method.getName(), - iface.getName(), - cls.getName(), + GLibLogger.critical("Cannot override method %s from interface %s in class %s: %s\n", + method.getName(), iface.getName(), cls.getName(), ite.getTargetException().toString()); } catch (Exception e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot override method %s from interface %s in class %s: %s\n", - method.getName(), - iface.getName(), - cls.getName(), + GLibLogger.critical("Cannot override method %s from interface %s in class %s: %s\n", + method.getName(), iface.getName(), cls.getName(), e.toString()); } } @@ -337,7 +318,7 @@ public static MemorySegment lookupVirtualMethod(MemorySegment address, // Get the TypeInterface implemented by the TypeClass MemorySegment iface = (MemorySegment) g_type_interface_peek - .invokeExact(myClass,ifaceType.getValue().longValue()); + .invokeExact(myClass, ifaceType.getValue().longValue()); // Return a pointer to the requested virtual method address in the // dispatch table @@ -376,7 +357,7 @@ public static MemorySegment lookupVirtualMethodParent(MemorySegment address, // Get the TypeInterface implemented by the parent TypeClass var parentIface = (MemorySegment) g_type_interface_peek.invokeExact( - parentClass,ifaceType.getValue().longValue()); + parentClass, ifaceType.getValue().longValue()); // Return a pointer to the requested virtual method address in the // dispatch table diff --git a/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/types/Properties.java b/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/types/Properties.java index 08e2c1d0..814ac3b2 100644 --- a/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/types/Properties.java +++ b/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/types/Properties.java @@ -19,12 +19,11 @@ package io.github.jwharm.javagi.gobject.types; +import io.github.jwharm.javagi.base.GLibLogger; import io.github.jwharm.javagi.gobject.annotations.Property; import io.github.jwharm.javagi.base.Proxy; import io.github.jwharm.javagi.base.ProxyInstance; import io.github.jwharm.javagi.gobject.ValueUtil; -import org.gnome.glib.GLib; -import org.gnome.glib.LogLevelFlags; import org.gnome.glib.Type; import org.gnome.gobject.*; @@ -34,11 +33,8 @@ import java.util.ArrayList; import java.util.EnumSet; import java.util.List; -import java.util.Set; import java.util.function.Consumer; -import static io.github.jwharm.javagi.Constants.LOG_DOMAIN; - /** * Helper class to register properties in a new GType. */ @@ -215,8 +211,7 @@ private static Class inferType(Method method) { // Setter cls = method.getParameterTypes()[0]; } else { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Invalid property getter/setter %s in class %s\n", + GLibLogger.critical("Invalid property getter/setter %s in class %s\n", method.getName(), method.getDeclaringClass().getName()); return null; } @@ -261,18 +256,15 @@ else if (ProxyInstance.class.isAssignableFrom(cls)) else if (Proxy.class.isAssignableFrom(cls)) return ParamSpecObject.class; - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Invalid property type %s in method %s in class %s\n", - cls.getName(), - method.getName(), - method.getDeclaringClass().getName()); + GLibLogger.critical("Invalid property type %s in method %s in class %s\n", + cls.getName(), method.getName(), method.getDeclaringClass().getName()); return null; } /* * Create a GParamFlags based on {@code @Property} annotation parameters. */ - private static Set getFlags(Property property) { + private static ParamFlags[] getFlags(Property property) { EnumSet flags = EnumSet.noneOf(ParamFlags.class); if (property.readable()) flags.add(ParamFlags.READABLE); if (property.writable()) flags.add(ParamFlags.WRITABLE); @@ -280,7 +272,7 @@ private static Set getFlags(Property property) { if (property.constructOnly()) flags.add(ParamFlags.CONSTRUCT_ONLY); if (property.explicitNotify()) flags.add(ParamFlags.EXPLICIT_NOTIFY); if (property.deprecated()) flags.add(ParamFlags.DEPRECATED); - return flags; + return flags.toArray(ParamFlags[]::new); } /** @@ -401,8 +393,7 @@ else if (paramspec.equals(ParamSpecUnichar.class)) 0, getFlags(p)); else { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Unsupported ParamSpec %s in class %s:\n", + GLibLogger.critical("Unsupported ParamSpec %s in class %s:\n", paramspec.getName(), cls.getName()); return null; } @@ -452,16 +443,14 @@ else if (paramspec.equals(ParamSpecUnichar.class)) // Check for invalid property IDs if (propertyId < 1 || propertyId >= getters.length) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Invalid property id %d in %s.getProperty\n", + GLibLogger.critical("Invalid property id %d in %s.getProperty\n", propertyId, cls.getName()); return; } // Check for non-existing getter method if (getters[propertyId] == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "No getter method defined for property \"%s\" in %s\n", + GLibLogger.critical("No getter method defined for property \"%s\" in %s\n", propertyNames.get(propertyId), cls.getName()); return; } @@ -473,16 +462,13 @@ else if (paramspec.equals(ParamSpecUnichar.class)) } catch (InvocationTargetException e) { // Log exceptions thrown by the getter method Throwable t = e.getTargetException(); - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "%s.getProperty('%s'): %s\n", - cls.getName(), - propertyNames.get(propertyId), + GLibLogger.critical("%s.getProperty('%s'): %s\n", + cls.getName(), propertyNames.get(propertyId), t.toString()); return; } catch (IllegalAccessException e) { // Tried to call a private method - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "IllegalAccessException calling %s.getProperty('%s')\n", + GLibLogger.critical("IllegalAccessException calling %s.getProperty('%s')\n", cls.getName(), propertyNames.get(propertyId)); return; } @@ -497,16 +483,14 @@ else if (paramspec.equals(ParamSpecUnichar.class)) // Check for invalid property IDs if (propertyId < 1 || propertyId >= setters.length) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Invalid property id %d in %s.setProperty\n", + GLibLogger.critical("Invalid property id %d in %s.setProperty\n", propertyId, cls.getName()); return; } // Check for non-existing getter method if (setters[propertyId] == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "No setter method defined for property \"%s\" in %s\n", + GLibLogger.critical("No setter method defined for property \"%s\" in %s\n", propertyNames.get(propertyId), cls.getName()); return; } @@ -521,15 +505,12 @@ else if (paramspec.equals(ParamSpecUnichar.class)) } catch (InvocationTargetException e) { // Log exceptions thrown by the setter method Throwable t = e.getTargetException(); - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "%s.setProperty('%s'): %s\n", - cls.getName(), - propertyNames.get(propertyId), + GLibLogger.critical("%s.setProperty('%s'): %s\n", + cls.getName(), propertyNames.get(propertyId), t.toString()); } catch (IllegalAccessException e) { // Tried to call a private method - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "IllegalAccessException calling %s.setProperty('%s')\n", + GLibLogger.critical("IllegalAccessException calling %s.setProperty('%s')\n", cls.getName(), propertyNames.get(propertyId)); } } diff --git a/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/types/Types.java b/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/types/Types.java index 65daffa6..4491db8f 100644 --- a/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/types/Types.java +++ b/modules/gobject/src/main/java/io/github/jwharm/javagi/gobject/types/Types.java @@ -19,12 +19,11 @@ package io.github.jwharm.javagi.gobject.types; +import io.github.jwharm.javagi.base.GLibLogger; import io.github.jwharm.javagi.base.Proxy; import io.github.jwharm.javagi.gobject.annotations.*; import io.github.jwharm.javagi.gobject.InstanceCache; import io.github.jwharm.javagi.interop.Interop; -import org.gnome.glib.GLib; -import org.gnome.glib.LogLevelFlags; import org.gnome.glib.Type; import org.gnome.gobject.*; @@ -37,7 +36,6 @@ import java.util.function.Consumer; import java.util.function.Function; -import static io.github.jwharm.javagi.Constants.LOG_DOMAIN; import static org.gnome.gobject.GObjects.typeTestFlags; /** @@ -682,9 +680,8 @@ MemoryLayout getInstanceLayout(Class cls, String typeName) { MemoryLayout parentLayout = getLayout(cls.getSuperclass()); if (parentLayout == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot find memory layout definition for class %s\n", - cls.getName()); + GLibLogger.critical("Cannot find memory layout definition for class %s\n", + cls.getName()); return null; } @@ -754,8 +751,8 @@ public static MemoryLayout getClassLayout(Class cls, Stri // If the type-struct is unavailable, get it from the parent class. Class typeClass = getTypeClass(cls); if (typeClass == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot find TypeClass for class %s\n", cls.getName()); + GLibLogger.critical("Cannot find TypeClass for class %s\n", + cls.getName()); return null; } @@ -763,8 +760,8 @@ public static MemoryLayout getClassLayout(Class cls, Stri MemoryLayout parentLayout = getLayout(typeClass); if (parentLayout == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot find class memory layout definition for class %s\n", cls.getName()); + GLibLogger.critical("Cannot find class memory layout definition for class %s\n", + cls.getName()); return null; } @@ -787,9 +784,8 @@ public static Type getGType(Class cls) { if (gtypeMethod == null) { // No gtype method found - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot find static method that returns org.gnome.glib.Type in class %s\n", - cls.getName()); + GLibLogger.critical("Cannot find static method that returns org.gnome.glib.Type in class %s\n", + cls.getName()); return null; } @@ -797,8 +793,7 @@ public static Type getGType(Class cls) { return (Type) gtypeMethod.invoke(null); } catch (IllegalAccessException | InvocationTargetException e) { // Method is not public, or throws an exception - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Exception while trying to read %s.%s\n", + GLibLogger.critical("Exception while trying to read %s.%s\n", cls.getName(), gtypeMethod.getName()); return null; } @@ -842,8 +837,7 @@ public static MemoryLayout getLayout(Class cls) { // Check method signature if ((m.getParameterTypes().length != 0) || (! m.getReturnType().equals(MemoryLayout.class))) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Method %s.%s does not have expected signature () -> MemoryLayout\n", + GLibLogger.critical("Method %s.%s does not have expected signature () -> MemoryLayout\n", cls.getName(), m.getName()); return null; } @@ -852,15 +846,12 @@ public static MemoryLayout getLayout(Class cls) { try { return (MemoryLayout) m.invoke(null); } catch (IllegalAccessException e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "IllegalAccessException when calling %s.%s\n", + GLibLogger.critical("IllegalAccessException when calling %s.%s\n", cls.getName(), m.getName()); return null; } catch (InvocationTargetException e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Exception when calling %s.%s: %s\n", - cls.getName(), - m.getName(), + GLibLogger.critical("Exception when calling %s.%s: %s\n", + cls.getName(), m.getName(), e.getTargetException().toString()); return null; } @@ -897,9 +888,8 @@ Function getAddressConstructor(Class cls) { // Get memory address constructor ctor = cls.getConstructor(MemorySegment.class); } catch (NoSuchMethodException e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot find memory-address constructor definition for class %s: %s\n", - cls.getName(), e.toString()); + GLibLogger.critical("Cannot find memory-address constructor definition for class %s: %s\n", + cls.getName(), e.toString()); return null; } @@ -909,13 +899,11 @@ Function getAddressConstructor(Class cls) { try { return ctor.newInstance(addr); } catch (InvocationTargetException ite) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Exception in constructor for class %s: %s\n", + GLibLogger.critical("Exception in constructor for class %s: %s\n", cls.getName(), ite.getTargetException().toString()); return null; } catch (Exception e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Exception in constructor for class %s: %s\n", + GLibLogger.critical("Exception in constructor for class %s: %s\n", cls.getName(), e.toString()); return null; } @@ -944,22 +932,16 @@ Consumer getInstanceInit(Class cls) { method.invoke(inst); } catch (InvocationTargetException ite) { Throwable t = ite.getTargetException(); - if (t instanceof ExceptionInInitializerError eiie) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "ExceptionInInitializerError in %s instance init: %s\n", - cls.getName(), - eiie.getCause().toString()); + if (t instanceof ExceptionInInitializerError err) { + GLibLogger.critical("ExceptionInInitializerError in %s instance init: %s\n", + cls.getName(), err.getCause().toString()); } else { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "InvocationTargetException in %s instance init: %s\n", - cls.getName(), - ite.getTargetException().toString()); + GLibLogger.critical("InvocationTargetException in %s instance init: %s\n", + cls.getName(), ite.getTargetException().toString()); } } catch (Exception e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Exception in %s instance init: %s\n", - cls.getName(), - e.toString()); + GLibLogger.critical("Exception in %s instance init: %s\n", + cls.getName(), e.toString()); } }; } @@ -989,15 +971,11 @@ Consumer getClassInit(Class cls) { try { method.invoke(null, gclass); } catch (InvocationTargetException ite) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Exception in %s class init: %s\n", - cls.getName(), - ite.getTargetException().toString()); + GLibLogger.critical("Exception in %s class init: %s\n", + cls.getName(), ite.getTargetException().toString()); } catch (Exception e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Exception in %s class init: %s\n", - cls.getName(), - e.toString()); + GLibLogger.critical("Exception in %s class init: %s\n", + cls.getName(), e.toString()); } }; } @@ -1020,16 +998,14 @@ Consumer getInterfaceInit(Class cls, Class iface) { // Find all overridden methods Class typeStruct = getTypeInterface(iface); if (typeStruct == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot find TypeInterface class for interface %s\n", - iface); + GLibLogger.critical("Cannot find TypeInterface class for interface %s\n", + iface); return null; } var constructor = getAddressConstructor(typeStruct); if (constructor == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot find constructor in TypeInterface %s\n", - typeStruct); + GLibLogger.critical("Cannot find constructor in TypeInterface %s\n", + typeStruct); return null; } @@ -1051,8 +1027,7 @@ Consumer getInterfaceInit(Class cls, Class iface) { TI ifaceInstance = constructor.apply(giface.handle()); method.invoke(null, ifaceInstance); } catch (Exception e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Exception in %s interface init: %s\n", + GLibLogger.critical("Exception in %s interface init: %s\n", cls.getName(), e.toString()); } }; @@ -1067,14 +1042,14 @@ Consumer getInterfaceInit(Class cls, Class iface) { * @param cls the class for which to generate typeflags * @return the generated typeflags */ - public static Set getTypeFlags(Class cls) { + public static TypeFlags[] getTypeFlags(Class cls) { // Set type flags Set flags = EnumSet.noneOf(TypeFlags.class); if (Modifier.isAbstract(cls.getModifiers())) flags.add(TypeFlags.ABSTRACT); if (Modifier.isFinal(cls.getModifiers())) flags.add(TypeFlags.FINAL); - return flags; + return flags.toArray(TypeFlags[]::new); } /** @@ -1101,8 +1076,7 @@ public static Set getTypeFlags(Class cls) { Type register(Class cls) { if (cls == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Class is null\n"); + GLibLogger.critical("Class is null\n"); return null; } @@ -1118,14 +1092,13 @@ Type register(Class cls) { MemoryLayout instanceLayout = getInstanceLayout(cls, typeName); Consumer instanceInit = getInstanceInit(cls); Function constructor = getAddressConstructor(cls); - Set flags = getTypeFlags(cls); + TypeFlags[] flags = getTypeFlags(cls); if (parentType == null || classLayout == null || instanceLayout == null || constructor == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot register type %s\n", cls.getName()); + GLibLogger.critical("Cannot register type %s\n", cls.getName()); return null; } @@ -1161,8 +1134,7 @@ Type register(Class cls) { if (Proxy.class.isAssignableFrom(iface)) { Type ifaceType = getGType(iface); if (ifaceType == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot implement interface %s on class %s: No GType\n", + GLibLogger.critical("Cannot implement interface %s on class %s: No GType\n", iface.getName(), cls.getName()); continue; } @@ -1191,9 +1163,8 @@ Type register(Class cls) { return type; } catch (Exception e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot register type %s: %s\n", - cls.getName(), e.toString()); + GLibLogger.critical("Cannot register type %s: %s\n", + cls.getName(), e.toString()); return null; } } @@ -1214,7 +1185,9 @@ Type register(Class cls) { * @param the class initializer function must accept a * parameter that is a subclass of TypeClass * @return the new GType + * @deprecated This method should not be called directly. Use {@link #register(Class)} */ + @Deprecated(since="0.11.0") public static Type register(Type parentType, String typeName, @@ -1223,7 +1196,7 @@ Type register(Type parentType, MemoryLayout instanceLayout, Consumer instanceInit, Function constructor, - Set flags) { + TypeFlags... flags) { @SuppressWarnings("unchecked") Type type = GObjects.typeRegisterStaticSimple( diff --git a/modules/gobject/src/test/java/io/github/jwharm/javagi/test/gobject/ClosureTest.java b/modules/gobject/src/test/java/io/github/jwharm/javagi/test/gobject/ClosureTest.java index 621a4204..cbe7a601 100644 --- a/modules/gobject/src/test/java/io/github/jwharm/javagi/test/gobject/ClosureTest.java +++ b/modules/gobject/src/test/java/io/github/jwharm/javagi/test/gobject/ClosureTest.java @@ -1,5 +1,5 @@ /* Java-GI - Java language bindings for GObject-Introspection-based libraries - * Copyright (C) 2022-2024 Jan-Willem Harmannij + * Copyright (C) 2022-2023 Jan-Willem Harmannij * * SPDX-License-Identifier: LGPL-2.1-or-later * @@ -31,6 +31,7 @@ import java.lang.foreign.MemorySegment; import java.lang.reflect.Method; +import java.util.Set; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -60,7 +61,7 @@ public void methodReference() { // Create a property binding to run "timesTwo" every time the "num" property on n1 or n2 is changed // Keep a reference to the Binding object instance alive, or else the property binding will be disconnected @SuppressWarnings("unused") - Binding binding = n1.bindPropertyWithClosures("num", n2, "num", BindingFlags.BIDIRECTIONAL, closure, closure); + Binding binding = n1.bindPropertyWithClosures("num", n2, "num", Set.of(BindingFlags.BIDIRECTIONAL), closure, closure); // Set the "num" property of n1 to 10 n1.setProperty("num", 10); @@ -81,7 +82,7 @@ public void lambda() { // Create a property binding to run "timesTwo" every time the "num" property on n1 or n2 is changed // Keep a reference to the Binding object instance alive, or else the property binding will be disconnected @SuppressWarnings("unused") - Binding binding = n1.bindPropertyWithClosures("num", n2, "num", BindingFlags.BIDIRECTIONAL, closure, closure); + Binding binding = n1.bindPropertyWithClosures("num", n2, "num", Set.of(BindingFlags.BIDIRECTIONAL), closure, closure); // Set the "num" property of n1 to 10 n1.setProperty("num", -25); diff --git a/modules/gtk/src/main/java/io/github/jwharm/javagi/gtk/types/TemplateTypes.java b/modules/gtk/src/main/java/io/github/jwharm/javagi/gtk/types/TemplateTypes.java index a5a37553..d2ba7560 100644 --- a/modules/gtk/src/main/java/io/github/jwharm/javagi/gtk/types/TemplateTypes.java +++ b/modules/gtk/src/main/java/io/github/jwharm/javagi/gtk/types/TemplateTypes.java @@ -19,6 +19,7 @@ package io.github.jwharm.javagi.gtk.types; +import io.github.jwharm.javagi.base.GLibLogger; import io.github.jwharm.javagi.base.Proxy; import io.github.jwharm.javagi.gobject.types.Overrides; import io.github.jwharm.javagi.gobject.types.Properties; @@ -27,8 +28,6 @@ import io.github.jwharm.javagi.gtk.annotations.GtkTemplate; import io.github.jwharm.javagi.gtk.util.BuilderJavaScope; import io.github.jwharm.javagi.interop.Interop; -import org.gnome.glib.GLib; -import org.gnome.glib.LogLevelFlags; import org.gnome.glib.Type; import org.gnome.gobject.GObject; import org.gnome.gobject.TypeFlags; @@ -37,11 +36,9 @@ import java.lang.foreign.*; import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.Set; import java.util.function.Consumer; import java.util.function.Function; -import static io.github.jwharm.javagi.Constants.LOG_DOMAIN; import static io.github.jwharm.javagi.gobject.types.Types.*; /** @@ -90,14 +87,12 @@ private static String getChildName(Field field) { * @param typeName the name of the struct * @return the generated memory layout */ - private static MemoryLayout getTemplateInstanceLayout(Class cls, - String typeName) { + private static MemoryLayout getTemplateInstanceLayout(Class cls, String typeName) { MemoryLayout parentLayout = getLayout(cls.getSuperclass()); if (parentLayout == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot find memory layout of class %s\n", - cls.getSimpleName()); + GLibLogger.critical("Cannot find memory layout of class %s\n", + cls.getSimpleName()); return null; } @@ -139,8 +134,7 @@ else if (Proxy.class.isAssignableFrom(field.getType())) size = add(ValueLayout.ADDRESS.withName(fieldName), elements, size); else - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Unsupported type '%s' of field %s\n", + GLibLogger.critical("Unsupported type '%s' of field %s\n", field.getType().getSimpleName(), fieldName); } } @@ -249,8 +243,7 @@ Consumer getTemplateInstanceInit(Class cls) { try { setField(field, widget); } catch (Exception e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot get template child %s in class %s: %s\n", + GLibLogger.critical("Cannot get template child %s in class %s: %s\n", field.getName(), cls.getName(), e.getMessage()); } } @@ -285,7 +278,7 @@ private static Type registerTemplate(Class cls) { Type parentType = getGType(parentClass); MemoryLayout classLayout = getClassLayout(cls, name); Function constructor = getAddressConstructor(cls); - Set flags = getTypeFlags(cls); + TypeFlags[] flags = getTypeFlags(cls); // Chain template class init with user-defined class init function var overridesInit = Overrides.overrideClassMethods(cls); @@ -321,8 +314,7 @@ private static Type registerTemplate(Class cls) { ); } catch (Exception e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot register type %s: %s\n", + GLibLogger.critical("Cannot register type %s: %s\n", cls == null ? "null" : cls.getName(), e.getMessage()); return null; } @@ -351,7 +343,7 @@ Type register(Class cls) { /** * Convenience function that redirects to - * {@link io.github.jwharm.javagi.gobject.types.Types#register(Type, String, MemoryLayout, Consumer, MemoryLayout, Consumer, Function, Set)} + * {@link io.github.jwharm.javagi.gobject.types.Types#register(Type, String, MemoryLayout, Consumer, MemoryLayout, Consumer, Function, TypeFlags...)} * * @param parentType parent GType * @param typeName name of the GType @@ -366,7 +358,9 @@ Type register(Class cls) { * @param the class initializer function must accept a * parameter that is a subclass of TypeClass * @return the new GType + * @deprecated This method should not be called directly. Use {@link #register(Class)} */ + @Deprecated(since="0.11.0", forRemoval = true) public static Type register(Type parentType, String typeName, @@ -375,7 +369,7 @@ Type register(Type parentType, MemoryLayout instanceLayout, Consumer instanceInit, Function constructor, - Set flags) { + TypeFlags... flags) { return io.github.jwharm.javagi.gobject.types.Types.register( parentType, typeName, classLayout, classInit, instanceLayout, instanceInit, constructor, flags); diff --git a/modules/gtk/src/main/java/io/github/jwharm/javagi/gtk/types/Types.java b/modules/gtk/src/main/java/io/github/jwharm/javagi/gtk/types/Types.java index 964b0677..00e231fd 100644 --- a/modules/gtk/src/main/java/io/github/jwharm/javagi/gtk/types/Types.java +++ b/modules/gtk/src/main/java/io/github/jwharm/javagi/gtk/types/Types.java @@ -27,7 +27,6 @@ import org.gnome.gtk.Widget; import java.lang.foreign.*; -import java.util.Set; import java.util.function.Consumer; import java.util.function.Function; @@ -40,7 +39,7 @@ * * @deprecated This class was renamed to {@link TemplateTypes} */ -@Deprecated +@Deprecated(since="0.11.0", forRemoval = true) public class Types { /** @@ -50,9 +49,9 @@ public class Types { * * @param cls the class that is registered as a new GType * @return the name - * @deprecated see {@link TemplateTypes#getTemplateName} + * @deprecated Moved to {@link TemplateTypes#getTemplateName} */ - @Deprecated + @Deprecated(since="0.11.0", forRemoval = true) public static String getTemplateName(Class cls) { return TemplateTypes.getTemplateName(cls); } @@ -67,9 +66,9 @@ public static String getTemplateName(Class cls) { * @param cls the class to register as a new GType * @param the class must extend {@link org.gnome.gobject.GObject} * @return the new GType - * @deprecated see {@link TemplateTypes#register(Class)} + * @deprecated Moved to {@link TemplateTypes#register(Class)} */ - @Deprecated + @Deprecated(since="0.11.0", forRemoval = true) public static Type register(Class cls) { return TemplateTypes.register(cls); @@ -77,7 +76,7 @@ Type register(Class cls) { /** * Convenience function that redirects to - * {@link io.github.jwharm.javagi.gobject.types.Types#register(Type, String, MemoryLayout, Consumer, MemoryLayout, Consumer, Function, Set)} + * {@link io.github.jwharm.javagi.gobject.types.Types#register(Type, String, MemoryLayout, Consumer, MemoryLayout, Consumer, Function, TypeFlags...)} * * @param parentType parent GType * @param typeName name of the GType @@ -92,9 +91,9 @@ Type register(Class cls) { * @param the class initializer function must accept a * parameter that is a subclass of TypeClass * @return the new GType - * @deprecated see {@link TemplateTypes#register(Type, String, MemoryLayout, Consumer, MemoryLayout, Consumer, Function, Set)} + * @deprecated This method should not be called directly. Use {@link TemplateTypes#register(Class)} */ - @Deprecated + @Deprecated(since="0.11.0", forRemoval = true) public static Type register(Type parentType, String typeName, @@ -103,8 +102,8 @@ Type register(Type parentType, MemoryLayout instanceLayout, Consumer instanceInit, Function constructor, - Set flags) { - return TemplateTypes.register( + TypeFlags... flags) { + return io.github.jwharm.javagi.gobject.types.Types.register( parentType, typeName, classLayout, classInit, instanceLayout, instanceInit, constructor, flags); } diff --git a/modules/gtk/src/main/java/io/github/jwharm/javagi/gtk/util/BuilderJavaScope.java b/modules/gtk/src/main/java/io/github/jwharm/javagi/gtk/util/BuilderJavaScope.java index b9f27904..70255524 100644 --- a/modules/gtk/src/main/java/io/github/jwharm/javagi/gtk/util/BuilderJavaScope.java +++ b/modules/gtk/src/main/java/io/github/jwharm/javagi/gtk/util/BuilderJavaScope.java @@ -20,22 +20,19 @@ package io.github.jwharm.javagi.gtk.util; import io.github.jwharm.javagi.base.GErrorException; +import io.github.jwharm.javagi.base.GLibLogger; import io.github.jwharm.javagi.gtk.annotations.GtkCallback; import io.github.jwharm.javagi.gobject.JavaClosure; -import org.gnome.glib.GLib; -import org.gnome.glib.LogLevelFlags; import org.gnome.glib.Type; import org.gnome.gobject.*; import org.gnome.gtk.*; -import io.github.jwharm.javagi.gtk.types.Types; +import io.github.jwharm.javagi.gobject.types.Types; import java.lang.foreign.MemorySegment; import java.lang.reflect.Method; import java.util.Set; import java.util.function.BooleanSupplier; -import static io.github.jwharm.javagi.Constants.LOG_DOMAIN; - /** * The {@code BuilderJavaScope} class can be used with a {@link GtkBuilder} to * refer to Java instance methods from a ui file. @@ -105,9 +102,8 @@ public Closure createClosure(GtkBuilder builder, // Get the instance object GObject currentObject = builder.getCurrentObject(); if (currentObject == null) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot create closure for handler %s: Current object not set\n", - function); + GLibLogger.critical("Cannot create closure for handler %s: Current object not set\n", + function); return asParent().createClosure(builder, function, flags, object); } @@ -122,10 +118,8 @@ public Closure createClosure(GtkBuilder builder, try { return (boolean) method.invoke(currentObject); } catch (Exception e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot invoke method %s in class %s: %s\n", - function, - currentObject.getClass().getName(), + GLibLogger.critical("Cannot invoke method %s in class %s: %s\n", + function, currentObject.getClass().getName(), e.getMessage()); return false; } @@ -137,17 +131,14 @@ public Closure createClosure(GtkBuilder builder, try { method.invoke(currentObject); } catch (Exception e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot invoke method %s in class %s: %s\n", - function, - currentObject.getClass().getName(), + GLibLogger.critical("Cannot invoke method %s in class %s: %s\n", + function, currentObject.getClass().getName(), e.getMessage()); } }); } } catch (NoSuchMethodException e) { - GLib.log(LOG_DOMAIN, LogLevelFlags.LEVEL_CRITICAL, - "Cannot find method %s in class %s\n", + GLibLogger.critical("Cannot find method %s in class %s\n", function, currentObject.getClass().getName()); return asParent().createClosure(builder, function, flags, object); }