Example usage for android.os ConditionVariable block

List of usage examples for android.os ConditionVariable block

Introduction

In this page you can find the example usage for android.os ConditionVariable block.

Prototype

public void block() 

Source Link

Document

Block the current thread until the condition is opened.

Usage

From source file:com.jogden.spunkycharts.pricebyvolumechart.PriceByVolumeChartFragmentAdapter.java

private Thread _createPriceAxisAndMainPanel() {
    Thread thisThread = new Thread() {
        public void run() {
            ///////////////////////////////////
            /*     START PREEMPTION LOGIC     */
            /////////////////////////////////
            boolean noWait;
            final int MAX_PREEMPT_COUNT = ApplicationPreferences.getMaxPreemptCount();
            if (!(noWait = _priceAxisLck.tryLock())) {
                synchronized (_priceAxisThrdMntr) {
                    if (_priceAxisPrmptCnt++ > MAX_PREEMPT_COUNT)
                        return;
                    if (_priceAxisThrd != null)
                        _priceAxisThrd.interrupt();
                }/*from   www.j  a va  2  s .co m*/
                _priceAxisPrmptStck.offer(this);
                _priceAxisLck.lock();
            }
            try { /* everything that follows should assume we own monitor */
                if (!noWait) {
                    if (this != _priceAxisPrmptStck.peekLast())
                        return;
                    else { /* don't assume stack hasn't grown since the peek */
                        Iterator<Thread> dIter = _priceAxisPrmptStck.iterator();
                        do {
                            _priceAxisPrmptStck.poll();
                        } while (dIter.next() != this);
                    }
                }
                synchronized (_priceAxisThrdMntr) {
                    _priceAxisThrd = this;
                }
                /////////////////////////////////
                /*     END PREEMPTION LOGIC     */
                //////////////////////////////                            

                float rangeDiff = _highPrice - _lowPrice;
                /* deal with problematic high/low parameters */
                if (rangeDiff <= 0 || _highPrice < 0 || _lowPrice < 0)
                    if (rangeDiff == 0 && _highPrice > 0) {
                        _highPrice *= 1.001;
                        _lowPrice *= .999;
                        rangeDiff = _highPrice - _lowPrice;
                    } else
                        throw new IllegalStateException("Invalid high and/or low price in the ChartAdapter");
                /* if we haven't calculated the height of a price-label view */
                if (_priceElemHght == 0) {/* can cached value doesn't go stale? */
                    final YAxisPriceLabel tv1 = (YAxisPriceLabel) _inflater.inflate(R.layout.y_axis_price_label,
                            null);
                    tv1.setText("X");
                    tv1.setTextSize(_axisFontSz);
                    tv1.setVisibility(View.INVISIBLE);
                    final ConditionVariable cond = new ConditionVariable();
                    _guiThrdHndlr.post(new Runnable() {
                        public void run() {
                            _priceAxis.removeAllViews();
                            _priceAxis.addView(tv1);
                            cond.open();
                        }
                    });
                    cond.block();
                    cond.close();
                    YAxisPriceLabel tv1b = (YAxisPriceLabel) _priceAxis.getChildAt(0);
                    /* make sure a valid priceElemHeightt, or quit entirely */
                    /* just spin, a new thread preempts us anyway */
                    while ((_priceElemHght = tv1b.getHeight()) == 0)
                        Thread.sleep(_axisTimeoutIncr);
                }
                _guiThrdHndlr.post(new Runnable() {
                    public void run() {
                        _priceAxis.removeAllViews();
                    }
                });
                int totalHeight;
                /* make sure a valid totalHeight, or quit entirely */
                /* just spin, a new thread preempts us anyway */
                while ((totalHeight = _priceAxis.getHeight()) == 0 || totalHeight > _myContainer.getHeight())
                    Thread.sleep(_axisTimeoutIncr);
                float[] incrVals = new float[2];
                try {
                    int maxNodes = (int) (totalHeight / _priceElemHght);
                    if (rangeDiff < 0 || maxNodes < 0)
                        throw new PriceByVolumeChartLogicError("rangeDiff and maxNodes can't be negative.");
                    incrVals = /* call down to our native sub to find increment values */
                            MainApplication.IncrementRegressNative(rangeDiff, maxNodes);
                    if (incrVals[0] < 0 || incrVals[1] <= 0)
                        throw new PriceByVolumeChartLogicError("IncrementRegressNative() sub-routine aborted. "
                                + "retVals[0]: " + incrVals[0] + "retVals[1]: " + incrVals[1] + "adjRangeDiff: "
                                + rangeDiff + "maxNodes" + maxNodes);
                    _segCount = (int) incrVals[1];
                    _segSize = incrVals[0];
                } catch (PriceByVolumeChartLogicError e) {
                    Log.e("PriceByVolumeChartLogicError", e.getMessage());
                    return; /* just leave the axis empty*/
                }

                /* adjust height to new increment values */
                final int adjPriceElemHeight = (int) (totalHeight / _segCount);
                /* we'll need to account for any unused spaced in the axis */
                final int vacantHeight = totalHeight - (int) (adjPriceElemHeight * _segCount);
                double distFromIncr = Math.IEEEremainder((double) _highPrice,
                        (double) _segSize); /* distance from rounded incr value */
                double adjTopNodeVal = (double) _highPrice - distFromIncr;
                if (distFromIncr > 0) /* be sure to round to the upper incr */
                    adjTopNodeVal += _segSize;
                DecimalFormat df = new DecimalFormat("0.00");
                double lastNodeVal = adjTopNodeVal;
                int count = 0;
                do { /* loop through the increments */
                    final YAxisPriceLabel tv = (YAxisPriceLabel) _inflater.inflate(R.layout.y_axis_price_label,
                            null);
                    tv.setTextSize(_axisFontSz);
                    tv.setText(df.format(lastNodeVal));
                    tv.setTextColor(_axisFontColor);
                    tv.setLayoutParams(
                            new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 0, 1));
                    _guiThrdHndlr.post(new Runnable() {
                        public void run() {
                            _priceAxis.addView(tv);
                        }
                    }); /* for the loop-contingent side-effect */
                } while (++count < (int) _segCount && (lastNodeVal -= _segSize) > 0);
                final float halfVacantHeight = vacantHeight / 2;
                _mainSgmnt.setVerticalBuffers((int) halfVacantHeight, (int) halfVacantHeight);
                _guiThrdHndlr.post(new Runnable() {
                    public void run() {
                        _priceAxis.setPadding( /* center price-views */
                                0, (int) halfVacantHeight, 0, (int) halfVacantHeight);
                        _priceAxis.setClipChildren(false);
                        _priceAxis.setClipToPadding(false);
                        _priceAxis.invalidate();
                    }
                });

                synchronized (_priceAxisThrdMntr) {
                    _priceAxisPrmptCnt = 0;
                }
            } catch (InterruptedException e) {
            } catch (IllegalStateException e) {
                Log.d("IllegalState(High, Low): ",
                        "IllegalStateException caught in _createPriceAxisAndMainPanelY: "
                                + Float.toString(_highPrice) + " - " + Float.toString(_lowPrice));
            } catch (RuntimeException e) {
                e.printStackTrace();
                throw e;
            } finally {

                synchronized (_priceAxisThrdMntr) {
                    _priceAxisThrd = null;
                }
                _activeThreads.remove(this);
                _priceAxisLck.unlock();
            }
        }
    };
    _activeThreads.add(thisThread);
    thisThread.start();
    return thisThread;
}

