Skip to content

Commit

Permalink
Syntax Refactor + target_var_type Param
Browse files Browse the repository at this point in the history
It's a bit faster and now you can tell if the target output is Switch, Variable, or StringVar.
  • Loading branch information
jetrotal committed May 20, 2024
1 parent e79d587 commit 3d444dc
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 107 deletions.
73 changes: 51 additions & 22 deletions src/game_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5117,35 +5117,64 @@ bool Game_Interpreter::CommandProcessJson(lcf::rpg::EventCommand const& com) {
}

int operation = ValueOrVariable(com.parameters[0], com.parameters[1]);
int sourceVarId = ValueOrVariable(com.parameters[2], com.parameters[3]);
int targetVarId = ValueOrVariable(com.parameters[4], com.parameters[5]);
int source_var_id = ValueOrVariable(com.parameters[2], com.parameters[3]);
int target_var_type = ValueOrVariable(com.parameters[4], com.parameters[5]);
int target_var_id = ValueOrVariable(com.parameters[6], com.parameters[7]);
std::string json_path = ToString(CommandStringOrVariable(com, 8, 9));
std::string json_data = ToString(Main_Data::game_strings->Get(source_var_id));

std::string jsonPath = ToString(CommandStringOrVariable(com, 6, 7));
std::string jsonData = ToString(Main_Data::game_strings->Get(sourceVarId));

int assignVarId = 0;
std::string result;
std::string newValue;

switch (operation) {
case 0: // Get operation: Extract a value from JSON data
result = Json_Helper::GetValue(jsonData, jsonPath);
assignVarId = targetVarId;
break;
if (operation == 0) { // Get operation: Extract a value from JSON data
result = Json_Helper::GetValue(json_data, json_path);

case 1: // Set operation: Update JSON data with a new value
newValue = ToString(Main_Data::game_strings->Get(targetVarId));
result = Json_Helper::SetValue(jsonData, jsonPath, newValue);
assignVarId = sourceVarId;
break;
if (result != "<<INVALID_OUTPUT>>") {
int output_value = 0;

default:
Output::Warning("Process JSON - Invalid Operation: {}", operation);
result = "<<INVALID_OUTPUT>>";
break;
try {
output_value = std::stoi(result);
}
catch (const std::invalid_argument&) {
output_value = 0; // Set value to zero if conversion fails
}

switch (target_var_type) {
case 0: // Switch
Main_Data::game_switches->Set({ target_var_id }, output_value);
break;
case 1: // Variable
Main_Data::game_variables->Set({ target_var_id }, output_value);
break;
default: // String
Main_Data::game_strings->Asg({ target_var_id }, result);
break;
}
}
}
else if (operation == 1) { // Set operation: Update JSON data with a new value
std::string new_value;

switch (target_var_type) {
case 0: // Switch
new_value = std::to_string(Main_Data::game_switches->Get(target_var_id));
break;
case 1: // Variable
new_value = std::to_string(Main_Data::game_variables->Get(target_var_id));
break;
default: // String
new_value = ToString(Main_Data::game_strings->Get(target_var_id));
break;
}

result = Json_Helper::SetValue(json_data, json_path, new_value);

if (result != "<<INVALID_OUTPUT>>") Main_Data::game_strings->Asg({ assignVarId }, result);
if (result != "<<INVALID_OUTPUT>>") {
Main_Data::game_strings->Asg({ source_var_id }, result);
}
}
else {
Output::Warning("Process JSON - Invalid Operation: {}", operation);
}

return true;
}
Expand Down
198 changes: 115 additions & 83 deletions src/json_helper.cpp
Original file line number Diff line number Diff line change
@@ -1,118 +1,150 @@
#include "json_helper.h"
#include "output.h"
#include <nlohmann/json.hpp>
#include <sstream>
#include <unordered_map>

