org.gnome.gobject.GObject Maven / Gradle / Ivy
// Java-GI - Java language bindings for GObject-Introspection-based libraries
// Copyright (C) 2022-2024 Jan-Willem Harmannij
//
// SPDX-License-Identifier: LGPL-2.1-or-later
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see .
//
// This file has been generated with Java-GI.
// Do not edit this file directly!
// Visit for more information.
//
package org.gnome.gobject;
import io.github.jwharm.javagi.Constants;
import io.github.jwharm.javagi.base.GLibLogger;
import io.github.jwharm.javagi.base.Out;
import io.github.jwharm.javagi.gobject.InstanceCache;
import io.github.jwharm.javagi.gobject.JavaClosure;
import io.github.jwharm.javagi.gobject.SignalConnection;
import io.github.jwharm.javagi.gobject.types.Overrides;
import io.github.jwharm.javagi.gobject.types.Properties;
import io.github.jwharm.javagi.gobject.types.Signals;
import io.github.jwharm.javagi.interop.ArenaCloseAction;
import io.github.jwharm.javagi.interop.Interop;
import io.github.jwharm.javagi.interop.MemoryCleaner;
import java.lang.Deprecated;
import java.lang.FunctionalInterface;
import java.lang.Integer;
import java.lang.NullPointerException;
import java.lang.Object;
import java.lang.String;
import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.Linker;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.annotation.processing.Generated;
import org.gnome.glib.DestroyNotify;
import org.gnome.glib.DuplicateFunc;
import org.gnome.glib.GLib;
import org.gnome.glib.LogLevelFlags;
import org.gnome.glib.Quark;
import org.gnome.glib.SList;
import org.gnome.glib.Type;
import org.jetbrains.annotations.Nullable;
/**
* The base object type.
*
* All the fields in the {@code GObject} structure are private to the implementation
* and should never be accessed directly.
*
* Since GLib 2.72, all {@code GObjects} are guaranteed to be aligned to at least the
* alignment of the largest basic GLib type (typically this is {@code guint64} or
* {@code gdouble}). If you need larger alignment for an element in a {@code GObject}, you
* should allocate it on the heap (aligned), or arrange for your {@code GObject} to be
* appropriately padded. This guarantee applies to the {@code GObject} (or derived)
* struct, the {@code GObjectClass} (or derived) struct, and any private data allocated
* by G_ADD_PRIVATE().
*/
@Generated("io.github.jwharm.JavaGI")
public class GObject extends TypeInstance {
static {
GObjects.javagi$ensureInitialized();
}
/**
* Create a GObject proxy instance for the provided memory address.
* @param address the memory address of the native object
*/
public GObject(MemorySegment address) {
super(address == null ? null : Interop.reinterpret(address, getMemoryLayout().byteSize()));
MemoryCleaner.setFreeFunc(handle(), "g_object_unref");
}
/**
* Creates a new instance of a {@code GObject} subtype and sets its properties.
*
* Construction parameters (see {@link org.gnome.gobject.ParamFlags#CONSTRUCT}, {@link org.gnome.gobject.ParamFlags#CONSTRUCT_ONLY})
* which are not explicitly specified are set to their default values. Any
* private data for the object is guaranteed to be initialized with zeros, as
* per g_type_create_instance().
*
* Note that in C, small integer types in variable argument lists are promoted
* up to {@code gint} or {@code guint} as appropriate, and read back accordingly. {@code gint} is
* 32 bits on every platform on which GLib is currently supported. This means that
* you can use C expressions of type {@code gint} with g_object_new() and properties of
* type {@code gint} or {@code guint} or smaller. Specifically, you can use integer literals
* with these property types.
*
* When using property types of {@code gint64} or {@code guint64}, you must ensure that the
* value that you provide is 64 bit. This means that you should use a cast or
* make use of the {@code G_GINT64_CONSTANT} or {@code G_GUINT64_CONSTANT} macros.
*
* Similarly, {@code gfloat} is promoted to {@code gdouble}, so you must ensure that the value
* you provide is a {@code gdouble}, even for a property of type {@code gfloat}.
*
* Since GLib 2.72, all {@code GObjects} are guaranteed to be aligned to at least the
* alignment of the largest basic GLib type (typically this is {@code guint64} or
* {@code gdouble}). If you need larger alignment for an element in a {@code GObject}, you
* should allocate it on the heap (aligned), or arrange for your {@code GObject} to be
* appropriately padded.
* @param objectType the type id of the {@code GObject} subtype to instantiate
* @param firstPropertyName the name of the first property
* @param varargs the value of the first property, followed optionally by more
* name/value pairs, followed by {@code null}
*/
public GObject(Type objectType, String firstPropertyName, Object... varargs) {
super(constructNew(objectType, firstPropertyName, varargs));
InstanceCache.put(handle(), this);
}
/**
* Get the GType of the GObject class
*
* @return the GType
*/
public static Type getType() {
return Interop.getType("g_object_get_type");
}
/**
* The memory layout of the native struct.
* @return the memory layout
*/
public static MemoryLayout getMemoryLayout() {
return MemoryLayout.structLayout(
TypeInstance.getMemoryLayout().withName("g_type_instance"),
ValueLayout.JAVA_INT.withName("ref_count"),
MemoryLayout.paddingLayout(4),
ValueLayout.ADDRESS.withName("qdata")
).withName("GObject");
}
/**
* Returns this instance as if it were its parent type. This is mostly
* synonymous to the Java {@code super} keyword, but will set the native
* typeclass function pointers to the parent type. When overriding a native
* virtual method in Java, "chaining up" with {@code super.methodName()}
* doesn't work, because it invokes the overridden function pointer again.
* To chain up, call {@code asParent().methodName()}. This will call the
* native function pointer of this virtual method in the typeclass of the
* parent type.
*/
protected GObject asParent() {
GObject _parent = new GObject(handle());
_parent.callParent(true);
return _parent;
}
/**
* Creates a new instance of a {@code GObject} subtype and sets its properties.
*
* Construction parameters (see {@link org.gnome.gobject.ParamFlags#CONSTRUCT}, {@link org.gnome.gobject.ParamFlags#CONSTRUCT_ONLY})
* which are not explicitly specified are set to their default values. Any
* private data for the object is guaranteed to be initialized with zeros, as
* per g_type_create_instance().
*
* Note that in C, small integer types in variable argument lists are promoted
* up to {@code gint} or {@code guint} as appropriate, and read back accordingly. {@code gint} is
* 32 bits on every platform on which GLib is currently supported. This means that
* you can use C expressions of type {@code gint} with g_object_new() and properties of
* type {@code gint} or {@code guint} or smaller. Specifically, you can use integer literals
* with these property types.
*
* When using property types of {@code gint64} or {@code guint64}, you must ensure that the
* value that you provide is 64 bit. This means that you should use a cast or
* make use of the {@code G_GINT64_CONSTANT} or {@code G_GUINT64_CONSTANT} macros.
*
* Similarly, {@code gfloat} is promoted to {@code gdouble}, so you must ensure that the value
* you provide is a {@code gdouble}, even for a property of type {@code gfloat}.
*
* Since GLib 2.72, all {@code GObjects} are guaranteed to be aligned to at least the
* alignment of the largest basic GLib type (typically this is {@code guint64} or
* {@code gdouble}). If you need larger alignment for an element in a {@code GObject}, you
* should allocate it on the heap (aligned), or arrange for your {@code GObject} to be
* appropriately padded.
* @param objectType the type id of the {@code GObject} subtype to instantiate
* @param firstPropertyName the name of the first property
* @param varargs the value of the first property, followed optionally by more
* name/value pairs, followed by {@code null}
*/
private static MemorySegment constructNew(Type objectType, String firstPropertyName,
Object... varargs) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.JAVA_LONG, ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_new", _fdesc, true)
.invokeExact(objectType.getValue().longValue(),
(MemorySegment) (firstPropertyName == null ? MemorySegment.NULL : Interop.allocateNativeString(firstPropertyName, _arena)),
varargs);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return _result;
}
}
/**
* Creates a new instance of a {@code GObject} subtype and sets its properties using
* the provided arrays. Both arrays must have exactly {@code n_properties} elements,
* and the names and values correspond by index.
*
* Construction parameters (see {@link org.gnome.gobject.ParamFlags#CONSTRUCT}, {@link org.gnome.gobject.ParamFlags#CONSTRUCT_ONLY})
* which are not explicitly specified are set to their default values.
* @param objectType the object type to instantiate
* @param names the names of each property to be set
* @param values the values of each property to be set
* @return a new instance of
* {@code object_type}
*/
public static GObject withProperties(Type objectType, String[] names, Value[] values) {
var _result = constructWithProperties(objectType, names, values);
var _object = (GObject) InstanceCache.getForType(_result, org.gnome.gobject.GObject::new, true);
if (_object instanceof GObject _gobject) {
GLibLogger.debug("Ref org.gnome.gobject.GObject %ld\\n", _gobject.handle());
_gobject.ref();
}
return (GObject) _object;
}
/**
* Creates a new instance of a {@code GObject} subtype and sets its properties using
* the provided arrays. Both arrays must have exactly {@code n_properties} elements,
* and the names and values correspond by index.
*
* Construction parameters (see {@link org.gnome.gobject.ParamFlags#CONSTRUCT}, {@link org.gnome.gobject.ParamFlags#CONSTRUCT_ONLY})
* which are not explicitly specified are set to their default values.
* @param objectType the object type to instantiate
* @param names the names of each property to be set
* @param values the values of each property to be set
* @return a new instance of
* {@code object_type}
*/
private static MemorySegment constructWithProperties(Type objectType, String[] names,
Value[] values) {
try (var _arena = Arena.ofConfined()) {
int nProperties = names == null ? 0 : names.length;
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.JAVA_LONG, ValueLayout.JAVA_INT, ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_new_with_properties", _fdesc, false)
.invokeExact(objectType.getValue().longValue(), nProperties,
(MemorySegment) (names == null ? MemorySegment.NULL : Interop.allocateNativeArray(names, false, _arena)),
(MemorySegment) (values == null ? MemorySegment.NULL : Interop.allocateNativeArray(values, Value.getMemoryLayout(), false, _arena)));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return _result;
}
}
/**
* Creates a new instance of a {@code GObject} subtype and sets its properties.
*
* Construction parameters (see {@link org.gnome.gobject.ParamFlags#CONSTRUCT}, {@link org.gnome.gobject.ParamFlags#CONSTRUCT_ONLY})
* which are not explicitly specified are set to their default values.
* @param objectType the type id of the {@code GObject} subtype to instantiate
* @param parameters an array of {@code GParameter}
* @return a new instance of
* {@code object_type}
* @deprecated Use g_object_new_with_properties() instead.
* deprecated. See {@code GParameter} for more information.
*/
@Deprecated
public static GObject newv(Type objectType, Parameter[] parameters) {
var _result = constructNewv(objectType, parameters);
var _object = (GObject) InstanceCache.getForType(_result, org.gnome.gobject.GObject::new, true);
if (_object instanceof GObject _gobject) {
GLibLogger.debug("Ref org.gnome.gobject.GObject %ld\\n", _gobject.handle());
_gobject.ref();
}
return (GObject) _object;
}
/**
* Creates a new instance of a {@code GObject} subtype and sets its properties.
*
* Construction parameters (see {@link org.gnome.gobject.ParamFlags#CONSTRUCT}, {@link org.gnome.gobject.ParamFlags#CONSTRUCT_ONLY})
* which are not explicitly specified are set to their default values.
* @param objectType the type id of the {@code GObject} subtype to instantiate
* @param parameters an array of {@code GParameter}
* @return a new instance of
* {@code object_type}
* @deprecated Use g_object_new_with_properties() instead.
* deprecated. See {@code GParameter} for more information.
*/
@Deprecated
private static MemorySegment constructNewv(Type objectType, Parameter[] parameters) {
try (var _arena = Arena.ofConfined()) {
int nParameters = parameters == null ? 0 : parameters.length;
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.JAVA_LONG, ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_newv", _fdesc, false)
.invokeExact(objectType.getValue().longValue(), nParameters,
(MemorySegment) (parameters == null ? MemorySegment.NULL : Interop.allocateNativeArray(parameters, Parameter.getMemoryLayout(), false, _arena)));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return _result;
}
}
public static long compatControl(long what, @Nullable MemorySegment data) {
long _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.JAVA_LONG,
ValueLayout.JAVA_LONG, ValueLayout.ADDRESS);
_result = (long) Interop.downcallHandle("g_object_compat_control", _fdesc, false)
.invokeExact(what, (MemorySegment) (data == null ? MemorySegment.NULL : data));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return _result;
}
/**
* Find the {@code GParamSpec} with the given name for an
* interface. Generally, the interface vtable passed in as {@code g_iface}
* will be the default vtable from g_type_default_interface_ref(), or,
* if you know the interface has already been loaded,
* g_type_default_interface_peek().
* @param gIface any interface vtable for the
* interface, or the default vtable for the interface
* @param propertyName name of a property to look up.
* @return the {@code GParamSpec} for the property of the
* interface with the name {@code property_name}, or {@code null} if no
* such property exists.
*/
public static ParamSpec interfaceFindProperty(TypeInterface gIface, String propertyName) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_interface_find_property", _fdesc, false)
.invokeExact(
(MemorySegment) (gIface == null ? MemorySegment.NULL : gIface.handle()),
(MemorySegment) (propertyName == null ? MemorySegment.NULL : Interop.allocateNativeString(propertyName, _arena)));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return (ParamSpec) InstanceCache.getForType(_result, org.gnome.gobject.ParamSpec.ParamSpecImpl::new, true);
}
}
/**
* Add a property to an interface; this is only useful for interfaces
* that are added to GObject-derived types. Adding a property to an
* interface forces all objects classes with that interface to have a
* compatible property. The compatible property could be a newly
* created {@code GParamSpec}, but normally
* g_object_class_override_property() will be used so that the object
* class only needs to provide an implementation and inherits the
* property description, default value, bounds, and so forth from the
* interface property.
*
* This function is meant to be called from the interface's default
* vtable initialization function (the {@code class_init} member of
* {@code GTypeInfo}.) It must not be called after after {@code class_init} has
* been called for any object types implementing this interface.
*
* If {@code pspec} is a floating reference, it will be consumed.
* @param gIface any interface vtable for the
* interface, or the default
* vtable for the interface.
* @param pspec the {@code GParamSpec} for the new property
*/
public static void interfaceInstallProperty(TypeInterface gIface, ParamSpec pspec) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_interface_install_property", _fdesc, false)
.invokeExact(
(MemorySegment) (gIface == null ? MemorySegment.NULL : gIface.handle()),
(MemorySegment) (pspec == null ? MemorySegment.NULL : pspec.handle()));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* Lists the properties of an interface.Generally, the interface
* vtable passed in as {@code g_iface} will be the default vtable from
* g_type_default_interface_ref(), or, if you know the interface has
* already been loaded, g_type_default_interface_peek().
* @param gIface any interface vtable for the
* interface, or the default vtable for the interface
* @return a
* pointer to an array of pointers to {@code GParamSpec}
* structures. The paramspecs are owned by GLib, but the
* array should be freed with g_free() when you are done with
* it.
*/
public static ParamSpec[] interfaceListProperties(TypeInterface gIface) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _nPropertiesPPointer = _arena.allocate(ValueLayout.JAVA_INT);
_nPropertiesPPointer.set(ValueLayout.JAVA_INT, 0L, 0);
Out nPropertiesP = new Out<>();
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_interface_list_properties", _fdesc, false)
.invokeExact(
(MemorySegment) (gIface == null ? MemorySegment.NULL : gIface.handle()),
_nPropertiesPPointer);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
nPropertiesP.set(_nPropertiesPPointer.get(ValueLayout.JAVA_INT, 0));
return Interop.getProxyArrayFrom(_result, (int) nPropertiesP.get().intValue(), ParamSpec.class, org.gnome.gobject.ParamSpec.ParamSpecImpl::new);
}
}
/**
* Increases the reference count of the object by one and sets a
* callback to be called when all other references to the object are
* dropped, or when this is already the last reference to the object
* and another reference is established.
*
* This functionality is intended for binding {@code object} to a proxy
* object managed by another memory manager. This is done with two
* paired references: the strong reference added by
* g_object_add_toggle_ref() and a reverse reference to the proxy
* object which is either a strong reference or weak reference.
*
* The setup is that when there are no other references to {@code object},
* only a weak reference is held in the reverse direction from {@code object}
* to the proxy object, but when there are other references held to
* {@code object}, a strong reference is held. The {@code notify} callback is called
* when the reference from {@code object} to the proxy object should be
* "toggled" from strong to weak ({@code is_last_ref} true) or weak to strong
* ({@code is_last_ref} false).
*
* Since a (normal) reference must be held to the object before
* calling g_object_add_toggle_ref(), the initial state of the reverse
* link is always strong.
*
* Multiple toggle references may be added to the same gobject,
* however if there are multiple toggle references to an object, none
* of them will ever be notified until all but one are removed. For
* this reason, you should only ever use a toggle reference if there
* is important state in the proxy object.
* @param notify a function to call when this reference is the
* last reference to the object, or is no longer
* the last reference.
*/
public void addToggleRef(ToggleNotify notify) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_add_toggle_ref", _fdesc, false).invokeExact(
handle(),
(MemorySegment) (notify == null ? MemorySegment.NULL : notify.toCallback(Interop.attachArena(Arena.ofConfined(), this))),
MemorySegment.NULL);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Adds a weak reference from weak_pointer to {@code object} to indicate that
* the pointer located at {@code weak_pointer_location} is only valid during
* the lifetime of {@code object}. When the {@code object} is finalized,
* {@code weak_pointer} will be set to {@code null}.
*
* Note that as with g_object_weak_ref(), the weak references created by
* this method are not thread-safe: they cannot safely be used in one
* thread if the object's last g_object_unref() might happen in another
* thread. Use {@code GWeakRef} if thread-safety is required.
* @param weakPointerLocation The memory address
* of a pointer.
*/
public void addWeakPointer(Out weakPointerLocation) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _weakPointerLocationPointer = _arena.allocate(ValueLayout.ADDRESS);
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_add_weak_pointer", _fdesc, false).invokeExact(
handle(),
(MemorySegment) (weakPointerLocation == null ? MemorySegment.NULL : _weakPointerLocationPointer));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
if (weakPointerLocation != null) {
weakPointerLocation.set(_weakPointerLocationPointer.get(ValueLayout.ADDRESS, 0));
}
}
}
/**
* Creates a binding between {@code source_property} on {@code source} and {@code target_property}
* on {@code target}.
*
* Whenever the {@code source_property} is changed the {@code target_property} is
* updated using the same value. For instance:
*
{@code
* g_object_bind_property (action, "active", widget, "sensitive", 0);
* }
*
* Will result in the "sensitive" property of the widget {@code GObject} instance to be
* updated with the same value of the "active" property of the action {@code GObject}
* instance.
*
* If {@code flags} contains {@link org.gnome.gobject.BindingFlags#BIDIRECTIONAL} then the binding will be mutual:
* if {@code target_property} on {@code target} changes then the {@code source_property} on {@code source}
* will be updated as well.
*
* The binding will automatically be removed when either the {@code source} or the
* {@code target} instances are finalized. To remove the binding without affecting the
* {@code source} and the {@code target} you can just call g_object_unref() on the returned
* {@code GBinding} instance.
*
* Removing the binding by calling g_object_unref() on it must only be done if
* the binding, {@code source} and {@code target} are only used from a single thread and it
* is clear that both {@code source} and {@code target} outlive the binding. Especially it
* is not safe to rely on this if the binding, {@code source} or {@code target} can be
* finalized from different threads. Keep another reference to the binding and
* use g_binding_unbind() instead to be on the safe side.
*
* A {@code GObject} can have multiple bindings.
* @param sourceProperty the property on {@code source} to bind
* @param target the target {@code GObject}
* @param targetProperty the property on {@code target} to bind
* @param flags flags to pass to {@code GBinding}
* @return the {@code GBinding} instance representing the
* binding between the two {@code GObject} instances. The binding is released
* whenever the {@code GBinding} reference count reaches zero.
*/
public Binding bindProperty(String sourceProperty, GObject target, String targetProperty,
BindingFlags flags) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.JAVA_INT);
_result = (MemorySegment) Interop.downcallHandle("g_object_bind_property", _fdesc, false)
.invokeExact(handle(),
(MemorySegment) (sourceProperty == null ? MemorySegment.NULL : Interop.allocateNativeString(sourceProperty, _arena)),
(MemorySegment) (target == null ? MemorySegment.NULL : target.handle()),
(MemorySegment) (targetProperty == null ? MemorySegment.NULL : Interop.allocateNativeString(targetProperty, _arena)),
flags.getValue());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
var _object = (Binding) InstanceCache.getForType(_result, org.gnome.gobject.Binding::new, true);
if (_object instanceof GObject _gobject) {
GLibLogger.debug("Ref org.gnome.gobject.Binding %ld\\n", _gobject.handle());
_gobject.ref();
}
return _object;
}
}
/**
* Creates a binding between {@code source_property} on {@code source} and {@code target_property}
* on {@code target}, allowing you to set the transformation functions to be used by
* the binding.
*
* This function is the language bindings friendly version of
* g_object_bind_property_full(), using {@code GClosures} instead of
* function pointers.
* @param sourceProperty the property on {@code source} to bind
* @param target the target {@code GObject}
* @param targetProperty the property on {@code target} to bind
* @param flags flags to pass to {@code GBinding}
* @param transformTo a {@code GClosure} wrapping the transformation function
* from the {@code source} to the {@code target}, or {@code null} to use the default
* @param transformFrom a {@code GClosure} wrapping the transformation function
* from the {@code target} to the {@code source}, or {@code null} to use the default
* @return the {@code GBinding} instance representing the
* binding between the two {@code GObject} instances. The binding is released
* whenever the {@code GBinding} reference count reaches zero.
*/
public Binding bindPropertyFull(String sourceProperty, GObject target, String targetProperty,
BindingFlags flags, Closure transformTo, Closure transformFrom) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_bind_property_with_closures", _fdesc, false)
.invokeExact(handle(),
(MemorySegment) (sourceProperty == null ? MemorySegment.NULL : Interop.allocateNativeString(sourceProperty, _arena)),
(MemorySegment) (target == null ? MemorySegment.NULL : target.handle()),
(MemorySegment) (targetProperty == null ? MemorySegment.NULL : Interop.allocateNativeString(targetProperty, _arena)),
flags.getValue(),
(MemorySegment) (transformTo == null ? MemorySegment.NULL : transformTo.handle()),
(MemorySegment) (transformFrom == null ? MemorySegment.NULL : transformFrom.handle()));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
var _object = (Binding) InstanceCache.getForType(_result, org.gnome.gobject.Binding::new, true);
if (_object instanceof GObject _gobject) {
GLibLogger.debug("Ref org.gnome.gobject.Binding %ld\\n", _gobject.handle());
_gobject.ref();
}
return _object;
}
}
/**
* A convenience function to connect multiple signals at once.
*
* The signal specs expected by this function have the form
* "modifier::signal_name", where modifier can be one of the following:
*
* - signal: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_DEFAULT)
*
- object-signal, object_signal: equivalent to g_signal_connect_object (..., G_CONNECT_DEFAULT)
*
- swapped-signal, swapped_signal: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_SWAPPED)
*
- swapped_object_signal, swapped-object-signal: equivalent to g_signal_connect_object (..., G_CONNECT_SWAPPED)
*
- signal_after, signal-after: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_AFTER)
*
- object_signal_after, object-signal-after: equivalent to g_signal_connect_object (..., G_CONNECT_AFTER)
*
- swapped_signal_after, swapped-signal-after: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_SWAPPED | G_CONNECT_AFTER)
*
- swapped_object_signal_after, swapped-object-signal-after: equivalent to g_signal_connect_object (..., G_CONNECT_SWAPPED | G_CONNECT_AFTER)
*
* {@code
* menu->toplevel = g_object_connect (g_object_new (GTK_TYPE_WINDOW,
* "type", GTK_WINDOW_POPUP,
* "child", menu,
* NULL),
* "signal::event", gtk_menu_window_event, menu,
* "signal::size_request", gtk_menu_window_size_request, menu,
* "signal::destroy", gtk_widget_destroyed, &menu->toplevel,
* NULL);
* }
* @param signalSpec the spec for the first signal
* @param varargs {@code GCallback} for the first signal, followed by data for the
* first signal, followed optionally by more signal
* spec/callback/data triples, followed by {@code null}
* @return {@code object}
*/
public GObject connect(String signalSpec, Object... varargs) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_connect", _fdesc, true)
.invokeExact(handle(),
(MemorySegment) (signalSpec == null ? MemorySegment.NULL : Interop.allocateNativeString(signalSpec, _arena)),
varargs);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
var _object = (GObject) InstanceCache.getForType(_result, org.gnome.gobject.GObject::new, true);
if (_object instanceof GObject _gobject) {
GLibLogger.debug("Ref org.gnome.gobject.GObject %ld\\n", _gobject.handle());
_gobject.ref();
}
return _object;
}
}
/**
* A convenience function to disconnect multiple signals at once.
*
* The signal specs expected by this function have the form
* "any_signal", which means to disconnect any signal with matching
* callback and data, or "any_signal::signal_name", which only
* disconnects the signal named "signal_name".
* @param signalSpec the spec for the first signal
* @param varargs {@code GCallback} for the first signal, followed by data for the first signal,
* followed optionally by more signal spec/callback/data triples,
* followed by {@code null}
*/
public void disconnect(String signalSpec, Object... varargs) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_disconnect", _fdesc, true).invokeExact(handle(),
(MemorySegment) (signalSpec == null ? MemorySegment.NULL : Interop.allocateNativeString(signalSpec, _arena)),
varargs);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* This is a variant of g_object_get_data() which returns
* a 'duplicate' of the value. {@code dup_func} defines the
* meaning of 'duplicate' in this context, it could e.g.
* take a reference on a ref-counted object.
*
* If the {@code key} is not set on the object then {@code dup_func}
* will be called with a {@code null} argument.
*
* Note that {@code dup_func} is called while user data of {@code object}
* is locked.
*
* This function can be useful to avoid races when multiple
* threads are using object data on the same key on the same
* object.
* @param key a string, naming the user data pointer
* @param dupFunc function to dup the value
* @return the result of calling {@code dup_func} on the value
* associated with {@code key} on {@code object}, or {@code null} if not set.
* If {@code dup_func} is {@code null}, the value is returned
* unmodified.
*/
public MemorySegment dupData(String key, @Nullable DuplicateFunc dupFunc) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_dup_data", _fdesc, false)
.invokeExact(handle(),
(MemorySegment) (key == null ? MemorySegment.NULL : Interop.allocateNativeString(key, _arena)),
(MemorySegment) (dupFunc == null ? MemorySegment.NULL : dupFunc.toCallback(Interop.attachArena(Arena.ofConfined(), this))),
MemorySegment.NULL);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return _result;
}
}
/**
* This is a variant of g_object_get_qdata() which returns
* a 'duplicate' of the value. {@code dup_func} defines the
* meaning of 'duplicate' in this context, it could e.g.
* take a reference on a ref-counted object.
*
* If the {@code quark} is not set on the object then {@code dup_func}
* will be called with a {@code null} argument.
*
* Note that {@code dup_func} is called while user data of {@code object}
* is locked.
*
* This function can be useful to avoid races when multiple
* threads are using object data on the same key on the same
* object.
* @param quark a {@code GQuark}, naming the user data pointer
* @param dupFunc function to dup the value
* @return the result of calling {@code dup_func} on the value
* associated with {@code quark} on {@code object}, or {@code null} if not set.
* If {@code dup_func} is {@code null}, the value is returned
* unmodified.
*/
public MemorySegment dupQdata(Quark quark, @Nullable DuplicateFunc dupFunc) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_dup_qdata", _fdesc, false)
.invokeExact(handle(), quark.getValue().intValue(),
(MemorySegment) (dupFunc == null ? MemorySegment.NULL : dupFunc.toCallback(Interop.attachArena(Arena.ofConfined(), this))),
MemorySegment.NULL);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return _result;
}
}
/**
* This function is intended for {@code GObject} implementations to re-enforce
* a [floating][floating-ref] object reference. Doing this is seldom
* required: all {@code GInitiallyUnowneds} are created with a floating reference
* which usually just needs to be sunken by calling g_object_ref_sink().
*/
public void forceFloating() {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_force_floating", _fdesc, false).invokeExact(handle());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* Increases the freeze count on {@code object}. If the freeze count is
* non-zero, the emission of "notify" signals on {@code object} is
* stopped. The signals are queued until the freeze count is decreased
* to zero. Duplicate notifications are squashed so that at most one
* {@code GObject}::notify signal is emitted for each property modified while the
* object is frozen.
*
* This is necessary for accessors that modify multiple properties to prevent
* premature notification while the object is still being modified.
*/
public void freezeNotify() {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_freeze_notify", _fdesc, false).invokeExact(handle());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* Gets properties of an object.
*
* In general, a copy is made of the property contents and the caller
* is responsible for freeing the memory in the appropriate manner for
* the type, for instance by calling g_free() or g_object_unref().
*
* Here is an example of using g_object_get() to get the contents
* of three properties: an integer, a string and an object:
*
{@code
* gint intval;
* guint64 uint64val;
* gchar *strval;
* GObject *objval;
*
* g_object_get (my_object,
* "int-property", &intval,
* "uint64-property", &uint64val,
* "str-property", &strval,
* "obj-property", &objval,
* NULL);
*
* // Do something with intval, uint64val, strval, objval
*
* g_free (strval);
* g_object_unref (objval);
* }
* @param firstPropertyName name of the first property to get
* @param varargs return location for the first property, followed optionally by more
* name/return location pairs, followed by {@code null}
*/
public void get(String firstPropertyName, Object... varargs) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_get", _fdesc, true).invokeExact(handle(),
(MemorySegment) (firstPropertyName == null ? MemorySegment.NULL : Interop.allocateNativeString(firstPropertyName, _arena)),
varargs);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Gets a named field from the objects table of associations (see g_object_set_data()).
* @param key name of the key for that association
* @return the data if found,
* or {@code null} if no such data exists.
*/
public MemorySegment getData(String key) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_get_data", _fdesc, false)
.invokeExact(handle(),
(MemorySegment) (key == null ? MemorySegment.NULL : Interop.allocateNativeString(key, _arena)));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return _result;
}
}
/**
* Gets a property of an object.
*
* The {@code value} can be:
*
* - an empty {@code GValue} initialized by {@code G_VALUE_INIT}, which will be
* automatically initialized with the expected type of the property
* (since GLib 2.60)
*
- a {@code GValue} initialized with the expected type of the property
*
- a {@code GValue} initialized with a type to which the expected type
* of the property can be transformed
*
*
* In general, a copy is made of the property contents and the caller is
* responsible for freeing the memory by calling g_value_unset().
*
* Note that g_object_get_property() is really intended for language
* bindings, g_object_get() is much more convenient for C programming.
* @param propertyName the name of the property to get
* @param value return location for the property value
*/
public void getProperty(String propertyName, Value value) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_get_property", _fdesc, false).invokeExact(
handle(),
(MemorySegment) (propertyName == null ? MemorySegment.NULL : Interop.allocateNativeString(propertyName, _arena)),
(MemorySegment) (value == null ? MemorySegment.NULL : value.handle()));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* This function gets back user data pointers stored via
* g_object_set_qdata().
* @param quark A {@code GQuark}, naming the user data pointer
* @return The user data pointer set, or {@code null}
*/
public MemorySegment getQdata(Quark quark) {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.JAVA_INT);
_result = (MemorySegment) Interop.downcallHandle("g_object_get_qdata", _fdesc, false)
.invokeExact(handle(), quark.getValue().intValue());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return _result;
}
/**
* Gets {@code n_properties} properties for an {@code object}.
* Obtained properties will be set to {@code values}. All properties must be valid.
* Warnings will be emitted and undefined behaviour may result if invalid
* properties are passed in.
* @param names the names of each property to get
* @param values the values of each property to get
*/
public void getv(String[] names, Value[] values) {
try (var _arena = Arena.ofConfined()) {
int nProperties = names == null ? 0 : names.length;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_getv", _fdesc, false).invokeExact(handle(),
nProperties,
(MemorySegment) (names == null ? MemorySegment.NULL : Interop.allocateNativeArray(names, false, _arena)),
(MemorySegment) (values == null ? MemorySegment.NULL : Interop.allocateNativeArray(values, Value.getMemoryLayout(), false, _arena)));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Checks whether {@code object} has a [floating][floating-ref] reference.
* @return {@code true} if {@code object} has a floating reference
*/
public boolean isFloating() {
int _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.JAVA_INT,
ValueLayout.ADDRESS);
_result = (int) Interop.downcallHandle("g_object_is_floating", _fdesc, false)
.invokeExact(handle());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return _result != 0;
}
/**
* Emits a "notify" signal for the property {@code property_name} on {@code object}.
*
* When possible, eg. when signaling a property change from within the class
* that registered the property, you should use g_object_notify_by_pspec()
* instead.
*
* Note that emission of the notify signal may be blocked with
* g_object_freeze_notify(). In this case, the signal emissions are queued
* and will be emitted (in reverse order) when g_object_thaw_notify() is
* called.
* @param propertyName the name of a property installed on the class of {@code object}.
*/
public void notify(String propertyName) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_notify", _fdesc, false).invokeExact(handle(),
(MemorySegment) (propertyName == null ? MemorySegment.NULL : Interop.allocateNativeString(propertyName, _arena)));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Emits a "notify" signal for the property specified by {@code pspec} on {@code object}.
*
* This function omits the property name lookup, hence it is faster than
* g_object_notify().
*
* One way to avoid using g_object_notify() from within the
* class that registered the properties, and using g_object_notify_by_pspec()
* instead, is to store the GParamSpec used with
* g_object_class_install_property() inside a static array, e.g.:
*
{@code
* typedef enum
* {
* PROP_FOO = 1,
* PROP_LAST
* } MyObjectProperty;
*
* static GParamSpec *properties[PROP_LAST];
*
* static void
* my_object_class_init (MyObjectClass *klass)
* {
* properties[PROP_FOO] = g_param_spec_int ("foo", "Foo", "The foo",
* 0, 100,
* 50,
* G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
* g_object_class_install_property (gobject_class,
* PROP_FOO,
* properties[PROP_FOO]);
* }
* }
*
* and then notify a change on the "foo" property with:
*
{@code
* g_object_notify_by_pspec (self, properties[PROP_FOO]);
* }
* @param pspec the {@code GParamSpec} of a property installed on the class of {@code object}.
*/
public void notifyByPspec(ParamSpec pspec) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_notify_by_pspec", _fdesc, false).invokeExact(handle(),
(MemorySegment) (pspec == null ? MemorySegment.NULL : pspec.handle()));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* Increases the reference count of {@code object}.
*
* Since GLib 2.56, if {@code GLIB_VERSION_MAX_ALLOWED} is 2.56 or greater, the type
* of {@code object} will be propagated to the return type (using the GCC typeof()
* extension), so any casting the caller needs to do on the return type must be
* explicit.
* @return the same {@code object}
*/
public GObject ref() {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_ref", _fdesc, false)
.invokeExact(handle());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return (GObject) InstanceCache.getForType(_result, org.gnome.gobject.GObject::new, true);
}
/**
* Increase the reference count of {@code object}, and possibly remove the
* [floating][floating-ref] reference, if {@code object} has a floating reference.
*
* In other words, if the object is floating, then this call "assumes
* ownership" of the floating reference, converting it to a normal
* reference by clearing the floating flag while leaving the reference
* count unchanged. If the object is not floating, then this call
* adds a new normal reference increasing the reference count by one.
*
* Since GLib 2.56, the type of {@code object} will be propagated to the return type
* under the same conditions as for g_object_ref().
* @return {@code object}
*/
public GObject refSink() {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_ref_sink", _fdesc, false)
.invokeExact(handle());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
var _object = (GObject) InstanceCache.getForType(_result, org.gnome.gobject.GObject::new, true);
if (_object instanceof GObject _gobject) {
GLibLogger.debug("Ref org.gnome.gobject.GObject %ld\\n", _gobject.handle());
_gobject.ref();
}
return _object;
}
/**
* Removes a reference added with g_object_add_toggle_ref(). The
* reference count of the object is decreased by one.
* @param notify a function to call when this reference is the
* last reference to the object, or is no longer
* the last reference.
*/
public void removeToggleRef(ToggleNotify notify) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_remove_toggle_ref", _fdesc, false).invokeExact(
handle(),
(MemorySegment) (notify == null ? MemorySegment.NULL : notify.toCallback(Interop.attachArena(Arena.ofConfined(), this))),
MemorySegment.NULL);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Removes a weak reference from {@code object} that was previously added
* using g_object_add_weak_pointer(). The {@code weak_pointer_location} has
* to match the one used with g_object_add_weak_pointer().
* @param weakPointerLocation The memory address
* of a pointer.
*/
public void removeWeakPointer(Out weakPointerLocation) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _weakPointerLocationPointer = _arena.allocate(ValueLayout.ADDRESS);
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_remove_weak_pointer", _fdesc, false).invokeExact(
handle(),
(MemorySegment) (weakPointerLocation == null ? MemorySegment.NULL : _weakPointerLocationPointer));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
if (weakPointerLocation != null) {
weakPointerLocation.set(_weakPointerLocationPointer.get(ValueLayout.ADDRESS, 0));
}
}
}
/**
* Compares the user data for the key {@code key} on {@code object} with
* {@code oldval}, and if they are the same, replaces {@code oldval} with
* {@code newval}.
*
* This is like a typical atomic compare-and-exchange
* operation, for user data on an object.
*
* If the previous value was replaced then ownership of the
* old value ({@code oldval}) is passed to the caller, including
* the registered destroy notify for it (passed out in {@code old_destroy}).
* It’s up to the caller to free this as needed, which may
* or may not include using {@code old_destroy} as sometimes replacement
* should not destroy the object in the normal way.
*
* See g_object_set_data() for guidance on using a small, bounded set of values
* for {@code key}.
* @param key a string, naming the user data pointer
* @param oldval the old value to compare against
* @param newval the new value
* @param oldDestroy destroy notify for the existing value
* @return {@code true} if the existing value for {@code key} was replaced
* by {@code newval}, {@code false} otherwise.
*/
public boolean replaceData(String key, @Nullable MemorySegment oldval,
@Nullable MemorySegment newval, @Nullable Out oldDestroy) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _oldDestroyPointer = _arena.allocate(ValueLayout.ADDRESS);
final Arena _oldDestroyScope = Arena.ofConfined();
if (oldDestroy != null) ArenaCloseAction.CLEANER.register(oldDestroy, new ArenaCloseAction(_oldDestroyScope));
int _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.JAVA_INT,
ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
_result = (int) Interop.downcallHandle("g_object_replace_data", _fdesc, false)
.invokeExact(handle(),
(MemorySegment) (key == null ? MemorySegment.NULL : Interop.allocateNativeString(key, _arena)),
(MemorySegment) (oldval == null ? MemorySegment.NULL : oldval),
(MemorySegment) (newval == null ? MemorySegment.NULL : newval),
MemorySegment.NULL,
(MemorySegment) (oldDestroy == null ? MemorySegment.NULL : _oldDestroyPointer));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
if (oldDestroy != null) {
oldDestroy.set(null /* Unsupported parameter type */);
}
return _result != 0;
}
}
/**
* Compares the user data for the key {@code quark} on {@code object} with
* {@code oldval}, and if they are the same, replaces {@code oldval} with
* {@code newval}.
*
* This is like a typical atomic compare-and-exchange
* operation, for user data on an object.
*
* If the previous value was replaced then ownership of the
* old value ({@code oldval}) is passed to the caller, including
* the registered destroy notify for it (passed out in {@code old_destroy}).
* It’s up to the caller to free this as needed, which may
* or may not include using {@code old_destroy} as sometimes replacement
* should not destroy the object in the normal way.
* @param quark a {@code GQuark}, naming the user data pointer
* @param oldval the old value to compare against
* @param newval the new value
* @param oldDestroy destroy notify for the existing value
* @return {@code true} if the existing value for {@code quark} was replaced
* by {@code newval}, {@code false} otherwise.
*/
public boolean replaceQdata(Quark quark, @Nullable MemorySegment oldval,
@Nullable MemorySegment newval, @Nullable Out oldDestroy) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _oldDestroyPointer = _arena.allocate(ValueLayout.ADDRESS);
final Arena _oldDestroyScope = Arena.ofConfined();
if (oldDestroy != null) ArenaCloseAction.CLEANER.register(oldDestroy, new ArenaCloseAction(_oldDestroyScope));
int _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.JAVA_INT,
ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
_result = (int) Interop.downcallHandle("g_object_replace_qdata", _fdesc, false)
.invokeExact(handle(), quark.getValue().intValue(),
(MemorySegment) (oldval == null ? MemorySegment.NULL : oldval),
(MemorySegment) (newval == null ? MemorySegment.NULL : newval),
MemorySegment.NULL,
(MemorySegment) (oldDestroy == null ? MemorySegment.NULL : _oldDestroyPointer));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
if (oldDestroy != null) {
oldDestroy.set(null /* Unsupported parameter type */);
}
return _result != 0;
}
}
/**
* Releases all references to other objects. This can be used to break
* reference cycles.
*
* This function should only be called from object system implementations.
*/
public void runDispose() {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_run_dispose", _fdesc, false).invokeExact(handle());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* Sets properties on an object.
*
* The same caveats about passing integer literals as varargs apply as with
* g_object_new(). In particular, any integer literals set as the values for
* properties of type {@code gint64} or {@code guint64} must be 64 bits wide, using the
* {@code G_GINT64_CONSTANT} or {@code G_GUINT64_CONSTANT} macros.
*
* Note that the "notify" signals are queued and only emitted (in
* reverse order) after all properties have been set. See
* g_object_freeze_notify().
* @param firstPropertyName name of the first property to set
* @param varargs value for the first property, followed optionally by more
* name/value pairs, followed by {@code null}
*/
public void set(String firstPropertyName, Object... varargs) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_set", _fdesc, true).invokeExact(handle(),
(MemorySegment) (firstPropertyName == null ? MemorySegment.NULL : Interop.allocateNativeString(firstPropertyName, _arena)),
varargs);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Each object carries around a table of associations from
* strings to pointers. This function lets you set an association.
*
* If the object already had an association with that name,
* the old association will be destroyed.
*
* Internally, the {@code key} is converted to a {@code GQuark} using g_quark_from_string().
* This means a copy of {@code key} is kept permanently (even after {@code object} has been
* finalized) — so it is recommended to only use a small, bounded set of values
* for {@code key} in your program, to avoid the {@code GQuark} storage growing unbounded.
* @param key name of the key
* @param data data to associate with that key
*/
public void setData(String key, @Nullable MemorySegment data) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_set_data", _fdesc, false).invokeExact(handle(),
(MemorySegment) (key == null ? MemorySegment.NULL : Interop.allocateNativeString(key, _arena)),
(MemorySegment) (data == null ? MemorySegment.NULL : data));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Like g_object_set_data() except it adds notification
* for when the association is destroyed, either by setting it
* to a different value or when the object is destroyed.
*
* Note that the {@code destroy} callback is not called if {@code data} is {@code null}.
* @param key name of the key
* @param data data to associate with that key
*/
public void setDataFull(String key, @Nullable MemorySegment data) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_set_data_full", _fdesc, false).invokeExact(
handle(),
(MemorySegment) (key == null ? MemorySegment.NULL : Interop.allocateNativeString(key, _arena)),
(MemorySegment) (data == null ? MemorySegment.NULL : data),
MemorySegment.NULL);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Sets a property on an object.
* @param propertyName the name of the property to set
* @param value the value
*/
public void setProperty(String propertyName, Value value) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_set_property", _fdesc, false).invokeExact(
handle(),
(MemorySegment) (propertyName == null ? MemorySegment.NULL : Interop.allocateNativeString(propertyName, _arena)),
(MemorySegment) (value == null ? MemorySegment.NULL : value.handle()));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* This sets an opaque, named pointer on an object.
* The name is specified through a {@code GQuark} (retrieved e.g. via
* g_quark_from_static_string()), and the pointer
* can be gotten back from the {@code object} with g_object_get_qdata()
* until the {@code object} is finalized.
* Setting a previously set user data pointer, overrides (frees)
* the old pointer set, using {@code NULL} as pointer essentially
* removes the data stored.
* @param quark A {@code GQuark}, naming the user data pointer
* @param data An opaque user data pointer
*/
public void setQdata(Quark quark, @Nullable MemorySegment data) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_set_qdata", _fdesc, false).invokeExact(handle(),
quark.getValue().intValue(),
(MemorySegment) (data == null ? MemorySegment.NULL : data));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* This function works like g_object_set_qdata(), but in addition,
* a void (*destroy) (gpointer) function may be specified which is
* called with {@code data} as argument when the {@code object} is finalized, or
* the data is being overwritten by a call to g_object_set_qdata()
* with the same {@code quark}.
* @param quark A {@code GQuark}, naming the user data pointer
* @param data An opaque user data pointer
*/
public void setQdataFull(Quark quark, @Nullable MemorySegment data) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_set_qdata_full", _fdesc, false).invokeExact(
handle(), quark.getValue().intValue(),
(MemorySegment) (data == null ? MemorySegment.NULL : data),
MemorySegment.NULL);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Sets {@code n_properties} properties for an {@code object}.
* Properties to be set will be taken from {@code values}. All properties must be
* valid. Warnings will be emitted and undefined behaviour may result if invalid
* properties are passed in.
* @param names the names of each property to be set
* @param values the values of each property to be set
*/
public void setv(String[] names, Value[] values) {
try (var _arena = Arena.ofConfined()) {
int nProperties = names == null ? 0 : names.length;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_setv", _fdesc, false).invokeExact(handle(),
nProperties,
(MemorySegment) (names == null ? MemorySegment.NULL : Interop.allocateNativeArray(names, false, _arena)),
(MemorySegment) (values == null ? MemorySegment.NULL : Interop.allocateNativeArray(values, Value.getMemoryLayout(), false, _arena)));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Remove a specified datum from the object's data associations,
* without invoking the association's destroy handler.
* @param key name of the key
* @return the data if found, or {@code null}
* if no such data exists.
*/
public MemorySegment stealData(String key) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_steal_data", _fdesc, false)
.invokeExact(handle(),
(MemorySegment) (key == null ? MemorySegment.NULL : Interop.allocateNativeString(key, _arena)));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return _result;
}
}
/**
* This function gets back user data pointers stored via
* g_object_set_qdata() and removes the {@code data} from object
* without invoking its destroy() function (if any was
* set).
* Usually, calling this function is only required to update
* user data pointers with a destroy notifier, for example:
*
{@code
* void
* object_add_to_user_list (GObject *object,
* const gchar *new_string)
* {
* // the quark, naming the object data
* GQuark quark_string_list = g_quark_from_static_string ("my-string-list");
* // retrieve the old string list
* GList *list = g_object_steal_qdata (object, quark_string_list);
*
* // prepend new string
* list = g_list_prepend (list, g_strdup (new_string));
* // this changed 'list', so we need to set it again
* g_object_set_qdata_full (object, quark_string_list, list, free_string_list);
* }
* static void
* free_string_list (gpointer data)
* {
* GList *node, *list = data;
*
* for (node = list; node; node = node->next)
* g_free (node->data);
* g_list_free (list);
* }
* }
* Using g_object_get_qdata() in the above example, instead of
* g_object_steal_qdata() would have left the destroy function set,
* and thus the partial string list would have been freed upon
* g_object_set_qdata_full().
* @param quark A {@code GQuark}, naming the user data pointer
* @return The user data pointer set, or {@code null}
*/
public MemorySegment stealQdata(Quark quark) {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.JAVA_INT);
_result = (MemorySegment) Interop.downcallHandle("g_object_steal_qdata", _fdesc, false)
.invokeExact(handle(), quark.getValue().intValue());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return _result;
}
/**
* If {@code object} is floating, sink it. Otherwise, do nothing.
*
* In other words, this function will convert a floating reference (if
* present) into a full reference.
*
* Typically you want to use g_object_ref_sink() in order to
* automatically do the correct thing with respect to floating or
* non-floating references, but there is one specific scenario where
* this function is helpful.
*
* The situation where this function is helpful is when creating an API
* that allows the user to provide a callback function that returns a
* GObject. We certainly want to allow the user the flexibility to
* return a non-floating reference from this callback (for the case
* where the object that is being returned already exists).
*
* At the same time, the API style of some popular GObject-based
* libraries (such as Gtk) make it likely that for newly-created GObject
* instances, the user can be saved some typing if they are allowed to
* return a floating reference.
*
* Using this function on the return value of the user's callback allows
* the user to do whichever is more convenient for them. The caller will
* alway receives exactly one full reference to the value: either the
* one that was returned in the first place, or a floating reference
* that has been converted to a full reference.
*
* This function has an odd interaction when combined with
* g_object_ref_sink() running at the same time in another thread on
* the same {@code GObject} instance. If g_object_ref_sink() runs first then
* the result will be that the floating reference is converted to a hard
* reference. If g_object_take_ref() runs first then the result will be
* that the floating reference is converted to a hard reference and an
* additional reference on top of that one is added. It is best to avoid
* this situation.
* @return {@code object}
*/
public GObject takeRef() {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_take_ref", _fdesc, false)
.invokeExact(handle());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return (GObject) InstanceCache.getForType(_result, org.gnome.gobject.GObject::new, true);
}
/**
* Reverts the effect of a previous call to
* g_object_freeze_notify(). The freeze count is decreased on {@code object}
* and when it reaches zero, queued "notify" signals are emitted.
*
* Duplicate notifications for each property are squashed so that at most one
* {@code GObject}::notify signal is emitted for each property, in the reverse order
* in which they have been queued.
*
* It is an error to call this function when the freeze count is zero.
*/
public void thawNotify() {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_thaw_notify", _fdesc, false).invokeExact(handle());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* Decreases the reference count of {@code object}. When its reference count
* drops to 0, the object is finalized (i.e. its memory is freed).
*
* If the pointer to the {@code GObject} may be reused in future (for example, if it is
* an instance variable of another object), it is recommended to clear the
* pointer to {@code null} rather than retain a dangling pointer to a potentially
* invalid {@code GObject} instance. Use g_clear_object() for this.
*/
public void unref() {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_unref", _fdesc, false).invokeExact(handle());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* This function essentially limits the life time of the {@code closure} to
* the life time of the object. That is, when the object is finalized,
* the {@code closure} is invalidated by calling g_closure_invalidate() on
* it, in order to prevent invocations of the closure with a finalized
* (nonexisting) object. Also, g_object_ref() and g_object_unref() are
* added as marshal guards to the {@code closure}, to ensure that an extra
* reference count is held on {@code object} during invocation of the
* {@code closure}. Usually, this function will be called on closures that
* use this {@code object} as closure data.
* @param closure {@code GClosure} to watch
*/
public void watchClosure(Closure closure) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_watch_closure", _fdesc, false).invokeExact(handle(),
(MemorySegment) (closure == null ? MemorySegment.NULL : closure.handle()));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* Adds a weak reference callback to an object. Weak references are
* used for notification when an object is disposed. They are called
* "weak references" because they allow you to safely hold a pointer
* to an object without calling g_object_ref() (g_object_ref() adds a
* strong reference, that is, forces the object to stay alive).
*
* Note that the weak references created by this method are not
* thread-safe: they cannot safely be used in one thread if the
* object's last g_object_unref() might happen in another thread.
* Use {@code GWeakRef} if thread-safety is required.
* @param notify callback to invoke before the object is freed
*/
public void weakRef(WeakNotify notify) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_weak_ref", _fdesc, false).invokeExact(handle(),
(MemorySegment) (notify == null ? MemorySegment.NULL : notify.toCallback(Interop.attachArena(Arena.ofConfined(), this))),
MemorySegment.NULL);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Removes a weak reference callback to an object.
* @param notify callback to search for
*/
public void weakUnref(WeakNotify notify) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_weak_unref", _fdesc, false).invokeExact(handle(),
(MemorySegment) (notify == null ? MemorySegment.NULL : notify.toCallback(Interop.attachArena(Arena.ofConfined(), this))),
MemorySegment.NULL);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
protected void constructed() {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
MemorySegment _func = Overrides.lookupVirtualMethodParent(handle(),
ObjectClass.getMemoryLayout(), "constructed");
if (_func.equals(MemorySegment.NULL)) throw new NullPointerException();
Interop.downcallHandle(_func, _fdesc).invokeExact(handle());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
protected void dispatchPropertiesChanged(int nPspecs, ParamSpec[] pspecs) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
MemorySegment _func = Overrides.lookupVirtualMethodParent(handle(),
ObjectClass.getMemoryLayout(), "dispatch_properties_changed");
if (_func.equals(MemorySegment.NULL)) throw new NullPointerException();
Interop.downcallHandle(_func, _fdesc).invokeExact(handle(), nPspecs,
(MemorySegment) (pspecs == null ? MemorySegment.NULL : Interop.allocateNativeArray(pspecs, false, _arena)));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
protected void dispose() {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
MemorySegment _func = Overrides.lookupVirtualMethodParent(handle(),
ObjectClass.getMemoryLayout(), "dispose");
if (_func.equals(MemorySegment.NULL)) throw new NullPointerException();
Interop.downcallHandle(_func, _fdesc).invokeExact(handle());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
protected void finalize_() {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
MemorySegment _func = Overrides.lookupVirtualMethodParent(handle(),
ObjectClass.getMemoryLayout(), "finalize");
if (_func.equals(MemorySegment.NULL)) throw new NullPointerException();
Interop.downcallHandle(_func, _fdesc).invokeExact(handle());
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
protected void getProperty(int propertyId, Value value, ParamSpec pspec) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
MemorySegment _func = Overrides.lookupVirtualMethodParent(handle(),
ObjectClass.getMemoryLayout(), "get_property");
if (_func.equals(MemorySegment.NULL)) throw new NullPointerException();
Interop.downcallHandle(_func, _fdesc).invokeExact(handle(), propertyId,
(MemorySegment) (value == null ? MemorySegment.NULL : value.handle()),
(MemorySegment) (pspec == null ? MemorySegment.NULL : pspec.handle()));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* Emits a "notify" signal for the property {@code property_name} on {@code object}.
*
* When possible, eg. when signaling a property change from within the class
* that registered the property, you should use g_object_notify_by_pspec()
* instead.
*
* Note that emission of the notify signal may be blocked with
* g_object_freeze_notify(). In this case, the signal emissions are queued
* and will be emitted (in reverse order) when g_object_thaw_notify() is
* called.
*/
protected void notify(ParamSpec pspec) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
MemorySegment _func = Overrides.lookupVirtualMethodParent(handle(),
ObjectClass.getMemoryLayout(), "notify");
if (_func.equals(MemorySegment.NULL)) throw new NullPointerException();
Interop.downcallHandle(_func, _fdesc).invokeExact(handle(),
(MemorySegment) (pspec == null ? MemorySegment.NULL : pspec.handle()));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
protected void setProperty(int propertyId, Value value, ParamSpec pspec) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
MemorySegment _func = Overrides.lookupVirtualMethodParent(handle(),
ObjectClass.getMemoryLayout(), "set_property");
if (_func.equals(MemorySegment.NULL)) throw new NullPointerException();
Interop.downcallHandle(_func, _fdesc).invokeExact(handle(), propertyId,
(MemorySegment) (value == null ? MemorySegment.NULL : value.handle()),
(MemorySegment) (pspec == null ? MemorySegment.NULL : pspec.handle()));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* The notify signal is emitted on an object when one of its properties has
* its value set through g_object_set_property(), g_object_set(), et al.
*
* Note that getting this signal doesn’t itself guarantee that the value of
* the property has actually changed. When it is emitted is determined by the
* derived GObject class. If the implementor did not create the property with
* {@link org.gnome.gobject.ParamFlags#EXPLICIT_NOTIFY}, then any call to g_object_set_property() results
* in ::notify being emitted, even if the new value is the same as the old.
* If they did pass {@link org.gnome.gobject.ParamFlags#EXPLICIT_NOTIFY}, then this signal is emitted only
* when they explicitly call g_object_notify() or g_object_notify_by_pspec(),
* and common practice is to do that only when the value has actually changed.
*
* This signal is typically used to obtain change notification for a
* single property, by specifying the property name as a detail in the
* g_signal_connect() call, like this:
*
{@code
* g_signal_connect (text_view->buffer, "notify::paste-target-list",
* G_CALLBACK (gtk_text_view_target_list_notify),
* text_view)
* }
*
* It is important to note that you must use
* [canonical parameter names][canonical-parameter-names] as
* detail strings for the notify signal.
* @param detail the signal detail
* @param handler the signal handler
* @return a {@link SignalConnection} object to keep track of the signal connection
*/
public SignalConnection onNotify(@Nullable String detail,
NotifyCallback handler) {
try (Arena _arena = Arena.ofConfined()) {
try {
var _name = Interop.allocateNativeString("notify" + ((detail == null || detail.isBlank()) ? "" : ("::" + detail)), _arena);
var _callback = handler.toCallback(Arena.global());
var _result = (long) Signals.g_signal_connect_data.invokeExact(
handle(), _name, _callback, MemorySegment.NULL, MemorySegment.NULL, 0);
return new SignalConnection<>(handle(), _result);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Emits the "notify" signal. See {@link #onNotify}.
*/
public void emitNotify(@Nullable String detail, ParamSpec pspec) {
try (Arena _arena = Arena.ofConfined()) {
MemorySegment _name = Interop.allocateNativeString("notify" + ((detail == null || detail.isBlank()) ? "" : ("::" + detail)), _arena);
Object[] _args = new Object[] {
(MemorySegment) (pspec == null ? MemorySegment.NULL : pspec.handle())};
Signals.g_signal_emit_by_name.invokeExact(handle(), _name, _args);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* A {@link Builder} object constructs a {@code GObject}
* using the builder pattern to set property values.
* Use the various {@code set...()} methods to set properties,
* and finish construction with {@link Builder#build()}.
*/
public static Builder extends Builder> builder() {
return new Builder<>();
}
/**
* Creates a new GObject instance of the provided GType.
*
* @param objectType the GType of the new GObject
* @return the newly created GObject instance
*/
public static T newInstance(Type objectType) {
var _result = constructNew(objectType, null);
T _object = (T) InstanceCache.getForType(_result, GObject::new, true);
return _object;
}
/**
* Creates a new GObject instance of the provided GType and with the provided property values.
*
* @param objectType the GType of the new GObject
* @param propertyNamesAndValues pairs of property names and values (Strings and Objects)
* @return the newly created GObject instance
* @throws IllegalArgumentException invalid property name
*/
public static T newInstance(Type objectType,
Object... propertyNamesAndValues) {
return Properties.newGObjectWithProperties(objectType, propertyNamesAndValues);
}
/**
* Get a property of an object.
*
* @param propertyName the name of the property to get
* @return the property value
* @throws IllegalArgumentException invalid property name
*/
public Object getProperty(String propertyName) {
return Properties.getProperty(this, propertyName);
}
/**
* Set a property of an object.
*
* @param propertyName the name of the property to set
* @param value the new property value
* @throws IllegalArgumentException invalid property name
*/
public void setProperty(String propertyName, Object value) {
Properties.setProperty(this, propertyName, value);
}
/**
* Connect a callback to a signal for this object. The handler will be called
* before the default handler of the signal.
*
* @param detailedSignal a string of the form "signal-name::detail"
* @param callback the callback to connect
* @return a SignalConnection object to track, block and disconnect the signal
* connection
*/
public SignalConnection connect(String detailedSignal, T callback) {
return connect(detailedSignal, callback, false);
}
/**
* Connect a callback to a signal for this object.
*
* @param detailedSignal a string of the form "signal-name::detail"
* @param callback the callback to connect
* @param after whether the handler should be called before or after
* the default handler of the signal
* @return a SignalConnection object to track, block and disconnect the signal
* connection
*/
public SignalConnection connect(String detailedSignal, T callback, boolean after) {
JavaClosure closure = new JavaClosure(callback);
int handlerId = GObjects.signalConnectClosure(this, detailedSignal, closure, after);
return new SignalConnection(handle(), handlerId);
}
/**
* Emits a signal from this object.
*
* @param detailedSignal a string of the form "signal-name::detail"
* @param params the parameters to emit for this signal
* @return the return value of the signal, or {@code null} if the signal
* has no return value
* @throws IllegalArgumentException if a signal with this name is not found for the object
*/
public Object emit(String detailedSignal, Object... params) {
return Signals.emit(this, detailedSignal, params);
}
/**
* Functional interface declaration of the {@code NotifyCallback} callback.
*/
@FunctionalInterface
public interface NotifyCallback {
/**
* The notify signal is emitted on an object when one of its properties has
* its value set through g_object_set_property(), g_object_set(), et al.
*
* Note that getting this signal doesn’t itself guarantee that the value of
* the property has actually changed. When it is emitted is determined by the
* derived GObject class. If the implementor did not create the property with
* {@link org.gnome.gobject.ParamFlags#EXPLICIT_NOTIFY}, then any call to g_object_set_property() results
* in ::notify being emitted, even if the new value is the same as the old.
* If they did pass {@link org.gnome.gobject.ParamFlags#EXPLICIT_NOTIFY}, then this signal is emitted only
* when they explicitly call g_object_notify() or g_object_notify_by_pspec(),
* and common practice is to do that only when the value has actually changed.
*
* This signal is typically used to obtain change notification for a
* single property, by specifying the property name as a detail in the
* g_signal_connect() call, like this:
*
{@code
* g_signal_connect (text_view->buffer, "notify::paste-target-list",
* G_CALLBACK (gtk_text_view_target_list_notify),
* text_view)
* }
*
* It is important to note that you must use
* [canonical parameter names][canonical-parameter-names] as
* detail strings for the notify signal.
*/
void run(ParamSpec pspec);
/**
* The {@code upcall} method is called from native code. The parameters
* are marshaled and {@link #run} is executed.
*/
default void upcall(MemorySegment sourceObject, MemorySegment pspec) {
run((ParamSpec) InstanceCache.getForType(pspec, org.gnome.gobject.ParamSpec.ParamSpecImpl::new, false));
}
/**
* Creates a native function pointer to the {@link #upcall} method.
*
* @return the native function pointer
*/
default MemorySegment toCallback(Arena arena) {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), NotifyCallback.class, _fdesc);
return Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
}
}
/**
* The class structure for the GObject type.
*
{@code
* // Example of implementing a singleton using a constructor.
* static MySingleton *the_singleton = NULL;
*
* static GObject*
* my_singleton_constructor (GType type,
* guint n_construct_params,
* GObjectConstructParam *construct_params)
* {
* GObject *object;
*
* if (!the_singleton)
* {
* object = G_OBJECT_CLASS (parent_class)->constructor (type,
* n_construct_params,
* construct_params);
* the_singleton = MY_SINGLETON (object);
* }
* else
* object = g_object_ref (G_OBJECT (the_singleton));
*
* return object;
* }
* }
*/
public static class ObjectClass extends TypeClass {
private Method _constructorMethod;
private Method _setPropertyMethod;
private Method _getPropertyMethod;
private Method _disposeMethod;
private Method _finalize_Method;
private Method _dispatchPropertiesChangedMethod;
private Method _notifyMethod;
private Method _constructedMethod;
/**
* Create a ObjectClass proxy instance for the provided memory address.
* @param address the memory address of the native object
*/
public ObjectClass(MemorySegment address) {
super(Interop.reinterpret(address, getMemoryLayout().byteSize()));
}
/**
* The memory layout of the native struct.
* @return the memory layout
*/
public static MemoryLayout getMemoryLayout() {
return MemoryLayout.structLayout(
TypeClass.getMemoryLayout().withName("g_type_class"),
ValueLayout.ADDRESS.withName("construct_properties"),
ValueLayout.ADDRESS.withName("constructor"),
ValueLayout.ADDRESS.withName("set_property"),
ValueLayout.ADDRESS.withName("get_property"),
ValueLayout.ADDRESS.withName("dispose"),
ValueLayout.ADDRESS.withName("finalize"),
ValueLayout.ADDRESS.withName("dispatch_properties_changed"),
ValueLayout.ADDRESS.withName("notify"),
ValueLayout.ADDRESS.withName("constructed"),
ValueLayout.JAVA_LONG.withName("flags"),
ValueLayout.JAVA_LONG.withName("n_construct_properties"),
ValueLayout.ADDRESS.withName("pspecs"),
ValueLayout.JAVA_LONG.withName("n_pspecs"),
MemoryLayout.sequenceLayout(3, ValueLayout.ADDRESS).withName("pdummy")
).withName("GObjectClass");
}
/**
* Allocate a new ObjectClass.
*
* @param arena to control the memory allocation scope
* @return a new, uninitialized {@link ObjectClass}
*/
public static ObjectClass allocate(Arena arena) {
MemorySegment segment = arena.allocate(getMemoryLayout());
return new ObjectClass(segment);
}
/**
* Read the value of the field {@code g_type_class}.
*
* @return The value of the field {@code g_type_class}
*/
public TypeClass readGTypeClass() {
var _result = (MemorySegment) getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("g_type_class")).get(handle());
return (TypeClass) InstanceCache.getForTypeClass(_result, org.gnome.gobject.TypeClass::new, true);
}
/**
* Write a value in the field {@code g_type_class}.
*
* @param gTypeClass The new value for the field {@code g_type_class}
*/
public void writeGTypeClass(TypeClass gTypeClass) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("g_type_class"))
.set(handle(), (gTypeClass == null ? MemorySegment.NULL : gTypeClass.handle()));
}
/**
* Read the value of the field {@code construct_properties}.
*
* @return The value of the field {@code construct_properties}
*/
public SList readConstructProperties() {
var _result = (MemorySegment) getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("construct_properties")).get(handle());
return MemorySegment.NULL.equals(_result) ? null : new SList(_result);
}
/**
* Write a value in the field {@code construct_properties}.
*
* @param constructProperties The new value for the field {@code construct_properties}
*/
public void writeConstructProperties(SList constructProperties) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("construct_properties"))
.set(handle(), (constructProperties == null ? MemorySegment.NULL : constructProperties.handle()));
}
/**
* Override virtual method {@code constructor}.
*
* @param method the method to invoke
*/
public void overrideConstructor(Arena arena, Method method) {
this._constructorMethod = method;
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.JAVA_LONG, ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), ObjectClass.class, "constructorUpcall", _fdesc);
MemorySegment _address = Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("constructor"))
.set(handle(), (method == null ? MemorySegment.NULL : _address));
}
private MemorySegment constructorUpcall(long type, int nConstructProperties,
MemorySegment constructProperties) {
try {
Arena _arena = Arena.ofAuto();
var _result = (GObject) this._constructorMethod.invoke(new Type(type), nConstructProperties, MemorySegment.NULL.equals(constructProperties) ? null : new ObjectConstructParam(constructProperties));
if (_result == null) return MemorySegment.NULL;
return _result.handle();
} catch (InvocationTargetException ite) {
GLib.log(Constants.LOG_DOMAIN, LogLevelFlags.LEVEL_WARNING, ite.getCause().toString() + " in " + _constructorMethod);
return MemorySegment.NULL;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Write a value in the field {@code constructor}.
*
* @param constructor The new value for the field {@code constructor}
*/
public void overrideConstructor(Arena _arena, ConstructorCallback constructor) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("constructor"))
.set(handle(), (constructor == null ? MemorySegment.NULL : constructor.toCallback(_arena)));
}
/**
* Override virtual method {@code set_property}.
*
* @param method the method to invoke
*/
public void overrideSetProperty(Arena arena, Method method) {
this._setPropertyMethod = method;
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), ObjectClass.class, "setPropertyUpcall", _fdesc);
MemorySegment _address = Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("set_property"))
.set(handle(), (method == null ? MemorySegment.NULL : _address));
}
private void setPropertyUpcall(MemorySegment object, int propertyId, MemorySegment value,
MemorySegment pspec) {
try {
Arena _arena = Arena.ofAuto();
this._setPropertyMethod.invoke((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false), propertyId, MemorySegment.NULL.equals(value) ? null : new Value(value), (ParamSpec) InstanceCache.getForType(pspec, org.gnome.gobject.ParamSpec.ParamSpecImpl::new, false));
} catch (InvocationTargetException ite) {
GLib.log(Constants.LOG_DOMAIN, LogLevelFlags.LEVEL_WARNING, ite.getCause().toString() + " in " + _setPropertyMethod);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Write a value in the field {@code set_property}.
*
* @param setProperty The new value for the field {@code set_property}
*/
public void overrideSetProperty(Arena _arena, SetPropertyCallback setProperty) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("set_property"))
.set(handle(), (setProperty == null ? MemorySegment.NULL : setProperty.toCallback(_arena)));
}
/**
* Override virtual method {@code get_property}.
*
* @param method the method to invoke
*/
public void overrideGetProperty(Arena arena, Method method) {
this._getPropertyMethod = method;
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), ObjectClass.class, "getPropertyUpcall", _fdesc);
MemorySegment _address = Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("get_property"))
.set(handle(), (method == null ? MemorySegment.NULL : _address));
}
private void getPropertyUpcall(MemorySegment object, int propertyId, MemorySegment value,
MemorySegment pspec) {
try {
Arena _arena = Arena.ofAuto();
this._getPropertyMethod.invoke((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false), propertyId, MemorySegment.NULL.equals(value) ? null : new Value(value), (ParamSpec) InstanceCache.getForType(pspec, org.gnome.gobject.ParamSpec.ParamSpecImpl::new, false));
} catch (InvocationTargetException ite) {
GLib.log(Constants.LOG_DOMAIN, LogLevelFlags.LEVEL_WARNING, ite.getCause().toString() + " in " + _getPropertyMethod);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Write a value in the field {@code get_property}.
*
* @param getProperty The new value for the field {@code get_property}
*/
public void overrideGetProperty(Arena _arena, GetPropertyCallback getProperty) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("get_property"))
.set(handle(), (getProperty == null ? MemorySegment.NULL : getProperty.toCallback(_arena)));
}
/**
* Override virtual method {@code dispose}.
*
* @param method the method to invoke
*/
public void overrideDispose(Arena arena, Method method) {
this._disposeMethod = method;
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), ObjectClass.class, "disposeUpcall", _fdesc);
MemorySegment _address = Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("dispose"))
.set(handle(), (method == null ? MemorySegment.NULL : _address));
}
private void disposeUpcall(MemorySegment object) {
try {
Arena _arena = Arena.ofAuto();
this._disposeMethod.invoke((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false));
} catch (InvocationTargetException ite) {
GLib.log(Constants.LOG_DOMAIN, LogLevelFlags.LEVEL_WARNING, ite.getCause().toString() + " in " + _disposeMethod);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Write a value in the field {@code dispose}.
*
* @param dispose The new value for the field {@code dispose}
*/
public void overrideDispose(Arena _arena, DisposeCallback dispose) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("dispose"))
.set(handle(), (dispose == null ? MemorySegment.NULL : dispose.toCallback(_arena)));
}
/**
* Override virtual method {@code finalize}.
*
* @param method the method to invoke
*/
public void overrideFinalize(Arena arena, Method method) {
this._finalize_Method = method;
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), ObjectClass.class, "finalize_Upcall", _fdesc);
MemorySegment _address = Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("finalize"))
.set(handle(), (method == null ? MemorySegment.NULL : _address));
}
private void finalize_Upcall(MemorySegment object) {
try {
Arena _arena = Arena.ofAuto();
this._finalize_Method.invoke((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false));
} catch (InvocationTargetException ite) {
GLib.log(Constants.LOG_DOMAIN, LogLevelFlags.LEVEL_WARNING, ite.getCause().toString() + " in " + _finalize_Method);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Write a value in the field {@code finalize}.
*
* @param finalize_ The new value for the field {@code finalize}
*/
public void overrideFinalize(Arena _arena, FinalizeCallback finalize_) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("finalize"))
.set(handle(), (finalize_ == null ? MemorySegment.NULL : finalize_.toCallback(_arena)));
}
/**
* Override virtual method {@code dispatch_properties_changed}.
*
* @param method the method to invoke
*/
public void overrideDispatchPropertiesChanged(Arena arena, Method method) {
this._dispatchPropertiesChangedMethod = method;
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), ObjectClass.class, "dispatchPropertiesChangedUpcall", _fdesc);
MemorySegment _address = Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("dispatch_properties_changed"))
.set(handle(), (method == null ? MemorySegment.NULL : _address));
}
private void dispatchPropertiesChangedUpcall(MemorySegment object, int nPspecs,
MemorySegment pspecs) {
try {
Arena _arena = Arena.ofAuto();
this._dispatchPropertiesChangedMethod.invoke((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false), nPspecs, (Object) Interop.getProxyArrayFrom(pspecs, ParamSpec.class, org.gnome.gobject.ParamSpec.ParamSpecImpl::new));
} catch (InvocationTargetException ite) {
GLib.log(Constants.LOG_DOMAIN, LogLevelFlags.LEVEL_WARNING, ite.getCause().toString() + " in " + _dispatchPropertiesChangedMethod);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Write a value in the field {@code dispatch_properties_changed}.
*
* @param dispatchPropertiesChanged The new value for the field {@code dispatch_properties_changed}
*/
public void overrideDispatchPropertiesChanged(Arena _arena,
DispatchPropertiesChangedCallback dispatchPropertiesChanged) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("dispatch_properties_changed"))
.set(handle(), (dispatchPropertiesChanged == null ? MemorySegment.NULL : dispatchPropertiesChanged.toCallback(_arena)));
}
/**
* Override virtual method {@code notify}.
*
* @param method the method to invoke
*/
public void overrideNotify(Arena arena, Method method) {
this._notifyMethod = method;
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), ObjectClass.class, "notifyUpcall", _fdesc);
MemorySegment _address = Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("notify"))
.set(handle(), (method == null ? MemorySegment.NULL : _address));
}
private void notifyUpcall(MemorySegment object, MemorySegment pspec) {
try {
Arena _arena = Arena.ofAuto();
this._notifyMethod.invoke((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false), (ParamSpec) InstanceCache.getForType(pspec, org.gnome.gobject.ParamSpec.ParamSpecImpl::new, false));
} catch (InvocationTargetException ite) {
GLib.log(Constants.LOG_DOMAIN, LogLevelFlags.LEVEL_WARNING, ite.getCause().toString() + " in " + _notifyMethod);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Write a value in the field {@code notify}.
*
* @param notify The new value for the field {@code notify}
*/
public void overrideNotify(Arena _arena, NotifyCallback notify) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("notify"))
.set(handle(), (notify == null ? MemorySegment.NULL : notify.toCallback(_arena)));
}
/**
* Override virtual method {@code constructed}.
*
* @param method the method to invoke
*/
public void overrideConstructed(Arena arena, Method method) {
this._constructedMethod = method;
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), ObjectClass.class, "constructedUpcall", _fdesc);
MemorySegment _address = Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("constructed"))
.set(handle(), (method == null ? MemorySegment.NULL : _address));
}
private void constructedUpcall(MemorySegment object) {
try {
Arena _arena = Arena.ofAuto();
this._constructedMethod.invoke((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false));
} catch (InvocationTargetException ite) {
GLib.log(Constants.LOG_DOMAIN, LogLevelFlags.LEVEL_WARNING, ite.getCause().toString() + " in " + _constructedMethod);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Write a value in the field {@code constructed}.
*
* @param constructed The new value for the field {@code constructed}
*/
public void overrideConstructed(Arena _arena, ConstructedCallback constructed) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("constructed"))
.set(handle(), (constructed == null ? MemorySegment.NULL : constructed.toCallback(_arena)));
}
/**
* Read the value of the field {@code flags}.
*
* @return The value of the field {@code flags}
*/
public long readFlags() {
var _result = (long) getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("flags")).get(handle());
return _result;
}
/**
* Write a value in the field {@code flags}.
*
* @param flags The new value for the field {@code flags}
*/
public void writeFlags(long flags) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("flags"))
.set(handle(), flags);
}
/**
* Read the value of the field {@code n_construct_properties}.
*
* @return The value of the field {@code n_construct_properties}
*/
public long readNConstructProperties() {
var _result = (long) getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("n_construct_properties")).get(handle());
return _result;
}
/**
* Write a value in the field {@code n_construct_properties}.
*
* @param nConstructProperties The new value for the field {@code n_construct_properties}
*/
public void writeNConstructProperties(long nConstructProperties) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("n_construct_properties"))
.set(handle(), nConstructProperties);
}
/**
* Read the value of the field {@code pspecs}.
*
* @return The value of the field {@code pspecs}
*/
public MemorySegment readPspecs() {
var _result = (MemorySegment) getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("pspecs")).get(handle());
return _result;
}
/**
* Write a value in the field {@code pspecs}.
*
* @param pspecs The new value for the field {@code pspecs}
*/
public void writePspecs(MemorySegment pspecs) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("pspecs"))
.set(handle(), (pspecs == null ? MemorySegment.NULL : pspecs));
}
/**
* Read the value of the field {@code n_pspecs}.
*
* @return The value of the field {@code n_pspecs}
*/
public long readNPspecs() {
var _result = (long) getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("n_pspecs")).get(handle());
return _result;
}
/**
* Write a value in the field {@code n_pspecs}.
*
* @param nPspecs The new value for the field {@code n_pspecs}
*/
public void writeNPspecs(long nPspecs) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("n_pspecs"))
.set(handle(), nPspecs);
}
/**
* Read the value of the field {@code pdummy}.
*
* @return The value of the field {@code pdummy}
*/
public MemorySegment[] readPdummy() {
Arena _arena = Arena.ofAuto();
var _result = (MemorySegment) getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("pdummy")).get(handle());
return Interop.getAddressArrayFrom(_result, 3, false);
}
/**
* Write a value in the field {@code pdummy}.
*
* @param pdummy The new value for the field {@code pdummy}
*/
public void writePdummy(Arena _arena, MemorySegment[] pdummy) {
getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("pdummy"))
.set(handle(), (pdummy == null ? MemorySegment.NULL : Interop.allocateNativeArray(pdummy, false, _arena)));
}
/**
* Looks up the {@code GParamSpec} for a property of a class.
* @param propertyName the name of the property to look up
* @return the {@code GParamSpec} for the property, or
* {@code null} if the class doesn't have a property of that name
*/
public ParamSpec findProperty(String propertyName) {
try (var _arena = Arena.ofConfined()) {
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_class_find_property", _fdesc, false)
.invokeExact(handle(),
(MemorySegment) (propertyName == null ? MemorySegment.NULL : Interop.allocateNativeString(propertyName, _arena)));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
return (ParamSpec) InstanceCache.getForType(_result, org.gnome.gobject.ParamSpec.ParamSpecImpl::new, true);
}
}
/**
* Installs new properties from an array of {@code GParamSpecs}.
*
* All properties should be installed during the class initializer. It
* is possible to install properties after that, but doing so is not
* recommend, and specifically, is not guaranteed to be thread-safe vs.
* use of properties on the same type on other threads.
*
* The property id of each property is the index of each {@code GParamSpec} in
* the {@code pspecs} array.
*
* The property id of 0 is treated specially by {@code GObject} and it should not
* be used to store a {@code GParamSpec}.
*
* This function should be used if you plan to use a static array of
* {@code GParamSpecs} and g_object_notify_by_pspec(). For instance, this
* class initialization:
*
{@code
* typedef enum {
* PROP_FOO = 1,
* PROP_BAR,
* N_PROPERTIES
* } MyObjectProperty;
*
* static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
*
* static void
* my_object_class_init (MyObjectClass *klass)
* {
* GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
*
* obj_properties[PROP_FOO] =
* g_param_spec_int ("foo", "Foo", "Foo",
* -1, G_MAXINT,
* 0,
* G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
*
* obj_properties[PROP_BAR] =
* g_param_spec_string ("bar", "Bar", "Bar",
* NULL,
* G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
*
* gobject_class->set_property = my_object_set_property;
* gobject_class->get_property = my_object_get_property;
* g_object_class_install_properties (gobject_class,
* G_N_ELEMENTS (obj_properties),
* obj_properties);
* }
* }
*
* allows calling g_object_notify_by_pspec() to notify of property changes:
*
{@code
* void
* my_object_set_foo (MyObject *self, gint foo)
* {
* if (self->foo != foo)
* {
* self->foo = foo;
* g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_FOO]);
* }
* }
* }
* @param pspecs the {@code GParamSpecs} array
* defining the new properties
*/
public void installProperties(ParamSpec[] pspecs) {
try (var _arena = Arena.ofConfined()) {
int nPspecs = pspecs == null ? 0 : pspecs.length;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_class_install_properties", _fdesc, false)
.invokeExact(handle(), nPspecs,
(MemorySegment) (pspecs == null ? MemorySegment.NULL : Interop.allocateNativeArray(pspecs, false, _arena)));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Installs a new property.
*
* All properties should be installed during the class initializer. It
* is possible to install properties after that, but doing so is not
* recommend, and specifically, is not guaranteed to be thread-safe vs.
* use of properties on the same type on other threads.
*
* Note that it is possible to redefine a property in a derived class,
* by installing a property with the same name. This can be useful at times,
* e.g. to change the range of allowed values or the default value.
* @param propertyId the id for the new property
* @param pspec the {@code GParamSpec} for the new property
*/
public void installProperty(int propertyId, ParamSpec pspec) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_class_install_property", _fdesc, false)
.invokeExact(handle(), propertyId,
(MemorySegment) (pspec == null ? MemorySegment.NULL : pspec.handle()));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
/**
* Get an array of {@code GParamSpec}* for all properties of a class.
* @return an array of
* {@code GParamSpec}* which should be freed after use
*/
public ParamSpec[] listProperties() {
try (var _arena = Arena.ofConfined()) {
MemorySegment _nPropertiesPointer = _arena.allocate(ValueLayout.JAVA_INT);
_nPropertiesPointer.set(ValueLayout.JAVA_INT, 0L, 0);
Out nProperties = new Out<>();
MemorySegment _result;
try {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS, ValueLayout.ADDRESS);
_result = (MemorySegment) Interop.downcallHandle("g_object_class_list_properties", _fdesc, false)
.invokeExact(handle(), _nPropertiesPointer);
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
nProperties.set(_nPropertiesPointer.get(ValueLayout.JAVA_INT, 0));
return Interop.getProxyArrayFrom(_result, (int) nProperties.get().intValue(), ParamSpec.class, org.gnome.gobject.ParamSpec.ParamSpecImpl::new);
}
}
/**
* Registers {@code property_id} as referring to a property with the name
* {@code name} in a parent class or in an interface implemented by {@code oclass}.
* This allows this class to "override" a property implementation in
* a parent class or to provide the implementation of a property from
* an interface.
*
* Internally, overriding is implemented by creating a property of type
* {@code GParamSpecOverride}; generally operations that query the properties of
* the object class, such as g_object_class_find_property() or
* g_object_class_list_properties() will return the overridden
* property. However, in one case, the {@code construct_properties} argument of
* the {@code constructor} virtual function, the {@code GParamSpecOverride} is passed
* instead, so that the {@code param_id} field of the {@code GParamSpec} will be
* correct. For virtually all uses, this makes no difference. If you
* need to get the overridden property, you can call
* g_param_spec_get_redirect_target().
* @param propertyId the new property ID
* @param name the name of a property registered in a parent class or
* in an interface of this class.
*/
public void overrideProperty(int propertyId, String name) {
try (var _arena = Arena.ofConfined()) {
try {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
Interop.downcallHandle("g_object_class_override_property", _fdesc, false)
.invokeExact(handle(), propertyId,
(MemorySegment) (name == null ? MemorySegment.NULL : Interop.allocateNativeString(name, _arena)));
} catch (Throwable _err) {
throw new AssertionError("Unexpected exception occurred: ", _err);
}
}
}
/**
* Functional interface declaration of the {@code ConstructorCallback} callback.
*/
@FunctionalInterface
public interface ConstructorCallback {
GObject run(Type type, int nConstructProperties,
ObjectConstructParam constructProperties);
/**
* The {@code upcall} method is called from native code. The parameters
* are marshaled and {@link #run} is executed.
*/
default MemorySegment upcall(long type, int nConstructProperties,
MemorySegment constructProperties) {
Arena _arena = Arena.ofAuto();
var _result = run(new Type(type), nConstructProperties, MemorySegment.NULL.equals(constructProperties) ? null : new ObjectConstructParam(constructProperties));
if (_result == null) return MemorySegment.NULL;
return _result.handle();
}
/**
* Creates a native function pointer to the {@link #upcall} method.
*
* @return the native function pointer
*/
default MemorySegment toCallback(Arena arena) {
FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.JAVA_LONG, ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), ConstructorCallback.class, _fdesc);
return Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
}
}
/**
* Functional interface declaration of the {@code SetPropertyCallback} callback.
*/
@FunctionalInterface
public interface SetPropertyCallback {
void run(GObject object, int propertyId, Value value, ParamSpec pspec);
/**
* The {@code upcall} method is called from native code. The parameters
* are marshaled and {@link #run} is executed.
*/
default void upcall(MemorySegment object, int propertyId, MemorySegment value,
MemorySegment pspec) {
Arena _arena = Arena.ofAuto();
run((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false), propertyId, MemorySegment.NULL.equals(value) ? null : new Value(value), (ParamSpec) InstanceCache.getForType(pspec, org.gnome.gobject.ParamSpec.ParamSpecImpl::new, false));
}
/**
* Creates a native function pointer to the {@link #upcall} method.
*
* @return the native function pointer
*/
default MemorySegment toCallback(Arena arena) {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), SetPropertyCallback.class, _fdesc);
return Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
}
}
/**
* Functional interface declaration of the {@code GetPropertyCallback} callback.
*/
@FunctionalInterface
public interface GetPropertyCallback {
void run(GObject object, int propertyId, Value value, ParamSpec pspec);
/**
* The {@code upcall} method is called from native code. The parameters
* are marshaled and {@link #run} is executed.
*/
default void upcall(MemorySegment object, int propertyId, MemorySegment value,
MemorySegment pspec) {
Arena _arena = Arena.ofAuto();
run((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false), propertyId, MemorySegment.NULL.equals(value) ? null : new Value(value), (ParamSpec) InstanceCache.getForType(pspec, org.gnome.gobject.ParamSpec.ParamSpecImpl::new, false));
}
/**
* Creates a native function pointer to the {@link #upcall} method.
*
* @return the native function pointer
*/
default MemorySegment toCallback(Arena arena) {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), GetPropertyCallback.class, _fdesc);
return Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
}
}
/**
* Functional interface declaration of the {@code DisposeCallback} callback.
*/
@FunctionalInterface
public interface DisposeCallback {
void run(GObject object);
/**
* The {@code upcall} method is called from native code. The parameters
* are marshaled and {@link #run} is executed.
*/
default void upcall(MemorySegment object) {
Arena _arena = Arena.ofAuto();
run((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false));
}
/**
* Creates a native function pointer to the {@link #upcall} method.
*
* @return the native function pointer
*/
default MemorySegment toCallback(Arena arena) {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), DisposeCallback.class, _fdesc);
return Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
}
}
/**
* Functional interface declaration of the {@code FinalizeCallback} callback.
*/
@FunctionalInterface
public interface FinalizeCallback {
void run(GObject object);
/**
* The {@code upcall} method is called from native code. The parameters
* are marshaled and {@link #run} is executed.
*/
default void upcall(MemorySegment object) {
Arena _arena = Arena.ofAuto();
run((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false));
}
/**
* Creates a native function pointer to the {@link #upcall} method.
*
* @return the native function pointer
*/
default MemorySegment toCallback(Arena arena) {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), FinalizeCallback.class, _fdesc);
return Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
}
}
/**
* Functional interface declaration of the {@code DispatchPropertiesChangedCallback} callback.
*/
@FunctionalInterface
public interface DispatchPropertiesChangedCallback {
void run(GObject object, int nPspecs, ParamSpec[] pspecs);
/**
* The {@code upcall} method is called from native code. The parameters
* are marshaled and {@link #run} is executed.
*/
default void upcall(MemorySegment object, int nPspecs, MemorySegment pspecs) {
Arena _arena = Arena.ofAuto();
run((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false), nPspecs, Interop.getProxyArrayFrom(pspecs, ParamSpec.class, org.gnome.gobject.ParamSpec.ParamSpecImpl::new));
}
/**
* Creates a native function pointer to the {@link #upcall} method.
*
* @return the native function pointer
*/
default MemorySegment toCallback(Arena arena) {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), DispatchPropertiesChangedCallback.class, _fdesc);
return Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
}
}
/**
* Functional interface declaration of the {@code NotifyCallback} callback.
*/
@FunctionalInterface
public interface NotifyCallback {
void run(GObject object, ParamSpec pspec);
/**
* The {@code upcall} method is called from native code. The parameters
* are marshaled and {@link #run} is executed.
*/
default void upcall(MemorySegment object, MemorySegment pspec) {
Arena _arena = Arena.ofAuto();
run((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false), (ParamSpec) InstanceCache.getForType(pspec, org.gnome.gobject.ParamSpec.ParamSpecImpl::new, false));
}
/**
* Creates a native function pointer to the {@link #upcall} method.
*
* @return the native function pointer
*/
default MemorySegment toCallback(Arena arena) {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS,
ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), NotifyCallback.class, _fdesc);
return Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
}
}
/**
* Functional interface declaration of the {@code ConstructedCallback} callback.
*/
@FunctionalInterface
public interface ConstructedCallback {
void run(GObject object);
/**
* The {@code upcall} method is called from native code. The parameters
* are marshaled and {@link #run} is executed.
*/
default void upcall(MemorySegment object) {
Arena _arena = Arena.ofAuto();
run((GObject) InstanceCache.getForType(object, org.gnome.gobject.GObject::new, false));
}
/**
* Creates a native function pointer to the {@link #upcall} method.
*
* @return the native function pointer
*/
default MemorySegment toCallback(Arena arena) {
FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
MethodHandle _handle = Interop.upcallHandle(MethodHandles.lookup(), ConstructedCallback.class, _fdesc);
return Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena);
}
}
}
/**
* Inner class implementing a builder pattern to construct a GObject with
* properties.
*
* @param the type of the Builder that is returned
*/
public static class Builder> extends io.github.jwharm.javagi.gobject.Builder {
/**
* Default constructor for a {@code Builder} object.
*/
protected Builder() {
}
/**
* Finish building the {@code GObject} object. This will call
* {@link GObject#withProperties} to create a new GObject instance,
* which is then cast to {@code GObject}.
*
* @return a new instance of {@code GObject} with the properties
* that were set in the Builder object.
*/
public GObject build() {
try {
return (GObject) GObject.withProperties(GObject.getType(), getNames(), getValues());
} finally {
for (Value _value : getValues()) _value.unset();
getArena().close();
}
}
}
}