io.qt.internal.SignalUtility Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of qtjambi Show documentation
Show all versions of qtjambi Show documentation
QtJambi base module containing QtCore, QtGui and QtWidgets.
/****************************************************************************
**
** 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