Skip to content

Commit

Permalink
ProcessJson: Cache parsed JSON to make accessing significantly faster
Browse files Browse the repository at this point in the history
The cache is invalidated when the string is set
  • Loading branch information
Ghabry committed Nov 21, 2024
1 parent 4280490 commit 842c2a4
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 28 deletions.
11 changes: 8 additions & 3 deletions src/game_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5080,7 +5080,12 @@ bool Game_Interpreter::CommandEasyRpgProcessJson(lcf::rpg::EventCommand const& c
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));
auto* json_data = Main_Data::game_strings->ParseJson(source_var_id);

if (!json_data) {
Output::Warning("JSON Parse error for {}", Main_Data::game_strings->Get(source_var_id));
return true;
}

if (target_var_type == 2 && !Player::IsPatchManiac()) {
Output::Warning("CommandEasyRpgProcessJson: String operations require Maniac Patch support");
Expand All @@ -5090,7 +5095,7 @@ bool Game_Interpreter::CommandEasyRpgProcessJson(lcf::rpg::EventCommand const& c
std::optional<std::string> result;

if (operation == 0) { // Get operation: Extract a value from JSON data
result = Json_Helper::GetValue(json_data, json_path);
result = Json_Helper::GetValue(*json_data, json_path);

if (result) {
switch (target_var_type) {
Expand Down Expand Up @@ -5127,7 +5132,7 @@ bool Game_Interpreter::CommandEasyRpgProcessJson(lcf::rpg::EventCommand const& c
return true;
}

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

if (result) {
Main_Data::game_strings->Asg({ source_var_id }, *result);
Expand Down
23 changes: 23 additions & 0 deletions src/game_strings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,34 @@
#include "player.h"
#include "utils.h"

#ifdef HAVE_NLOHMANN_JSON
#include "json_helper.h"
#endif

void Game_Strings::WarnGet(int id) const {
Output::Debug("Invalid read strvar[{}]!", id);
--_warnings;
}

#ifdef HAVE_NLOHMANN_JSON
nlohmann::json* Game_Strings::ParseJson(int id) {
auto it = _json_cache.find(id);
if (it != _json_cache.end()) {
return &(it->second);
}

auto str = ToString(Get(id));
auto res = Json_Helper::Parse(str);

if (!res) {
return nullptr;
} else {
_json_cache[id] = *res;
return &_json_cache[id];
}
}
#endif

StringView Game_Strings::Asg(Str_Params params, StringView string) {
Set(params, string);
return Get(params.string_id);
Expand Down
28 changes: 26 additions & 2 deletions src/game_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
* along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
*/

// Headers
// Headers
#include "system.h"
#include <cstdint>
#include <string>
#include <lcf/data.h>
Expand All @@ -27,6 +28,10 @@
#include "player.h"
#include "string_view.h"

#ifdef HAVE_NLOHMANN_JSON
#include <nlohmann/json.hpp>
#endif

/**
* Game_Strings class.
*/
Expand Down Expand Up @@ -59,6 +64,10 @@ class Game_Strings {
StringView GetWithMode(StringView str_data, int mode, int arg, const Game_Variables& variables) const;
StringView GetWithModeAndPos(StringView str_data, int mode, int arg, int* pos, const Game_Variables& variables);

#ifdef HAVE_NLOHMANN_JSON
nlohmann::json* ParseJson(int id);
#endif

StringView Asg(Str_Params params, StringView string);
StringView Cat(Str_Params params, StringView string);
int ToNum(Str_Params params, int var_id, Game_Variables& variables);
Expand All @@ -85,8 +94,11 @@ class Game_Strings {

Strings_t _strings;
mutable int _warnings = max_warnings;
};

#ifdef HAVE_NLOHMANN_JSON
std::unordered_map<int, nlohmann::json> _json_cache;
#endif
};

inline void Game_Strings::Set(Str_Params params, StringView string) {
if (params.string_id <= 0) {
Expand All @@ -108,10 +120,18 @@ inline void Game_Strings::Set(Str_Params params, StringView string) {
} else {
it->second = ins_string;
}

#ifdef HAVE_NLOHMANN_JSON
_json_cache.erase(params.string_id);
#endif
}

inline void Game_Strings::SetData(Strings_t s) {
_strings = std::move(s);

#ifdef HAVE_NLOHMANN_JSON
_json_cache.clear();
#endif
}

inline void Game_Strings::SetData(const std::vector<lcf::DBString>& s) {
Expand All @@ -122,6 +142,10 @@ inline void Game_Strings::SetData(const std::vector<lcf::DBString>& s) {
}
++i;
}

#ifdef HAVE_NLOHMANN_JSON
_json_cache.clear();
#endif
}

inline const Game_Strings::Strings_t& Game_Strings::GetData() const {
Expand Down
28 changes: 7 additions & 21 deletions src/json_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,36 +61,22 @@ namespace Json_Helper {
return json_obj;
}

std::optional<std::string> GetValue(std::string_view json_data, std::string_view json_path) {
auto json_obj = Parse(json_data);

if (!json_obj) {
Output::Warning("JSON: Parse error for {}", json_data);
return {};
}

std::optional<std::string> GetValue(nlohmann::json& json_obj, std::string_view json_path) {
json::json_pointer ptr((std::string(json_path)));

if (ptr.empty()) {
Output::Warning("JSON: Bad json pointer {}", json_path);
return {};
}

if (!json_obj->contains(ptr)) {
if (!json_obj.contains(ptr)) {
return "";
}

return GetValueAsString((*json_obj)[ptr]);
return GetValueAsString(json_obj[ptr]);
}

std::string SetValue(std::string_view json_data, std::string_view json_path, std::string_view value) {
auto json_obj = Parse(json_data);

if (!json_obj) {
Output::Warning("JSON Parse error for {}", json_data);
return std::string(json_data);
}

std::string SetValue(nlohmann::json& json_obj, std::string_view json_path, std::string_view value) {
json::json_pointer ptr((std::string(json_path)));

if (ptr.empty()) {
Expand All @@ -102,12 +88,12 @@ namespace Json_Helper {

if (obj_value.is_discarded()) {
// If parsing fails, treat it as a string value
(*json_obj)[ptr] = std::string(value);
json_obj[ptr] = std::string(value);
} else {
(*json_obj)[ptr] = obj_value;
json_obj[ptr] = obj_value;
}

return (*json_obj).dump();
return json_obj.dump();
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/json_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@

namespace Json_Helper {
std::optional<nlohmann::json> Parse(std::string_view json_data);
std::optional<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);
std::optional<std::string> GetValue(nlohmann::json& json_obj, std::string_view json_path);
std::string SetValue(nlohmann::json& json_obj, std::string_view json_path, std::string_view value);
}

#endif // HAVE_NLOHMANN_JSON
Expand Down

0 comments on commit 842c2a4

Please sign in to comment.