修复 画布canvas默认白色改成默认透明
修复 画布canvas会覆盖其他View的问题
This commit is contained in:
@@ -1,188 +0,0 @@
|
||||
package com.stardust.autojs.core.graphics;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
|
||||
import com.stardust.autojs.core.eventloop.EventEmitter;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2018/3/16.
|
||||
*/
|
||||
|
||||
@SuppressLint("ViewConstructor")
|
||||
public class ScriptCanvasView extends SurfaceView implements SurfaceHolder.Callback {
|
||||
|
||||
private static final String LOG_TAG = "ScriptCanvasView";
|
||||
private volatile boolean mDrawing = true;
|
||||
private EventEmitter mEventEmitter;
|
||||
private final SurfaceHolder mHolder;
|
||||
private ExecutorService mDrawingThreadPool;
|
||||
private ScriptRuntime mScriptRuntime;
|
||||
private volatile long mTimePerDraw = 1000 / 30;
|
||||
|
||||
public ScriptCanvasView(Context context, ScriptRuntime scriptRuntime) {
|
||||
super(context);
|
||||
mScriptRuntime = scriptRuntime;
|
||||
mEventEmitter = new EventEmitter(mScriptRuntime.bridges);
|
||||
mHolder = getHolder();
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
public void setMaxFps(int maxFps) {
|
||||
if (maxFps <= 0) {
|
||||
mTimePerDraw = 0;
|
||||
} else {
|
||||
mTimePerDraw = 100 / maxFps;
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mHolder.addCallback(this);
|
||||
setZOrderOnTop(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
performDraw();
|
||||
Log.d(LOG_TAG, "surfaceCreated: " + this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
private synchronized void performDraw() {
|
||||
if (mDrawingThreadPool != null)
|
||||
return;
|
||||
mDrawingThreadPool = Executors.newCachedThreadPool();
|
||||
mDrawingThreadPool.execute(() -> {
|
||||
Canvas canvas = null;
|
||||
SurfaceHolder holder = getHolder();
|
||||
long time = SystemClock.uptimeMillis();
|
||||
ScriptCanvas scriptCanvas = new ScriptCanvas();
|
||||
try {
|
||||
while (mDrawing) {
|
||||
canvas = holder.lockCanvas();
|
||||
scriptCanvas.setCanvas(canvas);
|
||||
scriptCanvas.drawColor(Color.WHITE);
|
||||
emit("draw", scriptCanvas, ScriptCanvasView.this);
|
||||
holder.unlockCanvasAndPost(canvas);
|
||||
canvas = null;
|
||||
long dt = mTimePerDraw - (SystemClock.uptimeMillis() - time);
|
||||
if (dt > 0) {
|
||||
sleep(dt);
|
||||
}
|
||||
time = SystemClock.uptimeMillis();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
mScriptRuntime.exit(e);
|
||||
mDrawing = false;
|
||||
} finally {
|
||||
if (canvas != null) {
|
||||
holder.unlockCanvasAndPost(canvas);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void sleep(long dt) {
|
||||
try {
|
||||
Thread.sleep(dt);
|
||||
} catch (InterruptedException e) {
|
||||
throw new ScriptInterruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onWindowVisibilityChanged(int visibility) {
|
||||
Log.d(LOG_TAG, "onWindowVisibilityChanged: " + this + ": visibility=" + visibility + ", mDrawingThreadPool=" + mDrawingThreadPool);
|
||||
if (visibility == VISIBLE) {
|
||||
mDrawing = true;
|
||||
} else {
|
||||
mDrawing = false;
|
||||
}
|
||||
super.onWindowVisibilityChanged(visibility);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void surfaceDestroyed(SurfaceHolder holder) {
|
||||
mDrawing = false;
|
||||
mDrawingThreadPool.shutdown();
|
||||
mDrawingThreadPool = null;
|
||||
Log.d(LOG_TAG, "surfaceDestroyed: " + this);
|
||||
}
|
||||
|
||||
public EventEmitter once(String eventName, Object listener) {
|
||||
return mEventEmitter.once(eventName, listener);
|
||||
}
|
||||
|
||||
public EventEmitter on(String eventName, Object listener) {
|
||||
return mEventEmitter.on(eventName, listener);
|
||||
}
|
||||
|
||||
public EventEmitter addListener(String eventName, Object listener) {
|
||||
return mEventEmitter.addListener(eventName, listener);
|
||||
}
|
||||
|
||||
public boolean emit(String eventName, Object... args) {
|
||||
return mEventEmitter.emit(eventName, args);
|
||||
}
|
||||
|
||||
public String[] eventNames() {
|
||||
return mEventEmitter.eventNames();
|
||||
}
|
||||
|
||||
public int listenerCount(String eventName) {
|
||||
return mEventEmitter.listenerCount(eventName);
|
||||
}
|
||||
|
||||
public Object[] listeners(String eventName) {
|
||||
return mEventEmitter.listeners(eventName);
|
||||
}
|
||||
|
||||
public EventEmitter prependListener(String eventName, Object listener) {
|
||||
return mEventEmitter.prependListener(eventName, listener);
|
||||
}
|
||||
|
||||
public EventEmitter prependOnceListener(String eventName, Object listener) {
|
||||
return mEventEmitter.prependOnceListener(eventName, listener);
|
||||
}
|
||||
|
||||
public EventEmitter removeAllListeners() {
|
||||
return mEventEmitter.removeAllListeners();
|
||||
}
|
||||
|
||||
public EventEmitter removeAllListeners(String eventName) {
|
||||
return mEventEmitter.removeAllListeners(eventName);
|
||||
}
|
||||
|
||||
public EventEmitter removeListener(String eventName, Object listener) {
|
||||
return mEventEmitter.removeListener(eventName, listener);
|
||||
}
|
||||
|
||||
public EventEmitter setMaxListeners(int n) {
|
||||
return mEventEmitter.setMaxListeners(n);
|
||||
}
|
||||
|
||||
public int getMaxListeners() {
|
||||
return mEventEmitter.getMaxListeners();
|
||||
}
|
||||
|
||||
public static int defaultMaxListeners() {
|
||||
return EventEmitter.defaultMaxListeners();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
package com.stardust.autojs.core.graphics
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.SurfaceTexture
|
||||
import android.os.SystemClock
|
||||
import android.util.Log
|
||||
import android.view.TextureView
|
||||
import android.view.View
|
||||
import com.stardust.autojs.core.eventloop.EventEmitter
|
||||
import com.stardust.autojs.runtime.ScriptRuntime
|
||||
import com.stardust.autojs.runtime.exception.ScriptInterruptedException
|
||||
import com.stardust.ext.ifNull
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2018/3/16.
|
||||
*/
|
||||
|
||||
@SuppressLint("ViewConstructor")
|
||||
class ScriptCanvasView(context: Context, private val mScriptRuntime: ScriptRuntime) : TextureView(context), TextureView.SurfaceTextureListener {
|
||||
@Volatile
|
||||
private var mDrawing = true
|
||||
private val mEventEmitter: EventEmitter = EventEmitter(mScriptRuntime.bridges)
|
||||
private var mDrawingThreadPool: ExecutorService? = null
|
||||
@Volatile
|
||||
private var mTimePerDraw = (1000 / 30).toLong()
|
||||
|
||||
val maxListeners: Int
|
||||
get() = mEventEmitter.maxListeners
|
||||
|
||||
init {
|
||||
surfaceTextureListener = this
|
||||
}
|
||||
|
||||
fun setMaxFps(maxFps: Int) {
|
||||
mTimePerDraw = if (maxFps <= 0) {
|
||||
0
|
||||
} else {
|
||||
(100 / maxFps).toLong()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun performDraw() {
|
||||
::mDrawingThreadPool.ifNull {
|
||||
Executors.newCachedThreadPool()
|
||||
}.run {
|
||||
execute {
|
||||
var canvas: Canvas? = null
|
||||
var time = SystemClock.uptimeMillis()
|
||||
val scriptCanvas = ScriptCanvas()
|
||||
try {
|
||||
while (mDrawing) {
|
||||
canvas = lockCanvas()
|
||||
scriptCanvas.setCanvas(canvas)
|
||||
// scriptCanvas.drawColor(Color.WHITE);
|
||||
emit("draw", scriptCanvas, this@ScriptCanvasView)
|
||||
unlockCanvasAndPost(canvas)
|
||||
canvas = null
|
||||
val dt = mTimePerDraw - (SystemClock.uptimeMillis() - time)
|
||||
if (dt > 0) {
|
||||
sleep(dt)
|
||||
}
|
||||
time = SystemClock.uptimeMillis()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
mScriptRuntime.exit(e)
|
||||
mDrawing = false
|
||||
} finally {
|
||||
if (canvas != null) {
|
||||
unlockCanvasAndPost(canvas)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sleep(dt: Long) {
|
||||
try {
|
||||
Thread.sleep(dt)
|
||||
} catch (e: InterruptedException) {
|
||||
throw ScriptInterruptedException(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onWindowVisibilityChanged(visibility: Int) {
|
||||
Log.d(LOG_TAG, "onWindowVisibilityChanged: " + this + ": visibility=" + visibility + ", mDrawingThreadPool=" + mDrawingThreadPool)
|
||||
val oldDrawing = mDrawing
|
||||
mDrawing = visibility == View.VISIBLE
|
||||
if (!oldDrawing && mDrawing) {
|
||||
performDraw()
|
||||
}
|
||||
super.onWindowVisibilityChanged(visibility)
|
||||
}
|
||||
|
||||
fun once(eventName: String, listener: Any): EventEmitter {
|
||||
return mEventEmitter.once(eventName, listener)
|
||||
}
|
||||
|
||||
fun on(eventName: String, listener: Any): EventEmitter {
|
||||
return mEventEmitter.on(eventName, listener)
|
||||
}
|
||||
|
||||
fun addListener(eventName: String, listener: Any): EventEmitter {
|
||||
return mEventEmitter.addListener(eventName, listener)
|
||||
}
|
||||
|
||||
fun emit(eventName: String, vararg args: Any): Boolean {
|
||||
return mEventEmitter.emit(eventName, *args)
|
||||
}
|
||||
|
||||
fun eventNames(): Array<String> {
|
||||
return mEventEmitter.eventNames()
|
||||
}
|
||||
|
||||
fun listenerCount(eventName: String): Int {
|
||||
return mEventEmitter.listenerCount(eventName)
|
||||
}
|
||||
|
||||
fun listeners(eventName: String): Array<Any> {
|
||||
return mEventEmitter.listeners(eventName)
|
||||
}
|
||||
|
||||
fun prependListener(eventName: String, listener: Any): EventEmitter {
|
||||
return mEventEmitter.prependListener(eventName, listener)
|
||||
}
|
||||
|
||||
fun prependOnceListener(eventName: String, listener: Any): EventEmitter {
|
||||
return mEventEmitter.prependOnceListener(eventName, listener)
|
||||
}
|
||||
|
||||
fun removeAllListeners(): EventEmitter {
|
||||
return mEventEmitter.removeAllListeners()
|
||||
}
|
||||
|
||||
fun removeAllListeners(eventName: String): EventEmitter {
|
||||
return mEventEmitter.removeAllListeners(eventName)
|
||||
}
|
||||
|
||||
fun removeListener(eventName: String, listener: Any): EventEmitter {
|
||||
return mEventEmitter.removeListener(eventName, listener)
|
||||
}
|
||||
|
||||
fun setMaxListeners(n: Int): EventEmitter {
|
||||
return mEventEmitter.setMaxListeners(n)
|
||||
}
|
||||
|
||||
override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int) {
|
||||
performDraw()
|
||||
Log.d(LOG_TAG, "onSurfaceTextureAvailable: ${this}, width = $width, height = $height")
|
||||
}
|
||||
|
||||
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {}
|
||||
|
||||
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
|
||||
mDrawing = false
|
||||
mDrawingThreadPool?.shutdown()
|
||||
Log.d(LOG_TAG, "onSurfaceTextureDestroyed: ${this}")
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val LOG_TAG = "ScriptCanvasView"
|
||||
|
||||
fun defaultMaxListeners(): Int {
|
||||
return EventEmitter.defaultMaxListeners()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user