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