[dasher] Re-implement dynamic mode speed control:
- From: Patrick Welche <pwelche src gnome org>
- To: svn-commits-list gnome org
- Subject: [dasher] Re-implement dynamic mode speed control:
- Date: Wed, 17 Jun 2009 14:29:05 -0400 (EDT)
commit 825887a0dcbdcc0c08a354c9c7b7ed82292749a4
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date: Wed Jun 17 19:09:36 2009 +0100
Re-implement dynamic mode speed control:
Periodically increase speed as long as in a 'running' state; decrease
every time we start to reverse.
(Controlled by new settings for time period, increase and decrease,
added to both existing dynamic modes: LP_DYNAMIC_SPEED_{FREQ, INC, DEC}
respectively).
ChangeLog | 10 ++
Src/DasherCore/DynamicFilter.cpp | 27 +++++
Src/DasherCore/DynamicFilter.h | 11 +--
Src/DasherCore/OneButtonDynamicFilter.cpp | 7 +-
Src/DasherCore/Parameters.h | 14 ++-
Src/DasherCore/TwoButtonDynamicFilter.cpp | 152 +----------------------------
Src/DasherCore/TwoButtonDynamicFilter.h | 33 ------
7 files changed, 59 insertions(+), 195 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a9990af..92f45d2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2009-06-17 Alan Lawrence <acl33 inf phy cam ac uk>
+ * Re-implement dynamic mode speed control:
+ Periodically increase speed as long as in a 'running' state;
+ decrease every time we start to reverse.
+ (Controlled by new settings for time period, increase
+ and decrease, added to both existing dynamic modes:
+ LP_DYNAMIC_SPEED_{FREQ, INC, DEC} respectively).
+
+
+2009-06-17 Alan Lawrence <acl33 inf phy cam ac uk>
+
* Remove CDasherModel parameter to inputfilter constructor.
* Make DynamicFilter's states observable and changeable by
subclasses, and create a CButtonMultiPress subclass for
diff --git a/Src/DasherCore/DynamicFilter.cpp b/Src/DasherCore/DynamicFilter.cpp
index 8a7563c..6b05d90 100644
--- a/Src/DasherCore/DynamicFilter.cpp
+++ b/Src/DasherCore/DynamicFilter.cpp
@@ -37,6 +37,13 @@ bool CDynamicFilter::Timer(int iTime, CDasherView *m_pDasherView, CDasherModel *
}
if (isPaused()) return false;
if (isReversing()) return m_pDasherModel->OneStepTowards(41943,2048, iTime, pAdded, pNumDeleted);
+ //moving forwards. Check auto speed control...
+ if (GetLongParameter(BP_AUTO_SPEEDCONTROL) && m_iSpeedControlTime < iTime)
+ {
+ if (m_iSpeedControlTime > 0) //has actually been set?
+ SetLongParameter(LP_MAX_BITRATE, GetLongParameter(LP_MAX_BITRATE) * (1.0 + GetLongParameter(LP_DYNAMIC_SPEED_INC)/100.0));
+ m_iSpeedControlTime = iTime + 1000*GetLongParameter(LP_DYNAMIC_SPEED_FREQ);
+ }
return TimerImpl(iTime, m_pDasherView, m_pDasherModel, pAdded, pNumDeleted);
}
@@ -131,3 +138,23 @@ void CDynamicFilter::Event(int iTime, int iButton, int iType, CDasherModel *pMod
}
}
}
+
+void CDynamicFilter::reverse()
+{
+ m_iState = 1;
+ if (GetBoolParameter(BP_AUTO_SPEEDCONTROL))
+ {
+ //treat reversing as a sign of distress --> slow down!
+ SetLongParameter(LP_MAX_BITRATE, GetLongParameter(LP_MAX_BITRATE) *
+ (1.0 - GetLongParameter(LP_DYNAMIC_SPEED_DEC)/100.0));
+ }
+}
+
+void CDynamicFilter::run(int iSubclassState)
+{
+ DASHER_ASSERT(iSubclassState>=0);
+ if (m_iState<2) //wasn't running previously
+ m_iSpeedControlTime = 0; //will be set in Timer()
+ m_iState = iSubclassState+2;
+}
+
diff --git a/Src/DasherCore/DynamicFilter.h b/Src/DasherCore/DynamicFilter.h
index 86dd06e..b960e13 100644
--- a/Src/DasherCore/DynamicFilter.h
+++ b/Src/DasherCore/DynamicFilter.h
@@ -50,11 +50,8 @@ class CDynamicFilter : public CInputFilter {
bool isRunning(int &iSubclassState)
{if (m_iState < 2) return false; iSubclassState = m_iState-2; return true;}
virtual void pause() {m_iState = 0;}
- virtual void reverse() {m_iState = 1;}
- virtual void run(int iSubclassState) {
- DASHER_ASSERT(iSubclassState>=0);
- m_iState = iSubclassState+2;
- }
+ virtual void reverse();
+ virtual void run(int iSubclassState);
virtual bool TimerImpl(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted) = 0;
@@ -62,9 +59,9 @@ class CDynamicFilter : public CInputFilter {
int m_iState; // 0 = paused, 1 = reversing, >=2 = running (extensible by subclasses)
int m_iHeldId;
int m_iKeyDownTime;
-
+ int m_iSpeedControlTime;
+
CUserLogBase *m_pUserLog;
-
};
#endif
diff --git a/Src/DasherCore/OneButtonDynamicFilter.cpp b/Src/DasherCore/OneButtonDynamicFilter.cpp
index ab5fccc..727232b 100644
--- a/Src/DasherCore/OneButtonDynamicFilter.cpp
+++ b/Src/DasherCore/OneButtonDynamicFilter.cpp
@@ -32,7 +32,12 @@ static SModuleSettings sSettings[] = {
/* TRANSLATORS: Multiple button presses are special (like a generalisation on double clicks) in some situations. This is the number of times a button must be pressed to count as a multiple press.*/
{LP_MULTIPRESS_COUNT,T_LONG, 2, 10, 1, 1, _("Multiple press count")},
/* TRANSLATORS: Backoff = reversing in Dasher to correct mistakes. This allows a single button to be dedicated to activating backoff, rather than using multiple presses of other buttons.*/
- {BP_BACKOFF_BUTTON,T_BOOL, -1, -1, -1, -1, _("Enable backoff button")}
+ {BP_BACKOFF_BUTTON,T_BOOL, -1, -1, -1, -1, _("Enable backoff button")},
+ {BP_SLOW_START,T_BOOL, -1, -1, -1, -1, _("Slow startup")},
+ {LP_SLOW_START_TIME, T_LONG, 0, 10000, 1000, 100, _("Startup time")},
+ {LP_DYNAMIC_SPEED_INC, T_LONG, 1, 100, 1, 1, _("%age by which to automatically increase speed")},
+ {LP_DYNAMIC_SPEED_FREQ, T_LONG, 1, 1000, 1, 1, _("Time after which to automatically increase speed (secs)")},
+ {LP_DYNAMIC_SPEED_DEC, T_LONG, 1, 99, 1, 1, _("%age by which to decrease speed upon reverse")}
};
COneButtonDynamicFilter::COneButtonDynamicFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface)
diff --git a/Src/DasherCore/Parameters.h b/Src/DasherCore/Parameters.h
index ab20a9a..9bc5a34 100644
--- a/Src/DasherCore/Parameters.h
+++ b/Src/DasherCore/Parameters.h
@@ -44,7 +44,7 @@ enum {
BP_COMPASSMODE, BP_SOCKET_INPUT_ENABLE, BP_SOCKET_DEBUG,
BP_OLD_STYLE_PUSH, BP_CIRCLE_START, BP_GLOBAL_KEYBOARD,
BP_DELAY_VIEW, BP_CONVERSION_MODE, BP_PAUSE_OUTSIDE, BP_BACKOFF_BUTTON,
- BP_TWOBUTTON_REVERSE, BP_SLOW_START, BP_TWOBUTTON_SPEED, END_OF_BPS
+ BP_TWOBUTTON_REVERSE, BP_SLOW_START, END_OF_BPS
};
enum {
@@ -59,8 +59,9 @@ enum {
LP_BOOSTFACTOR, LP_AUTOSPEED_SENSITIVITY, LP_SOCKET_PORT, LP_SOCKET_INPUT_X_MIN, LP_SOCKET_INPUT_X_MAX,
LP_SOCKET_INPUT_Y_MIN, LP_SOCKET_INPUT_Y_MAX, LP_OX, LP_OY, LP_MAX_Y, LP_INPUT_FILTER,
LP_CIRCLE_PERCENT, LP_TWO_BUTTON_OFFSET, LP_HOLD_TIME, LP_MULTIPRESS_TIME, LP_MULTIPRESS_COUNT,
- LP_SLOW_START_TIME, LP_DYNAMIC_MEDIAN_FACTOR, LP_CONVERSION_ORDER, LP_CONVERSION_TYPE,
- LP_DEMO_SPRING, LP_DEMO_NOISE_MEM, LP_DEMO_NOISE_MAG, LP_MAXZOOM, END_OF_LPS
+ LP_SLOW_START_TIME, LP_CONVERSION_ORDER, LP_CONVERSION_TYPE,
+ LP_DEMO_SPRING, LP_DEMO_NOISE_MEM, LP_DEMO_NOISE_MAG, LP_MAXZOOM,
+ LP_DYNAMIC_SPEED_INC, LP_DYNAMIC_SPEED_FREQ, LP_DYNAMIC_SPEED_DEC, END_OF_LPS
};
enum {
@@ -160,7 +161,6 @@ static bp_table boolparamtable[] = {
{BP_BACKOFF_BUTTON, "BackoffButton", PERS, true, "Whether to enable the extra backoff button in dynamic mode"},
{BP_TWOBUTTON_REVERSE, "TwoButtonReverse", PERS, false, "Reverse the up/down buttons in two button mode"},
{BP_SLOW_START, "SlowStart", PERS, false, "Start at low speed and insrease"},
- {BP_TWOBUTTON_SPEED, "TwoButtonSpeed", PERS, true, "Two button mode auto speed control"}
};
static lp_table longparamtable[] = {
@@ -211,13 +211,15 @@ static lp_table longparamtable[] = {
{LP_MULTIPRESS_TIME, "MultipressTime", PERS, 1000, "Time in which multiple presses must occur, in ms"},
{LP_MULTIPRESS_COUNT, "MultipressCount", PERS, 2, "Time in which multiple presses must occur to count"},
{LP_SLOW_START_TIME, "SlowStartTime", PERS, 1000, "Time over which slow start occurs"},
- {LP_DYNAMIC_MEDIAN_FACTOR, "DynamicMedianFactor", PERS, 30, "Percentage of the median at which dynamic mode auto speed control kicks in"},
{LP_CONVERSION_ORDER, "ConversionOrder", PERS, 0, "Conversion ordering"},
{LP_CONVERSION_TYPE, "ConversionType", PERS, 0, "Conversion type"},
{LP_DEMO_SPRING, "DemoSpring", PERS, 100, "Springyness in Demo-mode"},
{LP_DEMO_NOISE_MEM, "DemoNoiseMem", PERS, 100, "Memory parameter for noise in Demo-mode"},
{LP_DEMO_NOISE_MAG, "DemoNoiseMag", PERS, 325, "Magnitude of noise in Demo-mode"},
- {LP_MAXZOOM, "ClickMaxZoom", PERS, 200, "Maximum zoom possible in click mode (times 10)"}
+ {LP_MAXZOOM, "ClickMaxZoom", PERS, 200, "Maximum zoom possible in click mode (times 10)"},
+ {LP_DYNAMIC_SPEED_INC, "DynamicSpeedInc", PERS, 1, "%age by which dynamic mode auto speed control increases speed"},
+ {LP_DYNAMIC_SPEED_FREQ, "DynamicSpeedFreq", PERS, 10, "Seconds after which dynamic mode auto speed control increases speed"},
+ {LP_DYNAMIC_SPEED_DEC, "DynamicSpeedDec", PERS, 10, "%age by which dynamic mode auto speed control decreases speed on reverse"},
};
static sp_table stringparamtable[] = {
diff --git a/Src/DasherCore/TwoButtonDynamicFilter.cpp b/Src/DasherCore/TwoButtonDynamicFilter.cpp
index 057f9b0..a7d490f 100644
--- a/Src/DasherCore/TwoButtonDynamicFilter.cpp
+++ b/Src/DasherCore/TwoButtonDynamicFilter.cpp
@@ -38,25 +38,13 @@ static SModuleSettings sSettings[] = {
{BP_TWOBUTTON_REVERSE,T_BOOL, -1, -1, -1, -1, _("Reverse up and down buttons")},
{BP_SLOW_START,T_BOOL, -1, -1, -1, -1, _("Slow startup")},
{LP_SLOW_START_TIME, T_LONG, 0, 10000, 1000, 100, _("Startup time")},
- {BP_TWOBUTTON_SPEED,T_BOOL, -1, -1, -1, -1, _("Auto speed control")},
- /* TRANSLATORS: The threshold time above which auto speed control is used. */
- {LP_DYNAMIC_MEDIAN_FACTOR, T_LONG, 10, 200, 100, 10, _("Auto speed threshold")}
+ {LP_DYNAMIC_SPEED_INC, T_LONG, 1, 100, 1, 1, _("%age by which to automatically increase speed")},
+ {LP_DYNAMIC_SPEED_FREQ, T_LONG, 1, 1000, 1, 1, _("Time after which to automatically increase speed (secs)")},
+ {LP_DYNAMIC_SPEED_DEC, T_LONG, 1, 99, 1, 1, _("%age by which to decrease speed upon reverse")}
};
CTwoButtonDynamicFilter::CTwoButtonDynamicFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface)
- : CButtonMultiPress(pEventHandler, pSettingsStore, pInterface, 14, 1, _("Two Button Dynamic Mode")) {
-
- m_iLastTime = -1;
-
- m_pTree = new SBTree(2000);
- m_pTree->Add(2000);
- m_pTree->Add(2000);
-}
-
-CTwoButtonDynamicFilter::~CTwoButtonDynamicFilter() {
- if(m_pTree)
- delete m_pTree;
-}
+ : CButtonMultiPress(pEventHandler, pSettingsStore, pInterface, 14, 1, _("Two Button Dynamic Mode")) { }
bool CTwoButtonDynamicFilter::DecorateView(CDasherView *pView) {
CDasherScreen *pScreen(pView->Screen());
@@ -117,15 +105,11 @@ void CTwoButtonDynamicFilter::ActionButton(int iTime, int iButton, int iType, CD
pModel->Offset(iFactor * GetLongParameter(LP_TWO_BUTTON_OFFSET));
if(pUserLog)
pUserLog->KeyDown(iButton, iType, 3);
- if(GetBoolParameter(BP_TWOBUTTON_SPEED))
- AutoSpeedSample(iTime, pModel);
}
else if((iButton == 3) || (iButton == 4)) {
pModel->Offset(iFactor * -GetLongParameter(LP_TWO_BUTTON_OFFSET));
if(pUserLog)
pUserLog->KeyDown(iButton, iType, 4);
- if(GetBoolParameter(BP_TWOBUTTON_SPEED))
- AutoSpeedSample(iTime, pModel);
}
else {
if(pUserLog)
@@ -140,134 +124,6 @@ bool CTwoButtonDynamicFilter::GetSettings(SModuleSettings **pSettings, int *iCou
return true;
};
-void CTwoButtonDynamicFilter::AutoSpeedSample(int iTime, CDasherModel *pModel) {
- if(m_iLastTime == -1) {
- m_iLastTime = iTime;
- return;
- }
-
- if(pModel->IsSlowdown(iTime))
- return;
-
- int iDiff(iTime - m_iLastTime);
- m_iLastTime = iTime;
- if(m_pTree) {
- int iMedian(m_pTree->GetOffset(m_pTree->GetCount() / 2));
- if((iDiff <= 300) || (iDiff < (iMedian * GetLongParameter(LP_DYNAMIC_MEDIAN_FACTOR)) / 100)) {
- pModel->TriggerSlowdown();
- }
- m_pTree->Add(iDiff);
- }
- else m_pTree = new SBTree(iDiff);
-
- m_deOffsetQueue.push_back(iDiff);
-
- while(m_deOffsetQueue.size() > 10) {
- m_pTree = m_pTree->Delete(m_deOffsetQueue.front());
- m_deOffsetQueue.pop_front();
- }
-}
-
-void CTwoButtonDynamicFilter::AutoSpeedUndo(int iCount) {
- for(int i(0); i < iCount; ++i) {
- if(m_deOffsetQueue.size() == 0)
- return;
-
- if(m_pTree)
- m_pTree = m_pTree->Delete(m_deOffsetQueue.back());
- m_deOffsetQueue.pop_back();
- }
-}
-
-CTwoButtonDynamicFilter::SBTree::SBTree(int iValue) {
- m_iValue = iValue;
- m_pLeft = NULL;
- m_pRight = NULL;
- m_iCount = 1;
-}
-
-CTwoButtonDynamicFilter::SBTree::~SBTree() {
- if(m_pLeft)
- delete m_pLeft;
-
- if(m_pRight)
- delete m_pRight;
-}
-
-void CTwoButtonDynamicFilter::SBTree::Add(int iValue) {
- ++m_iCount;
-
- if(iValue > m_iValue) {
- if(m_pRight)
- m_pRight->Add(iValue);
- else
- m_pRight = new SBTree(iValue);
- }
- else {
- if(m_pLeft)
- m_pLeft->Add(iValue);
- else
- m_pLeft = new SBTree(iValue);
- }
-}
-
-CTwoButtonDynamicFilter::SBTree* CTwoButtonDynamicFilter::SBTree::Delete(int iValue) {
- // Hmm... deleting is awkward in binary trees
-
- if(iValue == m_iValue) {
- if(!m_pLeft) {
- SBTree *pOldRight = m_pRight;
- m_pRight = NULL;
- delete this;
- return pOldRight;
- }
- else {
- SBTree *pOldLeft = m_pLeft;
- pOldLeft->SetRightMost(m_pRight);
- m_pLeft = NULL;
- m_pRight = NULL;
- delete this;
- return pOldLeft;
- }
- }
- else if(iValue > m_iValue) {
- --m_iCount;
- m_pRight = m_pRight->Delete(iValue);
- }
- else {
- --m_iCount;
- m_pLeft = m_pLeft->Delete(iValue);
- }
-
- return this;
-}
-
-void CTwoButtonDynamicFilter::SBTree::SetRightMost(CTwoButtonDynamicFilter::SBTree* pNewTree) {
- if(pNewTree)
- m_iCount += pNewTree->GetCount();
-
- if(m_pRight)
- m_pRight->SetRightMost(pNewTree);
- else
- m_pRight = pNewTree;
-}
-
-int CTwoButtonDynamicFilter::SBTree::GetOffset(int iOffset) {
- if(m_pLeft && (m_pLeft->GetCount() > iOffset))
- return m_pLeft->GetOffset(iOffset);
- else if((m_pLeft && (m_pLeft->GetCount() == iOffset)) || (!m_pLeft && (iOffset == 0)))
- return m_iValue;
- else if(m_pLeft)
- return m_pRight->GetOffset(iOffset - m_pLeft->GetCount() - 1);
- else
- return m_pRight->GetOffset(iOffset - 1);
-}
-
-void CTwoButtonDynamicFilter::RevertPresses(int iCount) {
- if(GetBoolParameter(BP_TWOBUTTON_SPEED))
- AutoSpeedUndo(iCount);
-}
-
bool CTwoButtonDynamicFilter::GetMinWidth(int &iMinWidth) {
iMinWidth = 1024;
return true;
diff --git a/Src/DasherCore/TwoButtonDynamicFilter.h b/Src/DasherCore/TwoButtonDynamicFilter.h
index 0a227a7..5219657 100644
--- a/Src/DasherCore/TwoButtonDynamicFilter.h
+++ b/Src/DasherCore/TwoButtonDynamicFilter.h
@@ -30,7 +30,6 @@
class CTwoButtonDynamicFilter : public CButtonMultiPress {
public:
CTwoButtonDynamicFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface);
- ~CTwoButtonDynamicFilter();
// Inherited methods
virtual bool DecorateView(CDasherView *pView);
@@ -45,38 +44,6 @@ class CTwoButtonDynamicFilter : public CButtonMultiPress {
private:
virtual bool TimerImpl(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted);
virtual void ActionButton(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog);
-
- virtual void RevertPresses(int iCount);
-
- void AutoSpeedSample(int iTime, CDasherModel *pModel);
- void AutoSpeedUndo(int iCount);
-
- class SBTree {
- public:
- SBTree(int iValue);
- ~SBTree();
-
- void Add(int iValue);
- SBTree* Delete(int iValue);
-
- int GetCount() {
- return m_iCount;
- };
-
- int GetOffset(int iOffset);
-
- void SetRightMost(SBTree* pNewTree);
-
- private:
- int m_iValue;
- SBTree *m_pLeft;
- SBTree *m_pRight;
- int m_iCount;
- };
-
- int m_iLastTime;
- SBTree *m_pTree;
- std::deque<int> m_deOffsetQueue;
};
/// @}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]