mirror of
				https://github.com/chibicitiberiu/rainmeter-studio.git
				synced 2024-02-24 04:33:31 +00:00 
			
		
		
		
	Calc/MathParser: Minor tweaks.
This commit is contained in:
		@@ -19,6 +19,7 @@
 | 
				
			|||||||
// Heavily based on ccalc 0.5.1 by Walery Studennikov <hqsoftware@mail.ru>
 | 
					// Heavily based on ccalc 0.5.1 by Walery Studennikov <hqsoftware@mail.ru>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "StdAfx.h"
 | 
					#include "StdAfx.h"
 | 
				
			||||||
 | 
					#include "MeasureCalc.h"
 | 
				
			||||||
#include "MathParser.h"
 | 
					#include "MathParser.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const int MAX_STACK_SIZE = 32;
 | 
					static const int MAX_STACK_SIZE = 32;
 | 
				
			||||||
@@ -261,7 +262,7 @@ char* MathParser::CheckParse(const char* formula, double* result)
 | 
				
			|||||||
	return NULL;
 | 
						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)
 | 
						if (!formula || !*formula)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -396,7 +397,7 @@ char* MathParser::Parse(const char* formula, ParameterSearchProc searchProc, dou
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
				else
 | 
									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;
 | 
											g_ValStack[++g_ValTop] = dblval;
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,15 +21,15 @@
 | 
				
			|||||||
#ifndef __MATHPARSER_H__
 | 
					#ifndef __MATHPARSER_H__
 | 
				
			||||||
#define __MATHPARSER_H__
 | 
					#define __MATHPARSER_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CMeasureCalc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MathParser
 | 
					namespace MathParser
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	typedef int (*ParameterSearchProc)(const char* str, int len, double* value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void Initialize();
 | 
						void Initialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char* Check(const char* formula);
 | 
						char* Check(const char* formula);
 | 
				
			||||||
	char* CheckParse(const char* formula, double* result);
 | 
						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
 | 
					#endif
 | 
				
			||||||
@@ -21,7 +21,6 @@
 | 
				
			|||||||
#include "Rainmeter.h"
 | 
					#include "Rainmeter.h"
 | 
				
			||||||
#include "MathParser.h"
 | 
					#include "MathParser.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CMeterWindow* CMeasureCalc::c_MeterWindow = NULL;
 | 
					 | 
				
			||||||
bool CMeasureCalc::c_RandSeeded = false;
 | 
					bool CMeasureCalc::c_RandSeeded = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@@ -31,6 +30,7 @@ bool CMeasureCalc::c_RandSeeded = false;
 | 
				
			|||||||
**
 | 
					**
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
CMeasureCalc::CMeasureCalc(CMeterWindow* meterWindow, const WCHAR* name) : CMeasure(meterWindow, name),
 | 
					CMeasureCalc::CMeasureCalc(CMeterWindow* meterWindow, const WCHAR* name) : CMeasure(meterWindow, name),
 | 
				
			||||||
 | 
						m_Random(),
 | 
				
			||||||
	m_LowBound(),
 | 
						m_LowBound(),
 | 
				
			||||||
	m_HighBound(100),
 | 
						m_HighBound(100),
 | 
				
			||||||
	m_UpdateRandom(false)
 | 
						m_UpdateRandom(false)
 | 
				
			||||||
@@ -64,12 +64,9 @@ bool CMeasureCalc::Update()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	if (!CMeasure::PreUpdate()) return false;
 | 
						if (!CMeasure::PreUpdate()) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (m_UpdateRandom)
 | 
						if (m_UpdateRandom) UpdateRandom();
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		FormulaReplace();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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)
 | 
						if (errMsg != NULL)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		std::wstring error = L"Calc: ";
 | 
							std::wstring error = L"Calc: ";
 | 
				
			||||||
@@ -83,29 +80,6 @@ bool CMeasureCalc::Update()
 | 
				
			|||||||
	return PostUpdate();
 | 
						return PostUpdate();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int CMeasureCalc::MatchMeasure(const char* str, int len, double* value)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	const std::list<CMeasure*>& measures = c_MeterWindow->GetMeasures();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	std::list<CMeasure*>::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
 | 
					** ReadConfig
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
@@ -121,6 +95,7 @@ void CMeasureCalc::ReadConfig(CConfigParser& parser, const WCHAR* section)
 | 
				
			|||||||
	int oldHighBound = m_HighBound;
 | 
						int oldHighBound = m_HighBound;
 | 
				
			||||||
	bool oldUpdateRandom = m_UpdateRandom;
 | 
						bool oldUpdateRandom = m_UpdateRandom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::wstring oldFormula = m_Formula;
 | 
				
			||||||
	m_Formula = parser.ReadString(section, L"Formula", L"");
 | 
						m_Formula = parser.ReadString(section, L"Formula", L"");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m_LowBound = parser.ReadInt(section, L"LowBound", 0);
 | 
						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);
 | 
						m_UpdateRandom = 0!=parser.ReadInt(section, L"UpdateRandom", 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!m_Initialized ||
 | 
						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 ||
 | 
							oldLowBound != m_LowBound ||
 | 
				
			||||||
		oldHighBound != m_HighBound ||
 | 
							oldHighBound != m_HighBound ||
 | 
				
			||||||
		oldUpdateRandom != m_UpdateRandom)
 | 
							oldUpdateRandom != m_UpdateRandom)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// Hold onto the formula, we are going to change it
 | 
							if (!m_UpdateRandom) UpdateRandom();
 | 
				
			||||||
		m_FormulaHolder = m_Formula;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (!m_UpdateRandom)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			FormulaReplace();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		char* errMsg = MathParser::Check(ConvertToAscii(m_Formula.c_str()).c_str());
 | 
							char* errMsg = MathParser::Check(ConvertToAscii(m_Formula.c_str()).c_str());
 | 
				
			||||||
		if (errMsg != NULL)
 | 
							if (errMsg != NULL)
 | 
				
			||||||
