Implement new intrin params; fix parseSynonyms
Previously parseSynonyms didn't properly return the last provided synonym of the param in question, so fix it here to do that.
This commit is contained in:
@@ -121,24 +121,31 @@ public:
|
||||
* @param synonymNames The collection of synonymous parameter names to try
|
||||
* @param defaultValue The default value to return if no parameter is found
|
||||
* @return The parsed integer value, or defaultValue if none found
|
||||
* @note Synonyms are tried in reverse order; lattermost synonym wins if multiple are present
|
||||
* @note The lattermost supplied matching param wins if multiple are present
|
||||
*/
|
||||
template <typename SynonymCollectionT>
|
||||
static int parseOptionalParamAsIntWithSynonyms(
|
||||
const std::vector<std::pair<std::string,std::string>>& params,
|
||||
const std::vector<std::string>& synonymNames,
|
||||
const SynonymCollectionT& synonymNames,
|
||||
int defaultValue
|
||||
)
|
||||
{
|
||||
// Loop through synonyms in reverse order; lattermost synonym wins.
|
||||
for (auto synIt = synonymNames.rbegin();
|
||||
synIt != synonymNames.rend(); ++synIt)
|
||||
// Loop through params in reverse order; lattermost supplied param wins.
|
||||
for (auto paramIt = params.rbegin(); paramIt != params.rend(); ++paramIt)
|
||||
{
|
||||
const auto& paramName = *synIt;
|
||||
const auto& [paramName, paramValue] = *paramIt;
|
||||
auto synonymIt = std::find(
|
||||
synonymNames.begin(), synonymNames.end(), paramName);
|
||||
|
||||
if (synonymIt == synonymNames.end())
|
||||
{ continue; }
|
||||
|
||||
try {
|
||||
return parseRequiredParamAsInt(params, paramName);
|
||||
} catch (const std::exception&) {
|
||||
// Parameter not found or parse error, continue to next synonym
|
||||
continue;
|
||||
return std::stoi(paramValue);
|
||||
} catch (const std::exception& e) {
|
||||
throw std::runtime_error(
|
||||
"Failed to parse '" + paramName + "' param value '"
|
||||
+ paramValue + "' as integer: " + e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
#ifndef SMO_INTRIN_THRESHOLD_PARAMS_H
|
||||
#define SMO_INTRIN_THRESHOLD_PARAMS_H
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace smo::intrin {
|
||||
|
||||
enum class ThresholdUnit
|
||||
{
|
||||
Percentage,
|
||||
Absolute,
|
||||
};
|
||||
|
||||
struct ParsedThresholdParam
|
||||
{
|
||||
int value;
|
||||
ThresholdUnit unit;
|
||||
std::string_view matchedName;
|
||||
bool wasSpecified;
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 2> kPosIntPcParamNames = {
|
||||
"postrin-interest-percentage",
|
||||
"postrin-interest-pc",
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 3> kPosIntThrParamNames = {
|
||||
"postrin-interest-threshold",
|
||||
"postrin-interest-thresh",
|
||||
"postrin-interest-thr",
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 2> kNegIntPcParamNames = {
|
||||
"negtrin-interest-percentage",
|
||||
"negtrin-interest-pc",
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 3> kNegIntThrParamNames = {
|
||||
"negtrin-interest-threshold",
|
||||
"negtrin-interest-thresh",
|
||||
"negtrin-interest-thr",
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 2> kPosDistPcParamNames = {
|
||||
"postrin-distraction-percentage",
|
||||
"postrin-distraction-pc",
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 3> kPosDistThrParamNames = {
|
||||
"postrin-distraction-threshold",
|
||||
"postrin-distraction-thresh",
|
||||
"postrin-distraction-thr",
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 2> kNegDistPcParamNames = {
|
||||
"negtrin-distraction-percentage",
|
||||
"negtrin-distraction-pc",
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 3> kNegDistThrParamNames = {
|
||||
"negtrin-distraction-threshold",
|
||||
"negtrin-distraction-thresh",
|
||||
"negtrin-distraction-thr",
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 8> kStupefactionPcParamNames = {
|
||||
"postrin-stupefaction-percentage",
|
||||
"postrin-stupefaction-pc",
|
||||
"postrin-stupefying-percentage",
|
||||
"postrin-stupefying-pc",
|
||||
"stupefaction-percentage",
|
||||
"stupefaction-pc",
|
||||
"stupefying-percentage",
|
||||
"stupefying-pc",
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 12> kStupefactionThrParamNames = {
|
||||
"postrin-stupefaction-threshold",
|
||||
"postrin-stupefaction-thresh",
|
||||
"postrin-stupefaction-thr",
|
||||
"postrin-stupefying-threshold",
|
||||
"postrin-stupefying-thresh",
|
||||
"postrin-stupefying-thr",
|
||||
"stupefaction-threshold",
|
||||
"stupefaction-thresh",
|
||||
"stupefaction-thr",
|
||||
"stupefying-threshold",
|
||||
"stupefying-thresh",
|
||||
"stupefying-thr",
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 4> kIntolerablePcParamNames = {
|
||||
"negtrin-intolerable-percentage",
|
||||
"negtrin-intolerable-pc",
|
||||
"intolerable-percentage",
|
||||
"intolerable-pc",
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 6> kIntolerableThrParamNames = {
|
||||
"negtrin-intolerable-threshold",
|
||||
"negtrin-intolerable-thresh",
|
||||
"negtrin-intolerable-thr",
|
||||
"intolerable-threshold",
|
||||
"intolerable-thresh",
|
||||
"intolerable-thr",
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 10> kForbiddenUnitlessIntrinParamNames = {
|
||||
"postrin-interest",
|
||||
"negtrin-interest",
|
||||
"postrin-distraction",
|
||||
"negtrin-distraction",
|
||||
"postrin-stupefaction",
|
||||
"postrin-stupefying",
|
||||
"stupefaction",
|
||||
"stupefying",
|
||||
"negtrin-intolerable",
|
||||
"intolerable",
|
||||
};
|
||||
|
||||
template <std::size_t N>
|
||||
bool arrayContains(
|
||||
const std::array<std::string_view, N>& names,
|
||||
std::string_view candidate)
|
||||
{
|
||||
for (const auto& name : names) {
|
||||
if (name == candidate) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename NameCollectionT>
|
||||
bool namesContain(
|
||||
const NameCollectionT& names,
|
||||
std::string_view candidate)
|
||||
{
|
||||
for (const auto& name : names) {
|
||||
if (name == candidate) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void validateNoForbiddenUnitlessIntrinParams(
|
||||
const std::vector<std::pair<std::string, std::string>>& params)
|
||||
{
|
||||
for (const auto& [name, value] : params)
|
||||
{
|
||||
(void)value;
|
||||
|
||||
if (arrayContains(kForbiddenUnitlessIntrinParamNames, name))
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"Intrinsic threshold param '" + name
|
||||
+ "' is invalid without a unit suffix. Use a "
|
||||
"'-percentage'/'-pc' or '-threshold'/'-thresh'/'-thr' variant.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline std::optional<std::pair<std::string_view, int>> findLastMatchingIntParam(
|
||||
const std::vector<std::pair<std::string, std::string>>& params,
|
||||
const auto& synonymNames)
|
||||
{
|
||||
for (auto paramIt = params.rbegin(); paramIt != params.rend(); ++paramIt)
|
||||
{
|
||||
const auto& [name, value] = *paramIt;
|
||||
if (!namesContain(synonymNames, name))
|
||||
{ continue; }
|
||||
|
||||
try {
|
||||
return std::pair<std::string_view, int>(name, std::stoi(value));
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"Failed to parse '" + name + "' param value '" + value
|
||||
+ "' as integer: " + e.what());
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
inline ParsedThresholdParam parseOptionalThresholdParam(
|
||||
const std::vector<std::pair<std::string, std::string>>& params,
|
||||
const auto& percentageNames,
|
||||
const auto& absoluteNames,
|
||||
int defaultValue,
|
||||
ThresholdUnit defaultUnit)
|
||||
{
|
||||
for (auto paramIt = params.rbegin(); paramIt != params.rend(); ++paramIt)
|
||||
{
|
||||
const auto& [name, value] = *paramIt;
|
||||
ThresholdUnit unit;
|
||||
|
||||
if (namesContain(percentageNames, name))
|
||||
{ unit = ThresholdUnit::Percentage; }
|
||||
else if (namesContain(absoluteNames, name))
|
||||
{ unit = ThresholdUnit::Absolute; }
|
||||
else
|
||||
{ continue; }
|
||||
|
||||
try
|
||||
{
|
||||
return ParsedThresholdParam{
|
||||
.value = std::stoi(value),
|
||||
.unit = unit,
|
||||
.matchedName = name,
|
||||
.wasSpecified = true,
|
||||
};
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"Failed to parse '" + name + "' param value '" + value
|
||||
+ "' as integer: " + e.what());
|
||||
}
|
||||
}
|
||||
|
||||
return ParsedThresholdParam{
|
||||
.value = defaultValue,
|
||||
.unit = defaultUnit,
|
||||
.matchedName = {},
|
||||
.wasSpecified = false,
|
||||
};
|
||||
}
|
||||
|
||||
inline uint32_t resolveThresholdValue(
|
||||
const ParsedThresholdParam& param,
|
||||
size_t percentageBase)
|
||||
{
|
||||
if (param.unit == ThresholdUnit::Percentage) {
|
||||
return static_cast<uint32_t>((percentageBase * param.value) / 100);
|
||||
}
|
||||
|
||||
return static_cast<uint32_t>(param.value);
|
||||
}
|
||||
|
||||
} // namespace smo::intrin
|
||||
|
||||
#endif // SMO_INTRIN_THRESHOLD_PARAMS_H
|
||||
@@ -10,11 +10,23 @@
|
||||
#include <user/stimulusBuffer.h>
|
||||
#include <user/stagingBuffer.h>
|
||||
#include <user/deviceAttachmentSpec.h>
|
||||
#include <user/intrinThresholdParams.h>
|
||||
#include "lg1PcloudAmbienceStencil.h"
|
||||
|
||||
namespace smo {
|
||||
namespace stim_buff {
|
||||
|
||||
inline intrin::ParsedThresholdParam parsePostrinInterestParam(
|
||||
const std::shared_ptr<device::DeviceAttachmentSpec>& deviceAttachmentSpec)
|
||||
{
|
||||
return intrin::parseOptionalThresholdParam(
|
||||
deviceAttachmentSpec->qualeIfaceApiParams,
|
||||
intrin::kPosIntPcParamNames,
|
||||
intrin::kPosIntThrParamNames,
|
||||
90,
|
||||
intrin::ThresholdUnit::Percentage);
|
||||
}
|
||||
|
||||
// Forward declaration
|
||||
class StimulusProducer;
|
||||
|
||||
@@ -40,22 +52,18 @@ public:
|
||||
callbacks, flags),
|
||||
nStencils(nStencils_)
|
||||
{
|
||||
// Parse postrinInterestPercentage (interpreted as percentage 0-100)
|
||||
const std::vector<std::string> postrinInterestThresholdParamNames = {
|
||||
"postrin-interest-percentage",
|
||||
"postrin-interest-pc",
|
||||
"postrin-interest"
|
||||
};
|
||||
intrin::validateNoForbiddenUnitlessIntrinParams(
|
||||
deviceAttachmentSpec->qualeIfaceApiParams);
|
||||
|
||||
postrinInterestPercentage = static_cast<uint32_t>(
|
||||
device::DeviceAttachmentSpec::parseOptionalParamAsIntWithSynonyms(
|
||||
deviceAttachmentSpec->qualeIfaceApiParams,
|
||||
postrinInterestThresholdParamNames,
|
||||
90));
|
||||
const auto postrinInterestParam =
|
||||
parsePostrinInterestParam(deviceAttachmentSpec);
|
||||
postrinInterestPercentage =
|
||||
postrinInterestParam.unit == intrin::ThresholdUnit::Percentage
|
||||
? static_cast<uint32_t>(postrinInterestParam.value)
|
||||
: 0U;
|
||||
postrinInterestThreshold = intrin::resolveThresholdValue(
|
||||
postrinInterestParam, nDgramsPerFrame_);
|
||||
|
||||
// Convert percentage to absolute frame count
|
||||
postrinInterestThreshold = static_cast<uint32_t>(
|
||||
(nDgramsPerFrame_ * postrinInterestPercentage) / 100);
|
||||
// Parse ambienceIntensityLowVal from qualeIfaceApiParams
|
||||
const std::vector<std::string> ambienceIntensityLowValParamNames = {
|
||||
"ambience-intensity-low-val"
|
||||
|
||||
Reference in New Issue
Block a user