Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ open class AnimView @JvmOverloads constructor(context: Context, attrs: Attribute
player.pluginManager.getMixAnimPlugin()?.resourceRequest = fetchResource
}

override fun setFetchResourceAsync(async: Boolean) {
player.pluginManager.getMixAnimPlugin()?.async = async
}

override fun setOnResourceClickListener(resourceClickListener: OnResourceClickListener?) {
player.pluginManager.getMixAnimPlugin()?.resourceClickListener = resourceClickListener
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ interface IAnimView {

fun setFetchResource(fetchResource: IFetchResource?)

fun setFetchResourceAsync(async: Boolean)

fun setOnResourceClickListener(resourceClickListener: OnResourceClickListener?)

fun setLoop(playLoop: Int)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.tencent.qgame.animplayer.mix

interface IMixResourceRequest {
fun fetchResource(): Int
fun destroy()
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@
*/
package com.tencent.qgame.animplayer.mix

import android.graphics.Bitmap
import android.os.Handler
import android.os.Looper
import android.os.SystemClock
import android.view.MotionEvent
import com.tencent.qgame.animplayer.AnimConfig
import com.tencent.qgame.animplayer.AnimPlayer
Expand All @@ -27,7 +25,6 @@ import com.tencent.qgame.animplayer.inter.IFetchResource
import com.tencent.qgame.animplayer.inter.OnResourceClickListener
import com.tencent.qgame.animplayer.plugin.IAnimPlugin
import com.tencent.qgame.animplayer.util.ALog
import com.tencent.qgame.animplayer.util.BitmapUtil

class MixAnimPlugin(val player: AnimPlayer): IAnimPlugin {

Expand All @@ -39,15 +36,12 @@ class MixAnimPlugin(val player: AnimPlayer): IAnimPlugin {
var srcMap: SrcMap? = null
var frameAll: FrameAll? = null
var curFrameIndex = -1 // 当前帧
private var resultCbCount = 0 // 回调次数
private var mixRender:MixRender? = null
private val mixTouch by lazy { MixTouch(this) }
var autoTxtColorFill = true // 是否启动自动文字填充 默认开启

// 同步锁
private val lock = Object()
private var forceStopLock = false

var async: Boolean = false
private var mixResourceRequest: IMixResourceRequest? = null

override fun onConfigCreate(config: AnimConfig): Int {
if (!config.isMix) return Constant.OK
Expand All @@ -62,27 +56,16 @@ class MixAnimPlugin(val player: AnimPlayer): IAnimPlugin {
// step 2 parse frame
parseFrame(config)

// step 3 fetch resource
fetchResourceSync()
mixResourceRequest = createMixResourceRequest()
return mixResourceRequest?.fetchResource() ?: Constant.OK
}

// step 4 生成文字bitmap
val result = createBitmap()
if (!result) {
return Constant.REPORT_ERROR_TYPE_CONFIG_PLUGIN_MIX
private fun createMixResourceRequest(): IMixResourceRequest {
return if (async) {
MixResourceRequestASync(resourceRequest, srcMap)
} else {
MixResourceRequestSync(resourceRequest, srcMap)
}

// step 5 check resource
ALog.i(TAG, "load resource $resultCbCount")
srcMap?.map?.values?.forEach {
if (it.bitmap == null) {
ALog.e(TAG, "missing src $it")
return Constant.REPORT_ERROR_TYPE_CONFIG_PLUGIN_MIX
} else if (it.bitmap?.config == Bitmap.Config.ALPHA_8) {
ALog.e(TAG, "src $it bitmap must not be ALPHA_8")
return Constant.REPORT_ERROR_TYPE_CONFIG_PLUGIN_MIX
}
}
return Constant.OK
}

override fun onRenderCreate() {
Expand Down Expand Up @@ -126,8 +109,7 @@ class MixAnimPlugin(val player: AnimPlayer): IAnimPlugin {
}

private fun destroy() {
// 强制结束等待
forceStopLockThread()
mixResourceRequest?.destroy()
if (player.configManager.config?.isMix == false) return
val resources = ArrayList<Resource>()
srcMap?.map?.values?.forEach {src ->
Expand Down Expand Up @@ -159,71 +141,4 @@ class MixAnimPlugin(val player: AnimPlayer): IAnimPlugin {
}
}


private fun fetchResourceSync() {
synchronized(lock) {
forceStopLock = false // 开始时不会强制关闭
}
val time = SystemClock.elapsedRealtime()
val totalSrc = srcMap?.map?.size ?: 0
ALog.i(TAG, "load resource totalSrc = $totalSrc")

resultCbCount = 0
srcMap?.map?.values?.forEach {src ->
if (src.srcType == Src.SrcType.IMG) {
ALog.i(TAG, "fetch image ${src.srcId}")
resourceRequest?.fetchImage(Resource(src)) {
src.bitmap = if (it == null) {
ALog.e(TAG, "fetch image ${src.srcId} bitmap return null")
BitmapUtil.createEmptyBitmap()
} else it
ALog.i(TAG, "fetch image ${src.srcId} finish bitmap is ${it?.hashCode()}")
resultCall()
}
} else if (src.srcType == Src.SrcType.TXT) {
ALog.i(TAG, "fetch txt ${src.srcId}")
resourceRequest?.fetchText(Resource(src)) {
src.txt = it ?: ""
ALog.i(TAG, "fetch text ${src.srcId} finish txt is $it")
resultCall()
}
}
}

// 同步等待所有资源完成
synchronized(lock) {
while (resultCbCount < totalSrc && !forceStopLock) {
lock.wait()
}
}
ALog.i(TAG, "fetchResourceSync cost=${SystemClock.elapsedRealtime() - time}ms")
}

private fun forceStopLockThread() {
synchronized(lock) {
forceStopLock = true
lock.notifyAll()
}
}

private fun resultCall() {
synchronized(lock) {
resultCbCount++
lock.notifyAll()
}
}

private fun createBitmap(): Boolean {
return try {
srcMap?.map?.values?.forEach { src ->
if (src.srcType == Src.SrcType.TXT) {
src.bitmap = BitmapUtil.createTxtBitmap(src)
}
}
true
} catch (e: OutOfMemoryError) {
ALog.e(TAG, "draw text OOM $e", e)
false
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.tencent.qgame.animplayer.mix

import android.graphics.Bitmap
import android.os.Handler
import android.os.SystemClock
import com.tencent.qgame.animplayer.Constant
import com.tencent.qgame.animplayer.inter.IFetchResource
import com.tencent.qgame.animplayer.util.ALog
import com.tencent.qgame.animplayer.util.BitmapUtil
import com.tencent.qgame.animplayer.util.TextureLoadUtil


class MixResourceRequestASync(
private val resourceRequest: IFetchResource?,
private val srcMap: SrcMap?
) :
IMixResourceRequest {
companion object {
private const val TAG = "${Constant.TAG}.MixResourceRequestASync"
}

private var resultCbCount = 0 // 回调次数

var handler: Handler? = null

override fun fetchResource(): Int {
fetchResourceASync()

ALog.i(TAG, "load resource $resultCbCount")
srcMap?.map?.values?.forEach {
if (it.bitmap?.config == Bitmap.Config.ALPHA_8) {
ALog.e(TAG, "src $it bitmap must not be ALPHA_8")
return Constant.REPORT_ERROR_TYPE_CONFIG_PLUGIN_MIX
}
}
return Constant.OK
}

override fun destroy() {
handler = null
}

private fun fetchResourceASync() {
val time = SystemClock.elapsedRealtime()
val totalSrc = srcMap?.map?.size ?: 0
ALog.i(TAG, "load resource totalSrc = $totalSrc")

resultCbCount = 0
srcMap?.map?.values?.apply {
handler = Handler()
forEach { src ->
if (src.srcType == Src.SrcType.IMG) {
ALog.i(TAG, "fetch image ${src.srcId}")
resourceRequest?.fetchImage(Resource(src)) {
handler?.post {
src.bitmap = if (it == null) {
ALog.e(TAG, "fetch image ${src.srcId} bitmap return null")
BitmapUtil.createEmptyBitmap()
} else it
src.srcTextureId = TextureLoadUtil.loadTexture(src.bitmap)
ALog.i(
TAG,
"fetch image ${src.srcId} finish bitmap is ${it?.hashCode()}"
+ ",cost=${SystemClock.elapsedRealtime() - time}ms"
)
resultCall()
}
}
} else if (src.srcType == Src.SrcType.TXT) {
ALog.i(TAG, "fetch txt ${src.srcId}")
resourceRequest?.fetchText(Resource(src)) {
handler?.post {
src.txt = it ?: ""
try {
src.bitmap = BitmapUtil.createTxtBitmap(src)
src.srcTextureId = TextureLoadUtil.loadTexture(src.bitmap)
} catch (e: OutOfMemoryError) {
ALog.e(TAG, "draw text OOM $e", e)
}
ALog.i(
TAG, "fetch text ${src.srcId} finish txt is $it"
+ ",cost=${SystemClock.elapsedRealtime() - time}ms"
)
resultCall()
}
}
}
}
}
}

private fun resultCall() {
resultCbCount++
}

}
Loading