Browse Source

Replace config file class and loader with JSON file and loader

master
C. J. Howard 3 years ago
parent
commit
04c98dac95
10 changed files with 235 additions and 154 deletions
  1. +36
    -0
      src/entity/components/select.hpp
  2. +22
    -17
      src/game/bootloader.cpp
  3. +3
    -3
      src/game/context.hpp
  4. +94
    -12
      src/game/states/forage.cpp
  5. +13
    -3
      src/game/states/loading.cpp
  6. +1
    -2
      src/game/states/nuptial-flight.cpp
  7. +0
    -53
      src/resources/config-file-loader.cpp
  8. +0
    -64
      src/resources/config-file.hpp
  9. +38
    -0
      src/resources/json-loader.cpp
  10. +28
    -0
      src/resources/json.hpp

+ 36
- 0
src/entity/components/select.hpp View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_ENTITY_COMPONENT_SELECT_HPP
#define ANTKEEPER_ENTITY_COMPONENT_SELECT_HPP
namespace entity {
namespace component {
/// Allows an entity to be selected.
struct select
{
/// Radius of selection bounds.
float radius;
};
} // namespace component
} // namespace entity
#endif // ANTKEEPER_ENTITY_COMPONENT_SELECT_HPP

+ 22
- 17
src/game/bootloader.cpp View File

