javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/common_j2me/org/eclipse/swt/internal/qt/EventLoop.java
author hgs
Mon, 04 Oct 2010 11:29:25 +0300
changeset 78 71ad690e91f5
permissions -rw-r--r--
v2.2.17_1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
78
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
     1
/*******************************************************************************
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
     2
 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
     3
 * All rights reserved. This program and the accompanying materials
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
     4
 * are made available under the terms of the Eclipse Public License v1.0
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
     5
 * which accompanies this distribution, and is available at
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
     6
 * http://www.eclipse.org/legal/epl-v10.html
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
     7
 *
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
     8
 * Contributors:
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
     9
 *     Nokia Corporation - initial implementation
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    10
 *******************************************************************************/
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    11
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    12
package org.eclipse.swt.internal.qt;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    13
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    14
import org.eclipse.swt.internal.qt.midp.UIThreadLauncher;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    15
import org.eclipse.swt.widgets.Display;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    16
import org.eclipse.swt.widgets.Internal_PackageSupport;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    17
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    18
import com.nokia.mj.impl.rt.support.ApplicationUtils;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    19
import com.nokia.mj.impl.rt.support.ShutdownListener;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    20
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    21
/**
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    22
 * The internal event loop which will run until the application requests the UI 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    23
 * thread. Then UI thread is handed over to the application which will continue
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    24
 * running the loop as it pleases. If the application exits cleanly the UI 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    25
 * thread will return back to here and the event loop can continue to run
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    26
 * until the runtime signals shutdown. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    27
 * 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    28
 * This class is the owner of the internal Display instance. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    29
 */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    30
