All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gnome.gio.FileMonitor Maven / Gradle / Ivy

The newest version!
// This file was automatically generated by Java-GI. Do not edit this file
// directly! Visit  for more information.
//
// The API documentation in this file was derived from GObject-Introspection
// metadata and may include text or comments from the original C sources.
//
// Copyright (c), upstream authors as identified in the GObject-Introspection
// metadata.
//
// This generated file is distributed under the same license as the original
// GObject-Introspection data, unless otherwise specified. Users of this file
// are responsible for complying with any licenses or terms required by the
// original authors.
//
// THIS FILE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
//
package org.gnome.gio;

import io.github.jwharm.javagi.Constants;
import io.github.jwharm.javagi.base.FunctionPointer;
import io.github.jwharm.javagi.gobject.InstanceCache;
import io.github.jwharm.javagi.gobject.SignalConnection;
import io.github.jwharm.javagi.gobject.types.Overrides;
import io.github.jwharm.javagi.gobject.types.Signals;
import io.github.jwharm.javagi.gobject.types.Types;
import io.github.jwharm.javagi.interop.Arenas;
import io.github.jwharm.javagi.interop.Interop;
import java.lang.FunctionalInterface;
import java.lang.NullPointerException;
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.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.annotation.processing.Generated;
import org.gnome.glib.GLib;
import org.gnome.glib.LogLevelFlags;
import org.gnome.glib.Type;
import org.gnome.gobject.GObject;
import org.gnome.gobject.Value;
import org.jetbrains.annotations.Nullable;

