Files
Editor2D/include/Format/Layer.hpp

130 lines
4.0 KiB
C++

#pragma once
#include <string>
#include <vector>
#include <json.hpp>
#include <Format/Layer.hpp>
#include <Re2DLevelAPI.hpp>
enum class DataFormat
{
SignedInt32,
};
/// @class Layer
/// @brief Represents a single plane of tiles within a level.
///
/// A layer stores the grid of tile IDs and properties specific to that layer,
/// such as its dimensions, visibility, opacity, and parallax scroll factors.
/// The actual tile data is stored in a separate binary file for efficiency.
/// Our current chosen format is sequential signed 32-bit integers, one for each tile ID.
///
/// TODO: Make this configurable
///
/// TODO: Support endianness management
class Layer
{
public:
#pragma region json properties
/// The file path to the binary file containing this layer's tile data.
/// @note This path is typically relative to the main level's JSON file.
std::string binary_path;
/// The unique name of the layer (e.g., "Ground", "Decor", "Collisions").
std::string name;
/// The width of the layer in tiles.
int rows;
/// The height of the layer in tiles.
int cols;
/// The width of the individual cells of this layer, measured in pixels.
int cell_width;
/// The height of the individual cells of this layer, measured in pixels.
int cell_height;
/// The horizontal parallax scrolling factor for this layer.
float parallax_x;
/// The vertical parallax scrolling factor for this layer.
float parallax_y;
bool visible = true;
int order;
float opacity;
#pragma endregion
#pragma region binary data storage
int** cells = nullptr;
#pragma endregion
/// The default constructor for Layer initializes member variables to default, zero values.
/// @note The tile-ID grid is initialized to a null-pointer, as well.
Layer();
/// This constructor creates an empty layer of a given size, and cell-size.
/// @note The tile-ID grid is initialized to a null-pointer.
Layer(int rows, int cols, int cell_width, int cell_height);
/// Constructs a Layer object by deserializing metadata from a JSON object.
/// The binary tile data will need to be loaded separately using `ReadFromFile()`
explicit Layer(const json::value& json);
/// Destructor for Layer cleans up all dynamically allocated memory for the tile grid.
~Layer();
/// Constructs a layer object from the JSON contained in the file at the given path.
explicit Layer(const std::filesystem::path& path);
/// Serializes the current layer object's metadata into a JSON object.
/// This does *NOT* include the actual tile grid data, which is stored in a separate binary file.
json::value Serialize() const;
/// Deserializes a JSON object into the current Layer object's metadata.
/// This also allocates the internal tile grid based on the deserialized width and height,
/// but does NOT load the actual tile grid data; use ReadBinaryData() for that.
void Deserialize(const json::value& json);
void InitGrid();
void DeleteGrid();
/// Resizes the layer's dimensions and reinitialize the tile data.
///
/// This method creates a new internal tile grid with the specified dimensions.
/// Existing tile data is copied to the new grid, preserving data within the
/// overlapping region. Any data outside the new bounds is truncated, and
/// new cells are initialized to -1 (empty tile).
///
void Resize(int newWidth, int newHeight);
void LoadFromDataBuffer(const int* buffer);
void WriteToDataBuffer(int* buffer) const;
/// Writes the current tile grid data to a specified raw binary file.
/// The file path should typically be stored in the layer's JSON metadata.
/// @param path
/// @return True if the binary data was written successfully, false otherwise.
/// @see Save().
bool WriteBinaryData(const std::filesystem::path& path) const;
bool Save();
bool Load();
/// Reads tile grid data from a specified raw binary file.
/// The file path should typically be stored in the layer's JSON metadata.
/// @param path
/// @return True if the binary data was loaded successfully, false otherwise.
/// @see Load().
bool ReadBinaryData(const std::filesystem::path& path);
protected:
bool grid_allocated = false;
};