silly little json

main
Brett 2024-07-27 20:53:47 -04:00
parent 04ff53315d
commit 8588583acf
10 changed files with 179 additions and 11 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "lib/BLT-With-Graphics-Template"]
path = lib/BLT-With-Graphics-Template
url = https://git.tpgc.me/tri11paragon/BLT-With-Graphics-Template
[submodule "lib/json"]
path = lib/json
url = https://github.com/nlohmann/json.git

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25)
project(graphs VERSION 0.1.1)
project(graphs VERSION 0.1.2)
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)
@ -11,6 +11,8 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(lib/BLT-With-Graphics-Template SYSTEM)
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(lib/json)
include_directories(include/)
file(GLOB_RECURSE PROJECT_BUILD_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
@ -21,6 +23,7 @@ target_compile_options(graphs PRIVATE -Wall -Wextra -Wno-comment)
target_link_options(graphs PRIVATE -Wall -Wextra -Wno-comment)
target_link_libraries(graphs PUBLIC BLT_WITH_GRAPHICS)
target_link_libraries(graphs PRIVATE nlohmann_json::nlohmann_json)
if (${ENABLE_ADDRSAN} MATCHES ON)
target_compile_options(graphs PRIVATE -fsanitize=address)

View File

@ -29,6 +29,7 @@ namespace conf
inline constexpr float DEFAULT_SPRING_LENGTH = 175.0;
inline constexpr float DEFAULT_INITIAL_TEMPERATURE = 100;
inline constexpr float POINT_SIZE = 35;
inline constexpr auto DEFAULT_IMAGE = "parker_point";
inline constexpr auto POINT_OUTLINE_COLOR = blt::make_color(0, 0.6, 0.6);
inline constexpr auto POINT_HIGHLIGHT_COLOR = blt::make_color(0, 1.0, 1.0);
@ -38,4 +39,7 @@ namespace conf
inline constexpr auto EDGE_OUTLINE_COLOR = blt::make_color(0, 1, 0);
}
class graph_t;
struct loader_t;
#endif //GRAPHS_CONFIG_H

View File