/**
 * Monitors a file or directory for changes.
 * 

* To obtain a {@code GFileMonitor} for a file or directory, use * {@link File#monitor}, {@link File#monitorFile}, or * {@link File#monitorDirectory}. *

* To get informed about changes to the file or directory you are * monitoring, connect to the {@code Gio.FileMonitor::changed} signal. The * signal will be emitted in the thread-default main context (see * {@link org.gnome.glib.MainContext#pushThreadDefault}) of the thread that the monitor * was created in (though if the global default main context is blocked, this * may cause notifications to be blocked even if the thread-default * context is still running). */ @Generated("io.github.jwharm.JavaGI") public abstract class FileMonitor extends GObject { static { Gio.javagi$ensureInitialized(); } /** * Create a FileMonitor proxy instance for the provided memory address. * * @param address the memory address of the native object */ public FileMonitor(MemorySegment address) { super(Interop.reinterpret(address, getMemoryLayout().byteSize())); } /** * Get the GType of the FileMonitor class * * @return the GType */ public static Type getType() { return Interop.getType("g_file_monitor_get_type"); } /** * The memory layout of the native struct. * @return the memory layout */ public static MemoryLayout getMemoryLayout() { return MemoryLayout.structLayout( GObject.getMemoryLayout().withName("parent_instance"), ValueLayout.ADDRESS.withName("priv") ).withName("GFileMonitor"); } /** * 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 FileMonitor asParent() { FileMonitor _parent = new FileMonitorImpl(handle()); _parent.callParent(true); return _parent; } /** * Cancels a file monitor. * * @return always {@code true} */ public boolean cancel() { int _result; try { if (callParent()) { FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS); MemorySegment _func = Overrides.lookupVirtualMethodParent(handle(), FileMonitorClass.getMemoryLayout(), "cancel"); if (_func.equals(MemorySegment.NULL)) throw new NullPointerException(); _result = (int) Interop.downcallHandle(_func, _fdesc).invokeExact(handle()); } else { _result = (int) MethodHandles.g_file_monitor_cancel.invokeExact(handle()); } } catch (Throwable _err) { throw new AssertionError(_err); } return _result != 0; } /** * Emits the {@code GFileMonitor}::changed signal if a change * has taken place. Should be called from file monitor * implementations only. *

* Implementations are responsible to call this method from the * [thread-default main context][g-main-context-push-thread-default] of the * thread that the monitor was created in. * * @param child a {@code GFile}. * @param otherFile a {@code GFile}. * @param eventType a set of {@code GFileMonitorEvent} flags. */ public void emitEvent(File child, File otherFile, FileMonitorEvent eventType) { try { MethodHandles.g_file_monitor_emit_event.invokeExact(handle(), (MemorySegment) (child == null ? MemorySegment.NULL : child.handle()), (MemorySegment) (otherFile == null ? MemorySegment.NULL : otherFile.handle()), eventType.getValue()); } catch (Throwable _err) { throw new AssertionError(_err); } } /** * Returns whether the monitor is canceled. * * @return {@code true} if monitor is canceled. {@code false} otherwise. */ public boolean isCancelled() { int _result; try { _result = (int) MethodHandles.g_file_monitor_is_cancelled.invokeExact(handle()); } catch (Throwable _err) { throw new AssertionError(_err); } return _result != 0; } /** * Sets the rate limit to which the this FileMonitor will report * consecutive change events to the same file. * * @param limitMsecs a non-negative integer with the limit in milliseconds * to poll for changes */ public void setRateLimit(int limitMsecs) { try { MethodHandles.g_file_monitor_set_rate_limit.invokeExact(handle(), limitMsecs); } catch (Throwable _err) { throw new AssertionError(_err); } } protected void changed(File file, File otherFile, FileMonitorEvent eventType) { try { FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.JAVA_INT); MemorySegment _func = Overrides.lookupVirtualMethodParent(handle(), FileMonitorClass.getMemoryLayout(), "changed"); if (_func.equals(MemorySegment.NULL)) throw new NullPointerException(); Interop.downcallHandle(_func, _fdesc).invokeExact(handle(), (MemorySegment) (file == null ? MemorySegment.NULL : file.handle()), (MemorySegment) (otherFile == null ? MemorySegment.NULL : otherFile.handle()), eventType.getValue()); } catch (Throwable _err) { throw new AssertionError(_err); } } /** * Emitted when {@code file} has been changed. *

* If using {@link org.gnome.gio.FileMonitorFlags#WATCH_MOVES} on a directory monitor, and * the information is available (and if supported by the backend), * {@code eventType} may be {@link org.gnome.gio.FileMonitorEvent#RENAMED}, * {@link org.gnome.gio.FileMonitorEvent#MOVED_IN} or {@link org.gnome.gio.FileMonitorEvent#MOVED_OUT}. *

* In all cases {@code file} will be a child of the monitored directory. For * renames, {@code file} will be the old name and {@code otherFile} is the new * name. For "moved in" events, {@code file} is the name of the file that * appeared and {@code otherFile} is the old name that it was moved from (in * another directory). For "moved out" events, {@code file} is the name of * the file that used to be in this directory and {@code otherFile} is the * name of the file at its new location. *

* It makes sense to treat {@link org.gnome.gio.FileMonitorEvent#MOVED_IN} as * equivalent to {@link org.gnome.gio.FileMonitorEvent#CREATED} and * {@link org.gnome.gio.FileMonitorEvent#MOVED_OUT} as equivalent to * {@link org.gnome.gio.FileMonitorEvent#DELETED}, with extra information. * {@link org.gnome.gio.FileMonitorEvent#RENAMED} is equivalent to a delete/create * pair. This is exactly how the events will be reported in the case * that the {@link org.gnome.gio.FileMonitorFlags#WATCH_MOVES} flag is not in use. *

* If using the deprecated flag {@link org.gnome.gio.FileMonitorFlags#SEND_MOVED} flag and {@code eventType} is * {@link org.gnome.gio.FileMonitorEvent#MOVED}, {@code file} will be set to a {@code GFile} containing the * old path, and {@code otherFile} will be set to a {@code GFile} containing the new path. *

* In all the other cases, {@code otherFile} will be set to {@code NULL}. * * @param handler the signal handler * @return a signal handler ID to keep track of the signal connection * @see ChangedCallback#run */ public SignalConnection onChanged(ChangedCallback handler) { try (Arena _arena = Arena.ofConfined()) { try { var _name = Interop.allocateNativeString("changed", _arena); var _callbackArena = Arena.ofShared(); var _result = (int) (long) Signals.g_signal_connect_data.invokeExact(handle(), _name, handler.toCallback(_callbackArena), Arenas.cacheArena(_callbackArena), Arenas.CLOSE_CB_SYM, 0); return new SignalConnection<>(handle(), _result); } catch (Throwable _err) { throw new AssertionError(_err); } } } /** * Emits the "changed" signal. See {@link #onChanged}. */ public void emitChanged(File file, @Nullable File otherFile, FileMonitorEvent eventType) { try (Arena _arena = Arena.ofConfined()) { MemorySegment _name = Interop.allocateNativeString("changed", _arena); Object[] _args = new Object[] { (MemorySegment) (file == null ? MemorySegment.NULL : file.handle()), (MemorySegment) (otherFile == null ? MemorySegment.NULL : otherFile.handle()), eventType.getValue()}; Signals.g_signal_emit_by_name.invokeExact(handle(), _name, _args); } catch (Throwable _err) { throw new AssertionError(_err); } } /** * A {@link Builder} object constructs a {@code FileMonitor} * with the specified properties. * Use the various {@code set...()} methods to set properties, * and finish construction with {@link Builder#build()}. */ public static Builder builder() { return new Builder<>(); } /** * Functional interface declaration of the {@code ChangedCallback} callback. *

* @see ChangedCallback#run */ @FunctionalInterface public interface ChangedCallback extends FunctionPointer { /** * Emitted when {@code file} has been changed. *

* If using {@link org.gnome.gio.FileMonitorFlags#WATCH_MOVES} on a directory monitor, and * the information is available (and if supported by the backend), * {@code eventType} may be {@link org.gnome.gio.FileMonitorEvent#RENAMED}, * {@link org.gnome.gio.FileMonitorEvent#MOVED_IN} or {@link org.gnome.gio.FileMonitorEvent#MOVED_OUT}. *

* In all cases {@code file} will be a child of the monitored directory. For * renames, {@code file} will be the old name and {@code otherFile} is the new * name. For "moved in" events, {@code file} is the name of the file that * appeared and {@code otherFile} is the old name that it was moved from (in * another directory). For "moved out" events, {@code file} is the name of * the file that used to be in this directory and {@code otherFile} is the * name of the file at its new location. *

* It makes sense to treat {@link org.gnome.gio.FileMonitorEvent#MOVED_IN} as * equivalent to {@link org.gnome.gio.FileMonitorEvent#CREATED} and * {@link org.gnome.gio.FileMonitorEvent#MOVED_OUT} as equivalent to * {@link org.gnome.gio.FileMonitorEvent#DELETED}, with extra information. * {@link org.gnome.gio.FileMonitorEvent#RENAMED} is equivalent to a delete/create * pair. This is exactly how the events will be reported in the case * that the {@link org.gnome.gio.FileMonitorFlags#WATCH_MOVES} flag is not in use. *

* If using the deprecated flag {@link org.gnome.gio.FileMonitorFlags#SEND_MOVED} flag and {@code eventType} is * {@link org.gnome.gio.FileMonitorEvent#MOVED}, {@code file} will be set to a {@code GFile} containing the * old path, and {@code otherFile} will be set to a {@code GFile} containing the new path. *

* In all the other cases, {@code otherFile} will be set to {@code NULL}. */ void run(File file, @Nullable File otherFile, FileMonitorEvent eventType); /** * The {@code upcall} method is called from native code. The parameters * are marshaled and {@link #run} is executed. */ default void upcall(MemorySegment sourceFileMonitor, MemorySegment file, MemorySegment otherFile, int eventType) { run((File) InstanceCache.getForType(file, File.FileImpl::new, false), (File) InstanceCache.getForType(otherFile, File.FileImpl::new, false), FileMonitorEvent.of(eventType)); } /** * 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, ValueLayout.ADDRESS, ValueLayout.JAVA_INT); MethodHandle _handle = Interop.upcallHandle(java.lang.invoke.MethodHandles.lookup(), ChangedCallback.class, _fdesc); return Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena); } } public static class FileMonitorClass extends GObject.ObjectClass { private Method _changedMethod; private Method _cancelMethod; /** * Create a FileMonitorClass proxy instance for the provided memory address. * * @param address the memory address of the native object */ public FileMonitorClass(MemorySegment address) { super(Interop.reinterpret(address, getMemoryLayout().byteSize())); } /** * Allocate a new FileMonitorClass. * * @param arena to control the memory allocation scope */ public FileMonitorClass(Arena arena) { super(arena.allocate(getMemoryLayout())); } /** * Allocate a new FileMonitorClass. * The memory is allocated with {@link Arena#ofAuto}. */ public FileMonitorClass() { super(Arena.ofAuto().allocate(getMemoryLayout())); } /** * The memory layout of the native struct. * @return the memory layout */ public static MemoryLayout getMemoryLayout() { return MemoryLayout.structLayout( GObject.ObjectClass.getMemoryLayout().withName("parent_class"), ValueLayout.ADDRESS.withName("changed"), ValueLayout.ADDRESS.withName("cancel"), ValueLayout.ADDRESS.withName("_g_reserved1"), ValueLayout.ADDRESS.withName("_g_reserved2"), ValueLayout.ADDRESS.withName("_g_reserved3"), ValueLayout.ADDRESS.withName("_g_reserved4"), ValueLayout.ADDRESS.withName("_g_reserved5") ).withName("GFileMonitorClass"); } /** * Override virtual method {@code changed}. * * @param method the method to invoke */ public void overrideChanged(Arena arena, Method method) { this._changedMethod = method; FunctionDescriptor _fdesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.JAVA_INT); MethodHandle _handle = Interop.upcallHandle(java.lang.invoke.MethodHandles.lookup(), FileMonitorClass.class, "changedUpcall", _fdesc); MemorySegment _address = Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena); getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("changed")) .set(handle(), 0, (method == null ? MemorySegment.NULL : _address)); } private void changedUpcall(MemorySegment monitor, MemorySegment file, MemorySegment otherFile, int eventType) { try { Arena _arena = Arena.ofAuto(); this._changedMethod.invoke((FileMonitor) InstanceCache.getForType(monitor, FileMonitorImpl::new, false), (File) InstanceCache.getForType(file, File.FileImpl::new, false), (File) InstanceCache.getForType(otherFile, File.FileImpl::new, false), FileMonitorEvent.of(eventType)); } catch (InvocationTargetException ite) { GLib.log(Constants.LOG_DOMAIN, LogLevelFlags.LEVEL_WARNING, ite.getCause().toString() + " in " + _changedMethod); } catch (Exception e) { throw new RuntimeException(e); } } /** * Override virtual method {@code cancel}. * * @param method the method to invoke */ public void overrideCancel(Arena arena, Method method) { this._cancelMethod = method; FunctionDescriptor _fdesc = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS); MethodHandle _handle = Interop.upcallHandle(java.lang.invoke.MethodHandles.lookup(), FileMonitorClass.class, "cancelUpcall", _fdesc); MemorySegment _address = Linker.nativeLinker().upcallStub(_handle.bindTo(this), _fdesc, arena); getMemoryLayout().varHandle(MemoryLayout.PathElement.groupElement("cancel")) .set(handle(), 0, (method == null ? MemorySegment.NULL : _address)); } private int cancelUpcall(MemorySegment monitor) { try { Arena _arena = Arena.ofAuto(); var _result = (boolean) this._cancelMethod.invoke((FileMonitor) InstanceCache.getForType(monitor, FileMonitorImpl::new, false)); return _result ? 1 : 0; } catch (InvocationTargetException ite) { GLib.log(Constants.LOG_DOMAIN, LogLevelFlags.LEVEL_WARNING, ite.getCause().toString() + " in " + _cancelMethod); return 0; } catch (Exception e) { throw new RuntimeException(e); } } } /** * The FileMonitorImpl type represents a native instance of the abstract FileMonitor class. */ public static class FileMonitorImpl extends FileMonitor { /** * Creates a new instance of FileMonitor for the provided memory address. * * @param address the memory address of the instance */ public FileMonitorImpl(MemorySegment address) { super(address); } } /** * 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 GObject.Builder { /** * Default constructor for a {@code Builder} object. */ protected Builder() { } /** * Finish building the {@code FileMonitor} object. This will call * {@link GObject#withProperties} to create a new GObject instance, * which is then cast to {@code FileMonitor}. * * @return a new instance of {@code FileMonitor} with the properties * that were set in the Builder object. */ public FileMonitor build() { try { var _instance = (FileMonitor) GObject.withProperties(FileMonitor.getType(), getNames(), getValues()); connectSignals(_instance.handle()); return _instance; } finally { for (Value _value : getValues()) _value.unset(); getArena().close(); } } /** * The limit of the monitor to watch for changes, in milliseconds. * * @param rateLimit the value for the {@code rate-limit} property * @return the {@code Builder} instance is returned, to allow method chaining */ public B setRateLimit(int rateLimit) { Arena _arena = getArena(); Value _value = new Value(_arena); _value.init(Types.INT); _value.setInt(rateLimit); addBuilderProperty("rate-limit", _value); return (B) this; } /** * Emitted when {@code file} has been changed. *

* If using {@link org.gnome.gio.FileMonitorFlags#WATCH_MOVES} on a directory monitor, and * the information is available (and if supported by the backend), * {@code eventType} may be {@link org.gnome.gio.FileMonitorEvent#RENAMED}, * {@link org.gnome.gio.FileMonitorEvent#MOVED_IN} or {@link org.gnome.gio.FileMonitorEvent#MOVED_OUT}. *

* In all cases {@code file} will be a child of the monitored directory. For * renames, {@code file} will be the old name and {@code otherFile} is the new * name. For "moved in" events, {@code file} is the name of the file that * appeared and {@code otherFile} is the old name that it was moved from (in * another directory). For "moved out" events, {@code file} is the name of * the file that used to be in this directory and {@code otherFile} is the * name of the file at its new location. *

* It makes sense to treat {@link org.gnome.gio.FileMonitorEvent#MOVED_IN} as * equivalent to {@link org.gnome.gio.FileMonitorEvent#CREATED} and * {@link org.gnome.gio.FileMonitorEvent#MOVED_OUT} as equivalent to * {@link org.gnome.gio.FileMonitorEvent#DELETED}, with extra information. * {@link org.gnome.gio.FileMonitorEvent#RENAMED} is equivalent to a delete/create * pair. This is exactly how the events will be reported in the case * that the {@link org.gnome.gio.FileMonitorFlags#WATCH_MOVES} flag is not in use. *

* If using the deprecated flag {@link org.gnome.gio.FileMonitorFlags#SEND_MOVED} flag and {@code eventType} is * {@link org.gnome.gio.FileMonitorEvent#MOVED}, {@code file} will be set to a {@code GFile} containing the * old path, and {@code otherFile} will be set to a {@code GFile} containing the new path. *

* In all the other cases, {@code otherFile} will be set to {@code NULL}. * * @param handler the signal handler * @return the {@code Builder} instance is returned, to allow method chaining * @see ChangedCallback#run */ public B onChanged(ChangedCallback handler) { connect("changed", handler); return (B) this; } } private static final class MethodHandles { static final MethodHandle g_file_monitor_cancel = Interop.downcallHandle( "g_file_monitor_cancel", FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS), false); static final MethodHandle g_file_monitor_emit_event = Interop.downcallHandle( "g_file_monitor_emit_event", FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.JAVA_INT), false); static final MethodHandle g_file_monitor_is_cancelled = Interop.downcallHandle( "g_file_monitor_is_cancelled", FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS), false); static final MethodHandle g_file_monitor_set_rate_limit = Interop.downcallHandle( "g_file_monitor_set_rate_limit", FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT), false); } }