Skip to content

Commit

Permalink
Tileset serialization
Browse files Browse the repository at this point in the history
Load and save the tileset with nlohmann::json. The tile prototypes
stored in the tileset can be modified at runtime, and the new values
are kept between a run and another.
  • Loading branch information
Fahien committed Jun 5, 2020
1 parent 122ab3b commit 931bba6
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 13 deletions.
15 changes: 15 additions & 0 deletions include/spot/jam/serialization/tileset.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <nlohmann/json.hpp>


namespace spot::jam
{


class Tileset;

void to_json( nlohmann::json& j, const Tileset& t );


} // namespace spot::jam
20 changes: 19 additions & 1 deletion include/spot/jam/tileset.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,28 @@ namespace spot::jam
class Tileset
{
public:
using Resources = std::unordered_map<TileId, std::pair<Tile, Handle<gfx::Mesh>>>;

/// @brief Constructs a new editor from json file
/// @param path File path containing tileset data
/// @param model Model used to store meshes and nodes
static Tileset from_json( const char* path, gfx::Model& model );

/// @param path File path of the image to be loaded
/// @param model Model where to store resources
Tileset( const char* path, gfx::Model& model );

/// @brief Save tileset to file
/// @param path File path where to save tileset data
void save( const char* path ) const;

/// @brief Adds a tile to the tileset creating a mesh for it
/// It does not do anything if the tile is already in the tileset
/// @param tile Tile from which to create a mesh
/// @param model Model where to store resources
/// @return An iterator to tile resources
Resources::iterator emplace( const Tile& tile, gfx::Model& model );

/// @param tile Tile from which to create a node
/// @param model Model where to store resources
/// @return A new node from that tile
Expand All @@ -41,7 +59,7 @@ class Tileset
Handle<gfx::Material> material;

/// Map of tiles and their quad meshes
std::unordered_map<TileId, std::pair<Tile, Handle<gfx::Mesh>>> tiles;
Resources tiles;
};


Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ set( LIB_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/serialization/serialization.cc
${CMAKE_CURRENT_SOURCE_DIR}/serialization/entity.cc
${CMAKE_CURRENT_SOURCE_DIR}/serialization/tile.cc
${CMAKE_CURRENT_SOURCE_DIR}/serialization/tileset.cc
${CMAKE_CURRENT_SOURCE_DIR}/serialization/node.cc
${CMAKE_CURRENT_SOURCE_DIR}/serialization/map.cc
${CMAKE_CURRENT_SOURCE_DIR}/editor/tileset.cc
Expand Down
3 changes: 2 additions & 1 deletion src/game.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ VkViewport create_viewport( VkExtent2D extent )
Game::Game()
: gfx { VkExtent2D { 320 * 3, 240 * 3 }, true }
, model { gfx.models.push() }
, tileset { "res/img/assets.png", *model }
, tileset { Tileset::from_json( "res/data/tileset.json", *model ) }
, player { "res/data/player.json", tileset, *model }
, map { "res/data/map.json", tileset, *model }
{
Expand Down Expand Up @@ -79,6 +79,7 @@ Game::~Game()
{
map.save( "res/data/map.json" );
player.save( "res/data/player.json" );
tileset.save( "res/data/tileset.json" );
gfx.device.wait_idle();
}

Expand Down
54 changes: 54 additions & 0 deletions src/serialization/tileset.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "spot/jam/serialization/tileset.h"
#include "spot/jam/tileset.h"

#include <spot/file/ifstream.h>
#include <spot/gfx/model.h>

#include "spot/jam/serialization/tile.h"

namespace spot::jam
{


void to_json( nlohmann::json& j, const Tileset& t )
{
j["image"] = t.image->uri;

auto tiles = nlohmann::json::array();
for ( auto& [_,pair] : t.tiles )
{
const Tile& tile = pair.first;
tiles.emplace_back( tile );
}
j["tiles"] = tiles;
}


Tileset Tileset::from_json( const char* path, gfx::Model& model )
{
auto file = file::Ifstream( path );
nlohmann::json j;
file >> j;

auto image_path = j["image"].get<std::string>();

auto tileset = Tileset( image_path.c_str(), model );

for ( auto& tile : j["tiles"] )
{
tileset.emplace( tile.get<Tile>(), model );
}

return tileset;
}


void Tileset::save( const char* path ) const
{
nlohmann::json j = *this;
auto file = std::fstream( path, std::ios::trunc | std::ios::out );
file << j;
}


} // namespace spot::jam
26 changes: 15 additions & 11 deletions src/tileset.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,27 @@ Tileset::Tileset( const char* path, gfx::Model& model )
{}


Handle<gfx::Node> Tileset::create_node( const Tile& tile, gfx::Model& model )
Tileset::Resources::iterator Tileset::emplace( const Tile& tile, gfx::Model& model )
{
Handle<gfx::Node> node = model.nodes.push();

// Reuse meshes for node created from the same tile
if ( auto it = tiles.find( tile.id ); it != std::end( tiles ) )
{
node->mesh = it->second.second;
}
else
{
Handle<gfx::Mesh> mesh = tile.create_quad( *material, model );
node->mesh = mesh;
auto pair = std::make_pair( std::move( tile ), std::move( mesh ) );
auto [_, ok] = tiles.emplace( tile.id, std::move( pair ) );
return it;
}

Handle<gfx::Mesh> mesh = tile.create_quad( *material, model );
auto pair = std::make_pair( std::move( tile ), std::move( mesh ) );
auto [it, ok] = tiles.emplace( tile.id, std::move( pair ) );
assert( ok && "Can not add tile to tileset" );
return it;
}


Handle<gfx::Node> Tileset::create_node( const Tile& tile, gfx::Model& model )
{
Handle<gfx::Node> node = model.nodes.push();
node->mesh = emplace( tile, model )->second.second;

// Create collision bounds for the node
auto bounds = model.bounds.push();
node->bounds = bounds;
Expand Down

0 comments on commit 931bba6

Please sign in to comment.