From source file:com.jogden.spunkycharts.traditionalchart.TraditionalChartFragmentAdapter.java

private void _createTimeAxisX() {
    Thread thisThread = new Thread() {
        public void run() {
            if (!_timeAxisLck.tryLock()) /* be sure only one running */
                return;
            try {
                int axisWidth;
                final HideHorizontalLeftOverflowWrapper axisWrapper = (HideHorizontalLeftOverflowWrapper) _myContainer
                        .findViewById(R.id.ofwrap_xAxis);
                int failCount = 0;
                /* if we can't get valid width data, exit completely */
                while ((axisWidth = axisWrapper.getWidth()) == 0 || axisWidth > _myContainer.getWidth()) {
                    Thread.sleep(_axisTimeoutIncr);
                    if ((failCount += _axisTimeoutIncr) >= _axisTimeout)
                        return;
                }// w  w  w  .  ja  va 2  s . c om
                int xElemWidth = 0;
                final XAxisTimeLabel tvSent = (XAxisTimeLabel) _inflater.inflate(R.layout.x_axis_time_label,
                        null);
                tvSent.setTag("sentinel_x_axis_view");
                tvSent.setTextSize(_axisFontSz);
                /* sacrifice first time-stamp for size info, otherwise block */
                //TODO: re-think why we have to sacrifice it ??
                // could be a big deal on narrow charts
                tvSent.setText(_timeStampQueue.take());
                /*    Log.d("Data-Consumer-Time-Take",                                 
                String.valueOf(lastElem) 
                );*/
                final ConditionVariable cond = new ConditionVariable();
                _guiThrdHndlr.post(new Runnable() {
                    public void run() {
                        tvSent.setVisibility(View.INVISIBLE);
                        _timeAxis.addView(tvSent);
                        cond.open();
                    }
                });
                cond.block();
                cond.close();
                final XAxisTimeLabel tvSentB = (XAxisTimeLabel) _timeAxis
                        .findViewWithTag("sentinel_x_axis_view");
                failCount = 0;
                while ((xElemWidth = tvSentB.getWidth()) == 0) {
                    Thread.sleep(_axisTimeoutIncr);
                    if ((failCount += _axisTimeoutIncr) >= _axisTimeout)
                        return;
                }
                _guiThrdHndlr.post(new Runnable() {
                    public void run() {
                        _timeAxis.removeView(tvSentB);
                    }
                });
                /* how much space we'll need to 'stradle' price segs */
                int adjElem = xElemWidth + _xAxisPadSz;
                int reqPriceSegs = (int) Math.ceil((double) adjElem / _priceSegWdth);
                if ((reqPriceSegs % 2) == 0)
                    ++reqPriceSegs;
                adjElem = reqPriceSegs * _priceSegWdth;
                /* how much space is open for  a new view at each iteration*/
                int openSpace = _priceSegWdth * (reqPriceSegs / 2);
                /* also, do we need to drop views from the other side ? */
                int fullSpace = _priceSegWdth * (reqPriceSegs / 2);
                CharSequence cachedElem = null;
                int rOffset = _myResources.getDimensionPixelSize(R.dimen.chart_frag_trad_segs_right_padding);
                /* a view to hold open space that isn't big enough yet */
                final XAxisTimeLabel spaceHolder = (XAxisTimeLabel) _inflater
                        .inflate(R.layout.x_axis_time_label, null);
                spaceHolder.setTag("front_adj_x_axis_view");
                spaceHolder.setVisibility(View.INVISIBLE);

                /// START MAIN TIME-STAMP UPDATE LOOP ///
                while (!this.isInterrupted()) {
                    CharSequence lastElem = _timeStampQueue.take();
                    /*    Log.d("Data-Consumer-Time-Take",                                 
                        String.valueOf(lastElem) 
                        );*/
                    openSpace += _priceSegWdth;
                    /* if no open space but need THIS element */
                    if ((openSpace >= (adjElem / 2)) && cachedElem == null)
                        cachedElem = lastElem;
                    /* if this pushes past the container limits, drop oldest */
                    if ((fullSpace + _priceSegWdth) > (axisWidth - rOffset)) {
                        _guiThrdHndlr.post(new Runnable() {
                            public void run() { /* be sure its big enough */
                                if (_timeAxis.getChildCount() > 0)
                                    _timeAxis.removeViewAt(0);
                                _timeAxis.forceLayout();
                            }
                        });
                        fullSpace -= adjElem;
                    }
                    /* if element cached and open space for it is large enough */
                    if ((cachedElem != null) && openSpace == adjElem) {
                        final XAxisTimeLabel tvVal = (XAxisTimeLabel) _inflater
                                .inflate(R.layout.x_axis_time_label, null);
                        tvVal.setTag("valid_x_axis_view");
                        tvVal.setTextSize(_axisFontSz);
                        tvVal.setTextColor(_axisFontColor);
                        tvVal.setText(cachedElem);
                        tvVal.setWidth(adjElem);
                        _guiThrdHndlr.post(new Runnable() {
                            public void run() {
                                /* remove the view holding space */
                                _timeAxis.removeView(spaceHolder);
                                _timeAxis.addView(tvVal);
                                spaceHolder.setWidth(0);
                                spaceHolder.invalidate();
                                /* after adjusting re-insert at front */
                                _timeAxis.addView(spaceHolder);
                                _timeAxis.forceLayout();
                            }
                        });
                        /* no open space and that much more full space */
                        cachedElem = null;
                        openSpace = 0;
                        fullSpace += _priceSegWdth;
                    } else { /* if no element cached or not enough space */
                        final int fOpenSpace = openSpace;
                        _guiThrdHndlr.post(new Runnable() {
                            public void run() {
                                /* shift all views left regardless */
                                spaceHolder.setWidth(fOpenSpace);
                                spaceHolder.invalidate();
                                _timeAxis.forceLayout();
                            }
                        });
                        fullSpace += _priceSegWdth;
                    }
                }
                ///    END MAIN TIME-STAMP UPDATE LOOP    ///                        
            } catch (InterruptedException e) {
            } catch (RuntimeException e) {
                throw e;
            } finally {
                _activeThreads.remove(this);
                _timeAxisLck.unlock();
            }
        }
    };
    _activeThreads.add(thisThread);
    thisThread.start();
}

