/* ** Updates the value(s) from the measures. ** */ bool CMeterBitmap::Update() { if (CMeter::Update() && !m_Measures.empty()) { CMeasure* measure = m_Measures[0]; double value = (m_Extend) ? measure->GetValue() : measure->GetRelativeValue(); if (m_TransitionFrameCount > 0) { int realFrames = m_FrameCount / (m_TransitionFrameCount + 1); if ((int)(value * realFrames) != (int)(m_Value * realFrames)) { m_TransitionStartValue = m_Value; m_TransitionStartTicks = CSystem::GetTickCount64(); } else { m_TransitionStartTicks = 0; } } m_Value = value; return true; } return false; }
static int Enable(lua_State* L) { CMeasure* self = GetSelf(L); self->Enable(); return 0; }
static int GetValueRange(lua_State* L) { CMeasure* self = GetSelf(L); lua_pushnumber(L, self->GetValueRange()); return 1; }
static int GetName(lua_State* L) { CMeasure* self = GetSelf(L); LuaManager::PushWide(L, self->GetName()); return 1; }
static int GetNumberOption(lua_State* L) { CMeasure* self = GetSelf(L); CMeterWindow* meterWindow = self->GetMeterWindow(); CConfigParser& parser = meterWindow->GetParser(); std::wstring strTmp = LuaManager::ToWide(L, 2); double value = parser.ReadFormula(self->GetName(), strTmp.c_str(), lua_tonumber(L, 3)); lua_pushnumber(L, value); return 1; }
static int GetOption(lua_State* L) { CMeasure* self = GetSelf(L); CMeterWindow* meterWindow = self->GetMeterWindow(); CConfigParser& parser = meterWindow->GetParser(); std::wstring strTmp = LuaManager::ToWide(L, 2); strTmp = parser.ReadString(self->GetName(), strTmp.c_str(), LuaManager::ToWide(L, 3).c_str()); LuaManager::PushWide(L, strTmp.c_str()); return 1; }
static int GetStringValue(lua_State* L) { CMeasure* self = GetSelf(L); int top = lua_gettop(L); AUTOSCALE autoScale = (top > 1) ? (AUTOSCALE)(int)lua_tonumber(L, 2) : AUTOSCALE_OFF; double scale = (top > 2) ? lua_tonumber(L, 3) : 1.0; int decimals = (int)lua_tonumber(L, 4); bool percentual = lua_toboolean(L, 5); const WCHAR* val = self->GetStringValue(autoScale, scale, decimals, percentual); LuaManager::PushWide(L, val); return 1; }
/* ** Updates the value(s) from the measures. ** */ bool CMeterRoundLine::Update() { if (CMeter::Update() && !m_Measures.empty()) { CMeasure* measure = m_Measures[0]; if (m_ValueRemainder > 0) { LONGLONG time = (LONGLONG)measure->GetValue(); m_Value = (double)(time % m_ValueRemainder); m_Value /= (double)m_ValueRemainder; } else { m_Value = measure->GetRelativeValue(); } return true; } return false; }
/* ** Updates the value(s) from the measures. ** */ bool CMeterHistogram::Update() { if (CMeter::Update() && !m_Measures.empty()) { int maxSize = m_GraphHorizontalOrientation ? m_H : m_W; if (maxSize > 0) // m_PrimaryValues is not NULL { CMeasure* measure = m_Measures[0]; CMeasure* secondaryMeasure = (m_Measures.size() >= 2) ? m_Measures[1] : NULL; // Gather values m_PrimaryValues[m_MeterPos] = measure->GetValue(); if (secondaryMeasure && m_SecondaryValues) { m_SecondaryValues[m_MeterPos] = secondaryMeasure->GetValue(); } ++m_MeterPos; m_MeterPos %= maxSize; m_MaxPrimaryValue = measure->GetMaxValue(); m_MinPrimaryValue = measure->GetMinValue(); m_MaxSecondaryValue = 0.0; m_MinSecondaryValue = 0.0; if (secondaryMeasure) { m_MaxSecondaryValue = secondaryMeasure->GetMaxValue(); m_MinSecondaryValue = secondaryMeasure->GetMinValue(); } if (m_Autoscale) { // Go through all values and find the max double newValue = 0.0; for (int i = 0; i < maxSize; ++i) { newValue = max(newValue, m_PrimaryValues[i]); } // Scale the value up to nearest power of 2 if (newValue > DBL_MAX / 2.0) { m_MaxPrimaryValue = DBL_MAX; } else { m_MaxPrimaryValue = 2.0; while (m_MaxPrimaryValue < newValue) { m_MaxPrimaryValue *= 2.0; } } if (secondaryMeasure && m_SecondaryValues) { for (int i = 0; i < maxSize; ++i) { newValue = max(newValue, m_SecondaryValues[i]); } // Scale the value up to nearest power of 2 if (newValue > DBL_MAX / 2.0) { m_MaxSecondaryValue = DBL_MAX; } else { m_MaxSecondaryValue = 2.0; while (m_MaxSecondaryValue < newValue) { m_MaxSecondaryValue *= 2.0; } } } } } return true; } return false; }
/* ** Replaces measures in the given string. ** */ bool CConfigParser::ReplaceMeasures(std::wstring& result) { bool replaced = false; size_t start = 0; while ((start = result.find(L'[', start)) != std::wstring::npos) { size_t si = start + 1; size_t end = result.find(L']', si); if (end == std::wstring::npos) { break; } size_t next = result.find(L'[', si); if (next == std::wstring::npos || end < next) { size_t ei = end - 1; if (si != ei && result[si] == L'*' && result[ei] == L'*') { result.erase(ei, 1); result.erase(si, 1); start = ei; } else { std::wstring var = result.substr(si, end - si); CMeasure* measure = GetMeasure(var); if (measure) { const WCHAR* value = measure->GetStringValue(AUTOSCALE_OFF, 1, -1, false); size_t valueLen = wcslen(value); // Measure found, replace it with the value result.replace(start, end - start + 1, value, valueLen); start += valueLen; replaced = true; } else { std::wstring value; if (GetSectionVariable(var, value)) { // Replace section variable with the value. result.replace(start, end - start + 1, value); start += value.length(); replaced = true; } else { start = end; } } } } else { start = next; } } return replaced; }
/* ** Gets the value of a section variable. Returns true if strValue is set. ** The selector is stripped from strVariable. ** */ bool CConfigParser::GetSectionVariable(std::wstring& strVariable, std::wstring& strValue) { size_t colonPos = strVariable.find_last_of(L':'); if (colonPos == std::wstring::npos) { return false; } const std::wstring selector = strVariable.substr(colonPos + 1); const WCHAR* selectorSz = selector.c_str(); strVariable.resize(colonPos); bool isKeySelector = (!selector.empty() && iswalpha(selectorSz[0])); if (isKeySelector) { // [Meter:X], [Meter:Y], [Meter:W], [Meter:H] CMeter* meter = m_MeterWindow->GetMeter(strVariable); if (meter) { WCHAR buffer[32]; if (_wcsicmp(selectorSz, L"X") == 0) { _itow_s(meter->GetX(), buffer, 10); } else if (_wcsicmp(selectorSz, L"Y") == 0) { _itow_s(meter->GetY(), buffer, 10); } else if (_wcsicmp(selectorSz, L"W") == 0) { _itow_s(meter->GetW(), buffer, 10); } else if (_wcsicmp(selectorSz, L"H") == 0) { _itow_s(meter->GetH(), buffer, 10); } else { return false; } strValue = buffer; return true; } } // Number: [Measure:], [Measure:dec] // Percentual: [Measure:%], [Measure:%, dec] // Scale: [Measure:/scale], [Measure:/scale, dec] // Max/Min: [Measure:MaxValue], [Measure:MaxValue:/scale, dec] ('%' cannot be used) enum VALUETYPE { RAW = 0, PERCENTUAL = 1, MAX = 2, MIN = 3 } valueType = RAW; if (isKeySelector) { if (_wcsicmp(selectorSz, L"MaxValue") == 0) { valueType = MAX; } else if (_wcsicmp(selectorSz, L"MinValue") == 0) { valueType = MIN; } else { return false; } selectorSz = L""; } else { colonPos = strVariable.find_last_of(L':'); if (colonPos != std::wstring::npos) { do { const WCHAR* keySelectorSz = strVariable.c_str() + colonPos + 1; if (_wcsicmp(keySelectorSz, L"MaxValue") == 0) { valueType = MAX; } else if (_wcsicmp(keySelectorSz, L"MinValue") == 0) { valueType = MIN; } else { // Section name contains ':' ? break; } strVariable.resize(colonPos); } while (0); } } CMeasure* measure = m_MeterWindow->GetMeasure(strVariable); if (measure) { int scale = 1; const WCHAR* decimalsSz = wcschr(selectorSz, L','); if (decimalsSz) { ++decimalsSz; } if (*selectorSz == L'%') // Percentual { if (valueType == MAX || valueType == MIN) // '%' cannot be used with MAX/MIN value { return false; } valueType = PERCENTUAL; } else if (*selectorSz == L'/') // Scale { errno = 0; scale = _wtoi(selectorSz + 1); if (errno == EINVAL || scale == 0) // Invalid scale value { return false; } } else { if (decimalsSz) { return false; } decimalsSz = selectorSz; } double value = (valueType == PERCENTUAL) ? measure->GetRelativeValue() * 100.0 : (valueType == MAX) ? measure->GetMaxValue() / scale : (valueType == MIN) ? measure->GetMinValue() / scale : measure->GetValue() / scale; int decimals = 10; if (decimalsSz) { while (iswspace(*decimalsSz)) ++decimalsSz; if (*decimalsSz) { decimals = _wtoi(decimalsSz); decimals = max(0, decimals); decimals = min(32, decimals); } else { decimalsSz = NULL; } } WCHAR format[32]; WCHAR buffer[128]; _snwprintf_s(format, _TRUNCATE, L"%%.%if", decimals); int bufferLen = _snwprintf_s(buffer, _TRUNCATE, format, value); if (!decimalsSz) { // Remove trailing zeros if decimal count was not specified. measure->RemoveTrailingZero(buffer, bufferLen); bufferLen = (int)wcslen(buffer); } strValue.assign(buffer, bufferLen); return true; } return false; }
/* ** Replaces measures in the given string. ** */ bool CConfigParser::ReplaceMeasures(std::wstring& result) { bool replaced = false; // Check for measures ([Measure]) if (!m_Measures.empty()) { size_t start = 0, end, next; bool loop = true; do { start = result.find(L'[', start); if (start != std::wstring::npos) { size_t si = start + 1; end = result.find(L']', si); if (end != std::wstring::npos) { next = result.find(L'[', si); if (next == std::wstring::npos || end < next) { size_t ei = end - 1; if (si != ei && result[si] == L'*' && result[ei] == L'*') { result.erase(ei, 1); result.erase(si, 1); start = ei; } else { std::wstring var = result.substr(si, end - si); CMeasure* measure = GetMeasure(var); if (measure) { const std::wstring& value = measure->GetStringValue(AUTOSCALE_OFF, 1, -1, false); // Measure found, replace it with the value result.replace(start, end - start + 1, value); start += value.length(); replaced = true; } else { start = end; } } } else { start = next; } } else { loop = false; } } else { loop = false; } } while (loop); } return replaced; }