Files
Editor2D/include/Format/Level.hpp

129 lines
5.8 KiB
C++

#pragma once
#include <string>
#include <vector>
#include <Format/Layer.hpp>
#include <Format/Entity.hpp>
#include <json.hpp>
#include <Re2DLevelAPI.hpp>
#include <Format/Tileset.hpp>
const float REDACTED_EDITOR_LIB_VERSION = 1;
/// @class Level
/// @brief Represents the complete game level, containing its metadata, tile layers, and entites.
///
/// This class serves as the primary data structure for loading, managing, and saving
/// all components that constitute the playable game map. It centralizes information
/// about the level's dimensions, graphical assets (tilesets), stuctural layers,
/// and interactive objects (entities).
class Level {
public:
/// The human-readable name of the level.
/// This is typically displayed in level selection menus or editors.
std::string name;
/// A UTC-timestamp of the last time the level file was modified.
std::string last_edit_timestamp;
/// A brief description of the level's content or purpose.
/// Useful for level browsers or internal documentation.
std::string description;
/// The name or identifier of the author who created or last modified the level.
std::string author;
/// A collection of keywords or categories associated with the level.
/// Can be used for filtering, searching, or thematic grouping (e.g., "forest", "puzzle").
std::vector<std::string> tags;
/// The height of the level grid in number of tiles (rows).
// TODO: I mixed up rows and columns. I'm just going to leave it as the convention this system follows for now. -josh
int rows;
/// The width of the level grid in number of tiles (columns).
int cols;
/// A collection of pointers to the tile layers that compose the level's tile grid.
/// Each layer typically represents a distinct plane of tiles (e.g., background, foreground, collisions).
/// @warning The `Level` class is responsible for the ownership and lifecycle of these `Layer` objects
/// if they are allocated dynamically. Consider using smart pointers like `std::unique_ptr<Layer>
/// for automatic memory management,
std::vector<Layer*> layers;
/// A collection of pointers to the entities placed within the level.
/// Entities represent interactive objects, characters, spawn points, or other dynamic elements.
/// @warning Similar to `layers`, the `Level` class is responsible for the ownership and lifecycle
/// of these `Entity` objects if they are dynamically allocated. Consider `std::unique_ptr<Entity>`.
std::vector<Entity*> entities;
/// The filesystem path to the primary tileset image or definition file used by this level.
/// This path is typically relative to the level's main JSON file.
std::string tileset_path;
/// A generic JSON value for storing arbitrary, unstructured level metdata.
/// This can include game-specific settings, editor-specific flags, or any data
/// not explicitly covered by other `Level` members.
json::value metadata;
#pragma region Member Functions
/// The default constructor initializes all member variables to their default or empty states.
/// The level will have zero dimensions, no layers, no entities, and empty metadata.
Level();
/// Destructor for the Level class.
/// Responsible for deallocating all dynamically allocated `Layer` and `Entity` objects
/// pointed to by the `layers` and `entities` vectors to prevent memory leaks.
~Level() = default;
/// Constructs a Level object by loading and parsing a level definition file from the given path.
/// This constructor typically reads a JSON file containing the level's metadata, and
/// may also initiate the loading of associated binary tile data or other assets. NOTE: Currently, we do not.
/// @param path
/// @throws std::runtime_error If the file cannot be opened, is malformed, or if associated data (like binary layers) is missing / invalid.
explicit Level(const std::filesystem::path& path);
/// Constructs a Level object by deserializing its state from a pre-existing JSON value.
/// This constructor assumes the JSON value is already loaded in memory and correct.
/// It will parse the JSON to populate the level's members, including layers and entities.
/// @param json
/// @throws json::exception If the JSON structure is malformed.
/// @see Deserialize() for the underlying parsing logic.
explicit Level(const json::value& json);
/// Deserializes the Level object's state from a provided JSON value.
/// This method takes a JSON object (typically parsed from a file) and populates
/// the current `Level` instance's member variables, including its layers and entities.
/// This is the core parsing logic for loading level data into memory.
/// @param json
/// @throws json::exception If the JSON structure is malformed.
void Deserialize(const json::value& json);
/// Serializes the current Level object's state into a JSON value.
/// This method converts all the level's metadata, layer properties, and entity data
/// into a json object, ready for saving to a file or transmitting.
/// @return a `json` value representing the complete level data.
/// @see Level::Save() for writing the serialized JSON to a file.
json::value Serialize() const;
bool Load(const std::filesystem::path& path);
bool Save(const std::filesystem::path& path);
Layer* CreateLayer(const std::string& name);
Layer* GetLayer(int index);
const Layer* GetLayer(int index) const;
Layer* FindLayer(const std::string& name);
const Layer* FindLayer(const std::string& name) const;
bool RemoveLayer(const std::string& name);
bool RemoveLayer(int index);
bool RemoveLayer(Layer* layer);
bool RemoveAllLayers();
Entity* CreateEntity(const std::string& name);
Entity* GetEntity(const std::string& name);
const Entity* GetEntity(const std::string& name) const;
bool RemoveEntity(Entity* entity);
Tile GetTileData(int gid) const;
Quad GetTileQuad(int gid) const;
#pragma endregion
protected:
private:
};