@ -50,7 +50,6 @@
#include "renderer/vertex-attributes.hpp" #include "renderer/vertex-attributes.hpp"
#include "renderer/compositor.hpp" #include "renderer/compositor.hpp"
#include "renderer/renderer.hpp" #include "renderer/renderer.hpp"
#include "resources/config-file.hpp"
#include "resources/resource-manager.hpp" #include "resources/resource-manager.hpp"
#include "resources/resource-manager.hpp" #include "resources/resource-manager.hpp"
#include "scene/scene.hpp" #include "scene/scene.hpp"
@ -357,7 +356,7 @@ void load_config(game::context* ctx)
logger->push_task("Loading config"); logger->push_task("Loading config");
// Load config file // Load config file
ctx->config = ctx->resource_manager->load<config_file>("config.txt");
ctx->config = ctx->resource_manager->load<json>("config.json");
if (!ctx->config) if (!ctx->config)
{ {
logger->pop_task(EXIT_FAILURE); logger->pop_task(EXIT_FAILURE);
@ -376,7 +375,7 @@ void load_strings(game::context* ctx)
build_string_table_map(&ctx->string_table_map, *ctx->string_table); build_string_table_map(&ctx->string_table_map, *ctx->string_table);
ctx->language_code = ctx->config->get<std::string>("language");
ctx->language_code = (*ctx->config)["language"].get<std::string>();
ctx->language_index = -1; ctx->language_index = -1;
for (int i = 2; i < (*ctx->string_table)[0].size(); ++i) for (int i = 2; i < (*ctx->string_table)[0].size(); ++i)
{ {
@ -397,7 +396,7 @@ void setup_window(game::context* ctx)
logger->push_task("Setting up window"); logger->push_task("Setting up window");
application* app = ctx->app; application* app = ctx->app;
config_file* config = ctx->config;
json* config = ctx->config;
// Set fullscreen or windowed mode // Set fullscreen or windowed mode
bool fullscreen = true; bool fullscreen = true;
@ -405,8 +404,8 @@ void setup_window(game::context* ctx)
fullscreen = true; fullscreen = true;
else if (ctx->option_windowed.has_value()) else if (ctx->option_windowed.has_value())
fullscreen = false; fullscreen = false;
else if (config->has("fullscreen"))
fullscreen = (config->get<int>("fullscreen") != 0);
else if (config->contains("fullscreen"))
fullscreen = (*config)["fullscreen"].get<bool>();
app->set_fullscreen(fullscreen); app->set_fullscreen(fullscreen);
// Set resolution // Set resolution
@ -414,13 +413,19 @@ void setup_window(game::context* ctx)
int2 resolution = {display_dimensions[0], display_dimensions[1]}; int2 resolution = {display_dimensions[0], display_dimensions[1]};
if (fullscreen) if (fullscreen)
{ {
if (config->has("fullscreen_resolution"))
resolution = config->get<int2>("fullscreen_resolution");
if (config->contains("fullscreen_resolution"))
{
resolution.x = (*config)["fullscreen_resolution"][0].get<int>();
resolution.y = (*config)["fullscreen_resolution"][1].get<int>();
}
} }
else else
{ {
if (config->has("windowed_resolution"))
resolution = config->get<int2>("windowed_resolution");
if (config->contains("windowed_resolution"))
{
resolution.x = (*config)["windowed_resolution"][0].get<int>();
resolution.y = (*config)["windowed_resolution"][1].get<int>();
}
} }
app->resize_window(resolution.x, resolution.y); app->resize_window(resolution.x, resolution.y);
@ -428,8 +433,8 @@ void setup_window(game::context* ctx)
bool vsync = true; bool vsync = true;
if (ctx->option_vsync.has_value()) if (ctx->option_vsync.has_value())
vsync = (ctx->option_vsync.value() != 0); vsync = (ctx->option_vsync.value() != 0);
else if (config->has("vsync"))
vsync = (config->get<int>("vsync") != 0);
else if (config->contains("vsync"))
vsync = (*config)["vsync"].get<bool>();
app->set_vsync(vsync); app->set_vsync(vsync);
// Set title // Set title
@ -466,9 +471,9 @@ void setup_rendering(game::context* ctx)
// Create shadow map framebuffer // Create shadow map framebuffer
int shadow_map_resolution = 4096; int shadow_map_resolution = 4096;
if (ctx->config->has("shadow_map_resolution"))
if (ctx->config->contains("shadow_map_resolution"))
{ {
shadow_map_resolution = ctx->config->get<int>("shadow_map_resolution");
shadow_map_resolution = (*ctx->config)["shadow_map_resolution"].get<int>();
} }
ctx->shadow_map_depth_texture = new gl::texture_2d(shadow_map_resolution, shadow_map_resolution, gl::pixel_type::float_32, gl::pixel_format::d); ctx->shadow_map_depth_texture = new gl::texture_2d(shadow_map_resolution, shadow_map_resolution, gl::pixel_type::float_32, gl::pixel_format::d);
ctx->shadow_map_depth_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend); ctx->shadow_map_depth_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
@ -846,10 +851,10 @@ void setup_systems(game::context* ctx)
ctx->proteome_system = new entity::system::proteome(*ctx->entity_registry); ctx->proteome_system = new entity::system::proteome(*ctx->entity_registry);
// Set time scale // Set time scale
float time_scale = 60.0f;
if (ctx->config->has("time_scale"))
double time_scale = 60.0;
if (ctx->config->contains("time_scale"))
{ {
time_scale = ctx->config->get<float>("time_scale");
time_scale = (*ctx->config)["time_scale"].get<double>();
} }
ctx->orbit_system->set_time_scale(time_scale / seconds_per_day); ctx->orbit_system->set_time_scale(time_scale / seconds_per_day);

+ 3
- 3
src/game/context.hpp View File

@ -42,6 +42,7 @@
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include "resources/json.hpp"
// Forward declarations // Forward declarations
class animator; class animator;
@ -49,7 +50,6 @@ class application;
class bloom_pass; class bloom_pass;
class clear_pass; class clear_pass;
class compositor; class compositor;
class config_file;
class final_pass; class final_pass;
class material; class material;
class material_pass; class material_pass;
@ -129,8 +129,8 @@ struct context
std::string screenshots_path; std::string screenshots_path;
std::string data_package_path; std::string data_package_path;
// Config
config_file* config;
// Configuration
json* config;
// Resources // Resources
resource_manager* resource_manager; resource_manager* resource_manager;

+ 94
- 12
src/game/states/forage.cpp View File

@ -38,6 +38,7 @@ namespace state {
namespace forage { namespace forage {
static void setup_camera(game::context* ctx); static void setup_camera(game::context* ctx);
static void setup_tools(game::context* ctx);
static void setup_controls(game::context* ctx); static void setup_controls(game::context* ctx);
void enter(game::context* ctx) void enter(game::context* ctx)
@ -187,6 +188,54 @@ void setup_camera(game::context* ctx)
ctx->surface_camera->set_exposure(-14.5f); ctx->surface_camera->set_exposure(-14.5f);
} }
void setup_tools(game::context* ctx)
{
if (!ctx->entities.count("move_tool"))
{
entity::id tool_eid = ctx->entity_registry->create();
ctx->entities["move_tool"] = tool_eid;
}
if (!ctx->entities.count("paint_tool"))
{
entity::id tool_eid = ctx->entity_registry->create();
ctx->entities["paint_tool"] = tool_eid;
}
if (!ctx->entities.count("flip_tool"))
{
entity::id tool_eid = ctx->entity_registry->create();
ctx->entities["flip_tool"] = tool_eid;
}
if (!ctx->entities.count("poke_tool"))
{
entity::id tool_eid = ctx->entity_registry->create();
ctx->entities["poke_tool"] = tool_eid;
}
if (!ctx->entities.count("inspect_tool"))
{
entity::id tool_eid = ctx->entity_registry->create();
ctx->entities["inspect_tool"] = tool_eid;
}
if (!ctx->entities.count("label_tool"))
{
entity::id tool_eid = ctx->entity_registry->create();
ctx->entities["label_tool"] = tool_eid;
}
if (!ctx->entities.count("wait_tool"))
{
entity::id tool_eid = ctx->entity_registry->create();
ctx->entities["wait_tool"] = tool_eid;
}
// Set move tool as active tool
ctx->entities["active_tool"] = ctx->entities["move_tool"];
}
void setup_controls(game::context* ctx) void setup_controls(game::context* ctx)
{ {
// Get underground camera entity // Get underground camera entity
@ -209,9 +258,9 @@ void setup_controls(game::context* ctx)
[ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value) [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
{ {
if (move_slow->is_active()) if (move_slow->is_active())
value *= 0.5f;
value *= 0.25f;
if (move_fast->is_active()) if (move_fast->is_active())
value *= 2.0f;
value *= 4.0f;
auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid); auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f}); const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
@ -227,9 +276,9 @@ void setup_controls(game::context* ctx)
[ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value) [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
{ {
if (move_slow->is_active()) if (move_slow->is_active())
value *= 0.5f;
value *= 0.25f;
if (move_fast->is_active()) if (move_fast->is_active())
value *= 2.0f;
value *= 4.0f;
auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid); auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f}); const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
@ -245,9 +294,9 @@ void setup_controls(game::context* ctx)
[ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value) [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
{ {
if (move_slow->is_active()) if (move_slow->is_active())
value *= 0.5f;
value *= 0.25f;
if (move_fast->is_active()) if (move_fast->is_active())
value *= 2.0f;
value *= 4.0f;
auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid); auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f}); const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
@ -263,9 +312,9 @@ void setup_controls(game::context* ctx)
[ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value) [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
{ {
if (move_slow->is_active()) if (move_slow->is_active())
value *= 0.5f;
value *= 0.25f;
if (move_fast->is_active()) if (move_fast->is_active())
value *= 2.0f;
value *= 4.0f;
auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid); auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f}); const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
@ -281,9 +330,9 @@ void setup_controls(game::context* ctx)
[ctx, target_eid, pedestal_speed, move_slow, move_fast](float value) [ctx, target_eid, pedestal_speed, move_slow, move_fast](float value)
{ {
if (move_slow->is_active()) if (move_slow->is_active())
value *= 0.5f;
value *= 0.25f;
if (move_fast->is_active()) if (move_fast->is_active())
value *= 2.0f;
value *= 4.0f;
const float3 movement = {0.0f, pedestal_speed * value * (1.0f / 60.0f), 0.0f}; const float3 movement = {0.0f, pedestal_speed * value * (1.0f / 60.0f), 0.0f};
entity::command::translate(*ctx->entity_registry, target_eid, movement); entity::command::translate(*ctx->entity_registry, target_eid, movement);
@ -296,9 +345,9 @@ void setup_controls(game::context* ctx)
[ctx, target_eid, pedestal_speed, move_slow, move_fast](float value) [ctx, target_eid, pedestal_speed, move_slow, move_fast](float value)
{ {
if (move_slow->is_active()) if (move_slow->is_active())
value *= 0.5f;
value *= 0.25f;
if (move_fast->is_active()) if (move_fast->is_active())
value *= 2.0f;
value *= 4.0f;
const float3 movement = {0.0f, -pedestal_speed * value * (1.0f / 60.0f), 0.0f}; const float3 movement = {0.0f, -pedestal_speed * value * (1.0f / 60.0f), 0.0f};
entity::command::translate(*ctx->entity_registry, target_eid, movement); entity::command::translate(*ctx->entity_registry, target_eid, movement);
@ -374,6 +423,39 @@ void setup_controls(game::context* ctx)
three_dof.pitch = std::min<float>(math::radians(90.0f), three_dof.pitch); three_dof.pitch = std::min<float>(math::radians(90.0f), three_dof.pitch);
} }
); );
// Use tool
ctx->controls["use_tool"]->set_activated_callback
(
[ctx]()
{
if (ctx->entities["active_tool"] == ctx->entities["move_tool"])
{
// Project mouse position into scene and grab selectable entity
auto [mouse_x, mouse_y] = ctx->app->get_mouse()->get_current_position();
}
}
);
ctx->controls["use_tool"]->set_deactivated_callback
(
[ctx]()
{
if (ctx->entities["active_tool"] == ctx->entities["move_tool"])
{
}
}
);
ctx->controls["use_tool"]->set_active_callback
(
[ctx](float value)
{
auto [mouse_x, mouse_y] = ctx->app->get_mouse()->get_current_position();
ctx->logger->log("tool used (" + std::to_string(mouse_x) + ", " + std::to_string(mouse_y) + ")");
}
);
} }
} // namespace forage } // namespace forage

+ 13
- 3
src/game/states/loading.cpp View File

@ -47,7 +47,6 @@
#include "resources/resource-manager.hpp" #include "resources/resource-manager.hpp"
#include "scene/ambient-light.hpp" #include "scene/ambient-light.hpp"
#include "scene/directional-light.hpp" #include "scene/directional-light.hpp"
#include "resources/config-file.hpp"
#include "utility/timestamp.hpp" #include "utility/timestamp.hpp"
namespace game { namespace game {
@ -143,11 +142,14 @@ void load_controls(game::context* ctx)
if (!fullscreen) if (!fullscreen)
{ {
int2 resolution = ctx->config->get<int2>("windowed_resolution");
int2 resolution;
resolution.x = (*ctx->config)["windowed_resolution"][0].get<int>();
resolution.y = (*ctx->config)["windowed_resolution"][1].get<int>();
ctx->app->resize_window(resolution.x, resolution.y); ctx->app->resize_window(resolution.x, resolution.y);
} }
ctx->config->set<int>("fullscreen", (fullscreen) ? 1 : 0);
(*ctx->config)["fullscreen"] = fullscreen;
} }
); );
@ -288,6 +290,14 @@ void load_controls(game::context* ctx)
ctx->input_event_router->add_mapping(input::mouse_motion_mapping(control, nullptr, input::mouse_motion_axis::positive_y)); ctx->input_event_router->add_mapping(input::mouse_motion_mapping(control, nullptr, input::mouse_motion_axis::positive_y));
ctx->controls["mouse_down"] = control; ctx->controls["mouse_down"] = control;
} }
// Use tool
if (!ctx->controls.count("use_tool"))
{
input::control* control = new input::control();
ctx->input_event_router->add_mapping(input::mouse_button_mapping(control, nullptr, 1));
ctx->controls["use_tool"] = control;
}
} }
void cosmogenesis(game::context* ctx) void cosmogenesis(game::context* ctx)

