silly little json
parent
04ff53315d
commit
8588583acf
|
@ -1,3 +1,6 @@
|
||||||
[submodule "lib/BLT-With-Graphics-Template"]
|
[submodule "lib/BLT-With-Graphics-Template"]
|
||||||
path = lib/BLT-With-Graphics-Template
|
path = lib/BLT-With-Graphics-Template
|
||||||
url = https://git.tpgc.me/tri11paragon/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
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
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_ADDRSAN "Enable the address sanitizer" OFF)
|
||||||
option(ENABLE_UBSAN "Enable the ub 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)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
add_subdirectory(lib/BLT-With-Graphics-Template SYSTEM)
|
add_subdirectory(lib/BLT-With-Graphics-Template SYSTEM)
|
||||||
|
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||||
|
add_subdirectory(lib/json)
|
||||||
|
|
||||||
include_directories(include/)
|
include_directories(include/)
|
||||||
file(GLOB_RECURSE PROJECT_BUILD_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
|
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_options(graphs PRIVATE -Wall -Wextra -Wno-comment)
|
||||||
|
|
||||||
target_link_libraries(graphs PUBLIC BLT_WITH_GRAPHICS)
|
target_link_libraries(graphs PUBLIC BLT_WITH_GRAPHICS)
|
||||||
|
target_link_libraries(graphs PRIVATE nlohmann_json::nlohmann_json)
|
||||||
|
|
||||||
if (${ENABLE_ADDRSAN} MATCHES ON)
|
if (${ENABLE_ADDRSAN} MATCHES ON)
|
||||||
target_compile_options(graphs PRIVATE -fsanitize=address)
|
target_compile_options(graphs PRIVATE -fsanitize=address)
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace conf
|
||||||
inline constexpr float DEFAULT_SPRING_LENGTH = 175.0;
|
inline constexpr float DEFAULT_SPRING_LENGTH = 175.0;
|
||||||
inline constexpr float DEFAULT_INITIAL_TEMPERATURE = 100;
|
inline constexpr float DEFAULT_INITIAL_TEMPERATURE = 100;
|
||||||
|
|
||||||
|
inline constexpr float POINT_SIZE = 35;
|
||||||
inline constexpr auto DEFAULT_IMAGE = "parker_point";
|
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_OUTLINE_COLOR = blt::make_color(0, 0.6, 0.6);
|
||||||
inline constexpr auto POINT_HIGHLIGHT_COLOR = blt::make_color(0, 1.0, 1.0);
|
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);
|
inline constexpr auto EDGE_OUTLINE_COLOR = blt::make_color(0, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class graph_t;
|
||||||
|
struct loader_t;
|
||||||
|
|
||||||
#endif //GRAPHS_CONFIG_H
|
#endif //GRAPHS_CONFIG_H
|
||||||
|
|
|
@ -52,8 +52,10 @@ struct bounding_box
|
||||||
|
|
||||||
class graph_t
|
class graph_t
|
||||||
{
|
{
|
||||||
|
friend struct loader_t;
|
||||||
private:
|
private:
|
||||||
std::vector<node> nodes;
|
std::vector<node> nodes;
|
||||||
|
blt::hashmap_t<std::string, blt::u64> names_to_node;
|
||||||
blt::hashset_t<edge, edge_hash> edges;
|
blt::hashset_t<edge, edge_hash> edges;
|
||||||
blt::hashmap_t<blt::u64, blt::hashset_t<blt::u64>> connected_nodes;
|
blt::hashmap_t<blt::u64, blt::hashset_t<blt::u64>> connected_nodes;
|
||||||
bool sim = false;
|
bool sim = false;
|
||||||
|
@ -64,7 +66,6 @@ class graph_t
|
||||||
int current_iterations = 0;
|
int current_iterations = 0;
|
||||||
int max_iterations = 5000;
|
int max_iterations = 5000;
|
||||||
std::unique_ptr<force_equation> equation;
|
std::unique_ptr<force_equation> equation;
|
||||||
static constexpr float POINT_SIZE = 35;
|
|
||||||
|
|
||||||
blt::i32 selected_node = -1;
|
blt::i32 selected_node = -1;
|
||||||
blt::quad_easing easing;
|
blt::quad_easing easing;
|
||||||
|
@ -74,12 +75,14 @@ class graph_t
|
||||||
blt::f64 scaling_connectivity, blt::f64 distance_factor);
|
blt::f64 scaling_connectivity, blt::f64 distance_factor);
|
||||||
|
|
||||||
public:
|
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)
|
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);
|
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,
|
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
|
class engine_t
|
||||||
{
|
{
|
||||||
|
friend struct loader_t;
|
||||||
private:
|
private:
|
||||||
graph_t graph;
|
graph_t graph;
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
struct node
|
struct node
|
||||||
{
|
{
|
||||||
float repulsiveness = 24.0f;
|
float repulsiveness = 24.0f;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
blt::gfx::point2d_t point;
|
blt::gfx::point2d_t point;
|
||||||
float outline_scale = 1.25f;
|
float outline_scale = 1.25f;
|
||||||
blt::vec2 velocity;
|
blt::vec2 velocity;
|
||||||
|
|
|
@ -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
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 960b763ecd144f156d05ec61f577b04107290137
|
|
@ -94,7 +94,7 @@ void graph_t::process_mouse_drag(const blt::i32 width, const blt::i32 height)
|
||||||
|
|
||||||
const auto mag = dist.magnitude();
|
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);
|
new_selection = static_cast<blt::i32>(index);
|
||||||
break;
|
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.
|
// don't allow points too close to the edges of the window.
|
||||||
if (bb.is_screen)
|
if (bb.is_screen)
|
||||||
{
|
{
|
||||||
bb.max_x -= POINT_SIZE;
|
bb.max_x -= conf::POINT_SIZE;
|
||||||
bb.max_y -= POINT_SIZE;
|
bb.max_y -= conf::POINT_SIZE;
|
||||||
bb.min_x += POINT_SIZE;
|
bb.min_x += conf::POINT_SIZE;
|
||||||
bb.min_y += POINT_SIZE;
|
bb.min_y += conf::POINT_SIZE;
|
||||||
}
|
}
|
||||||
static std::random_device dev;
|
static std::random_device dev;
|
||||||
static std::uniform_real_distribution chance(0.0, 1.0);
|
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 dx = rp.x() - x;
|
||||||
const float dy = rp.y() - y;
|
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;
|
can_break = false;
|
||||||
break;
|
break;
|
||||||
|
@ -173,7 +173,7 @@ void graph_t::create_random_graph(bounding_box bb, const blt::size_t min_nodes,
|
||||||
if (can_break)
|
if (can_break)
|
||||||
break;
|
break;
|
||||||
} while (true);
|
} 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))
|
for (const auto& [index1, node1] : blt::enumerate(nodes))
|
||||||
|
|
|
@ -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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
12
src/main.cpp
12
src/main.cpp
|
@ -23,6 +23,7 @@
|
||||||
#include <blt/std/time.h>
|
#include <blt/std/time.h>
|
||||||
#include <blt/math/log_util.h>
|
#include <blt/math/log_util.h>
|
||||||
#include <graph.h>
|
#include <graph.h>
|
||||||
|
#include <loader.h>
|
||||||
|
|
||||||
blt::gfx::matrix_state_manager global_matrices;
|
blt::gfx::matrix_state_manager global_matrices;
|
||||||
blt::gfx::resource_manager resources;
|
blt::gfx::resource_manager resources;
|
||||||
|
@ -42,6 +43,7 @@ namespace im = ImGui;
|
||||||
* - ability to remove nodes from graph (make use of multi selection?)
|
* - ability to remove nodes from graph (make use of multi selection?)
|
||||||
*/
|
*/
|
||||||
engine_t engine;
|
engine_t engine;
|
||||||
|
loader_t loader_data;
|
||||||
|
|
||||||
void init(const blt::gfx::window_data& 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/parkerpoint.png", "parker_point");
|
||||||
resources.enqueue("res/parker cat ears.jpg", "parkercat");
|
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();
|
global_matrices.create_internals();
|
||||||
resources.load_resources();
|
resources.load_resources();
|
||||||
renderer_2d.create();
|
renderer_2d.create();
|
||||||
|
@ -78,6 +87,9 @@ void update(const blt::gfx::window_data& data)
|
||||||
int main(int, const char**)
|
int main(int, const char**)
|
||||||
{
|
{
|
||||||
blt::gfx::init(blt::gfx::window_data{"Force-Directed Graph Drawing", init, update, 1440, 720}.setSyncInterval(1));
|
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();
|
global_matrices.cleanup();
|
||||||
resources.cleanup();
|
resources.cleanup();
|
||||||
renderer_2d.cleanup();
|
renderer_2d.cleanup();
|
||||||
|
|
Loading…
Reference in New Issue