Project

General

Profile

« Previous | Next » 

Revision de25bed3

Added by Leszek Koltunski 1 day ago

Convert EffectMessageSender to Kotlin Coroutines.

View differences:

build.gradle
8 8
            keyAlias = 'distorted'
9 9
        }
10 10
    }
11
    compileSdk 35
11
    compileSdk 36
12 12

  
13 13
    defaultConfig {
14 14
        minSdkVersion 21
......
33 33
    kotlinOptions {
34 34
        jvmTarget = '11'
35 35
    }
36

  
37
    dependencies {
38
        implementation(libs.kotlinx.coroutines.core.v190)
39
    }
40

  
36 41
}
src/main/java/org/distorted/library/effectqueue/EffectQueueFragment.kt
23 23
import android.opengl.GLES30
24 24
import org.distorted.library.effect.EffectType
25 25
import org.distorted.library.effect.FragmentEffect
26
import org.distorted.library.message.EffectMessageSender.Companion.newMessage
26
import org.distorted.library.message.EffectMessageSender
27 27

  
28 28
///////////////////////////////////////////////////////////////////////////////////////////////////
29 29
internal class EffectQueueFragment : EffectQueue
......
61 61

  
62 62
            for (i in 0..<numEffects)
63 63
                if (mEffects[i]!!.compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step))
64
                    newMessage(mEffects[i]!!)
64
                    EffectMessageSender.newMessage(mEffects[i]!!)
65 65
        }
66 66
    }
67 67

  
src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.kt
24 24
import org.distorted.library.effect.EffectType
25 25
import org.distorted.library.effect.MatrixEffect
26 26
import org.distorted.library.helpers.MatrixHelper.multiply
27
import org.distorted.library.message.EffectMessageSender.Companion.newMessage
27
import org.distorted.library.message.EffectMessageSender
28 28

  
29 29
///////////////////////////////////////////////////////////////////////////////////////////////////
30 30

  
......
66 66

  
67 67
            for (i in 0..<numEffects)
68 68
                if (mEffects[i]!!.compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step))
69
                    newMessage(mEffects[i]!!)
69
                    EffectMessageSender.newMessage(mEffects[i]!!)
70 70
        }
71 71
    }
72 72

  
src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.kt
30 30
import org.distorted.library.main.InternalOutputSurface
31 31
import org.distorted.library.main.InternalRenderState
32 32
import org.distorted.library.mesh.MeshBase
33
import org.distorted.library.message.EffectMessageSender.Companion.newMessage
33
import org.distorted.library.message.EffectMessageSender
34 34
import org.distorted.library.program.DistortedProgram
35 35
import java.io.InputStream
36 36

  
......
136 136
            val effect = mEffects[i] as PostprocessEffect
137 137

  
138 138
            if (effect.compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step))
139
                newMessage(mEffects[i]!!)
139
                EffectMessageSender.newMessage(mEffects[i]!!)
140 140

  
141 141
            halo = array[NUM_FLOAT_UNIFORMS*i].toInt()
142 142
            if (halo>mHalo) mHalo = halo
src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.kt
23 23
import android.opengl.GLES30
24 24
import org.distorted.library.effect.EffectType
25 25
import org.distorted.library.effect.VertexEffect
26
import org.distorted.library.message.EffectMessageSender.Companion.newMessage
26
import org.distorted.library.message.EffectMessageSender
27 27

  
28 28
///////////////////////////////////////////////////////////////////////////////////////////////////
29 29
/** Not part of public API, do not document (public only because has to be used in Meshes)
......
71 71

  
72 72
            for (i in 0..<numEffects)
73 73
                if (mEffects[i]!!.compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step))
74
                    newMessage(mEffects[i]!!)
74
                    EffectMessageSender.newMessage(mEffects[i]!!)
75 75

  
76 76
            mUBF!!.invalidate()
77 77
        }
src/main/java/org/distorted/library/main/DistortedLibrary.kt
43 43
import org.distorted.library.mesh.MeshBase
44 44
import org.distorted.library.mesh.MeshBase.Companion.maxEffComponents
45 45
import org.distorted.library.mesh.MeshBase.Companion.useCenters
46
import org.distorted.library.message.EffectMessageSender.Companion.startSending
46
import org.distorted.library.message.EffectMessageSender
47 47
import org.distorted.library.program.DistortedProgram
48 48
import org.distorted.library.program.VertexCompilationException
49 49
import org.distorted.library.type.Dynamic
......
1038 1038
        mOITCompilationAttempted = false
1039 1039

  
1040 1040
        detectBuggyDriversAndSetQueueSize(queueSize)
1041
        startSending()
1041
        EffectMessageSender.startSending()
1042 1042

  
1043 1043
        try
1044 1044
        {
src/main/java/org/distorted/library/main/InternalStackFrameList.kt
20 20
package org.distorted.library.main
21 21

  
22 22
import org.distorted.library.main.InternalMaster.Slave
23
import org.distorted.library.message.EffectMessageSender.Companion.stopSending
23
import org.distorted.library.message.EffectMessageSender
24 24

  
25 25
///////////////////////////////////////////////////////////////////////////////////////////////////
26 26
/**
......
132 132
        }
133 133

  
134 134
        isInitialized = false
135
        if (num<2) stopSending()
135
        if (num<2) EffectMessageSender.stopSending()
136 136
    }
137 137

  
138 138
    ///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/message/EffectMessageSender.kt
21 21
package org.distorted.library.message
22 22

  
23 23
import org.distorted.library.effect.Effect
24
import java.util.Vector
25
import kotlin.concurrent.Volatile
24
import kotlinx.coroutines.*
25
import kotlinx.coroutines.channels.Channel
26 26

  
27 27
///////////////////////////////////////////////////////////////////////////////////////////////////
28
/**
29
 * Not part of public API, do not document (public only because has to be used in Meshes)
30
 *
31
 * @y.exclude
32
 */
