package interdroid.swan.engine; import interdroid.swan.swansong.Expression; import interdroid.swan.swansong.Result; import interdroid.swan.swansong.TimestampedValue; import interdroid.swan.swansong.TriStateExpression; import interdroid.swan.swansong.ValueExpression; import android.content.Intent; import android.os.Bundle; public class QueuedExpression implements Comparable<QueuedExpression> { private Expression mExpression; private String mId; private Result mCurrentResult; private Intent mOnTrue; private Intent mOnFalse; private Intent mOnUndefined; private Intent mOnNewValues; private long mStartTime; private int mEvaluations; // number of evaluations private long mTotalEvaluationTime; // total time spent on evaluations so far private long mMinEvaluationTime = Long.MAX_VALUE; private long mMaxEvaluationTime = Long.MIN_VALUE; private long mTotalEvaluationDelay; // total delay private long mNumEvaluationsDelay; // number of evaluations with delay public QueuedExpression(String id, Expression expression, Intent onTrue, Intent onFalse, Intent onUndefined, Intent onNewValues) { mId = id; mExpression = expression; mStartTime = System.currentTimeMillis(); mOnTrue = onTrue; mOnFalse = onFalse; mOnUndefined = onUndefined; mOnNewValues = onNewValues; } public int compareTo(QueuedExpression another) { return mCurrentResult.compareTo(another.mCurrentResult); }; public Expression getExpression() { return mExpression; } public String getId() { return mId; } /** * update the current result and return whether this update caused a change * * @param result * @return */ public boolean update(Result result) { if (mExpression instanceof TriStateExpression && mCurrentResult != null && mCurrentResult.getTriState() == result.getTriState()) { mCurrentResult = result; return false; } else if (mExpression instanceof ValueExpression && mCurrentResult != null && !hasChanged(mCurrentResult.getValues(), result.getValues())) { mCurrentResult = result; return false; } mCurrentResult = result; return true; } private boolean hasChanged(TimestampedValue[] a, TimestampedValue[] b) { if (a == null || b == null) { return true; } if (a.length != b.length) { return true; } for (int i = 0; i < a.length; i++) { if (!a[i].equals(b[i])) { return true; } } return false; } public long getDeferUntil() { if (mCurrentResult != null) { return mCurrentResult.getDeferUntil(); } else { // we don't have a current result yet, so we can't defer return 0; } } public boolean isDeferUntilGuaranteed() { if (mCurrentResult != null) { return mCurrentResult.isDeferUntilGuaranteed(); } else { // we don't have a current result yet, so we can't defer return false; } } public String toString() { String id = mId; if (mId.contains(Expression.SEPARATOR)) { id = "<remote> " + mId.split(Expression.SEPARATOR, 2)[1]; } return id; } public void evaluated(long currentEvalutionTime, long evalDelay) { mEvaluations += 1; mTotalEvaluationTime += currentEvalutionTime; mMinEvaluationTime = Math.min(mMinEvaluationTime, currentEvalutionTime); mMaxEvaluationTime = Math.max(mMaxEvaluationTime, currentEvalutionTime); if (evalDelay != 0) { mTotalEvaluationDelay += evalDelay; mNumEvaluationsDelay += 1; } } public Bundle toBundle() { Bundle bundle = new Bundle(); bundle.putLong("start-time", mStartTime); bundle.putString("name", mId); bundle.putString("result", mCurrentResult == null ? "n.a." : mCurrentResult.toString()); bundle.putDouble( "evaluation-rate", (mEvaluations / ((System.currentTimeMillis() - mStartTime) / 1000.0))); bundle.putLong("min-evaluation-time", mMinEvaluationTime); bundle.putLong("max-evaluation-time", mMaxEvaluationTime); bundle.putLong("avg-evaluation-time", (mTotalEvaluationTime / Math.max(mEvaluations, 1))); bundle.putFloat("evaluation-percentage", ((mTotalEvaluationTime * 100) / (float) (System .currentTimeMillis() - mStartTime))); bundle.putLong("avg-evaluation-delay", (mTotalEvaluationDelay / Math.max(mNumEvaluationsDelay, 1))); return bundle; } public Intent getIntent(Result result) { if (mExpression instanceof TriStateExpression) { switch (result.getTriState()) { case TRUE: return mOnTrue; case FALSE: return mOnFalse; case UNDEFINED: return mOnUndefined; } } return mOnNewValues; } public Intent getOnTrue() { return mOnTrue; } public Intent getOnFalse() { return mOnFalse; } public Intent getOnUndefined() { return mOnUndefined; } public Intent getOnNewValues() { return mOnNewValues; } }