From source file:com.jogden.spunkycharts.traditionalchart.TraditionalChartFragmentAdapter.java

private void _createPriceAxisY() {
    Thread thisThread = new Thread() {
        public void run() {
            ///////////////////////////////////
            /*     START PREEMPTION LOGIC     */
            /////////////////////////////////
            boolean noWait;
            final int MAX_PREEMPT_COUNT = ApplicationPreferences.getMaxPreemptCount();
            if (!(noWait = _priceAxisLck.tryLock())) {
                synchronized (_priceAxisThrdMntr) {
                    if (_priceAxisPrmptCnt++ > MAX_PREEMPT_COUNT)
                        return;
                    if (_priceAxisThrd != null)
                        _priceAxisThrd.interrupt();
                }/*  w  w  w. java2s . c  o m*/
                _priceAxisPrmptStck.offer(this);
                _priceAxisLck.lock();
            }
            try { /* everything that follows should assume we own monitor */
                if (!noWait) {
                    if (this != _priceAxisPrmptStck.peekLast())
                        return;
                    else { /* don't assume stack hasn't grown since the peek */
                        Iterator<Thread> dIter = _priceAxisPrmptStck.iterator();
                        do {
                            _priceAxisPrmptStck.poll();
                        } while (dIter.next() != this);
                    }
                }
                synchronized (_priceAxisThrdMntr) {
                    _priceAxisThrd = this;
                }
                /////////////////////////////////
                /*     END PREEMPTION LOGIC     */
                ///////////////////////////////
                _updateLtch.await(); /* wait for historic data to be inserted */
                float rangeDiff = _highPriceDsply - _lowPriceDsply;
                /* deal with problematic high/low parameters */
                if (rangeDiff <= 0 || _highPriceDsply < 0 || _lowPriceDsply < 0)
                    if (rangeDiff == 0 && _highPriceDsply > 0) {
                        _highPriceDsply *= 1.001;
                        _lowPriceDsply *= .999;
                        rangeDiff = _highPriceDsply - _lowPriceDsply;
                        _priceSgmnt.setYRange(_highPriceDsply, _lowPriceDsply, _highPrice, _lowPrice);
                    } else
                        throw new IllegalStateException("Invalid high and/or low price in the ChartAdapter");
                /* if we haven't calculated the height of a price-label view */
                if (_priceElemHght == 0) {/* can cached value doesn't go stale? */
                    final YAxisPriceLabel tv1 = (YAxisPriceLabel) _inflater.inflate(R.layout.y_axis_price_label,
                            null);
                    tv1.setText("X");
                    tv1.setTextSize(_axisFontSz);
                    tv1.setVisibility(View.INVISIBLE);
                    final ConditionVariable cond = new ConditionVariable();
                    _guiThrdHndlr.post(new Runnable() {
                        public void run() {
                            _priceAxis.removeAllViews();
                            _priceAxis.addView(tv1);
                            cond.open();
                        }
                    });
                    cond.block();
                    cond.close();
                    YAxisPriceLabel tv1b = (YAxisPriceLabel) _priceAxis.getChildAt(0);
                    /* make sure a valid priceElemHeightt, or quit entirely */
                    /* just spin, a new thread preempts us anyway */
                    while ((_priceElemHght = tv1b.getHeight()) == 0)
                        Thread.sleep(_axisTimeoutIncr);
                }
                _guiThrdHndlr.post(new Runnable() {
                    public void run() {
                        _priceAxis.removeAllViews();
                    }
                });
                int totalHeight;
                /* make sure a valid totalHeight, or quit entirely */
                /* just spin, a new thread preempts us anyway */
                while ((totalHeight = _priceAxis.getHeight()) == 0 || totalHeight > _myContainer.getHeight())
                    Thread.sleep(_axisTimeoutIncr);
                float[] incrVals = new float[2];
                try {
                    int maxNodes = (int) (totalHeight / _priceElemHght);
                    if (rangeDiff < 0 || maxNodes < 0)
                        throw new TraditionalChartLogicError("rangeDiff and maxNodes can't be negative.");
                    /* call down to our native sub to find increment values */
                    incrVals = MainApplication.IncrementRegressNative(rangeDiff, maxNodes);
                    if (incrVals[0] < 0 || incrVals[1] <= 0)
                        throw new TraditionalChartLogicError("IncrementRegressNative() sub-routine aborted. "
                                + "retVals[0]: " + incrVals[0] + "retVals[1]: " + incrVals[1] + "adjRangeDiff: "
                                + rangeDiff + "maxNodes" + maxNodes);
                } catch (TraditionalChartLogicError e) {
                    Log.e("TraditionalChartLogicError", e.getMessage());
                    return; /* just leave the axis empty*/
                }

                /* adjust height to new increment values */
                final int adjPriceElemHeight = (int) (totalHeight / (int) incrVals[1]);
                /* we'll need to account for any unused space in the axis */
                final int vacantHeight = totalHeight - (int) (adjPriceElemHeight * (int) incrVals[1]);
                double distFromIncr = Math.IEEEremainder((double) _highPriceDsply,
                        (double) incrVals[0]); /* distance from rounded incr */
                double adjTopNodeVal = (double) _highPriceDsply - distFromIncr;
                if (distFromIncr > 0) /* be sure to round to the upper incr */
                    adjTopNodeVal += incrVals[0];
                DecimalFormat df = new DecimalFormat("0.00");
                double lastNodeVal = adjTopNodeVal;
                int count = 0;
                do { /* loop through the increments */
                    final YAxisPriceLabel tv = (YAxisPriceLabel) _inflater.inflate(R.layout.y_axis_price_label,
                            null);
                    tv.setTextSize(_axisFontSz);
                    tv.setText(df.format(lastNodeVal));
                    tv.setTextColor(_axisFontColor);
                    tv.setLayoutParams(
                            new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 0, 1));
                    _guiThrdHndlr.post(new Runnable() {
                        public void run() {
                            _priceAxis.addView(tv);
                        }
                    }); /* for the loop-contingent side-effect */
                } while (++count < (int) incrVals[1] && (lastNodeVal -= incrVals[0]) > 0);
                /* values for padding the axis and adjusting the segments */
                final double adjTopNodeOffset = ((adjTopNodeVal - _highPriceDsply) / rangeDiff) * totalHeight;
                final double adjBottomNodeOffset = ((_lowPriceDsply - lastNodeVal) / rangeDiff) * totalHeight;
                final float halfVacantHeight = vacantHeight / 2;
                final float halfPriceElemHeight = adjPriceElemHeight / 2;
                final int topBuf = (int) (adjTopNodeOffset + halfVacantHeight + halfPriceElemHeight);
                final int bottomBuf = (int) (adjBottomNodeOffset + halfVacantHeight + halfPriceElemHeight);
                /* adjust price segments so they align w/ axis vals */
                _priceSgmnt.setVerticalBuffers(topBuf, bottomBuf);
                _guiThrdHndlr.post(new Runnable() {
                    public void run() {
                        _priceAxis.setPadding( /* center price-views */
                                0, (int) halfVacantHeight, 0, (int) halfVacantHeight);
                        _priceAxis.setClipChildren(false);
                        _priceAxis.setClipToPadding(false);
                        _priceAxis.invalidate();
                        _priceSgmnt.forceDraw();
                    }
                });
                synchronized (_priceAxisThrdMntr) {
                    _priceAxisPrmptCnt = 0;
                }
            } catch (InterruptedException e) {
            } catch (IllegalStateException e) {
                Log.d("IllegalState(High, Low): ", "IllegalStateException caught in _createPriceAxisY: "
                        + Float.toString(_highPriceDsply) + " - " + Float.toString(_lowPriceDsply));
            } catch (RuntimeException e) {
                e.printStackTrace();
                throw e;
            } finally {
                synchronized (_priceAxisThrdMntr) {
                    _priceAxisThrd = null;
                }
                _activeThreads.remove(this);
                _priceAxisLck.unlock();
            }
        }
    };
    _activeThreads.add(thisThread);
    thisThread.start();
}