@@ -154,65 +123,37 @@ void CMeasureCalc::ReadConfig(CConfigParser& parser, const WCHAR* section)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					bool CMeasureCalc::GetMeasureValue(const char* str, int len, double* value)
 | 
				
			||||||
** FormulaReplace
 | 
					 | 
				
			||||||
**
 | 
					 | 
				
			||||||
** This replaces the word Random in m_Formula with a random number
 | 
					 | 
				
			||||||
**
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
void CMeasureCalc::FormulaReplace()
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// To implement random numbers the word "Random" in the string
 | 
						const std::list<CMeasure*>& measures = m_MeterWindow->GetMeasures();
 | 
				
			||||||
	// formula is being replaced by the random number value
 | 
					 | 
				
			||||||
	m_Formula = m_FormulaHolder;
 | 
					 | 
				
			||||||
	size_t start = 0, pos;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do
 | 
						std::list<CMeasure*>::const_iterator iter = measures.begin();
 | 
				
			||||||
 | 
						for ( ; iter != measures.end(); ++iter)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		pos = m_Formula.find_first_of(L"Rr", start);
 | 
							if (_strnicmp(str, (*iter)->GetAsciiName(), len) == 0)
 | 
				
			||||||
		if (pos != std::wstring::npos)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (_wcsnicmp(L"Random", m_Formula.c_str() + pos, 6) == 0 &&
 | 
								*value = (*iter)->GetValue();
 | 
				
			||||||
				(pos == 0 || IsDelimiter(*(m_Formula.c_str() + pos - 1))) &&
 | 
								return 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;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,25 +29,22 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	virtual bool Update();
 | 
						virtual bool Update();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static void SetCurrentMeterWindow(CMeterWindow* meterWindow) { c_MeterWindow = meterWindow; }
 | 
						bool GetMeasureValue(const char* str, int len, double* value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
	virtual void ReadConfig(CConfigParser& parser, const WCHAR* section);
 | 
						virtual void ReadConfig(CConfigParser& parser, const WCHAR* section);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void FormulaReplace();
 | 
						void UpdateRandom();
 | 
				
			||||||
	bool IsDelimiter(WCHAR ch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	static int MatchMeasure(const char* str, int len, double* value);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::wstring m_Formula;
 | 
						std::wstring m_Formula;
 | 
				
			||||||
	std::wstring m_FormulaHolder;
 | 
					
 | 
				
			||||||
 | 
						int m_Random;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int m_LowBound;
 | 
						int m_LowBound;
 | 
				
			||||||
	int m_HighBound;
 | 
						int m_HighBound;
 | 
				
			||||||
	bool m_UpdateRandom;
 | 
						bool m_UpdateRandom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static CMeterWindow* c_MeterWindow;
 | 
					 | 
				
			||||||
	static bool c_RandSeeded;
 | 
						static bool c_RandSeeded;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1414,12 +1414,6 @@ void CMeterWindow::UpdateMeasure(const WCHAR* name, bool group)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	if (name == NULL || *name == 0) return;
 | 
						if (name == NULL || *name == 0) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Pre-updates
 | 
					 | 
				
			||||||
	if (!m_Measures.empty())
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		CMeasureCalc::SetCurrentMeterWindow(this);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool bNetStats = m_HasNetMeasures;
 | 
						bool bNetStats = m_HasNetMeasures;
 | 
				
			||||||
	std::list<CMeasure*>::const_iterator i = m_Measures.begin();
 | 
						std::list<CMeasure*>::const_iterator i = m_Measures.begin();
 | 
				
			||||||
	for ( ; i != m_Measures.end(); ++i)
 | 
						for ( ; i != m_Measures.end(); ++i)
 | 
				
			||||||
@@ -2944,7 +2938,6 @@ void CMeterWindow::Update(bool nodraw)
 | 
				
			|||||||
			CMeasureNet::UpdateIFTable();
 | 
								CMeasureNet::UpdateIFTable();
 | 
				
			||||||
			CMeasureNet::UpdateStats();
 | 
								CMeasureNet::UpdateStats();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		CMeasureCalc::SetCurrentMeterWindow(this);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Update all measures
 | 
							// Update all measures
 | 
				
			||||||
		std::list<CMeasure*>::const_iterator i = m_Measures.begin();
 | 
							std::list<CMeasure*>::const_iterator i = m_Measures.begin();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user