mirror of
				https://github.com/chibicitiberiu/rainmeter-studio.git
				synced 2024-02-24 04:33:31 +00:00 
			
		
		
		
	IfActions: Read condition options after measure value is changed to properly support section variables
This commit is contained in:
		| @@ -34,7 +34,6 @@ IfActions::IfActions(MeterWindow* meterWindow, Measure* measure) : | ||||
| 	m_EqualCommitted(false), | ||||
| 	m_Conditions(), | ||||
| 	m_HasConditions(false), | ||||
| 	m_HasDynamicVariables(false), | ||||
| 	m_MeterWindow(meterWindow), | ||||
| 	m_Measure(measure) | ||||
| { | ||||
| @@ -46,9 +45,6 @@ IfActions::~IfActions() | ||||
|  | ||||
| void IfActions::ReadOptions(ConfigParser& parser, const WCHAR* section) | ||||
| { | ||||
| 	m_Parser = &parser; | ||||
| 	m_HasDynamicVariables = m_Measure->HasDynamicVariables(); | ||||
|  | ||||
| 	m_AboveAction = parser.ReadString(section, L"IfAboveAction", L"", false); | ||||
| 	m_AboveValue = parser.ReadFloat(section, L"IfAboveValue", 0.0f); | ||||
|  | ||||
| @@ -57,25 +53,14 @@ void IfActions::ReadOptions(ConfigParser& parser, const WCHAR* section) | ||||
|  | ||||
| 	m_EqualAction = parser.ReadString(section, L"IfEqualAction", L"", false); | ||||
| 	m_EqualValue = (int64_t)parser.ReadFloat(section, L"IfEqualValue", 0.0f); | ||||
| 	 | ||||
| } | ||||
|  | ||||
| void IfActions::ReadConditionOptions(ConfigParser& parser, const WCHAR* section) | ||||
| { | ||||
| 	m_HasConditions = false; | ||||
| 	bool hasSelf = false; | ||||
| 	std::wstring condition; | ||||
|  | ||||
| 	if (m_HasDynamicVariables) | ||||
| 	{ | ||||
| 		condition = parser.GetValue(section, L"IfCondition", L""); | ||||
| 		if (!condition.empty() && ReplaceSelf(condition, section, L"[]", L"{}")) | ||||
| 		{ | ||||
| 			parser.SetValue(section, L"IfCondition", condition); | ||||
| 			hasSelf = true; | ||||
| 		} | ||||
| 	} | ||||
| 	condition = parser.ReadString(section, L"IfCondition", L""); | ||||
|  | ||||
| 	std::wstring condition = parser.ReadString(section, L"IfCondition", L""); | ||||
| 	std::wstring tAction = parser.ReadString(section, L"IfTrueAction", L"", false); | ||||
| 	std::wstring fAction = parser.ReadString(section, L"IfFalseAction", L"", false); | ||||
|  | ||||
| 	if (!condition.empty() && (!tAction.empty() || !fAction.empty())) | ||||
| 	{ | ||||
| 		m_HasConditions = true; | ||||
| @@ -89,11 +74,9 @@ void IfActions::ReadOptions(ConfigParser& parser, const WCHAR* section) | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				m_Conditions.emplace_back(condition, tAction, fAction, hasSelf); | ||||
| 				m_Conditions.emplace_back(condition, tAction, fAction); | ||||
| 			} | ||||
|  | ||||
| 			hasSelf = false; | ||||
|  | ||||
| 			// Check for IfCondition2/IfTrueAction2/IfFalseAction2 ... etc. | ||||
| 			std::wstring key = L"IfTrueAction" + std::to_wstring(++i); | ||||
| 			tAction = parser.ReadString(section, key.c_str(), L"", false); | ||||
| @@ -101,15 +84,6 @@ void IfActions::ReadOptions(ConfigParser& parser, const WCHAR* section) | ||||
| 			fAction = parser.ReadString(section, key.c_str(), L"", false); | ||||
|  | ||||
| 			key = L"IfCondition" + std::to_wstring(i); | ||||
| 			if (m_HasDynamicVariables) | ||||
| 			{ | ||||
| 				condition = parser.GetValue(section, key, L""); | ||||
| 				if (!condition.empty() && ReplaceSelf(condition, section, L"[]", L"{}")) | ||||
| 				{ | ||||
| 					parser.SetValue(section, key, condition); | ||||
| 					hasSelf = true; | ||||
| 				} | ||||
| 			} | ||||
| 			condition = parser.ReadString(section, key.c_str(), L""); | ||||
|  | ||||
| 		} | ||||
| @@ -175,13 +149,6 @@ void IfActions::DoIfActions(double& value) | ||||
| 			++i; | ||||
| 			if (!item.condition.empty() && (!item.tAction.empty() || !item.fAction.empty())) | ||||
| 			{ | ||||
| 				//Replace measures (need it here in case the if actions reference themselves) | ||||
| 				if (m_HasDynamicVariables && item.containsSelf) | ||||
| 				{ | ||||
| 					ReplaceSelf(item.condition, m_Measure->GetName(), L"{}", L"[]"); | ||||
| 					m_Parser->ReplaceMeasures(item.condition); | ||||
| 				} | ||||
|  | ||||
| 				double result = 0.0f; | ||||
| 				const WCHAR* errMsg = MathParser::Parse(item.condition.c_str(), &result, m_Measure->GetCurrentMeasureValue, m_Measure); | ||||
| 				if (errMsg != nullptr) | ||||
| @@ -235,36 +202,3 @@ void IfActions::SetState(double value) | ||||
| 		m_BelowCommitted = false; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* | ||||
| ** Replaces a [MeasureName] with {MeasureName} and vice-versa. | ||||
| ** This is needed to support IfConditions referencing themselves. | ||||
| */ | ||||
| bool IfActions::ReplaceSelf(std::wstring& condition, const WCHAR* section, | ||||
| 							const std::wstring sBracket, const std::wstring eBracket) | ||||
| { | ||||
| 	bool replaced = false; | ||||
| 	std::wstring measureName = sBracket; | ||||
| 	measureName.replace(1, 1, section); | ||||
|  | ||||
| 	size_t pos = 0; | ||||
| 	while ((pos = condition.find(measureName, pos)) != std::wstring::npos) | ||||
| 	{ | ||||
| 		condition.replace(pos, 1, eBracket.substr(0, 1)); | ||||
| 		pos = condition.find(sBracket.substr(1, 1), pos); | ||||
|  | ||||
| 		if (pos != std::wstring::npos) | ||||
| 		{ | ||||
| 			condition.replace(pos, 1, eBracket.substr(1, 1)); | ||||
| 			++pos; | ||||
| 			replaced = true; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			replaced = false;	// No closing bracket found | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return replaced; | ||||
| } | ||||
|   | ||||
| @@ -30,11 +30,10 @@ class MeterWindow; | ||||
| class IfCondition | ||||
| { | ||||
| public: | ||||
| 	IfCondition(std::wstring value, std::wstring trueAction, std::wstring falseAction, bool hasSelf = false) : | ||||
| 	IfCondition(std::wstring value, std::wstring trueAction, std::wstring falseAction) : | ||||
| 		condition(), | ||||
| 		tAction(), | ||||
| 		fAction(), | ||||
| 		containsSelf(hasSelf), | ||||
| 		parseError(false) | ||||
| 	{ | ||||
| 		Set(value, trueAction, falseAction); | ||||
| @@ -51,7 +50,6 @@ public: | ||||
| 	std::wstring tAction;		// IfTrueAction | ||||
| 	std::wstring fAction;		// IfFalseAction | ||||
| 	bool parseError; | ||||
| 	bool containsSelf; | ||||
| }; | ||||
|  | ||||
| class IfActions | ||||
| @@ -61,13 +59,11 @@ public: | ||||
| 	~IfActions(); | ||||
|  | ||||
| 	void ReadOptions(ConfigParser& parser, const WCHAR* section); | ||||
| 	void ReadConditionOptions(ConfigParser& parser, const WCHAR* section); | ||||
| 	void DoIfActions(double& value); | ||||
| 	void SetState(double value = 0.0f); | ||||
|  | ||||
| private: | ||||
| 	bool ReplaceSelf(std::wstring& condition, const WCHAR* section, | ||||
| 		const std::wstring sBracket, const std::wstring eBracket); | ||||
|  | ||||
| 	double m_AboveValue; | ||||
| 	double m_BelowValue; | ||||
| 	int64_t m_EqualValue; | ||||
| @@ -83,9 +79,6 @@ private: | ||||
| 	std::vector<IfCondition> m_Conditions; | ||||
| 	bool m_HasConditions; | ||||
|  | ||||
| 	bool m_HasDynamicVariables; | ||||
|  | ||||
| 	ConfigParser* m_Parser; | ||||
| 	MeterWindow* m_MeterWindow; | ||||
| 	Measure* m_Measure; | ||||
| }; | ||||
|   | ||||
| @@ -131,6 +131,13 @@ void Measure::ReadOptions(ConfigParser& parser, const WCHAR* section) | ||||
|  | ||||
| 	m_IfActions.ReadOptions(parser, section); | ||||
|  | ||||
| 	// The first time around, we read the conditions here. Subsequent rereads will be done in | ||||
| 	// Update() if needed. | ||||
| 	if (!m_Initialized) | ||||
| 	{ | ||||
| 		m_IfActions.ReadConditionOptions(parser, section); | ||||
| 	} | ||||
|  | ||||
| 	m_OnChangeAction = parser.ReadString(section, L"OnChangeAction", L"", false); | ||||
|  | ||||
| 	m_AverageSize = parser.ReadUInt(section, L"AverageSize", 0); | ||||
| @@ -437,8 +444,13 @@ std::wstring Measure::ExtractWord(std::wstring& buffer) | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| bool Measure::Update() | ||||
| bool Measure::Update(bool rereadOptions) | ||||
| { | ||||
| 	if (rereadOptions) | ||||
| 	{ | ||||
| 		ReadOptions(m_MeterWindow->GetParser()); | ||||
| 	} | ||||
|  | ||||
| 	// Don't do anything if paused | ||||
| 	if (m_Paused) return false; | ||||
|  | ||||
| @@ -497,6 +509,13 @@ bool Measure::Update() | ||||
|  | ||||
| 		m_ValueAssigned = true; | ||||
|  | ||||
| 		// For the conditional options to work with the current measure value when using | ||||
| 		// [MeasureName], we need to read the options after m_Value has been changed. | ||||
| 		if (rereadOptions) | ||||
| 		{ | ||||
| 			m_IfActions.ReadConditionOptions(m_MeterWindow->GetParser(), GetName()); | ||||
| 		} | ||||
|  | ||||
| 		if (m_MeterWindow) | ||||
| 		{ | ||||
| 			m_IfActions.DoIfActions(m_Value); | ||||
|   | ||||
| @@ -61,7 +61,7 @@ public: | ||||
| 	void ReadOptions(ConfigParser& parser) { ReadOptions(parser, GetName()); } | ||||
|  | ||||
| 	virtual void Initialize(); | ||||
| 	bool Update(); | ||||
| 	bool Update(bool rereadOptions = false); | ||||
|  | ||||
| 	void Disable(); | ||||
| 	void Enable(); | ||||
|   | ||||
| @@ -2675,13 +2675,9 @@ bool MeterWindow::UpdateMeasure(Measure* measure, bool force) | ||||
| 	int updateDivider = measure->GetUpdateDivider(); | ||||
| 	if (updateDivider >= 0 || force) | ||||
| 	{ | ||||
| 		if (measure->HasDynamicVariables() && | ||||
| 			(measure->GetUpdateCounter() + 1) >= updateDivider) | ||||
| 		{ | ||||
| 			measure->ReadOptions(m_Parser); | ||||
| 		} | ||||
|  | ||||
| 		bUpdate = measure->Update(); | ||||
| 		const bool rereadOptions = | ||||
| 			measure->HasDynamicVariables() && (measure->GetUpdateCounter() + 1) >= updateDivider; | ||||
| 		bUpdate = measure->Update(rereadOptions); | ||||
| 	} | ||||
|  | ||||
| 	return bUpdate; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Birunthan Mohanathas
					Birunthan Mohanathas