public final class EventLoop {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    31
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    32
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    33
     * The internal Display instance. Owned by this class. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    34
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    35
    private static Display internalDisplay;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    36
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    37
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    38
     * Event loop can run here before the application's loop and after the UI
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    39
     * thread exits from the application's loop. These states are identifying
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    40
     * which of the two loops is currently running. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    41
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    42
    private static final int PRE_APPLICATION = 0;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    43
    private static final int POST_APPLICATION = 1;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    44
    
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    45
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    46
     * Boolean used to detect when application has requested the UI thread and
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    47
     * the hand-over must begin. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    48
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    49
    private static volatile boolean applicationRequestedUIThread;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    50
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    51
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    52
     * Boolean used to detect when the runtime wants to bring the UI down and
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    53
     * the event loop must come down also. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    54
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    55
    private static volatile boolean shuttingDownReceived;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    56
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    57
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    58
     * Boolean used to store if starting has been attempted already. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    59
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    60
    private static boolean started;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    61
    
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    62
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    63
     * Runnable that gets called in the UI thread when starting up. Named 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    64
     * class declared to be able to make it static. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    65
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    66
    private static final class LoopRunner implements Runnable {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    67
        public void run() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    68
            EventLoop.run();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    69
        }       
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    70
    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    71
    
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    72
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    73
     * Not to be instantiated. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    74
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    75
    private EventLoop() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    76
    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    77
    
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    78
    /**
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    79
     * Returns the internal Display owned by the EventLoop class. Caller must 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    80
     * not dispose it. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    81
     * @return The internal Display instance
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    82
     * @throws RuntimeException
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    83
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    84
    public static Display getInternalDisplay() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    85
        synchronized(EventLoop.class) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    86
            ensureStartedOrThrow();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    87
            return internalDisplay;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    88
        }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    89
    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    90
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    91
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    92
     * Starts the event loop. If this returns without throwing then the 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    93
     * internal Display instance has been successfully created and can be 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    94
     * asked with getInternalDisplay().
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    95
     * 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    96
     * Any calls after the first successful call are ignored. Any calls after
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    97
     * the first failed call will not retry but will throw.
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    98
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
    99
    private static void ensureStartedOrThrow() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   100
        // This is called synchronized with the Display creation that takes 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   101
        // place in the UI thread. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   102
        
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   103
        if(!started) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   104
            started = true;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   105
            
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   106
            // Start the UI thread
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   107
            if(!UIThreadLauncher.startInUIThread(new LoopRunner())) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   108
                // Failed to create the UI thread, release the starting thread
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   109
                EventLoop.class.notify();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   110
            }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   111
            
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   112
            // Wait until the Display gets created in the UI thread
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   113
            try {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   114
                EventLoop.class.wait();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   115
            } catch(InterruptedException e) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   116
                // Nothing to do
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   117
            }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   118
        }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   119
        
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   120
        // Check Display creation status
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   121
        if(internalDisplay == null) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   122
            throw new RuntimeException("Failed to start");
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   123
        }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   124
    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   125
    
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   126
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   127
     * Start listening for the application requesting the UI thread via the
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   128
     * eSWT's UIThreadSupport API. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   129
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   130
    private static void listenApplicationUIThreadRequest() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   131
        UIThreadHandOverManager.setApplicationUIListener(new ApplicationUIListener() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   132
            /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   133
             * Can get called in any thread but the UI thread. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   134
             */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   135
            public void applicationUIThreadRequest() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   136
                // Synchronized with the Display creation and destruction
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   137
                synchronized(EventLoop.class) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   138
                    applicationRequestedUIThread = true;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   139
                    // It's ok to skip wake if Display has not been created yet
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   140
                    if(internalDisplay != null && !internalDisplay.isDisposed()) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   141
                        internalDisplay.wake();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   142
                    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   143
                }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   144
            }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   145
        });
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   146
    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   147
    
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   148
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   149
     * Start listening for the runtime's shutting down message. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   150
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   151
    private static void listenRuntimeShutdownRequest() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   152
        ApplicationUtils.getInstance().addShutdownListener(
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   153
            /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   154
             * Can get called in any thread but the UI thread. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   155
             */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   156
            new ShutdownListener() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   157
                public void shuttingDown() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   158
                    // Synchronized with the Display creation and destruction
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   159
                    synchronized(EventLoop.class) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   160
                        shuttingDownReceived = true;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   161
                        // It's ok to skip wake if Display has not been created yet
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   162
                        if(internalDisplay != null && !internalDisplay.isDisposed()) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   163
                            internalDisplay.wake();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   164
                        }       
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   165
                    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   166
                }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   167
            });
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   168
    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   169
    
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   170
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   171
     * Creates the internal Display and runs the event loop. Called in the UI 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   172
     * thread. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   173
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   174
    private static void run() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   175
        try {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   176
            // Add the appropriate listeners. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   177
            listenRuntimeShutdownRequest();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   178
            listenApplicationUIThreadRequest();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   179
            
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   180
            // Create the internal Display. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   181
            createInternalDisplay();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   182
    
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   183
            // Run event loop until the application wants to take over or the 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   184
            // runtime signals shutdown. In the latter case exit from the UI 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   185
            // thread immediately. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   186
            loop(PRE_APPLICATION);
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   187
            if(shuttingDownReceived) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   188
                return;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   189
            }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   190
            
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   191
            // Hand over the UI thread to the application. The application is
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   192
            // responsible of the event loop until it allows the UI thread to
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   193
            // return back here. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   194
            UIThreadHandOverManager.runApplicationUI();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   195
            
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   196
            // Application allowed its event loop to exit. Continue 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   197
            // dispatching the events until the runtime wants to shut down. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   198
            loop(POST_APPLICATION);
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   199
            
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   200
        } finally {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   201
            destroy();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   202
        }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   203
    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   204
    
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   205
    /* 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   206
     * Creates the Display. Synchronized with the starting thread that 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   207
     * waits until the Display has been created. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   208
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   209
    private static void createInternalDisplay() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   210
        synchronized(EventLoop.class) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   211
            try {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   212
                // Will throw if fails
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   213
                internalDisplay = Internal_PackageSupport.internalInstance();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   214
            } finally {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   215
                // Release the starting thread
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   216
                EventLoop.class.notify();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   217
            }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   218
        }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   219
    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   220
    
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   221
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   222
     * Frees all the owned resources when shutting down. Ideally this would be
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   223
     * executed only after all the application's threads have been finalized. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   224
     * If the application's threads are still running it's possible that 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   225
     * someone would try to access the internal Display after this. This would 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   226
     * cause an exception with "device is disposed".
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   227
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   228
    private static void destroy() {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   229
        // Synchronized with the shutting down message and the application UI 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   230
        // thread request. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   231
        synchronized(EventLoop.class) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   232
            if(internalDisplay != null) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   233
                // If this throws then Display.dispose() was called on the 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   234
                // internal Display by someone who doesn't own it. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   235
                if(internalDisplay.isDisposed()) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   236
                    throw new RuntimeException(
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   237
                            "Internal Display has been disposed by someone who " +
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   238
                            "doesn't own it");
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   239
                }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   240
                
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   241
                // If the application's Display has been disposed then 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   242
                // disposing also the internal Display here would destroy the 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   243
                // QApplication and all the UI resources tied to it. Disposing 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   244
                // is not done but the resources are allowed to leak on 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   245
                // purpose:
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   246
                //
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   247
                // In MIDP many of the related APIs are thread-safe and are 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   248
                // exclusively using garbage collection for memory management. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   249
                // Disposing the UI resources of API objects that still may be 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   250
                // referenced would create a deviation from the pattern and 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   251
                // that would need special handling all around the API 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   252
                // implementations. That handling is not attempted but instead 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   253
                // the internal Display instance is allowed to live until the 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   254
                // process terminates. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   255
            }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   256
        }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   257
    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   258
    
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   259
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   260
     * The event loop that can run before and after the application's loop. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   261
     * State parameter tells which one of the two this is. The exit 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   262
     * condition depends on the state. 
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   263
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   264
    private static void loop(final int state) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   265
        while(!loopExitCondition(state)) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   266
            if(!internalDisplay.readAndDispatch()) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   267
                internalDisplay.sleep();
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   268
            }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   269
        }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   270
    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   271
    
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   272
    /*
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   273
     * Checks if the loop exit condition is met. The condition is different
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   274
     * depending on if the loop is running before or after the application's
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   275
     * loop.
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   276
     */
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   277
    private static boolean loopExitCondition(final int state) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   278
        switch(state) {
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   279
        case PRE_APPLICATION:
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   280
            return shuttingDownReceived || applicationRequestedUIThread;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   281
        case POST_APPLICATION:
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   282
            return shuttingDownReceived;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   283
        default:
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   284
            return true;
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   285
        }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   286
    }
71ad690e91f5 v2.2.17_1
hgs
parents:
diff changeset
   287
}