
io.qt.internal.SignalUtility Maven / Gradle / Ivy
/****************************************************************************
**
** Copyright (C) 2009-2024 Dr. Peter Droste, Omix Visualization GmbH & Co. KG. All rights reserved.
**
** This file is part of Qt Jambi.
**
** $BEGIN_LICENSE$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
** $END_LICENSE$
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
package io.qt.internal;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.Serializable;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.SerializedLambda;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import io.qt.NativeAccess;
import io.qt.QMisfittingSignatureException;
import io.qt.QNoSuchSignalException;
import io.qt.QNoSuchSlotException;
import io.qt.QSignalDeclarationException;
import io.qt.QSignalInitializationException;
import io.qt.QSignalInvocationException;
import io.qt.QUninvokableSlotException;
import io.qt.QtObject;
import io.qt.QtObjectInterface;
import io.qt.QtPointerType;
import io.qt.QtPrimitiveType;
import io.qt.QtReferenceType;
import io.qt.QtSignalBlockerInterface;
import io.qt.QtSignalEmitterInterface;
import io.qt.QtThreadAffineInterface;
import io.qt.QtUninvokable;
import io.qt.QtUtilities;
import io.qt.core.QByteArray;
import io.qt.core.QDeclarableSignals;
import io.qt.core.QHash;
import io.qt.core.QInstanceMemberSignals;
import io.qt.core.QList;
import io.qt.core.QMap;
import io.qt.core.QMetaMethod;
import io.qt.core.QMetaObject;
import io.qt.core.QMetaObject.Connection;
import io.qt.core.QMetaObject.GenericSlot;
import io.qt.core.QMetaObject.Slot0;
import io.qt.core.QMetaObject.Slot1;
import io.qt.core.QMetaObject.Slot2;
import io.qt.core.QMetaObject.Slot3;
import io.qt.core.QMetaObject.Slot4;
import io.qt.core.QMetaObject.Slot5;
import io.qt.core.QMetaObject.Slot6;
import io.qt.core.QMetaObject.Slot7;
import io.qt.core.QMetaObject.Slot8;
import io.qt.core.QMetaObject.Slot9;
import io.qt.core.QObject;
import io.qt.core.QPair;
import io.qt.core.QSet;
import io.qt.core.QStaticMemberSignals;
import io.qt.core.QStringList;
import io.qt.core.QThread;
import io.qt.core.Qt;
import io.qt.core.Qt.ConnectionType;
/**
* @hidden
*/
abstract class SignalUtility {
static {
QtJambi_LibraryUtilities.initialize();
}
private final static String wrapper = "Wrapper";
private final static String qvariant = "QVariant";
protected SignalUtility() {throw new RuntimeException();}
private final static java.util.logging.Logger logger = java.util.logging.Logger.getLogger("io.qt.internal");
private static final Map lookupSlots = Collections.synchronizedMap(new HashMap<>());
@NativeAccess
static final class SignalParameterType{
public SignalParameterType(Class> type, Type genericType, AnnotatedElement annotatedType, boolean isPointer, boolean isReference) {
super();
this.genericType = genericType;
this.annotatedType = annotatedType;
this.type = type;
if(annotatedType!=null) {
if(!isReference) {
QtReferenceType referenceType = annotatedType.getAnnotation(QtReferenceType.class);
isReference = referenceType!=null && !referenceType.isConst();
}
if(!isPointer) {
QtPointerType pointerType = annotatedType.getAnnotation(QtPointerType.class);
isPointer = pointerType!=null;
}
}
this.isPointer = isPointer;
this.isReference = isReference;
}
@NativeAccess
final Class> type;
final Type genericType;
final AnnotatedElement annotatedType;
final boolean isPointer;
final boolean isReference;
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof SignalParameterType) {
SignalParameterType other = (SignalParameterType) obj;
if(isPointer==other.isPointer
&& isReference==other.isReference) {
if(type==other.type)
return true;
}
return false;
}
return false;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((type == null) ? 0 : type.getName().hashCode());
result = prime * result + (isPointer ? 0 : 1);
result = prime * result + (isReference ? 0 : 1);
return result;
}
}
private interface SlotConnectionFactory{
public SlotObjectConnection create(Object lambdaOwner, Class> lambdaOwnerClass, int lambdaHashCode, Slot slotObject, Qt.ConnectionType[] connectionType);
}
private static abstract class AbstractSignalCore {
abstract List signalTypes(AbstractSignal signal);
abstract String name(AbstractSignal signal);
abstract void emitSignal(AbstractSignal signal, final Object[] args, Supplier>... suppliers);
abstract QMetaObject.Connection addConnectionToMethod(AbstractSignal signal, Object receiver, Method slot, MethodHandle slotHandle, List> lambdaArgs, Qt.ConnectionType... connectionType);
abstract QMetaObject.Connection addConnectionToMethod(AbstractSignal signal, Object receiver, QMetaMethod slot, Qt.ConnectionType... connectionType);
abstract QMetaObject.Connection addConnectionToSlotObject(AbstractSignal signal, SlotConnectionFactory factory, Object lambdaOwner, Class> lambdaOwnerClass, int lambdaHash, Slot slotObject, Qt.ConnectionType[] connectionType);
abstract boolean removeConnectionToMethod(AbstractSignal signal, Object receiver, Method slot, Object[] lambdaArgs, boolean allowNativeDisconnect);
abstract boolean removeConnectionToMethod(AbstractSignal signal, Object receiver, QMetaMethod slot, boolean allowNativeDisconnect);
int methodIndex(AbstractSignal signal) { return -1; }
Class> getDeclaringClass(AbstractSignal signal){ return null; }
abstract boolean removeConnectionToSlotObject(AbstractSignal signal,
Serializable slotObject, Class> _functionalInterfaceClass, Object _lambdaOwner, Class> _lambdaOwnerClass,
int _lambdaHashCode, boolean useLambdaInfo);
abstract boolean removeConnection(AbstractSignal signal, JavaConnection javaConnection);
boolean removeConnection(AbstractSignal signal, NativeConnection nativeConnection) {
if(nativeConnection.receiver()!=null && nativeConnection.method()!=null && !nativeConnection.isSlotObject()) {
return QObject.disconnect(nativeConnection.sender(), nativeConnection.signal(), nativeConnection.receiver(), nativeConnection.method());
}else {
long nativeId = NativeUtility.nativeId(nativeConnection);
if(nativeId!=0)
return disconnectConnection(nativeId);
else return false;
}
}
String toString(AbstractSignal signal) {
return String.format("%1$s(%2$s)", signal.fullName(), signal.signalParameters());
}
}
private interface AnalyzingSignalCoreInterface{
}
private static class AnalyzingSignalCore extends AbstractSignalCore implements AnalyzingSignalCoreInterface{
final static AnalyzingSignalCore instance = new AnalyzingSignalCore();
@Override
final List signalTypes(AbstractSignal signal) {
signal.resolveSignal();
return signal.core.signalTypes(signal);
}
@Override
final String name(AbstractSignal signal) {
signal.resolveSignal();
return signal.core.name(signal);
}
@Override
final Connection addConnectionToMethod(AbstractSignal signal, Object receiver, Method slot, MethodHandle slotHandle,
List> lambdaArgs, ConnectionType... connectionType) {
signal.resolveSignal();
return signal.core.addConnectionToMethod(signal, receiver, slot, slotHandle, lambdaArgs, connectionType);
}
@Override
final QMetaObject.Connection addConnectionToMethod(AbstractSignal signal, Object receiver, QMetaMethod slot, Qt.ConnectionType... connectionType){
signal.resolveSignal();
return signal.core.addConnectionToMethod(signal, receiver, slot, connectionType);
}
@Override
final void emitSignal(AbstractSignal signal, Object[] args, Supplier>... suppliers) {
signal.resolveSignal();
signal.core.emitSignal(signal, args, suppliers);
}
@Override
final Connection addConnectionToSlotObject(AbstractSignal signal,
SlotConnectionFactory factory, Object lambdaOwner, Class> lambdaOwnerClass, int lambdaHash, Slot slotObject, ConnectionType[] connectionType) {
signal.resolveSignal();
return signal.core.addConnectionToSlotObject(signal, factory, lambdaOwner, lambdaOwnerClass, lambdaHash, slotObject, connectionType);
}
final int methodIndex(AbstractSignal signal) {
signal.resolveSignal();
return signal.core.methodIndex(signal);
}
@Override
final boolean removeConnectionToMethod(AbstractSignal signal, Object receiver, Method slot, Object[] lambdaArgs,
boolean allowNativeDisconnect) {
signal.resolveSignal();
return signal.core.removeConnectionToMethod(signal, receiver, slot, lambdaArgs, allowNativeDisconnect);
}
@Override
final boolean removeConnectionToMethod(AbstractSignal signal, Object receiver, QMetaMethod slot, boolean allowNativeDisconnect) {
signal.resolveSignal();
return signal.core.removeConnectionToMethod(signal, receiver, slot, allowNativeDisconnect);
}
@Override
final boolean removeConnectionToSlotObject(AbstractSignal signal,
Serializable slotObject, Class> _functionalInterfaceClass, Object _lambdaOwner, Class> _lambdaOwnerClass,
int _lambdaHashCode, boolean useLambdaInfo) {
signal.resolveSignal();
return signal.core.removeConnectionToSlotObject(signal, slotObject, _functionalInterfaceClass, _lambdaOwner, _lambdaOwnerClass, _lambdaHashCode, useLambdaInfo);
}
@Override
final boolean removeConnection(AbstractSignal signal, JavaConnection javaConnection) {
signal.resolveSignal();
return signal.core.removeConnection(signal, javaConnection);
}
@Override
final boolean removeConnection(AbstractSignal signal, NativeConnection nativeConnection) {
signal.resolveSignal();
return signal.core.removeConnection(signal, nativeConnection);
}
final Class> getDeclaringClass(AbstractSignal signal){
signal.resolveSignal();
return signal.core.getDeclaringClass(signal);
}
final String toString(AbstractSignal signal) {
signal.resolveSignal();
return signal.core.toString(signal);
}
}
private static class AnalyzingCheckingSignalCore extends AnalyzingSignalCore{
private final Consumer
© 2015 - 2025 Weber Informatics LLC | Privacy Policy