DanmakuFlameMaster 0.7.3版本更新部分总结

CacheManagingDrawTask.java

0.5.0   public void invalidateDanmaku(BaseDanmakudanmaku, boolean remeasure) {

if(mHandler != null) {

mHandler.requestCancelCaching();

Pair<BaseDanmaku, Boolean> pair = newPair<>(danmaku, remeasure);

mHandler.obtainMessage(CacheHandler.REBUILD_CACHE,pair).sendToTarget();

}

}

0.7.3   public voidinvalidateDanmaku(BaseDanmaku danmaku, boolean remeasure) {

if(mHandler != null) {

mHandler.requestCancelCaching();

mHandler.obtainMessage(CacheHandler.REBUILD_CACHE, danmaku).sendToTarget();

}

}

0.5.0的参数存储的是BaseDanmaku和Boolean类型的remaeasure值,

0.7.3的参数只保留了BaseDanmaku。

 

 

对应的CacheHandler中的handlerMessage处理方法:

0.5.0   case REBUILD_CACHE:

Pair<BaseDanmaku, Boolean>pair = (Pair<BaseDanmaku, Boolean>) msg.obj;

if (pair != null) {

BaseDanmaku cacheitem= pair.first;

if (pair.second) {

cacheitem.requestFlags |= BaseDanmaku.FLAG_REQUEST_REMEASURE;

cacheitem.measureResetFlag++;

}

cacheitem.requestFlags |=BaseDanmaku.FLAG_REQUEST_INVALIDATE;

IDrawingCache<?> cache =cacheitem.getDrawingCache();

if (!pair.second &&cache != null && cache.get() !=null && !cache.hasReferences()){

cache =DanmakuUtils.buildDanmakuDrawingCache(cacheitem, mDisp, (DrawingCache)cacheitem.cache);

cacheitem.cache = cache;

push(cacheitem, 0, true);

return;

}

if (cacheitem.isLive){

clearCache(cacheitem);

createCache(cacheitem);

} else {

entryRemoved(true, cacheitem, null);

addDanmakuAndBuildCache(cacheitem);

}

}

break;

 

0.7.3    case REBUILD_CACHE:

BaseDanmaku cacheitem =(BaseDanmaku) msg.obj;

if (cacheitem != null) {

IDrawingCache<?> cache = cacheitem.getDrawingCache();

boolean requestRemeasure = 0 != (cacheitem.requestFlags &BaseDanmaku.FLAG_REQUEST_REMEASURE);

if (!requestRemeasure &&cache != null && cache.get() !=null && !cache.hasReferences()){

cache =DanmakuUtils.buildDanmakuDrawingCache(cacheitem, mDisp, (DrawingCache)cacheitem.cache);

cacheitem.cache = cache;

push(cacheitem, 0, true);

return;

}

if(cacheitem.isLive) {

clearCache(cacheitem);

createCache(cacheitem);

} else {

if (cache != null &&cache.hasReferences()) {

cache.destroy();

}

entryRemoved(true,cacheitem, null);

addDanmakuAndBuildCache(cacheitem);

}

}

break;

新增代码:

if(cache != null && cache.hasReferences()) {

cache.destroy();

}

 

0.5.0中从Pair中取出了BaseDanmaku和Boolean remeasure,如果remeasure为ture则更新Baseitem的measureResetFlag值。

0.7.3中直接通过BaseDanmaku的requestFlags和FLAG_REQUEST_REMEASURE给自定义变量赋值,然后执行相应操作。

优点:代码更简洁。

 

0.5.0  private void evictAll() {

if(mCaches != null) {

IDanmakuIterator it = mCaches.iterator();

while (it.hasNext()) {

BaseDanmaku danmaku = it.next();

entryRemoved(true, danmaku, null);

}

mCaches.clear();

}

mRealSize = 0;

}

 

0.7.0  private void evictAll() {

if (mCaches != null) {

mCaches.forEach(new IDanmakus.DefaultConsumer<BaseDanmaku>() {

@Override

public int accept(BaseDanmaku danmaku) {

entryRemoved(true, danmaku, null);

return ACTION_CONTINUE;

}

});

mCaches.clear();

}

mRealSize = 0;

}

 

在evictAll函数中,0.5.0通过自定义的IDanmakuIterator遍历mCaches,然后执行  entryRemoved(true, danmaku, null);方法,0.7.3通过mCaches.forEach方法遍历mCaChe,并执行entryRemoved函数,其中forEach方法为Danmakus类添加的方法,用来遍历集合,其中的遍历方法封装了0.5.0中的IDanmakuIterator遍历方法。

 

0.5.0    private void evictAllNotInScreen(booleanremoveAllReferences)

if(mCaches != null) {

IDanmakuIterator it =mCaches.iterator();

while (it.hasNext()) {

BaseDanmaku danmaku = it.next();

IDrawingCache<?> cache =danmaku.cache;

boolean hasReferences = cache != null&& cache.hasReferences();

if (removeAllReferences &&hasReferences) {

if (cache.get() != null) {

mRealSize -= cache.size();

cache.destroy();

}

entryRemoved(true, danmaku, null);

it.remove();

continue;

}

if(danmaku.isOutside()) {

entryRemoved(true, danmaku, null);

it.remove();

}

}

// mCaches.clear();

}

mRealSize= 0;

 

0.7.3      private void evictAllNotInScreen(final booleanremoveAllReferences)

 if (mCaches != null) {

mCaches.forEach(newIDanmakus.DefaultConsumer<BaseDanmaku>() {

@Override

public int accept(BaseDanmakudanmaku) {

IDrawingCache<?> cache = danmaku.cache;

boolean hasReferences = cache != null&& cache.hasReferences();

if (removeAllReferences &&hasReferences) {

if (cache.get() != null) {

mRealSize -= cache.size();

cache.destroy();

}

entryRemoved(true, danmaku, null);

return ACTION_REMOVE;

}

if(danmaku.isOutside()) {

entryRemoved(true, danmaku, null);

return ACTION_REMOVE;

}

return ACTION_CONTINUE;

}

});

}

 

0.5.0通过自定义的IDanmakuIterator遍历mCaches

0.7.0通过Danmakus自定义的forEach()方法遍历mCaches

 

