mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-08 12:39:49 -06:00
Changes to get lua table entries working using variant type
This commit is contained in:
@@ -54,6 +54,7 @@ enum class PropertyValueType {
|
||||
Table,
|
||||
Nil
|
||||
};
|
||||
typedef std::variant<bool, float, std::string, ghoul::lua::nil_t> ProfilePropertyLua;
|
||||
|
||||
class SceneInitializer;
|
||||
|
||||
@@ -255,6 +256,60 @@ public:
|
||||
void setPropertiesFromProfile(const Profile& p);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Accepts string version of a property value from a profile, converts it to the
|
||||
* appropriate type, and then pushes the value onto the lua state.
|
||||
*
|
||||
* \param L the lua state to push value to
|
||||
* \param value string representation of the value with which to set property
|
||||
*/
|
||||
void propertyPushValueFromProfileToLuaState(ghoul::lua::LuaState& L,
|
||||
std::string& value);
|
||||
|
||||
/**
|
||||
* Accepts string version of a property value from a profile, and processes it
|
||||
* according to the data type of the value
|
||||
*
|
||||
* \param L the lua state to (eventually) push to
|
||||
* \param value string representation of the value with which to set property
|
||||
* \param didPushToLua Bool reference that represents the lua push state at the end
|
||||
* of this function call. This will be set to true if the value (e.g. table)
|
||||
* has already been pushed to the lua stack
|
||||
* \return The ProfilePropertyLua variant type translated from string representation
|
||||
*/
|
||||
ProfilePropertyLua propertyProcessValue(ghoul::lua::LuaState& L,
|
||||
std::string& value, bool& didPushToLua);
|
||||
|
||||
/**
|
||||
* Accepts string version of a property value from a profile, and returns the
|
||||
* supported data types that can be pushed to a lua state. Currently, the full
|
||||
* range of possible lua values is not supported.
|
||||
*
|
||||
* \param value string representation of the value with which to set property
|
||||
*/
|
||||
PropertyValueType getPropertyValueType(std::string& value);
|
||||
|
||||
/**
|
||||
* Accepts string version of a property value from a profile, and adds it to a vector
|
||||
* which will later be used to push as a lua table containing values of type T
|
||||
*
|
||||
* \param L the lua state to (eventually) push to
|
||||
* \param value string representation of the value with which to set property
|
||||
* \param table the std::vector container which has elements of type T for a lua table
|
||||
*/
|
||||
template <typename T>
|
||||
void processPropertyValueTableEntries(ghoul::lua::LuaState& L, std::string& value,
|
||||
std::vector<T>& table);
|
||||
|
||||
/**
|
||||
* Handles a lua table entry, creating a vector of the correct variable type based
|
||||
* on the profile string, and pushes this vector to the lua stack.
|
||||
*
|
||||
* \param L the lua state to (eventually) push to
|
||||
* \param value string representation of the value with which to set property
|
||||
*/
|
||||
void handlePropertyLuaTableEntry(ghoul::lua::LuaState& L, std::string& value);
|
||||
|
||||
/**
|
||||
* Update dependencies.
|
||||
*/
|
||||
@@ -269,7 +324,7 @@ private:
|
||||
bool _dirtyNodeRegistry = false;
|
||||
SceneGraphNode _rootDummy;
|
||||
std::unique_ptr<SceneInitializer> _initializer;
|
||||
|
||||
std::string _profilePropertyName;
|
||||
std::vector<InterestingTime> _interestingTimes;
|
||||
|
||||
std::mutex _programUpdateLock;
|
||||
@@ -288,49 +343,7 @@ private:
|
||||
ghoul::MemoryPool<4096> _memoryPool;
|
||||
};
|
||||
|
||||
/**
|
||||
* Accepts string version of a property value from a profile, converts it to the
|
||||
* appropriate type, and then pushes the value onto the lua state.
|
||||
*
|
||||
* \param L the lua state to push value to
|
||||
* \param value string representation of the value with which to set property
|
||||
*/
|
||||
void propertyPushValueFromProfileToLuaState(ghoul::lua::LuaState& L,
|
||||
const std::string& value);
|
||||
|
||||
/**
|
||||
* Accepts string version of a property value from a profile, and processes it
|
||||
* according to the data type of the value
|
||||
*
|
||||
* \param L the lua state to (eventually) push to
|
||||
* \param value string representation of the value with which to set property
|
||||
* \param pushFn the std::function provided for pushing the result, which may be
|
||||
* a lambda that pushes to the lua state, or a lambda that pushes
|
||||
* to a vector (the vector will eventually be pushed to a lua table)
|
||||
*/
|
||||
void propertyProcessValue(ghoul::lua::LuaState& L, std::string& value,
|
||||
std::function<void(auto v)>pushFn);
|
||||
|
||||
/**
|
||||
* Accepts string version of a property value from a profile, and returns the
|
||||
* supported data types that can be pushed to a lua state. Currently, the full
|
||||
* range of possible lua values is not supported.
|
||||
*
|
||||
* \param value string representation of the value with which to set property
|
||||
*/
|
||||
PropertyValueType getPropertyValueType(std::string& value);
|
||||
|
||||
/**
|
||||
* Accepts string version of a property value from a profile, and adds it to a vector
|
||||
* which will later be used to push as a lua table containing values of type T
|
||||
*
|
||||
* \param L the lua state to (eventually) push to
|
||||
* \param value string representation of the value with which to set property
|
||||
* \param table the std::vector container which has elements of type T for a lua table
|
||||
*/
|
||||
template <typename T>
|
||||
void processPropertyValueTableEntries(ghoul::lua::LuaState& L, std::string& value,
|
||||
std::vector<T>& table);
|
||||
void trimSurroundingCharacters(std::string& valueString, const char c);
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
|
||||
@@ -73,6 +73,9 @@ namespace {
|
||||
}
|
||||
}
|
||||
#endif // TRACY_ENABLE
|
||||
|
||||
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
||||
template <class... Ts> overloaded(Ts...)->overloaded<Ts...>;
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
@@ -613,10 +616,14 @@ void Scene::setPropertiesFromProfile(const Profile& p) {
|
||||
// Remove group name from start of regex and replace with '*'
|
||||
uriOrRegex = removeGroupNameFromUri(uriOrRegex);
|
||||
}
|
||||
_profilePropertyName = uriOrRegex;
|
||||
ghoul::lua::push(L, uriOrRegex);
|
||||
ghoul::lua::push(L, 0.0);
|
||||
|
||||
std::string workingValue = prop.value;
|
||||
trimSurroundingCharacters(workingValue, ' ');
|
||||
// Later functions expect the value to be at the last position on the stack
|
||||
propertyPushValueFromProfileToLuaState(L, prop.value);
|
||||
propertyPushValueFromProfileToLuaState(L, workingValue);
|
||||
|
||||
applyRegularExpression(
|
||||
L,
|
||||
@@ -631,114 +638,145 @@ void Scene::setPropertiesFromProfile(const Profile& p) {
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void propertyPushValueFromProfileToLuaState(ghoul::lua::LuaState& L,
|
||||
std::string& value)
|
||||
void Scene::propertyPushValueFromProfileToLuaState(ghoul::lua::LuaState& L,
|
||||
std::string& value)
|
||||
{
|
||||
propertyProcessValue(
|
||||
L,
|
||||
value,
|
||||
[&](T resultValue) {
|
||||
ghoul::lua::push(L, resultValue);
|
||||
}
|
||||
);
|
||||
bool alreadyPushedToLua = false;
|
||||
ProfilePropertyLua elem = propertyProcessValue(L, value, alreadyPushedToLua);
|
||||
if (!alreadyPushedToLua) {
|
||||
std::visit(overloaded{
|
||||
[&L](const bool& value) {
|
||||
ghoul::lua::push(L, value);
|
||||
},
|
||||
[&L](const float& value) {
|
||||
ghoul::lua::push(L, value);
|
||||
},
|
||||
[&L](const std::string& value) {
|
||||
ghoul::lua::push(L, value);
|
||||
},
|
||||
[&L](const ghoul::lua::nil_t& nilValue) {
|
||||
ghoul::lua::push(L, nilValue);
|
||||
}
|
||||
}, elem);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void propertyProcessValue(ghoul::lua::LuaState& L, std::string& value,
|
||||
std::function<void(T val)>pushFn)
|
||||
ProfilePropertyLua Scene::propertyProcessValue(ghoul::lua::LuaState& L,std::string& value,
|
||||
bool& didPushToLua)
|
||||
{
|
||||
ProfilePropertyLua result;
|
||||
PropertyValueType pType = getPropertyValueType(value);
|
||||
switch (pType) {
|
||||
case PropertyValueType::Boolean:
|
||||
(value == "true") ? pushFn(true) : pushFn(false);
|
||||
result = (value == "true") ? true : false;
|
||||
break;
|
||||
|
||||
case PropertyValueType::Float:
|
||||
pushFn(L, std::stof(value));
|
||||
result = std::stof(value);
|
||||
break;
|
||||
|
||||
case PropertyValueType::Nil:
|
||||
ghoul::lua::nil_t n;
|
||||
pushFn(n);
|
||||
result = n;
|
||||
break;
|
||||
|
||||
case PropertyValueType::Table:
|
||||
std::string nextValue = value;
|
||||
size_t commaPos = value.find(',', commaPos);
|
||||
if (commaPos != std::string::npos) {
|
||||
nextValue = value.substr(1, commaPos);
|
||||
}
|
||||
PropertyValueType enclosedType = getPropertyValueType(nextValue);
|
||||
switch (enclosedType) {
|
||||
case PropertyValueType::Boolean:
|
||||
std::vector<bool> valsB;
|
||||
processPropertyValueTableEntries(L, value, valsB);
|
||||
pushFn(valsB);
|
||||
break;
|
||||
trimSurroundingCharacters(value, '{');
|
||||
trimSurroundingCharacters(value, '}');
|
||||
handlePropertyLuaTableEntry(L, value);
|
||||
didPushToLua = true;
|
||||
break;
|
||||
|
||||
case PropertyValueType::Float:
|
||||
case PropertyValueType::String:
|
||||
default:
|
||||
std::string newValue = value;
|
||||
newValue.insert(0, "[[");
|
||||
newValue.append("]]");
|
||||
result = newValue;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Scene::handlePropertyLuaTableEntry(ghoul::lua::LuaState& L, std::string& value) {
|
||||
std::string firstValue;
|
||||
size_t commaPos = 0;
|
||||
commaPos = value.find(',', commaPos);
|
||||
if (commaPos != std::string::npos) {
|
||||
firstValue = value.substr(0, commaPos);
|
||||
}
|
||||
else {
|
||||
firstValue = value;
|
||||
}
|
||||
|
||||
PropertyValueType enclosedType = getPropertyValueType(firstValue);
|
||||
switch (enclosedType) {
|
||||
case PropertyValueType::Boolean:
|
||||
LERROR(fmt::format(
|
||||
"A lua table of bool values is not supported. (processing property {})",
|
||||
_profilePropertyName)
|
||||
);
|
||||
break;
|
||||
|
||||
case PropertyValueType::Float:
|
||||
{
|
||||
std::vector<float> valsF;
|
||||
processPropertyValueTableEntries(L, value, valsF);
|
||||
pushFn(valsF);
|
||||
break;
|
||||
|
||||
case PropertyValueType::Nil:
|
||||
std::vector<ghoul::lua::nil_t> valsN;
|
||||
processPropertyValueTableEntries(L, value, valsN);
|
||||
pushFn(valsN);
|
||||
break;
|
||||
|
||||
case PropertyValueType::String:
|
||||
std::vector<std::string> valsS;
|
||||
processPropertyValueTableEntries(L, value, valsS);
|
||||
pushFn(valsS);
|
||||
break;
|
||||
|
||||
case PropertyValueType::Table:
|
||||
default:
|
||||
LERROR("Table-within-a-table values are not supported for profile property");
|
||||
break;
|
||||
ghoul::lua::push(L, valsF);
|
||||
}
|
||||
break;
|
||||
|
||||
case PropertyValueType::String:
|
||||
{
|
||||
std::vector<std::string> valsS;
|
||||
processPropertyValueTableEntries(L, value, valsS);
|
||||
ghoul::lua::push(L, valsS);
|
||||
}
|
||||
break;
|
||||
|
||||
case PropertyValueType::Table:
|
||||
default:
|
||||
value.insert(0, "[[");
|
||||
value.append("]]");
|
||||
pushFn(value);
|
||||
LERROR(fmt::format(
|
||||
"Table-within-a-table values are not supported for profile a "
|
||||
"property (processing property {})", _profilePropertyName)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void processPropertyValueTableEntries(ghoul::lua::LuaState& L, std::string& value,
|
||||
void Scene::processPropertyValueTableEntries(ghoul::lua::LuaState& L, std::string& value,
|
||||
std::vector<T>& table)
|
||||
{
|
||||
size_t commaPos = 0;
|
||||
size_t prevPos = 0;
|
||||
std::string nextValue;
|
||||
while (commaPos != std::string::npos) {
|
||||
commaPos = value.find(',', commaPos);
|
||||
commaPos = value.find(',', prevPos);
|
||||
if (commaPos != std::string::npos) {
|
||||
nextValue = value.substr(prevPos, commaPos);
|
||||
nextValue = value.substr(prevPos, commaPos - prevPos);
|
||||
prevPos = commaPos + 1;
|
||||
}
|
||||
else {
|
||||
nextValue = value.substr(prevPos);
|
||||
}
|
||||
propertyProcessValue(L, nextValue, [&](T val){table.push_back(val);});
|
||||
trimSurroundingCharacters(nextValue, ' ');
|
||||
bool alreadyPushedToLua = false;
|
||||
ProfilePropertyLua tableElement = propertyProcessValue(L, nextValue,
|
||||
alreadyPushedToLua);
|
||||
try {
|
||||
table.push_back(std::get<T>(tableElement));
|
||||
}
|
||||
catch (std::bad_variant_access& e) {
|
||||
LERROR(fmt::format(
|
||||
"Error attempting to parse profile property setting for "
|
||||
"{} using value = {}", _profilePropertyName, value)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PropertyValueType getPropertyValueType(std::string& value) {
|
||||
//First trim spaces from front and back of string
|
||||
while (value.front() == ' ') {
|
||||
value.erase(0, 1);
|
||||
}
|
||||
while (value.back() == ' ') {
|
||||
value.pop_back();
|
||||
}
|
||||
|
||||
PropertyValueType Scene::getPropertyValueType(std::string& value) {
|
||||
if (luascriptfunctions::isBoolValue(value)) {
|
||||
return PropertyValueType::Boolean;
|
||||
}
|
||||
@@ -756,6 +794,15 @@ PropertyValueType getPropertyValueType(std::string& value) {
|
||||
}
|
||||
}
|
||||
|
||||
void trimSurroundingCharacters(std::string& valueString, const char c) {
|
||||
while (valueString.front() == c) {
|
||||
valueString.erase(0, 1);
|
||||
}
|
||||
while (valueString.back() == c) {
|
||||
valueString.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
scripting::LuaLibrary Scene::luaLibrary() {
|
||||
return {
|
||||
"",
|
||||
|
||||
@@ -915,8 +915,14 @@ bool isBoolValue(const std::string& s) {
|
||||
*/
|
||||
bool isFloatValue(const std::string& s) {
|
||||
try {
|
||||
float converted = std::stof(s);
|
||||
return true;
|
||||
float converted = std::numeric_limits<float>::min();
|
||||
converted = std::stof(s);
|
||||
if (converted != std::numeric_limits<float>::min()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user