1+ /*
2+ * Copyright (C) 2020-2025 DiffPlug
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * https://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+ package com.diffplug.durian.swt.coroutines
17+
18+ import com.diffplug.common.swt.SwtExec
19+ import kotlinx.coroutines.InternalCoroutinesApi
20+ import kotlinx.coroutines.MainCoroutineDispatcher
21+ import kotlinx.coroutines.internal.MainDispatcherFactory
22+ import org.eclipse.swt.widgets.Display
23+
24+ /* *
25+ * Factory for creating SWT-based main coroutine dispatcher.
26+ *
27+ * This factory integrates SWT's UI thread with Kotlin coroutines by providing
28+ * the SWT Display thread as the main dispatcher. When this library is on the
29+ * classpath, coroutines launched on Dispatchers.Main will automatically execute
30+ * on the SWT UI thread.
31+ *
32+ * The factory uses [SwtExec.immediate] which provides optimal performance:
33+ * - Executes immediately when already on the SWT thread
34+ * - Uses Display.asyncExec for cross-thread dispatch
35+ *
36+ * @see SwtExec.immediate
37+ */
38+ @OptIn(InternalCoroutinesApi ::class )
39+ class SwtMainDispatcherFactory : MainDispatcherFactory {
40+
41+ /* *
42+ * Load order priority for this factory.
43+ * Higher values have higher priority. Using a moderate value to allow
44+ * other UI toolkit factories to potentially override if needed.
45+ */
46+ override val loadPriority: Int = 100
47+
48+ /* *
49+ * Creates the main dispatcher if SWT Display is available.
50+ *
51+ * @param allFactories All available main dispatcher factories (unused)
52+ * @return SWT-based main dispatcher
53+ * @throws IllegalStateException if SWT Display is not available
54+ */
55+ override fun createDispatcher (allFactories : List <MainDispatcherFactory >): MainCoroutineDispatcher {
56+ try {
57+ // Try to get the default Display - this will fail if SWT is not properly initialized
58+ // or if we're in a headless environment
59+ Display .getDefault()
60+
61+ // If we got here successfully, SWT is available
62+ // Return the dispatcher from SwtExec.immediate() which provides optimal thread handling
63+ return SwtExec .immediate().rxExecutor.dispatcher as MainCoroutineDispatcher
64+ } catch (e: Exception ) {
65+ // SWT Display is not available (headless environment, not initialized, etc.)
66+ // Throw an exception as the interface no longer supports nullable returns
67+ throw IllegalStateException (" SWT Display is not available" , e)
68+ }
69+ }
70+
71+ /* *
72+ * Hint about the expected dispatcher type.
73+ * Returns null since we throw an exception when SWT is not available.
74+ */
75+ override fun hintOnError (): String? = null
76+ }
0 commit comments