You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdebindings/qtjava/javalib/qtjava/QtUtils.cpp

147 lines
3.7 KiB

#include <tqapplication.h>
#include <tqmutex.h>
#include <qtjava/QtSupport.h>
#include <qtjava/QtUtils.h>
#include "QtUtils.moc"
#define SYNC_EVENT1 60001
#define SYNC_EVENT2 60002
#define ASYNC_EVENT 60003
class TQRunEvent : public TQCustomEvent
{
public:
TQRunEvent(int type, jobject r) :
TQCustomEvent(type),
runnable(r),
res(0),
lock(0)
{}
jobject runnable;
jobject *res;
TQMutex *lock;
};
QtUtils* QtUtils::gUtils = 0;
QtUtils::QtUtils()
{
}
QtUtils::~QtUtils()
{
}
void QtUtils::postSync(JNIEnv* env, jobject runnable) {
TQMutex lock;
TQRunEvent *e = new TQRunEvent(SYNC_EVENT1, env->NewGlobalRef(runnable));
e->lock = &lock;
lock.lock();
//post the event to the QT-UI thread
//and trigger its processing
TQApplication::postEvent(this, e);
TQApplication::sendPostedEvents();
//the lock is gained only
//after executing the runnable
lock.lock();
lock.unlock();
}
jobject QtUtils::postSyncRet(JNIEnv* env, jobject runnable) {
TQMutex lock;
jobject res;
TQRunEvent *e = new TQRunEvent(SYNC_EVENT2, env->NewGlobalRef(runnable));
e->lock = &lock;
e->res = &res;
lock.lock();
//post the event to the QT-UI thread and
//trigger its processing
TQApplication::postEvent(this, e);
TQApplication::sendPostedEvents();
//the lock is gained only
//after executing the runnable
lock.lock();
lock.unlock();
jobject lres = env->NewLocalRef(res);
env->DeleteGlobalRef(res);
return lres;
}
void QtUtils::postAsync(JNIEnv *env, jobject runnable) {
TQRunEvent *e = new TQRunEvent(ASYNC_EVENT, env->NewGlobalRef(runnable));
//post the event to the QT-UI thread,
//it will be processed in the next Qt-loop iterations
TQApplication::postEvent(this, e);
}
void QtUtils::customEvent(TQCustomEvent *e) {
if (e->type() >= SYNC_EVENT1 && e->type() <= ASYNC_EVENT) {
TQRunEvent *re = (TQRunEvent*) e;
JNIEnv *env = QtSupport::GetEnv();
jclass cls = env->GetObjectClass(re->runnable);
if (re->type() == SYNC_EVENT1) {
jmethodID m = env->GetMethodID(cls, "run", "()V");
if (m!=0) {
env->CallObjectMethod(re->runnable, m);
}
re->lock->unlock();
}
else if (re->type() == SYNC_EVENT2) {
jmethodID m = env->GetMethodID(cls, "run", "()Ljava/lang/Object;");
if (m!=0) {
jobject res = env->CallObjectMethod(re->runnable, m);
*(re->res) = env->NewGlobalRef(res);
}
re->lock->unlock();
}
else {
jmethodID m = env->GetMethodID(cls, "run", "()V");
if (m!=0) {
env->CallVoidMethod(re->runnable, m);
}
}
//runnable is no longer needed
env->DeleteGlobalRef(re->runnable);
}
}
JNIEXPORT jobject JNICALL
Java_org_trinitydesktop_qt_QtUtils_execSyncOnGUIThread__Lorg_trinitydesktop_qt_QtUtils_00024Compute_2
(JNIEnv *env, jclass, jobject runnable)
{
if (!runnable) return 0;
if (QtUtils::gUtils==0) QtUtils::gUtils = new QtUtils();
return QtUtils::gUtils->postSyncRet(env, runnable);
}
JNIEXPORT void JNICALL
Java_org_trinitydesktop_qt_QtUtils_execSyncOnGUIThread__Ljava_lang_Runnable_2
(JNIEnv *env, jclass, jobject runnable)
{
if (!runnable) return;
if (QtUtils::gUtils==0) QtUtils::gUtils = new QtUtils();
QtUtils::gUtils->postSync(env, runnable);
}
JNIEXPORT void JNICALL
Java_org_trinitydesktop_qt_QtUtils_execAsyncOnGUIThread
(JNIEnv *env, jclass, jobject runnable)
{
if (!runnable) return;
if (QtUtils::gUtils==0) QtUtils::gUtils = new QtUtils();
QtUtils::gUtils->postAsync(env, runnable);
}