namespace Json_Helper {
std::string invalid_str = "<<INVALID_OUTPUT>>";
std::string GetValue(const std::string& jsonData, const std::string& jsonPath) {
try {
nlohmann::json jsonObj = nlohmann::json::parse(jsonData);
nlohmann::json* currentObj = &jsonObj;

std::string mutableJsonPath = jsonPath;
size_t pos = 0;
std::string token;
while ((pos = mutableJsonPath.find('.')) != std::string::npos) {
token = mutableJsonPath.substr(0, pos);
if (token.back() == ']') {
size_t bracketPos = token.find('[');
std::string arrayName = token.substr(0, bracketPos);
int index = std::stoi(token.substr(bracketPos + 1, token.length() - bracketPos - 2));
if (currentObj->find(arrayName) == currentObj->end() || !(*currentObj)[arrayName].is_array() || index >= (*currentObj)[arrayName].size()) {
Output::Warning("JSON_ERROR - Invalid path: {}", jsonPath);
return invalid_str;

const std::string k_invalid_str = "<<INVALID_OUTPUT>>";

std::unordered_map<std::string, nlohmann::json> json_cache;

nlohmann::json* GetObjectAtPath(nlohmann::json& json_obj, std::string_view json_path, bool allow_path_creation = false) {
nlohmann::json* current_obj = &json_obj;

std::stringstream path_stream(json_path.data());
std::string token;

while (std::getline(path_stream, token, '.')) {
if (token.back() == ']') {
size_t bracket_pos = token.find('[');
std::string array_name = token.substr(0, bracket_pos);
int index = std::stoi(token.substr(bracket_pos + 1, token.length() - bracket_pos - 2));

if (!current_obj->contains(array_name)) {
if (allow_path_creation) {
(*current_obj)[array_name] = nlohmann::json::array();
}
currentObj = &((*currentObj)[arrayName][index]);
}
else {
if (currentObj->find(token) == currentObj->end()) {
Output::Warning("JSON_ERROR - Invalid path: {}", jsonPath);
return invalid_str;
else {
return nullptr;
}
currentObj = &((*currentObj)[token]);
}
mutableJsonPath.erase(0, pos + 1);
}

if (!mutableJsonPath.empty()) {
if (mutableJsonPath.back() == ']') {
size_t bracketPos = mutableJsonPath.find('[');
std::string arrayName = mutableJsonPath.substr(0, bracketPos);
int index = std::stoi(mutableJsonPath.substr(bracketPos + 1, mutableJsonPath.length() - bracketPos - 2));
if (currentObj->find(arrayName) == currentObj->end() || !(*currentObj)[arrayName].is_array() || index >= (*currentObj)[arrayName].size()) {
Output::Warning("JSON_ERROR - Invalid path: {}", jsonPath);
return invalid_str;
nlohmann::json& array_obj = (*current_obj)[array_name];

if (index >= array_obj.size()) {
if (allow_path_creation) {
array_obj.get_ref<nlohmann::json::array_t&>().resize(index + 1);
}
currentObj = &((*currentObj)[arrayName][index]);
}
else {
if (currentObj->find(mutableJsonPath) == currentObj->end()) {
Output::Warning("JSON_ERROR - Invalid path: {}", jsonPath);
return invalid_str;
else {
return nullptr;
}
currentObj = &((*currentObj)[mutableJsonPath]);
}
}

if (currentObj->is_string()) {
return currentObj->get<std::string>();
current_obj = &(array_obj[index]);
}
else if (currentObj->is_number_integer()) {
return std::to_string(currentObj->get<int>());
}
else if (currentObj->is_number_float()) {
return std::to_string(currentObj->get<float>());
else {
if (!current_obj->contains(token)) {
if (allow_path_creation) {
(*current_obj)[token] = nlohmann::json::object();
}
else {
return nullptr;
}
}

current_obj = &((*current_obj)[token]);
}
else if (currentObj->is_boolean()) {
return currentObj->get<bool>() ? "true" : "false";
}

return current_obj;
}

std::string GetValueAsString(const nlohmann::json& json_obj) {
std::string result;

if (json_obj.is_string()) {
result = json_obj.get<std::string>();
}
else if (json_obj.is_number_integer()) {
result = std::to_string(json_obj.get<int>());
}
else if (json_obj.is_number_float()) {
result = std::to_string(json_obj.get<float>());
}
else if (json_obj.is_boolean()) {
result = json_obj.get<bool>() ? "true" : "false";
}
else {
result = json_obj.dump();
}

return result;
}

std::string GetValue(std::string_view json_data, std::string_view json_path) {
try {
nlohmann::json json_obj;
auto it = json_cache.find(json_data.data());

if (it != json_cache.end()) {
json_obj = it->second;
}
else {
return currentObj->dump();
json_obj = nlohmann::json::parse(json_data);
json_cache[json_data.data()] = json_obj;
}

nlohmann::json* current_obj = GetObjectAtPath(json_obj, json_path);

if (current_obj == nullptr) {
Output::Warning("JSON_ERROR - Invalid path: {}", json_path);
return k_invalid_str;
}

return GetValueAsString(*current_obj);
}
catch (const std::exception& e) {
Output::Warning("JSON_ERROR - {}", e.what());
return invalid_str;
return k_invalid_str;
}
}

std::string SetValue(const std::string& jsonData, const std::string& jsonPath, const std::string& value) {
std::string SetValue(std::string_view json_data, std::string_view json_path, std::string_view value) {
try {
nlohmann::json jsonObj = nlohmann::json::parse(jsonData);
nlohmann::json* currentObj = &jsonObj;

std::string mutableJsonPath = jsonPath;
size_t pos = 0;
std::string token;
while ((pos = mutableJsonPath.find('.')) != std::string::npos) {
token = mutableJsonPath.substr(0, pos);
if (token.back() == ']') {
size_t bracketPos = token.find('[');
std::string arrayName = token.substr(0, bracketPos);
int index = std::stoi(token.substr(bracketPos + 1, token.length() - bracketPos - 2));
currentObj = &((*currentObj)[arrayName][index]);
}
else {
currentObj = &((*currentObj)[token]);
}
mutableJsonPath.erase(0, pos + 1);
}
nlohmann::json json_obj;
auto it = json_cache.find(json_data.data());

if (mutableJsonPath.back() == ']') {
size_t bracketPos = mutableJsonPath.find('[');
std::string arrayName = mutableJsonPath.substr(0, bracketPos);
int index = std::stoi(mutableJsonPath.substr(bracketPos + 1, mutableJsonPath.length() - bracketPos - 2));
(*currentObj)[arrayName][index] = value;
if (it != json_cache.end()) {
json_obj = it->second;
}
else {
(*currentObj)[mutableJsonPath] = value;
json_obj = nlohmann::json::parse(json_data);
json_cache[json_data.data()] = json_obj;
}

return jsonObj.dump();
nlohmann::json* current_obj = GetObjectAtPath(json_obj, json_path, true);

if (current_obj == nullptr) {
Output::Warning("JSON_ERROR - Invalid path: {}", json_path);
return std::string(json_data);
}

// Parse the value string and set the appropriate JSON type
try {
*current_obj = nlohmann::json::parse(value);
}
catch (const nlohmann::json::parse_error&) {
// If parsing fails, treat it as a string value
*current_obj = value;
}

return json_obj.dump();
}
catch (const std::exception& e) {
Output::Warning("JSON_ERROR - {}", e.what());
return jsonData;
return std::string(json_data);
}
}

}
5 changes: 3 additions & 2 deletions src/json_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
#define JSON_HELPER_H

#include <string>
#include <nlohmann/json.hpp>

namespace Json_Helper {
std::string GetValue(const std::string& jsonData, const std::string& jsonPath);
std::string SetValue(const std::string& jsonData, const std::string& jsonPath, const std::string& value);
std::string GetValue(std::string_view json_data, std::string_view json_path);
std::string SetValue(std::string_view json_data, std::string_view json_path, std::string_view value);
}

#endif // JSON_HELPER_H

0 comments on commit 3d444dc

Please sign in to comment.