0.5.0    private boolean push(BaseDanmaku item, intitemSize, boolean forcePush) {

  while (mRealSize + size >mMaxSize && mCaches.size() > 0) {

BaseDanmaku oldValue = mCaches.first();

if (oldValue.isTimeOut()) {

entryRemoved(false, oldValue, item);

mCaches.removeItem(oldValue);

}

 

0.7.3     private boolean push(BaseDanmaku item, intitemSize, boolean forcePush) {

while (mRealSize + size > mMaxSize && oldValue != null) {

if (oldValue.isTimeOut()) {

entryRemoved(false, oldValue, item);

mCaches.removeItem(oldValue);

oldValue = mCaches.first();

 }

 

0.5.0中while判断mCaches.size()

0.7.3中while判断oldValue,如果oldValue超时,则调用mCaches.removeItem(),并重新给oldValue赋值。

 

0.5.0    private void clearTimeOutCaches() {

            clearTimeOutCaches(mTimer.currMillisecond);

        }

 

        private void clearTimeOutCaches(longtime) {

            IDanmakuIterator it =mCaches.iterator();

            while (it.hasNext() &&!mEndFlag) {

                BaseDanmaku val = it.next();

                if (val.isTimeOut()) {

                    synchronized(mDrawingNotify) {

                        try {

                           mDrawingNotify.wait(30);

                        } catch(InterruptedException e) {

                           e.printStackTrace();

                            break;

                        }

                    }

                    entryRemoved(false, val,null);

                    it.remove();

                } else {

                    break;

                }

            }

        }

 

0.7.3   private void clearTimeOutCaches() {

            mCaches.forEach(newIDanmakus.DefaultConsumer<BaseDanmaku>() {

                @Override

                public int accept(BaseDanmakuval) {

                    if (val.isTimeOut()) {

                        synchronized(mDrawingNotify) {

                            try {

                               mDrawingNotify.wait(30);

                            } catch(InterruptedException e) {

                               e.printStackTrace();

                                returnACTION_BREAK;

                            }

                        }

                        entryRemoved(false,val, null);

                        return ACTION_REMOVE;

                    } else {

                        return ACTION_BREAK;

                    }

                }

            });

        }

 

0.5.0中通过自定义的IDanmakuIterator遍历

0.7.3中通过forEach遍历。

 

0.5.0    private BaseDanmakufindReuseableCache(BaseDanmaku refDanmaku,

                                              boolean strictMode,

                                              int maximumTimes) {

            IDanmakuIterator it = mCaches.iterator();

            int slopPixel = 0;

            if (!strictMode) {

                slopPixel =mDisp.getSlopPixel() * 2;

            }

            int count = 0;

            while (it.hasNext() && count++ < maximumTimes){  // limit maximum times

                BaseDanmaku danmaku = it.next();

                IDrawingCache<?> cache =danmaku.getDrawingCache();

                if (cache == null ||cache.get() == null) {

                    continue;

                }

                if (danmaku.paintWidth ==refDanmaku.paintWidth

                        &&danmaku.paintHeight == refDanmaku.paintHeight

                        &&danmaku.underlineColor == refDanmaku.underlineColor

                        &&danmaku.borderColor == refDanmaku.borderColor

                        &&danmaku.textColor == refDanmaku.textColor

                        &&danmaku.text.equals(refDanmaku.text)) {

                    return danmaku;

                }

                if (strictMode) {

                    continue;

                }

                if (!danmaku.isTimeOut()) {

                    break;

                }

                if (cache.hasReferences()) {

                    continue;

                }

                float widthGap = cache.width()- refDanmaku.paintWidth;

                float heightGap =cache.height() - refDanmaku.paintHeight;

                if (widthGap >= 0 &&widthGap <= slopPixel &&

                        heightGap >= 0&& heightGap <= slopPixel) {

                    return danmaku;

                }

            }

            return null;

        }

 

0.7.3   private BaseDanmaku findReuseableCache(finalBaseDanmaku refDanmaku,

                                              final boolean strictMode,

                                              final int maximumTimes) {

            int slopPixel = 0;

            if (!strictMode) {

                slopPixel =mDisp.getSlopPixel() * 2;

            }

            final int finalSlopPixel = slopPixel;

            IDanmakus.Consumer<BaseDanmaku, BaseDanmaku>consumer = new IDanmakus.Consumer<BaseDanmaku, BaseDanmaku>() {

                int count = 0;

                BaseDanmaku mResult;

 

                @Override

                public BaseDanmaku result() {

                    return mResult;

                }

 

                @Override

                public int accept(BaseDanmakudanmaku) {

                    if (count++ >=maximumTimes) {

                        return ACTION_BREAK;

                    }

                    IDrawingCache<?>cache = danmaku.getDrawingCache();

                    if (cache == null ||cache.get() == null) {

                        return ACTION_CONTINUE;

                    }

                    if (danmaku.paintWidth ==refDanmaku.paintWidth

                            &&danmaku.paintHeight == refDanmaku.paintHeight

                            &&danmaku.underlineColor == refDanmaku.underlineColor

                            &&danmaku.borderColor == refDanmaku.borderColor

                            &&danmaku.textColor == refDanmaku.textColor

                            &&danmaku.text.equals(refDanmaku.text)

                            &&danmaku.tag == refDanmaku.tag) {

                        mResult = danmaku;

                        return ACTION_BREAK;

                    }

                    if (strictMode) {

                        return ACTION_CONTINUE;

                    }

                    if (!danmaku.isTimeOut()) {

                        return ACTION_BREAK;

                    }

                    if (cache.hasReferences()){

                        return ACTION_CONTINUE;

                    }

                    float widthGap =cache.width() - refDanmaku.paintWidth;

                    float heightGap = cache.height() -refDanmaku.paintHeight;

                    if (widthGap >= 0&& widthGap <= finalSlopPixel &&

                            heightGap >= 0&& heightGap <= finalSlopPixel) {

                        mResult = danmaku;

                        return ACTION_BREAK;

                    }

                    return ACTION_CONTINUE;

                }

            };

            mCaches.forEach(consumer);

            return consumer.result();

        }

 

改变的核心还是:0.5.0中通过自定义的IDanmakuIterator遍历

0.7.3中通过forEach遍历。

 

0.5.0
0.7.3 新增

privatevoid preMeasure() {

                // pre measure

                IDanmakus danmakus = null;

                try {

                    long begin =mTimer.currMillisecond;

                    long end = begin +mContext.mDanmakuFactory.MAX_DANMAKU_DURATION * 2;

                    danmakus =danmakuList.subnew(begin - mContext.mDanmakuFactory.MAX_DANMAKU_DURATION, end);

                } catch (Exception e) {

 

                }

                if (danmakus == null ||danmakus.isEmpty()) {

                    return;

                }

                danmakus.forEach(newIDanmakus.DefaultConsumer<BaseDanmaku>() {

                    @Override

                    public int accept(BaseDanmakuitem) {

                        if (mPause ||mCancelFlag) {

                            returnACTION_BREAK;

                        }

                        if(!item.hasPassedFilter()) {

                           mContext.mDanmakuFilters.filter(item, 0, 0, null, true, mContext);

                        }

                        if (item.isFiltered()){

                            returnACTION_CONTINUE;

                        }

                        if (!item.isMeasured()){

                            item.measure(mDisp, true);

                        }

                        if (!item.isPrepared()){

                            item.prepare(mDisp,true);

                        }

                        return ACTION_CONTINUE;

                    }

                });

            }

 

0.7.3 中新增的preMeasure方法,预测量方法,在prepareCaches(final boolean repositioned)方法的第一句会调用,preMeasure中通forEach遍历danmakuList.subnew(begin - mContext.mDanmakuFactory.MAX_DANMAKU_DURATION, end)
 

0.5.0   private long prepareCaches(booleanrepositioned) {

long curr =mCacheTimer.currMillisecond;

long end = curr + mContext.mDanmakuFactory.MAX_DANMAKU_DURATION *mScreenSize;

IDanmakuIterator itr = danmakus.iterator();

BaseDanmaku item = null;

long consumingTime = 0;

int orderInScreen = 0;

int currScreenIndex = 0;

int sizeInScreen = danmakus.size();

//                String message = "";

while(!mPause && !mCancelFlag) {

boolean hasNext = itr.hasNext();

if (!hasNext) {

//                        message = "breakat not hasNext";

break;

}

item = itr.next();

 

if(last.getActualTime() < mTimer.currMillisecond) {

//                        message = "breakat last.time < mTimer.currMillisecond";

break;

}

 

IDrawingCache<?>cache = item.getDrawingCache();

if(cache != null && cache.get() != null) {

continue;

}

 

if(repositioned == false && (item.isTimeOut() || !item.isOutside())) {

continue;

}

 

if(!item.hasPassedFilter()) {

mContext.mDanmakuFilters.filter(item,orderInScreen, sizeInScreen, null, true, mContext);

}

 

//Log.e("prepareCache",currScreenIndex+","+indexInScreen+"," +item.time+"skip:"+skip);

if(item.priority == 0 && item.isFiltered()) {

continue;

}

 

0.7.3   private long prepareCaches(final booleanrepositioned) {

preMeasure();

final long curr = mCacheTimer.currMillisecond;

final long end = curr +mContext.mDanmakuFactory.MAX_DANMAKU_DURATION * mScreenSize;

final int sizeInScreen =danmakus.size();

//                String message = "";

 

danmakus.forEach(new IDanmakus.DefaultConsumer<BaseDanmaku>() {

int orderInScreen = 0;

int currScreenIndex = 0;

@Override

publicint accept(BaseDanmaku item) {

if(mPause || mCancelFlag) {

return ACTION_BREAK;

}

if(last.getActualTime() < mTimer.currMillisecond) {

return ACTION_BREAK;

}

 

IDrawingCache<?>cache = item.getDrawingCache();

if(cache != null && cache.get() != null) {

return ACTION_CONTINUE;

}

 

if(repositioned == false && (item.isTimeOut() || !item.isOutside())) {

return ACTION_CONTINUE;

}

 

if(!item.hasPassedFilter()) {

mContext.mDanmakuFilters.filter(item, orderInScreen, sizeInScreen,null, true, mContext);

}

 

//Log.e("prepareCache",currScreenIndex+","+indexInScreen+"," +item.time+"skip:"+skip);

if(item.priority == 0 && item.isFiltered()) {

returnACTION_CONTINUE;

}

 

不同0.7.3对于一些方法内的变量类型添加了final类型限制,并且0.5.0中遍历用的自定义的IDanmakuIterator,0.7.3用的是forEach()方法遍历。

 

DanmakuFilters

 

0.5.0 private final void removeTimeoutDanmakus(final IDanmakus danmakus,long limitTime) {

           IDanmakuIterator it= danmakus.iterator();

            long startTime =SystemClock.uptimeMillis();

            while (it.hasNext()){

                try {

                    BaseDanmaku item =it.next();

                    if (item.isTimeOut()) {

                        it.remove();

                    } else {

                        break;

                    }

                } catch (Exception e) {

                    break;

                }

                if (SystemClock.uptimeMillis()- startTime > limitTime) {

                    break;

                }

           }

       }

0.7.3  private final voidremoveTimeoutDanmakus(final IDanmakus danmakus, final long limitTime) {

           danmakus.forEachSync(newIDanmakus.DefaultConsumer<BaseDanmaku>() {

                long startTime =SystemClock.uptimeMillis();

                @Override

                public intaccept(BaseDanmaku item) {

                    try {

                        if(SystemClock.uptimeMillis() - startTime > limitTime) {

                            returnACTION_BREAK;

                        }

                        if (item.isTimeOut()) {

                            returnACTION_REMOVE;

                        } else {

                            returnACTION_BREAK;

                        }

                    } catch (Exception e) {

                        return ACTION_BREAK;

                    }

                }

           });

       }

 

0.5.0移除超时弹幕用的是IDanmakuIterator遍历去移除,依次遍历

0.7.3 移除超时弹幕用的是danmakus.forEachSync()方法,其中forEachSync为接口IDanmakus新增的方法。

 

DrawHandler

0.5.0

public long getPausedPosition() {

       return pausedPosition;

    }

 

   public void setPausedPosition(long pausedPosition) {

       this.pausedPosition = pausedPosition;

}

 

public booleanismReady() {

        return mReady;

    }

 

    public void setmReady(boolean mReady) {

        this.mReady = mReady;

    }

 

 

    public Callback getmCallback() {

        return mCallback;

    }

 

    public void setmCallback(CallbackmCallback) {

        this.mCallback = mCallback;

    }

 

  public IDrawTask getDrawTask() {

        return drawTask;

    }

 

    public void setDrawTask(IDrawTask drawTask){

        this.drawTask = drawTask;

    }

0.7.3 上述代码已经删除

 

0.5.0 privatevoid prepare(final Runnable runnable) {

@Override

public void onDanmakuAdd(BaseDanmaku danmaku) {

long delay =danmaku.getActualTime() - timer.currMillisecond;

if (delay > 0) {

sendEmptyMessageDelayed(NOTIFY_RENDERING, delay);

} else if (mInWaitingState) {

notifyRendering();

}

 

0.7.3private void prepare(final Runnable runnable) {

@Override

public void onDanmakuAdd(BaseDanmaku danmaku) {

if (danmaku.isTimeOut()) {

return;

}

long delay = danmaku.getActualTime() -getCurrentTime();

if (delay <mContext.mDanmakuFactory.MAX_DANMAKU_DURATION && (mInWaitingState ||mRenderingState.nothingRendered)) {

notifyRendering();

} else if (delay > 0 && delay <=mContext.mDanmakuFactory.MAX_DANMAKU_DURATION) {

sendEmptyMessageDelayed(NOTIFY_RENDERING, delay);

}

 

0.5.0 的填充弹幕逻辑是,如果delay大于0,则delay时间之后再填充,如果mInWaitingState为true则立即填充

0.7.3 的填充逻辑是如果delay小于弹幕的最大持续时间,并且mInWaitingState或者mRenderingState.nothingRendered为true,则立即填充。如果delay大于0并且小于弹幕工厂的最大持续时间,则delay时间之后再填充。

 

0.5.0  public void resume() {

        sendEmptyMessage(DrawHandler.RESUME);

    }

 

    public void prepare() {

        sendEmptyMessage(DrawHandler.PREPARE);

    }

 

    public void pause() {

        syncTimerIfNeeded();

        sendEmptyMessage(DrawHandler.PAUSE);

}

 

0.7.3  public void resume() {

        removeMessages(DrawHandler.PAUSE);

        sendEmptyMessage(DrawHandler.RESUME);

    }

 

    public void prepare() {

        mReady = false;

        sendEmptyMessage(DrawHandler.PREPARE);

    }

 

    public void pause() {

        removeMessages(DrawHandler.RESUME);

        syncTimerIfNeeded();

        sendEmptyMessage(DrawHandler.PAUSE);

}

 

0.5.0

0.7.3新增了对应方法,例如在resume中增加了removeMessage(DrawHandler.PAUSE)。

 

0.5.0  public RenderingState draw(Canvas canvas) {

        if (drawTask == null)

            return mRenderingState;

 

        if (!quitFlag && !mInWaitingState) {

            AbsDanmakuSync danmakuSync =mContext.danmakuSync;

            if (danmakuSync != null &&danmakuSync.getSyncState() == AbsDanmakuSync.SYNC_STATE_PLAYING) {

                long fromTime =timer.currMillisecond;

                long toTime =danmakuSync.getUptimeMillis();

                long offset = toTime -fromTime;

                if (Math.abs(offset) >danmakuSync.getThresholdTimeMills()) {

                   drawTask.requestSync(fromTime, toTime, offset);

                    timer.update(toTime);

                    mTimeBase =SystemClock.uptimeMillis() - toTime;

                    mRemainingTime = 0;

                }

            }

        }

        mDisp.setExtraData(canvas);

        mRenderingState.set(drawTask.draw(mDisp));

        recordRenderingTime();

        return mRenderingState;

}

 

0.7.3  public RenderingState draw(Canvas canvas) {

        if (drawTask == null)

            return mRenderingState;

 

        if (!mInWaitingState) {

            AbsDanmakuSync danmakuSync =mContext.danmakuSync;

            if (danmakuSync != null) {

                do {

                    boolean isSyncPlayingState= danmakuSync.isSyncPlayingState();

                    if (!isSyncPlayingState&& !quitFlag) {

                        break;

                    }

                    int syncState =danmakuSync.getSyncState();

                    if (syncState ==AbsDanmakuSync.SYNC_STATE_PLAYING) {

                        long fromTime =timer.currMillisecond;

                        long toTime =danmakuSync.getUptimeMillis();

                        long offset = toTime -fromTime;

                        if (Math.abs(offset)> danmakuSync.getThresholdTimeMills()) {

                            if (isSyncPlayingState&& quitFlag) {

                                resume();

                            }

                           drawTask.requestSync(fromTime, toTime, offset);

                           timer.update(toTime);

                            mTimeBase =SystemClock.uptimeMillis() - toTime;

                            mRemainingTime = 0;

                        }

                    } else if (syncState ==AbsDanmakuSync.SYNC_STATE_HALT) {

                        if (isSyncPlayingState&& !quitFlag) {

                            pause();

                        }

                    }

                } while (false);

            }

        }

        mDisp.setExtraData(canvas);

       mRenderingState.set(drawTask.draw(mDisp));

        recordRenderingTime();

        return mRenderingState;

}

 

0.5.0

0.7.3 在判断条件中去掉了字段!quitFlag,新加了danmakuSync字段的if判断,并且黄色代码中,新的版本用do{}while包住了执行代码,加了if(!isSyncPlayingState && !quitFlag),如果符合停止条件则break循环,增加了if (isSyncPlayingState && quitFlag) {resume();}代码等。

 

0.5.0  private synchronized longgetAverageRenderingTime() {

        int frames = mDrawTimes.size();

        if (frames <= 0)

            return 0;

        long dtime = mDrawTimes.getLast() -mDrawTimes.getFirst();

        return dtime / frames;

}

 

0.7.3private synchronized long getAverageRenderingTime() {

        int frames = mDrawTimes.size();

        if(frames <= 0)

            return 0;

        Long first = mDrawTimes.peekFirst();

        Long last = mDrawTimes.peekLast();

        if (first == null || last == null) {

            return 0;

        }

        long dtime = last - first;

        return dtime / frames;

}

0.5.00.7.3中dtime的计算方式有所改变。

 

DrawTask

0.5.0   public AbsDisplayergetmDisp() {

       return mDisp;

}

    public IDanmakus getDanmakuList() {

        return danmakuList;

    }

 

    public void setDanmakuList(IDanmakusdanmakuList) {

        this.danmakuList = danmakuList;

    }

 public DanmakuTimer getmTimer() {

       return mTimer;

    }

 

   public void setmTimer(DanmakuTimer mTimer) {

       this.mTimer = mTimer;

}

 

  public BaseDanmaku getmLastDanmaku() {

        return mLastDanmaku;

    }

 

    public void setmLastDanmaku(BaseDanmakumLastDanmaku) {

        this.mLastDanmaku = mLastDanmaku;

    }

 

0.7.3

0.7.3版本中,上述代码被移除。

 

0.5.0  @Override

   public void invalidateDanmaku(BaseDanmaku item, boolean remeasure) {

       mContext.getDisplayer().getCacheStuffer().clearCache(item);

       if (remeasure) {

           item.paintWidth = -1;

           item.paintHeight = -1;

       }

}

0.7.3  @Override

   public void invalidateDanmaku(BaseDanmaku item, boolean remeasure) {

       mContext.getDisplayer().getCacheStuffer().clearCache(item);

       item.requestFlags|= BaseDanmaku.FLAG_REQUEST_INVALIDATE;

       if (remeasure) {

           item.paintWidth = -1;

           item.paintHeight = -1;

           item.requestFlags|= BaseDanmaku.FLAG_REQUEST_REMEASURE;

           item.measureResetFlag++;

       }

}

 

0.7.3中 添加了invalidateDanmaku()方法的变量赋值,涉及到requestFlags和measureResetFlag两个变量。

 

0.5.0  protected voidloadDanmakus(BaseDanmakuParser parser) {

       danmakuList =parser.setConfig(mContext).setDisplayer(mDisp).setTimer(mTimer).getDanmakus();

       if (danmakuList !=null && !danmakuList.isEmpty()) {

            if(danmakuList.first().flags == null) {

                IDanmakuIteratorit = danmakuList.iterator();

                while(it.hasNext()) {

                    BaseDanmakuitem = it.next();

                    if (item != null) {

                       item.flags = mContext.mGlobalFlagValues;

                    }

                }

           }

       }

       mContext.mGlobalFlagValues.resetAll();

       if(danmakuList != null) {

           mLastDanmaku = danmakuList.last();

       }

}

 

0.7.3  protected voidloadDanmakus(BaseDanmakuParser parser) {

       danmakuList =parser.setConfig(mContext).setDisplayer(mDisp).setTimer(mTimer).setListener(newBaseDanmakuParser.Listener() {

           @Override

            public voidonDanmakuAdd(BaseDanmaku danmaku) {

                if (mTaskListener!= null) {

                   mTaskListener.onDanmakuAdd(danmaku);

                }

            }

        }).getDanmakus();

       mContext.mGlobalFlagValues.resetAll();

       if(danmakuList != null) {

           mLastDanmaku = danmakuList.last();

       }

}

 

0.5.0  通过IDanmakuIterator遍历danmakuList去依次设置BaseDanmaku.item值

0.7.3  通过通过BaseDanmakuParser设置接口回调,回调方法onDanmakuAdd()方法

 

其他的不同之处都是,0.5.0通过Iterator去遍历,0.7.3通过forEach去遍历。

 

IDanmakuView

0.5.0 public interface OnDanmakuClickListener {

    /**

     *

     * @param latest the latest one is clicked

     */

     void onDanmakuClick(BaseDanmaku latest);

 

    /**

     *

     * @param danmakus all to be clicked

     */

       void onDanmakuClick(IDanmakus danmakus);

}

0.7.3  public interfaceOnDanmakuClickListener {

        /**

         * @param danmakus all to be clicked, this value may be empty;

         *                 danmakus.last() is the latest danmakuwhich may be null;

         * @return True if the event was handled, false otherwise.

         */

        boolean onDanmakuClick(IDanmakus danmakus);

 

        boolean onViewClick(IDanmakuView view);

}

0.5.00.7.3对于OnDanmakuClickListener的回调方法的名称和参数都有改变。

 

AndroidDisplayer

0.5.0

0.7.3新增
   public voidapplyPaintConfig(BaseDanmaku danmaku, Paint paint, boolean stroke) {

if (danmaku.getType() == BaseDanmaku.TYPE_SPECIAL) {

                paint.setAlpha(danmaku.getAlpha());

         }

 

       }

 

private float locationZ;

 public int draw(BaseDanmaku danmaku) {

if (canvas !=null) {

if (!cacheDrawn) {

      if (alphaPaint != null) {

                  mDisplayConfig.PAINT_DUPLICATE.setAlpha(alphaPaint.getAlpha());

 

0.7.3针对特殊弹幕的透明度,新增了一个配置方法,在Draw方法中也添加了透明度的设置函数,并且新增了locationZ变量,我感觉是为了绘制搞基弹幕准备的。

 

0.5.0 private int saveCanvas(BaseDanmaku danmaku, Canvas canvas, floatleft, float top) {

       camera.save();

       camera.rotateY(-danmaku.rotationY);

       camera.rotateZ(-danmaku.rotationZ);

       camera.getMatrix(matrix);

       matrix.preTranslate(-left,-top);

       matrix.postTranslate(left, top);

       camera.restore();

       int count = canvas.save();

       canvas.concat(matrix);

       return count;

    }

0.7.3 private int saveCanvas(BaseDanmaku danmaku, Canvas canvas, floatleft, float top) {

       camera.save();

       if (locationZ !=0&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {

            camera.setLocation(0,0, locationZ);

        }

       camera.rotateY(-danmaku.rotationY);

       camera.rotateZ(-danmaku.rotationZ);

       camera.getMatrix(matrix);

//       matrix.preTranslate(-left, -top);

       matrix.postTranslate(left , top);

       camera.restore();

       int count = canvas.save();

       canvas.concat(matrix);

       return count;

    }

 

0.5.0

0.7.3 增加了根据locationZ等变量设置camera.setLocation()方法,去掉了matrix.preTranslate()方法。

 

0.5.0

0.7.3新增

@Override

    public voidprepare(BaseDanmaku danmaku, boolean fromWorkerThread) {

        if (sStuffer != null) {

           sStuffer.prepare(danmaku, fromWorkerThread);

        }

}

@Override

   public void setSize(int width, int height) {

       this.width = width;

        this.height = height;

       this.locationZ =(float) (width / 2f / Math.tan((Math.PI / 180) * (55f / 2f)));

    }

0.5.0

0.7.3 新增了prepare重写方法,并且增加了根据locationZ设置弹幕位置的变量。

 

BaseCacheStuffer

0.5.0

0.7.3 新增

public void prepare(BaseDanmaku danmaku, boolean fromWorkerThread) {

        if (mProxy != null) {

           mProxy.prepareDrawing(danmaku, fromWorkerThread);

        }

}

 

public boolean drawCache(BaseDanmakudanmaku, Canvas canvas, float left, float top, Paint alphaPaint, TextPaint paint) {

        IDrawingCache<?>cache = danmaku.getDrawingCache();

        if (cache != null) {

            DrawingCacheHolderholder = (DrawingCacheHolder) cache.get();

            if (holder != null) {

                returnholder.draw(canvas, left, top, alphaPaint);

            }

        }

        return false;

}

 

0.7.3 新增了prepare方法,此方法在AndroidDisplayer中有调用,在drawCache中,添加了具体的缓存绘制方法。

 

DanmakuFactory

0.5.0

private voidupdateSpecialDanmakusDate(float scaleX, float scaleY) {

        IDanmakus list = sSpecialDanmakus;

        IDanmakuIterator it =list.iterator();

        while (it.hasNext()) {

           SpecialDanmaku speicalDanmaku = (SpecialDanmaku) it.next();

           fillTranslationData(speicalDanmaku, speicalDanmaku.beginX,speicalDanmaku.beginY,

                    speicalDanmaku.endX,speicalDanmaku.endY, speicalDanmaku.translationDuration,

                   speicalDanmaku.translationStartDelay, scaleX, scaleY);

           LinePath[] linePaths = speicalDanmaku.linePaths;

           if (linePaths != null && linePaths.length > 0) {

                int length = linePaths.length;

                float[][] points = newfloat[length + 1][2];

                for (int j = 0; j < length;j++) {

                    points[j] =linePaths[j].getBeginPoint();

                    points[j + 1] =linePaths[j].getEndPoint();

                }

               fillLinePathData(speicalDanmaku, points, scaleX, scaleY);

           }

       }

    }

0.7.3

   private void updateSpecialDanmakusDate(final float scaleX, final floatscaleY) {

       IDanmakus list = sSpecialDanmakus;

       list.forEachSync(newIDanmakus.DefaultConsumer<BaseDanmaku>() {

            @Override

            public intaccept(BaseDanmaku danmaku) {

               SpecialDanmakuspeicalDanmaku = (SpecialDanmaku) danmaku;

               fillTranslationData(speicalDanmaku, speicalDanmaku.beginX,speicalDanmaku.beginY,

                        speicalDanmaku.endX,speicalDanmaku.endY, speicalDanmaku.translationDuration,

                       speicalDanmaku.translationStartDelay, scaleX, scaleY);

                LinePath[] linePaths =speicalDanmaku.linePaths;

                if (linePaths != null&& linePaths.length > 0) {

                    int length = linePaths.length;

                    float[][] points = newfloat[length + 1][2];

                    for (int j = 0; j <length; j++) {

                        points[j] =linePaths[j].getBeginPoint();

                        points[j + 1] =linePaths[j].getEndPoint();

                    }

                   fillLinePathData(speicalDanmaku, points, scaleX, scaleY);

                }

                return ACTION_CONTINUE;

           }

       });

}

0.5.0 采用Iterator的遍历方式

0.7.3 采用forEach的遍历方式。

 

Danmakus

0.5.0 删除:

 public static final int ST_BY_TIME = 0;

 

   public static final int ST_BY_YPOS = 1;

 

   public static final int ST_BY_YPOS_DESC = 2;

 

   /**

    * this type is used to iterate/remove/insert elements, not supportsub/subnew

    */

public static finalint ST_BY_LIST = 4;

 

 private DanmakuIterator iterator;

 

private class DanmakuIterator implementsIDanmakuIterator {

 

       private Collection<BaseDanmaku> mData;

       private Iterator<BaseDanmaku> it;

       private boolean mIteratorUsed;

 

       public DanmakuIterator(Collection<BaseDanmaku> datas) {

           setDatas(datas);

       }

 

       public synchronized void reset() {

           if (!mIteratorUsed && it != null) {

                return;

           }

           if (mData != null && mSize > 0) {

                it = mData.iterator();

           } else {

                it = null;

           }

           mIteratorUsed = false;

       }

 

       public synchronized void setDatas(Collection<BaseDanmaku> datas) {

           if (mData != datas) {

                mIteratorUsed = false;

                it = null;

           }

           mData = datas;

       }

 

       @Override

       public synchronized BaseDanmaku next() {

           mIteratorUsed = true;

           return it != null ? it.next() : null;

       }

 

       @Override

       public synchronized boolean hasNext() {

           return it != null && it.hasNext();

       }

 

       @Override

       public synchronized void remove() {

           mIteratorUsed = true;

           if (it != null) {

                it.remove();

                mSize--;

           }

       }

 

    }

 

   private class BaseComparator implements Comparator<BaseDanmaku> {

 

       protected boolean mDuplicateMergingEnable;

 

        public BaseComparator(booleanduplicateMergingEnabled) {

           setDuplicateMergingEnabled(duplicateMergingEnabled);

       }

 

       public void setDuplicateMergingEnabled(boolean enable) {

           mDuplicateMergingEnable = enable;

       }

 

       @Override

       public int compare(BaseDanmaku obj1, BaseDanmaku obj2) {

           if (mDuplicateMergingEnable && DanmakuUtils.isDuplicate(obj1,obj2)) {

                return 0;

           }

           return DanmakuUtils.compare(obj1, obj2);

       }

 

    }

 

   private class TimeComparator extends BaseComparator {

 

       public TimeComparator(boolean duplicateMergingEnabled) {

           super(duplicateMergingEnabled);

       }

 

       @Override

       public int compare(BaseDanmaku obj1, BaseDanmaku obj2) {

           return super.compare(obj1, obj2);

       }

    }

 

   private class YPosComparator extends BaseComparator {

 

       public YPosComparator(boolean duplicateMergingEnabled) {

           super(duplicateMergingEnabled);

       }

 

       @Override

       public int compare(BaseDanmaku obj1, BaseDanmaku obj2) {

           if (mDuplicateMergingEnable && DanmakuUtils.isDuplicate(obj1,obj2)) {

                return 0;

           }

           return Float.compare(obj1.getTop(), obj2.getTop());

       }

    }

 

   private class YPosDescComparator extends BaseComparator {

 

       public YPosDescComparator(boolean duplicateMergingEnabled) {

           super(duplicateMergingEnabled);

       }

 

       @Override

       public int compare(BaseDanmaku obj1, BaseDanmaku obj2) {

           if (mDuplicateMergingEnable && DanmakuUtils.isDuplicate(obj1,obj2)) {

                return 0;

           }

           return Float.compare(obj2.getTop(), obj1.getTop());

       }

0.7.3 新增:

@Override

   public Collection<BaseDanmaku> getCollection() {

       return this.items;

    }

 

   @Override

   public void forEachSync(Consumer<? super BaseDanmaku, ?> consumer){

       synchronized (this.mLockObject) {

           forEach(consumer);

       }

    }

 

   @Override

   public void forEach(Consumer<? super BaseDanmaku, ?> consumer) {

       consumer.before();

       Iterator<BaseDanmaku> it = items.iterator();

       while (it.hasNext()) {

           BaseDanmaku next = it.next();

           if (next == null) {

                continue;

           }

           int action = consumer.accept(next);

           if (action == DefaultConsumer.ACTION_BREAK) {

                break;

           } else if (action == DefaultConsumer.ACTION_REMOVE) {

                it.remove();

           } else if (action == DefaultConsumer.ACTION_REMOVE_AND_BREAK) {

                it.remove();

                break;

           }

       }

       consumer.after();

    }

 

   @Override

   public Object obtainSynchronizer() {

       return mLockObject;

}

 

0.7.3版本中Danmakus类主要的改变是去掉了之前通过自定义的Iterator遍历的方式,而是改用forEach的方式来遍历。其中,forEach内部的实现过程也是通过Iterator,只不过这样写更简洁,封装了一下。

 

SimpleTextCacheStuffer

0.5.0删除
   if (mProxy != null) {

           mProxy.prepareDrawing(danmaku, fromWorkerThread);

       }

 

@Override

   public boolean drawCache(BaseDanmaku danmaku, Canvas canvas, float left,float top, Paint alphaPaint, TextPaint paint) {

       IDrawingCache<?> cache = danmaku.getDrawingCache();

       if (cache != null) {

           DrawingCacheHolder holder = (DrawingCacheHolder) cache.get();

           if (holder != null) {

                return holder.draw(canvas,left, top, alphaPaint);

           }

       }

       return false;

    }

0.7.3

 

0.5.0的drawCache()方法在SimpleTextCacheStuffer中被移除,该方法被迁移到了BaseCacheStuffer中实现。

 

ViewCacheStuffer

该类为0.7.3版本中新增的类,该类没啥作用,只是在sample demo方法中的UglyViewCacheStufferSampleActivity测试页面中使用过,该类填充缓存使得弹幕内容都加上了图标,感觉是为了测试使用的。

 

AbsDanmakuSync

0.5.0

0.7.3 新增

/**

    * synchronize pause/resume state with outside playback

    * @return

    */

   public boolean isSyncPlayingState() {

       return false;

}

 

0.7.3中增加这个方法,为了同步播放页面的暂停/继续状态和手机的back键的状态。

 

BaseDanmaku

 

0.5.0

0.7.3新增

 

   /**

    * 重置位 prepare

    */

   public int prepareResetFlag = -1;

 

   /**

 

public boolean isPrepared() {

       return this.prepareResetFlag == flags.PREPARE_RESET_FLAG;

    }

 

   public void prepare(IDisplayer displayer, boolean fromWorkerThread) {

       displayer.prepare(this, fromWorkerThread);

       this.prepareResetFlag = flags.PREPARE_RESET_FLAG;

}

 

0.7.3 这两个函数感觉是用来标识当前的弹幕是否准备完成,是否可以在屏幕呈现。

 

GlobalFlagValues

0.5.0

0.7.3 新增

public int PREPARE_RESET_FLAG = 0;

 

public void resetAll() {

       VISIBLE_RESET_FLAG = 0;

       MEASURE_RESET_FLAG = 0;

       FILTER_RESET_FLAG = 0;

       FIRST_SHOWN_RESET_FLAG = 0;

       SYNC_TIME_OFFSET_RESET_FLAG= 0;

        PREPARE_RESET_FLAG = 0;

}

 

public void updatePrepareFlag() {

       PREPARE_RESET_FLAG++;

}

0.7.3 新增了准备状态的标志位,感觉是为了当弹幕准备完成时,做相应的操作。

 

IDanmakus

0.5.0

0.7.3 新增

abstract class Consumer<Progress,Result> {

 

       public static final int ACTION_CONTINUE = 0;

       public static final int ACTION_BREAK = 1;

       public static final int ACTION_REMOVE = 2;

       public static final int ACTION_REMOVE_AND_BREAK = 3;

 

       /**

        * Performs this operation on the given argument.

        *

        * @param t the input argument

        * @return next action of the loop

        *

        * @see #ACTION_CONTINUE

        * @see #ACTION_BREAK

        * @see #ACTION_REMOVE

        */

       public abstract int accept(Progress t);

 

       public void before() {

 

       }

 

        public void after() {

 

       }

 

       public Result result() {

           return null;

       }

    }

 

   abstract class DefaultConsumer<Progress> extendsConsumer<Progress, Void> {

 

    }

 

   int ST_BY_TIME = 0;

 

   int ST_BY_YPOS = 1;

 

    intST_BY_YPOS_DESC = 2;

 

   /**

    * this type is used to iterate/remove/insert elements, not supportsub/subnew

    */

int ST_BY_LIST =4;

 

boolean contains(BaseDanmaku item);

 

   boolean isEmpty();

   

   void setSubItemsDuplicateMergingEnabled(boolean enable);

 

   Collection<BaseDanmaku> getCollection();

 

   void forEachSync(Consumer<? super BaseDanmaku, ?> consumer);

 

   void forEach(Consumer<? super BaseDanmaku, ?> consumer);

 

   Object obtainSynchronizer();

 

   class BaseComparator implements Comparator<BaseDanmaku> {

 

       protected boolean mDuplicateMergingEnable;

 

       public BaseComparator(boolean duplicateMergingEnabled) {

           setDuplicateMergingEnabled(duplicateMergingEnabled);

       }

 

       public void setDuplicateMergingEnabled(boolean enable) {

           mDuplicateMergingEnable = enable;

       }

 

       @Override

       public int compare(BaseDanmaku obj1, BaseDanmaku obj2) {

           if (mDuplicateMergingEnable && DanmakuUtils.isDuplicate(obj1,obj2)) {

                return 0;

           }

           return DanmakuUtils.compare(obj1, obj2);

       }

 

    }

 

   class TimeComparator extends BaseComparator {

 

       public TimeComparator(boolean duplicateMergingEnabled) {

           super(duplicateMergingEnabled);

       }

 

       @Override

       public int compare(BaseDanmaku obj1, BaseDanmaku obj2) {

           return super.compare(obj1, obj2);

       }

    }

 

   class YPosComparator extends BaseComparator {

 

       public YPosComparator(boolean duplicateMergingEnabled) {

           super(duplicateMergingEnabled);

       }

 

       @Override

       public int compare(BaseDanmaku obj1, BaseDanmaku obj2) {

           if (mDuplicateMergingEnable && DanmakuUtils.isDuplicate(obj1,obj2)) {

                return 0;

           }

           return Float.compare(obj1.getTop(), obj2.getTop());

       }

    }

 

   class YPosDescComparator extends BaseComparator {

 

       public YPosDescComparator(boolean duplicateMergingEnabled) {

           super(duplicateMergingEnabled);

       }

 

       @Override

       public int compare(BaseDanmaku obj1, BaseDanmaku obj2) {

           if (mDuplicateMergingEnable && DanmakuUtils.isDuplicate(obj1,obj2)) {

                return 0;

            }

           return Float.compare(obj2.getTop(), obj1.getTop());

       }

}

 

0.7.3 新增的Consumer为了处理弹幕的RESUME、PAUSE等事件,新增的各种Comparator,为了处理合并重复弹幕,例如合并同一时间的弹幕,合并相同内容的弹幕,等。

 

Idisplayer

0.5.0

0.7.3 新增

void prepare(BaseDanmaku danmaku, booleanfromWorkerThread);

0.7.3 通知弹幕是否准备完成

 

BaseDanmakuParser

 

0.5.0

0.7.3 新增

public interface Listener {

       void onDanmakuAdd(BaseDanmaku danmaku);

}

 

protected Listener mListener;

 

public IDisplayer getDisplayer(){

        return mDisp;

    }

 

   public BaseDanmakuParser setListener(Listener listener) {

       mListener = listener;

       return this;

    }

   

删除

   public IDisplayer getDisplayer(){

       return mDisp;

    }

   

0.7.3 新增了新的弹幕添加的回调方法,获取当前弹幕的AndroidDisplayer,设置当前弹幕的Parser.

 

DanmakuRenderer

0.5.0 修改

@Override

   public void draw(IDisplayer disp, IDanmakus danmakus, longstartRenderTime, RenderingState renderingState) {

 

       mStartTimer = renderingState.timer;

       BaseDanmaku drawItem = null;

       IDanmakuIterator itr = danmakus.iterator();

       while (itr.hasNext()) {

 

           drawItem = itr.next();

 

           if (drawItem.isTimeOut()) {

                itr.remove();

                disp.recycle(drawItem);

                continue;

           }

 

           if (!renderingState.isRunningDanmakus && drawItem.isOffset()) {

                itr.remove();

                continue;

           }

 

           if (!drawItem.hasPassedFilter()) {

                mContext.mDanmakuFilters.filter(drawItem,renderingState.indexInScreen, renderingState.totalSizeInScreen,renderingState.timer, false, mContext);

           }

           if (drawItem.getActualTime() < startRenderTime

                    || (drawItem.priority == 0&& drawItem.isFiltered())) {

                continue;

           }

 

           if (drawItem.isLate()) {

                IDrawingCache<?> cache =drawItem.getDrawingCache();

                if (mCacheManager != null&& (cache == null || cache.get() == null)) {

                   mCacheManager.addDanmaku(drawItem);

                }

                break;

           }

 

           if (drawItem.getType() == BaseDanmaku.TYPE_SCROLL_RL){

                // 同屏弹幕密度只对滚动弹幕有效

                renderingState.indexInScreen++;

           }

 

           // measure

           if (!drawItem.isMeasured()) {

                drawItem.measure(disp, false);

           }

 

           // layout

           mDanmakusRetainer.fix(drawItem, disp, mVerifier);

 

           // draw

           if (drawItem.isShown()) {

                if (drawItem.lines == null&& drawItem.getBottom() > disp.getHeight()) {

                    continue;    // skip bottom outside danmaku

                }

                int renderingType =drawItem.draw(disp);

                if(renderingType ==IRenderer.CACHE_RENDERING) {

                   renderingState.cacheHitCount++;

                } else if(renderingType ==IRenderer.TEXT_RENDERING) {

                    renderingState.cacheMissCount++;

                    if (mCacheManager != null){

                       mCacheManager.addDanmaku(drawItem);

                    }

                }

               renderingState.addCount(drawItem.getType(), 1);

                renderingState.addTotalCount(1);

               renderingState.appendToRunningDanmakus(drawItem);

 

                if (mOnDanmakuShownListener !=null

                        &&drawItem.firstShownFlag != mContext.mGlobalFlagValues.FIRST_SHOWN_RESET_FLAG) {

                   drawItem.firstShownFlag= mContext.mGlobalFlagValues.FIRST_SHOWN_RESET_FLAG;

                   mOnDanmakuShownListener.onDanmakuShown(drawItem);

                }

           }

 

       }

 

       renderingState.lastDanmaku = drawItem;

 

    }

 

0.7.3 修改

private class Consumer extendsIDanmakus.DefaultConsumer<BaseDanmaku> {

       private BaseDanmaku lastItem;

       public IDisplayer disp;

       public RenderingState renderingState;

       public long startRenderTime;

 

       @Override

        public int accept(BaseDanmaku drawItem) {

           lastItem = drawItem;

           if (drawItem.isTimeOut()) {

                disp.recycle(drawItem);

                return ACTION_CONTINUE;

           }

 

           if (!renderingState.isRunningDanmakus && drawItem.isOffset()) {

                return ACTION_REMOVE;

           }

 

           if (!drawItem.hasPassedFilter()) {

               mContext.mDanmakuFilters.filter(drawItem, renderingState.indexInScreen,renderingState.totalSizeInScreen, renderingState.timer, false, mContext);

           }

           if (drawItem.getActualTime() < startRenderTime

                    || (drawItem.priority == 0&& drawItem.isFiltered())) {

                return ACTION_CONTINUE;

           }

 

           if (drawItem.isLate()) {

                IDrawingCache<?> cache =drawItem.getDrawingCache();

                if (mCacheManager != null&& (cache == null || cache.get() == null)) {

                   mCacheManager.addDanmaku(drawItem);

               }

                return ACTION_BREAK;

           }

 

           if (drawItem.getType() == BaseDanmaku.TYPE_SCROLL_RL) {

                // 同屏弹幕密度只对滚动弹幕有效

                renderingState.indexInScreen++;

           }

 

           // measure

            if (!drawItem.isMeasured()) {

                drawItem.measure(disp, false);

           }

 

           // notify prepare drawing

           if (!drawItem.isPrepared()) {

                drawItem.prepare(disp, false);

           }

 

           // layout

           mDanmakusRetainer.fix(drawItem, disp, mVerifier);

 

           // draw

           if (drawItem.isShown()) {

                if (drawItem.lines == null&& drawItem.getBottom() > disp.getHeight()) {

                    returnACTION_CONTINUE;    // skip bottomoutside danmaku

                }

                int renderingType =drawItem.draw(disp);

                if (renderingType ==IRenderer.CACHE_RENDERING) {

                   renderingState.cacheHitCount++;

               } else if (renderingType ==IRenderer.TEXT_RENDERING) {

                   renderingState.cacheMissCount++;

                    if (mCacheManager != null){

                       mCacheManager.addDanmaku(drawItem);

                    }

               }

               renderingState.addCount(drawItem.getType(), 1);

               renderingState.addTotalCount(1);

               renderingState.appendToRunningDanmakus(drawItem);

 

                if (mOnDanmakuShownListener !=null

                        && drawItem.firstShownFlag !=mContext.mGlobalFlagValues.FIRST_SHOWN_RESET_FLAG) {

                    drawItem.firstShownFlag =mContext.mGlobalFlagValues.FIRST_SHOWN_RESET_FLAG;

                   mOnDanmakuShownListener.onDanmakuShown(drawItem);

                }

           }

           return ACTION_CONTINUE;

       }

 

       @Override

       public void after() {

           renderingState.lastDanmaku = lastItem;

           super.after();

       }

    }

 

0.7.3中将draw()方法中的具体实现,合并到方法private class Consumer extendsIDanmakus.DefaultConsumer<BaseDanmaku>中去实现,将0.5.0的自定义Iterator通过0.7.3的forEach代替,并回调类Consumer的方法来代替draw()方法。

 

DanmakusRetainer

0.5.0

0.7.3 新增

  private static class AlignBottomRetainer extends FTDanmakusRetainer {

       protected class RetainerConsumer extendsIDanmakus.Consumer<BaseDanmaku, RetainerState> {

           public IDisplayer disp;

           int lines = 0;

           public BaseDanmaku removeItem = null, firstItem = null, drawItem = null;

           boolean willHit = false;

           float topPos;

 

           @Override

           public void before() {

                lines = 0;

                removeItem = firstItem = null;

                willHit = false;

           }

 

           @Override

           public int accept(BaseDanmaku item) {

                if (mCancelFixingFlag) {

                    return ACTION_BREAK;

                }

                lines++;

                if (item == drawItem) {

                    removeItem = null;

                    willHit = false;

                    return ACTION_BREAK;

                }

 

                if (firstItem == null) {

                    firstItem = item;

                    if (firstItem.getBottom()!= disp.getHeight()) {

                        return ACTION_BREAK;

                    }

                }

 

                if (topPos < 0) {

                    removeItem = null;

                    return ACTION_BREAK;

                }

 

                // 检查碰撞

                willHit = DanmakuUtils.willHitInDuration(disp,item, drawItem,

                        drawItem.getDuration(),drawItem.getTimer().currMillisecond);

                if (!willHit) {

                    removeItem = item;

                    // topPos =item.getBottom() - drawItem.paintHeight;

                    return ACTION_BREAK;

                }

 

                topPos = item.getTop() -drawItem.paintHeight;

                return ACTION_CONTINUE;

           }

 

           @Override

           public RetainerState result() {

                RetainerState retainerState =new RetainerState();

                retainerState.lines =this.lines;

                retainerState.firstItem =this.firstItem;

                retainerState.removeItem =this.removeItem;

               retainerState.willHit =this.willHit;

                return retainerState;

           }

       }

 

 private static class AlignTopRetainer implements IDanmakusRetainer {

       protected class RetainerConsumer extendsIDanmakus.Consumer<BaseDanmaku, RetainerState> {

           public IDisplayer disp;

           int lines = 0;

           public BaseDanmaku insertItem = null, firstItem = null, lastItem = null,minRightRow = null, drawItem = null;

           boolean overwriteInsert = false;

           boolean shown = false;

           boolean willHit = false;

 

           @Override

           public void before() {

                lines = 0;

                insertItem = firstItem =lastItem = minRightRow = null;

                overwriteInsert = shown =willHit = false;

           }

 

           @Override

           public int accept(BaseDanmaku item) {

                if (mCancelFixingFlag) {

                    return ACTION_BREAK;

                }

                lines++;

                if(item == drawItem){

                    insertItem = item;

                    lastItem = null;

                    shown = true;

                    willHit = false;

                    return ACTION_BREAK;

                }

 

                if (firstItem == null)

                    firstItem = item;

 

                if (drawItem.paintHeight +item.getTop() > disp.getHeight()) {

                    overwriteInsert = true;

                    return ACTION_BREAK;

                }

 

                if (minRightRow == null) {

                    minRightRow = item;

                } else {

                    if (minRightRow.getRight()>= item.getRight()) {

                        minRightRow = item;

                    }

                }

 

               // 检查碰撞

                willHit =DanmakuUtils.willHitInDuration(disp, item, drawItem,

                        drawItem.getDuration(),drawItem.getTimer().currMillisecond);

                if (!willHit) {

                    insertItem = item;

                   return ACTION_BREAK;

                }

 

                lastItem = item;

                return ACTION_CONTINUE;

           }

 

           @Override

           public RetainerState result() {

                RetainerState retainerState =new RetainerState();

                retainerState.lines =this.lines;

                retainerState.firstItem =this.firstItem;

                retainerState.insertItem =this.insertItem;

                retainerState.lastItem =this.lastItem;

                retainerState.minRightRow = this.minRightRow;

                retainerState.overwriteInsert =this.overwriteInsert;

                retainerState.shown =this.shown;

                retainerState.willHit =this.willHit;

                return retainerState;

           }

       }

 

0.7.3 首先关于方法AlignTopRetainer()和AlignBottomRetainer()都增加了具体的实现代码,将0.5.0中的IDanmakuIterator通过mVisibleDanmakus.forEachSync(mConsumer)代替,0.7.3将0.5.0的一些方法过程进行了封装。

 

DanmakuSurfaceView

0.5.0 @Override

   public boolean onTouchEvent(MotionEvent event) {

       if (null != mTouchHelper) {

           mTouchHelper.onTouchEvent(event);

       }

 

       return super.onTouchEvent(event);

    }

0.7.3        @Override

   public boolean onTouchEvent(MotionEvent event) {

        boolean isEventConsumed =mTouchHelper.onTouchEvent(event);

       if (!isEventConsumed) {

           return super.onTouchEvent(event);

       }

       return isEventConsumed;

}

删除代码:

@Override

   public void draw(Canvas canvas) {

       super.draw(canvas);

    }

 

   @Override

   public DrawHandler getHandler() {

       return handler;

    }

 

   public void setHandler(DrawHandler handler) {

       this.handler = handler;

}

0.7.3对于onTouchEvent()方法进行了重写,其逻辑为通过变量isEventConsumed来表明该touch事件是否被消费,如果没有被消费则调用super.onTouchEvent(event);,如果被消费了则返回true。

 

DanmakuTouchHelper

0.5.0

public boolean onTouchEvent(MotionEventevent) {

       switch (event.getAction()) {

           case MotionEvent.ACTION_UP:

                IDanmakus clickDanmakus = touchHitDanmaku(event.getX(),event.getY());

                BaseDanmaku newestDanmaku =null;

                if (null != clickDanmakus&& !clickDanmakus.isEmpty()) {

                   performClick(clickDanmakus);

                    newestDanmaku =fetchLatestOne(clickDanmakus);

                }

 

                if (null != newestDanmaku) {

                   performClickWithlatest(newestDanmaku);

                }

                break;

           default:

                break;

       }

 

        return false;

    }

 

0.7.3

 public boolean onTouchEvent(MotionEvent event) {

       return mTouchDelegate.onTouchEvent(event);

    }

 

 private final android.view.GestureDetector.OnGestureListenermOnGestureListener = new GestureDetector.SimpleOnGestureListener(){

       @Override

       public boolean onDown(MotionEvent event) {

           if(danmakuView != null) {

               IDanmakuView.OnDanmakuClickListener onDanmakuClickListener =danmakuView.getOnDanmakuClickListener();

                if (onDanmakuClickListener != null) {

                    return true;

                }

           }

           return false;

       }

 

       @Override

       public boolean onSingleTapConfirmed(MotionEvent event) {

           IDanmakus clickDanmakus = touchHitDanmaku(event.getX(), event.getY());

           boolean isEventConsumed = false;

           if (null != clickDanmakus && !clickDanmakus.isEmpty()) {

                isEventConsumed =performDanmakuClick(clickDanmakus);

           }

           if (!isEventConsumed) {

                isEventConsumed =performViewClick();

           }

           return isEventConsumed;

       }

};

 

0.7.3更改了用户点击事件的处理方式,0.5.0直接处理用户的点击事件,在onTouchEvent()方法中执行了点击事件处理。在0.7.3中通过new出GestureDetector的实例,并回调其onDown()方法和onSingleTapConfirmed()方法,来处理用户的点击事件。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值