33
class EffectMessageSender
34
private constructor() : Thread()
28

  
29
object EffectMessageSender
35 30
{
36
    private class Message (var mListener: EffectListener, var mEffectID: Long)
31
    private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
32
    private val channel = Channel<Message>(Channel.UNLIMITED)
33
    private data class Message(val listener: EffectListener, val effectID: Long)
34
    private var job: Job? = null
37 35

  
38
    override fun run()
36
    fun startSending()
39 37
    {
40
        var tmp: Message
41

  
42
        while (mThis!=null)
38
        if( job==null )
43 39
        {
44
            while (!mList!!.isEmpty())
45
            {
46
                tmp = mList!!.removeAt(0)
47
                tmp.mListener.effectFinished(tmp.mEffectID)
48
            }
49

  
50
            synchronized(mLock)
51
            {
52
                if (!mNotify)
53
                {
54
                    try { mLock.wait() }
55
                    catch (_: InterruptedException) { }
56
                }
57
                mNotify = false
40
            job = scope.launch {
41
                for (msg in channel) msg.listener.effectFinished(msg.effectID)
58 42
            }
59 43
        }
60

  
61
        mList!!.clear()
62 44
    }
63 45

  
64
    companion object
46
    fun stopSending()
65 47
    {
66
        private val mLock = Object()
67
        private var mList: Vector<Message>? = null
68
        private var mThis: EffectMessageSender? = null
69

  
70
        @Volatile
71
        private var mNotify = false
72

  
73
        // debug only, to be removed later
74
        private var mNumStarts       = 0
75
        private var mStartTime: Long = 0
76
        private var mStopTime: Long  = 0
77

  
78
        fun startSending()
79
        {
80
            synchronized(mLock)
81
            {
82
                if (mThis==null)
83
                {
84
                    mStartTime = System.currentTimeMillis()
85
                    mNumStarts++
86

  
87
                    mList = Vector()
88
                    mThis = EffectMessageSender()
89
                    mThis!!.start()
90
                }
91
            }
92
        }
93

  
94
        fun stopSending()
95
        {
96
            synchronized(mLock)
97
            {
98
                if (mThis!=null)
99
                {
100
                    mStopTime = System.currentTimeMillis()
101
                    mNumStarts--
48
        job?.cancel()
49
        job = null
102 50

  
103
                    mThis = null
104
                    mLock.notify()
105
                }
106
            }
107
        }
108

  
109
        fun newMessage(effect: Effect)
110
        {
111
            val numListeners = effect.numListeners
112

  
113
            if (numListeners>0)
114
            {
115
                val id = effect.iD
116

  
117
                for (i in 0 until numListeners)
118
                {
119
                    val listener = effect.removeFirstListener()
120
                    val msg = Message(listener!!, id)
121
                    mList!!.add(msg)
122
                }
123

  
124
                synchronized(mLock)
125
                {
126
                    mNotify = true
127
                    mLock.notify()
128
                }
129
            }
130
        }
131

  
132
        val isRunning: Boolean
133
            get() = mThis!=null
134

  
135
        fun restartThread()
51
        while (true) // drain the channel
136 52
        {
137
            synchronized(mLock)
138
            {
139
                if (mThis==null)
140
                {
141
                    if (mList==null) mList = Vector()
142
                    mThis = EffectMessageSender()
143
                    mThis!!.start()
144
                }
145
            }
53
            val msg = channel.tryReceive().getOrNull() ?: break
146 54
        }
55
    }
147 56

  
148
        fun reportState(): String
57
    fun newMessage(effect: Effect)
58
    {
59
        repeat(effect.numListeners)
149 60
        {
150
            return "running "+(mThis!=null)+" notify="+mNotify+" elements="+mList!!.size+
151
                    " start="+mStartTime+" stop="+mStopTime+" numStarts="+mNumStarts
61
            val listener = effect.removeFirstListener() ?: return
62
            channel.trySend(Message(listener, effect.iD))
152 63
        }
153 64
    }
154 65
}

Also available in: Unified diff