summaryrefslogtreecommitdiffstats
path: root/qtjava/javalib/qtjava/QtUtils.cpp
blob: ee56ebc132e3bfa0b7cca894fa8392d2f907daf6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

#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 QRunEvent : public TQCustomEvent 
{

public:
    QRunEvent(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;
    QRunEvent *e = new QRunEvent(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;
    QRunEvent *e = new QRunEvent(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) {
    QRunEvent *e = new QRunEvent(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) {
        QRunEvent *re = (QRunEvent*) 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_kde_qt_QtUtils_execSyncOnGUIThread__Lorg_kde_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_kde_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_kde_qt_QtUtils_execAsyncOnGUIThread
  (JNIEnv *env, jclass, jobject runnable)
{
    if (!runnable) return;
    if (QtUtils::gUtils==0) QtUtils::gUtils = new QtUtils();
    QtUtils::gUtils->postAsync(env, runnable);
}