diff --git a/Library/MathParser.cpp b/Library/MathParser.cpp index 4dcc0969..647ccbed 100644 --- a/Library/MathParser.cpp +++ b/Library/MathParser.cpp @@ -19,6 +19,7 @@ // Heavily based on ccalc 0.5.1 by Walery Studennikov #include "StdAfx.h" +#include "MeasureCalc.h" #include "MathParser.h" static const int MAX_STACK_SIZE = 32; @@ -261,7 +262,7 @@ char* MathParser::CheckParse(const char* formula, double* result) return NULL; } -char* MathParser::Parse(const char* formula, ParameterSearchProc searchProc, double* result) +char* MathParser::Parse(const char* formula, CMeasureCalc* calc, double* result) { if (!formula || !*formula) { @@ -396,7 +397,7 @@ char* MathParser::Parse(const char* formula, ParameterSearchProc searchProc, dou } else { - if (searchProc && (*searchProc)(g_Lexer.name, g_Lexer.nameLen, &dblval)) + if (calc && calc->GetMeasureValue(g_Lexer.name, g_Lexer.nameLen, &dblval)) { g_ValStack[++g_ValTop] = dblval; break; diff --git a/Library/MathParser.h b/Library/MathParser.h index 414532a5..e9588a08 100644 --- a/Library/MathParser.h +++ b/Library/MathParser.h @@ -21,15 +21,15 @@ #ifndef __MATHPARSER_H__ #define __MATHPARSER_H__ +class CMeasureCalc; + namespace MathParser { - typedef int (*ParameterSearchProc)(const char* str, int len, double* value); - void Initialize(); char* Check(const char* formula); char* CheckParse(const char* formula, double* result); - char* Parse(const char* formula, ParameterSearchProc searchProc, double* result); + char* Parse(const char* formula, CMeasureCalc* calc, double* result); }; #endif \ No newline at end of file diff --git a/Library/MeasureCalc.cpp b/Library/MeasureCalc.cpp index c89e360b..a4841c99 100644 --- a/Library/MeasureCalc.cpp +++ b/Library/MeasureCalc.cpp @@ -21,7 +21,6 @@ #include "Rainmeter.h" #include "MathParser.h" -CMeterWindow* CMeasureCalc::c_MeterWindow = NULL; bool CMeasureCalc::c_RandSeeded = false; /* @@ -31,6 +30,7 @@ bool CMeasureCalc::c_RandSeeded = false; ** */ CMeasureCalc::CMeasureCalc(CMeterWindow* meterWindow, const WCHAR* name) : CMeasure(meterWindow, name), + m_Random(), m_LowBound(), m_HighBound(100), m_UpdateRandom(false) @@ -64,12 +64,9 @@ bool CMeasureCalc::Update() { if (!CMeasure::PreUpdate()) return false; - if (m_UpdateRandom) - { - FormulaReplace(); - } + if (m_UpdateRandom) UpdateRandom(); - char* errMsg = MathParser::Parse(ConvertToAscii(m_Formula.c_str()).c_str(), MatchMeasure, &m_Value); + char* errMsg = MathParser::Parse(ConvertToAscii(m_Formula.c_str()).c_str(), this, &m_Value); if (errMsg != NULL) { std::wstring error = L"Calc: "; @@ -83,29 +80,6 @@ bool CMeasureCalc::Update() return PostUpdate(); } -int CMeasureCalc::MatchMeasure(const char* str, int len, double* value) -{ - const std::list& measures = c_MeterWindow->GetMeasures(); - - std::list::const_iterator iter = measures.begin(); - for ( ; iter != measures.end(); ++iter) - { - if (_strnicmp(str, (*iter)->GetAsciiName(), len) == 0) - { - *value = (*iter)->GetValue(); - return 1; - } - } - - if (_strnicmp(str, "counter", len) == 0) - { - *value = c_MeterWindow->GetUpdateCounter(); - return 1; - } - - return 0; -} - /* ** ReadConfig ** @@ -121,6 +95,7 @@ void CMeasureCalc::ReadConfig(CConfigParser& parser, const WCHAR* section) int oldHighBound = m_HighBound; bool oldUpdateRandom = m_UpdateRandom; + std::wstring oldFormula = m_Formula; m_Formula = parser.ReadString(section, L"Formula", L""); m_LowBound = parser.ReadInt(section, L"LowBound", 0); @@ -128,18 +103,12 @@ void CMeasureCalc::ReadConfig(CConfigParser& parser, const WCHAR* section) m_UpdateRandom = 0!=parser.ReadInt(section, L"UpdateRandom", 0); if (!m_Initialized || - wcscmp(m_FormulaHolder.c_str(), m_Formula.c_str()) != 0 || + wcscmp(m_Formula.c_str(), oldFormula.c_str()) != 0 || oldLowBound != m_LowBound || oldHighBound != m_HighBound || oldUpdateRandom != m_UpdateRandom) { - // Hold onto the formula, we are going to change it - m_FormulaHolder = m_Formula; - - if (!m_UpdateRandom) - { - FormulaReplace(); - } + if (!m_UpdateRandom) UpdateRandom(); char* errMsg = MathParser::Check(ConvertToAscii(m_Formula.c_str()).c_str()); if (errMsg != NULL) @@ -154,65 +123,37 @@ void CMeasureCalc::ReadConfig(CConfigParser& parser, const WCHAR* section) } } -/* -** FormulaReplace -** -** This replaces the word Random in m_Formula with a random number -** -*/ -void CMeasureCalc::FormulaReplace() +bool CMeasureCalc::GetMeasureValue(const char* str, int len, double* value) { - // To implement random numbers the word "Random" in the string - // formula is being replaced by the random number value - m_Formula = m_FormulaHolder; - size_t start = 0, pos; + const std::list& measures = m_MeterWindow->GetMeasures(); - do + std::list::const_iterator iter = measures.begin(); + for ( ; iter != measures.end(); ++iter) { - pos = m_Formula.find_first_of(L"Rr", start); - if (pos != std::wstring::npos) + if (_strnicmp(str, (*iter)->GetAsciiName(), len) == 0) { - if (_wcsnicmp(L"Random", m_Formula.c_str() + pos, 6) == 0 && - (pos == 0 || IsDelimiter(*(m_Formula.c_str() + pos - 1))) && - (pos == (m_Formula.length() - 6) || IsDelimiter(*(m_Formula.c_str() + pos + 6)))) - { - int range = (m_HighBound - m_LowBound) + 1; - srand((unsigned) rand()); - int randNumber = m_LowBound + (int)(range * rand() / (RAND_MAX + 1.0)); - - WCHAR buffer[32]; - _itow_s(randNumber, buffer, 10); - size_t len = wcslen(buffer); - - m_Formula.replace(pos, 6, buffer, len); - start = pos + len; - } - else - { - start = pos + 1; - } - } - } - while (pos != std::wstring::npos); -} - -/* -** IsDelimiter -** -** Checks whether the given character is a operator or a delimiter. -** -*/ -bool CMeasureCalc::IsDelimiter(WCHAR ch) -{ - const WCHAR* symbols = L" \t\n()+-/*^~<>%$,?:=&|;"; - - for (const WCHAR* sch = symbols; *sch != L'\0'; ++sch) - { - if (ch == *sch) - { - return true; + *value = (*iter)->GetValue(); + return 1; } } - return false; + if (_strnicmp(str, "counter", len) == 0) + { + *value = m_MeterWindow->GetUpdateCounter(); + return 1; + } + else if (_strnicmp(str, "random", len) == 0) + { + *value = (double)m_Random; + return 1; + } + + return 0; +} + +void CMeasureCalc::UpdateRandom() +{ + int range = (m_HighBound - m_LowBound) + 1; + srand((unsigned)rand()); + m_Random = m_LowBound + (int)(range * rand() / (RAND_MAX + 1.0)); } diff --git a/Library/MeasureCalc.h b/Library/MeasureCalc.h index 368dcc77..251e7e26 100644 --- a/Library/MeasureCalc.h +++ b/Library/MeasureCalc.h @@ -29,25 +29,22 @@ public: virtual bool Update(); - static void SetCurrentMeterWindow(CMeterWindow* meterWindow) { c_MeterWindow = meterWindow; } + bool GetMeasureValue(const char* str, int len, double* value); protected: virtual void ReadConfig(CConfigParser& parser, const WCHAR* section); private: - void FormulaReplace(); - bool IsDelimiter(WCHAR ch); - - static int MatchMeasure(const char* str, int len, double* value); + void UpdateRandom(); std::wstring m_Formula; - std::wstring m_FormulaHolder; + + int m_Random; int m_LowBound; int m_HighBound; bool m_UpdateRandom; - static CMeterWindow* c_MeterWindow; static bool c_RandSeeded; }; diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index 5a31ac3f..9fc7a5c9 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -1414,12 +1414,6 @@ void CMeterWindow::UpdateMeasure(const WCHAR* name, bool group) { if (name == NULL || *name == 0) return; - // Pre-updates - if (!m_Measures.empty()) - { - CMeasureCalc::SetCurrentMeterWindow(this); - } - bool bNetStats = m_HasNetMeasures; std::list::const_iterator i = m_Measures.begin(); for ( ; i != m_Measures.end(); ++i) @@ -2944,7 +2938,6 @@ void CMeterWindow::Update(bool nodraw) CMeasureNet::UpdateIFTable(); CMeasureNet::UpdateStats(); } - CMeasureCalc::SetCurrentMeterWindow(this); // Update all measures std::list::const_iterator i = m_Measures.begin();