@ -52,8 +52,10 @@ struct bounding_box
class graph_t
{
friend struct loader_t;
private:
std::vector<node> nodes;
blt::hashmap_t<std::string, blt::u64> names_to_node;
blt::hashset_t<edge, edge_hash> edges;
blt::hashmap_t<blt::u64, blt::hashset_t<blt::u64>> connected_nodes;
bool sim = false;
@ -64,7 +66,6 @@ class graph_t
int current_iterations = 0;
int max_iterations = 5000;
std::unique_ptr<force_equation> equation;
static constexpr float POINT_SIZE = 35;
blt::i32 selected_node = -1;
blt::quad_easing easing;
@ -74,12 +75,14 @@ class graph_t
blt::f64 scaling_connectivity, blt::f64 distance_factor);
public:
graph_t() = default;
graph_t()
{
use_Eades();
}
void make_new(const bounding_box& bb, const blt::size_t min_nodes, const blt::size_t max_nodes, const blt::f64 connectivity)
{
create_random_graph(bb, min_nodes, max_nodes, connectivity, 0, 25);
use_Eades();
}
void reset(const bounding_box& bb, const blt::size_t min_nodes, const blt::size_t max_nodes, const blt::f64 connectivity,
@ -198,6 +201,7 @@ class graph_t
class engine_t
{
friend struct loader_t;
private:
graph_t graph;

View File

@ -27,6 +27,8 @@
struct node
{
float repulsiveness = 24.0f;
std::string name;
blt::gfx::point2d_t point;
float outline_scale = 1.25f;
blt::vec2 velocity;

45
include/loader.h Normal file
View File

@ -0,0 +1,45 @@
#pragma once
/*
* Copyright (C) 2024 Brett Terpstra
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef GRAPHS_LOADER_H
#define GRAPHS_LOADER_H
#include <config.h>
#include <graph_base.h>
#include <graph.h>
#include <optional>
#include <string_view>
#include <blt/gfx/window.h>
struct loader_t
{
std::vector<std::pair<std::string, std::string>> textures;
/**
* if save path is present and a valid file it will be read from, otherwise path will be used as the default.
*/
static std::optional<loader_t> load_for(engine_t& engine, const blt::gfx::window_data& data, std::string_view path,
std::optional<std::string_view> save_path = {});
/**
* Saves engine to the path. Will also save any extra loader data like textures. Loader can be empty.
*/
static void save_for(engine_t& engine, const loader_t& loader, std::string_view path);
};
#endif //GRAPHS_LOADER_H

1
lib/json Submodule

@ -0,0 +1 @@
Subproject commit 960b763ecd144f156d05ec61f577b04107290137

View File

@ -94,7 +94,7 @@ void graph_t::process_mouse_drag(const blt::i32 width, const blt::i32 height)
const auto mag = dist.magnitude();
if (mag < POINT_SIZE && mouse_pressed)
if (mag < conf::POINT_SIZE && mouse_pressed)
{
new_selection = static_cast<blt::i32>(index);
break;
@ -137,10 +137,10 @@ void graph_t::create_random_graph(bounding_box bb, const blt::size_t min_nodes,
// don't allow points too close to the edges of the window.
if (bb.is_screen)
{
bb.max_x -= POINT_SIZE;
bb.max_y -= POINT_SIZE;
bb.min_x += POINT_SIZE;
bb.min_y += POINT_SIZE;
bb.max_x -= conf::POINT_SIZE;
bb.max_y -= conf::POINT_SIZE;
bb.min_x += conf::POINT_SIZE;
bb.min_y += conf::POINT_SIZE;
}
static std::random_device dev;
static std::uniform_real_distribution chance(0.0, 1.0);
@ -164,7 +164,7 @@ void graph_t::create_random_graph(bounding_box bb, const blt::size_t min_nodes,
const float dx = rp.x() - x;
const float dy = rp.y() - y;
if (const float dist = std::sqrt(dx * dx + dy * dy); dist <= POINT_SIZE)
if (const float dist = std::sqrt(dx * dx + dy * dy); dist <= conf::POINT_SIZE)
{
can_break = false;
break;
@ -173,7 +173,7 @@ void graph_t::create_random_graph(bounding_box bb, const blt::size_t min_nodes,
if (can_break)
break;
} while (true);
nodes.push_back(node({x, y, POINT_SIZE}));
nodes.push_back(node({x, y, conf::POINT_SIZE}));
}
for (const auto& [index1, node1] : blt::enumerate(nodes))

94
src/loader.cpp Normal file
View File

@ -0,0 +1,94 @@
/*
* <Short Description>
* Copyright (C) 2024 Brett Terpstra
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <loader.h>
#include <blt/std/logging.h>
#include <fstream>
#include <istream>
#include <random>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
template<typename T>
T load_with_default(const json& data, std::string_view key, T def)
{
if (data.contains(key))
return data[key].get<T>();
return def;
}
std::optional<loader_t> loader_t::load_for(engine_t& engine, const blt::gfx::window_data& window_data, std::string_view path,
std::optional<std::string_view> save_path)
{
auto& graph = engine.graph;
static std::random_device dev;
std::uniform_real_distribution pos_x_dist(0.0, static_cast<blt::f64>(window_data.width));
std::uniform_real_distribution pos_y_dist(0.0, static_cast<blt::f64>(window_data.height));
if (save_path && std::filesystem::exists(*save_path))
path = *save_path;
if (!std::filesystem::exists(path))
{
BLT_WARN("Unable to load graph file!");
return {};
}
std::ifstream file{std::string(path)};
json data = json::parse(file);
loader_t loader;
if (data.contains("textures"))
{
for (const auto& texture : data["textures"])
{
auto texture_path = texture["path"].get<std::string>();
auto texture_key = load_with_default(texture, "name", texture_path);
loader.textures.emplace_back(texture_key, texture_path);
}
}
if (data.contains("nodes"))
{
graph.nodes.clear();
for (const auto& node : data["nodes"])
{
auto x = static_cast<blt::f32>(load_with_default(node, "x", pos_x_dist(dev)));
auto y = static_cast<blt::f32>(load_with_default(node, "y", pos_y_dist(dev)));
auto size = static_cast<blt::f32>(load_with_default(node, "size", static_cast<f64>(conf::POINT_SIZE)));
auto name = load_with_default<std::string>(node, "name", "unnamed");
graph.names_to_node.insert({name, static_cast<blt::u64>(graph.nodes.size())});
graph.nodes.emplace_back(blt::gfx::point2d_t{x, y, size});
graph.nodes.back().name = std::move(name);
}
}
if (data.contains("connections"))
{
graph.edges.clear();
graph.connected_nodes.clear();
}
return loader;
}
void loader_t::save_for(engine_t& engine, const loader_t& loader, std::string_view path)
{
}

View File

@ -23,6 +23,7 @@
#include <blt/std/time.h>
#include <blt/math/log_util.h>
#include <graph.h>
#include <loader.h>
blt::gfx::matrix_state_manager global_matrices;
blt::gfx::resource_manager resources;
@ -42,6 +43,7 @@ namespace im = ImGui;
* - ability to remove nodes from graph (make use of multi selection?)
*/
engine_t engine;
loader_t loader_data;
void init(const blt::gfx::window_data& data)
{
@ -53,6 +55,13 @@ void init(const blt::gfx::window_data& data)
resources.enqueue("res/parkerpoint.png", "parker_point");
resources.enqueue("res/parker cat ears.jpg", "parkercat");
if (auto loader = loader_t::load_for(engine, data, "default.json", "save.json"))
{
loader_data = *loader;
for (const auto& [key, path] : loader_data.textures)
resources.enqueue(path, key);
}
global_matrices.create_internals();
resources.load_resources();
renderer_2d.create();
@ -78,6 +87,9 @@ void update(const blt::gfx::window_data& data)
int main(int, const char**)
{
blt::gfx::init(blt::gfx::window_data{"Force-Directed Graph Drawing", init, update, 1440, 720}.setSyncInterval(1));
loader_t::save_for(engine, loader_data, "save.json");
global_matrices.cleanup();
resources.cleanup();
renderer_2d.cleanup();