+ 1
- 2
src/game/states/nuptial-flight.cpp View File

@ -29,7 +29,6 @@
#include "renderer/material-property.hpp" #include "renderer/material-property.hpp"
#include "animation/screen-transition.hpp" #include "animation/screen-transition.hpp"
#include "animation/ease.hpp" #include "animation/ease.hpp"
#include "resources/config-file.hpp"
#include "resources/resource-manager.hpp" #include "resources/resource-manager.hpp"
namespace game { namespace game {
@ -102,7 +101,7 @@ void enter(game::context* ctx)
void exit(game::context* ctx) void exit(game::context* ctx)
{ {
// Resume motion of celestial objects // Resume motion of celestial objects
const double time_scale = ctx->config->get<double>("time_scale");
const double time_scale = (*ctx->config)["time_scale"].get<double>();
ctx->astronomy_system->set_time_scale(time_scale); ctx->astronomy_system->set_time_scale(time_scale);
ctx->orbit_system->set_time_scale(time_scale); ctx->orbit_system->set_time_scale(time_scale);
} }

+ 0
- 53
src/resources/config-file-loader.cpp View File

@ -1,53 +0,0 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#include "resources/resource-loader.hpp"
#include "resources/resource-manager.hpp"
#include "resources/config-file.hpp"
#include "resources/text-file.hpp"
template <>
config_file* resource_loader<config_file>::load(resource_manager* resource_manager, PHYSFS_File* file)
{
// Load as text file
text_file* text = resource_loader<text_file>::load(resource_manager, file);
config_file* config = new config_file();
for (const std::string& line: *text)
{
if (line[0] == '#')
continue;
std::size_t delimeter = line.find_first_of('=');
if (delimeter == std::string::npos)
continue;
std::string name = line.substr(0, delimeter);
std::string value = line.substr(delimeter + 1, line.length() - delimeter - 1);
if (name.empty() || value.empty())
continue;
config->set<std::string>(name, value);
}
delete text;
return config;
}

+ 0
- 64
src/resources/config-file.hpp View File

@ -1,64 +0,0 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_FILE_HPP
#define CONFIG_FILE_HPP
#include <sstream>
#include <string>
#include <unordered_map>
class config_file
{
public:
template <typename T>
void set(const std::string& name, const T& value);
template <typename T>
T get(const std::string& name) const;
bool has(const std::string& name) const;
private:
std::unordered_map<std::string, std::string> variables;
};
template <typename T>
void config_file::set(const std::string& name, const T& value)
{
std::stringstream stream;
stream << value;
variables[name] = stream.str();
}
template <typename T>
T config_file::get(const std::string& name) const
{
T value;
if (auto it = variables.find(name); it != variables.end())
std::stringstream(it->second) >> value;
return value;
}
inline bool config_file::has(const std::string& name) const
{
return (variables.find(name) != variables.end());
}
#endif // CONFIG_FILE_HPP

+ 38
- 0
src/resources/json-loader.cpp View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#include "resource-loader.hpp"
#include "resource-manager.hpp"
#include "json.hpp"
#include <physfs.h>
template <>
json* resource_loader<json>::load(resource_manager* resource_manager, PHYSFS_File* file)
{
// Read file into buffer
std::size_t size = static_cast<int>(PHYSFS_fileLength(file));
std::string buffer;
buffer.resize(size);
PHYSFS_readBytes(file, &buffer[0], size);
// Parse json from file buffer
json* data = new json(json::parse(buffer));
return data;
}

+ 28
- 0
src/resources/json.hpp View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_RESOURCES_JSON_HPP
#define ANTKEEPER_RESOURCES_JSON_HPP
#include <nlohmann/json.hpp>
/// JSON data
typedef nlohmann::json json;
#endif // ANTKEEPER_RESOURCES_JSON_HPP

Loading…
Cancel
Save