Adds serialization base classes

Adds file writing to BinaryFileBuffer
master
Joey Pollack 3 years ago
parent 5ada9d5e1c
commit 0160e7c623

@ -8,10 +8,10 @@ Build System:
Core:
☐ Figure out how to represent Unique Entities and entity instances - and how this will work with UUIDs @critical
☐ Implement generic serializeation system
☐ JSON serializeable base class
JSON implementions should be stubbed out in non-editor builds
☐ Binary serializeable base class
✔ Implement generic serialization system @done(22-06-29 18:44)
✔ JSON serializable base class @done(22-06-29 17:41)
JSON implementions should be stubbed out in non-editor builds @done(22-06-29 17:41)
✔ Binary serializable base class @done(22-06-29 18:44)
✔ Wrap NFD in an API in the platform module @low @done(22-05-31 15:44)
Wrapper added to utils - not platform
✔ Add custom (64 bit?) UUID generator (based on Chreno's UUIDs) @done(22-06-27 13:34)
@ -76,6 +76,9 @@ Core:
Enitity:
✔ Single UUID @done(22-06-01 14:01)
✔ Functionality for adding/working with components (through EnTT) @done(22-06-01 14:01)
☐ Serialize
☐ JSON
☐ Binary
Components:
✔ Tag @done(22-06-23 15:49)
@ -90,6 +93,9 @@ Core:
World (Lunariums version of a "Scene"):
☐ Implement the world without Regions first
☐ Serialize world
☐ JSON
☐ Binary
Implement Regions:
☐ Track/manage active regions
@ -145,7 +151,7 @@ Utils:
Assets:
✔ Internal Asset Manager @high @done (1/25/2022, 3:58:20 PM)
☐ Document Index.Dat and the AssetIndex class
Move the GenerateFont method from internal_font.h into data_manager.h
Move the GenerateFont method from internal_font.h into data_manager.h @done(22-06-29 17:42)
Types:
- Classes that represent each resource Types
@ -158,7 +164,7 @@ Assets:
Loaders:
- Need class (or classes?) to load resources from the packed format that the pipeline generates
Come up with binary file formats for each type:
☐ .xml (This will probably be multiple different formats depending on what the .xml file is describing)
☐ .json (This will probably be multiple different formats depending on what the .json file is describing)
☐ Image
☐ Script
☐ Audio

@ -42,6 +42,7 @@ Editor:
World View:
World Hierarchy (Tree View):
☐ Handle showing Enities with children @high
Asset Viewer:
✔ Get references to the EditorAsset objects instead of the raw file locations @done(22-06-01 18:48)

@ -0,0 +1,26 @@
/******************************************************************************
* File - binary_serializable.h
* Author - Joey Pollack
* Date - 2022/06/29 (y/m/d)
* Mod Date - 2022/06/29 (y/m/d)
* Description - base class for any object that can be serialized to binary
******************************************************************************/
#ifndef LUNARIUM_BINARY_SERIALIZABLE_H_
#define LUNARIUM_BINARY_SERIALIZABLE_H_
#include <utils/op_res.h>
namespace lunarium
{
class BinaryFileBuffer;
class BinarySerializable
{
public:
[[nodiscard]] OpRes Serialize(BinaryFileBuffer* pBuffer);
[[nodiscard]] OpRes Deserialize(BinaryFileBuffer* pBuffer);
};
}
#endif // LUNARIUM_BINARY_SERIALIZABLE_H_

@ -0,0 +1,28 @@
/******************************************************************************
* File - json_serializable.h
* Author - Joey Pollack
* Date - 2022/06/29 (y/m/d)
* Mod Date - 2022/06/29 (y/m/d)
* Description - Base class for any json serializable object
******************************************************************************/
#ifndef LUNARIUM_JSON_SERIALIZABLE_H_
#define LUNARIUM_JSON_SERIALIZABLE_H_
#include <utils/op_res.h>
#include <nlohmann/json.hpp>
namespace lunarium
{
class JSONSerializable
{
public:
[[nodiscard]] virtual OpRes Serialize(nlohmann::json& node) = 0;
[[nodiscard]] virtual OpRes Deserialize(nlohmann::json& node) = 0;
[[nodiscard]] virtual nlohmann::json AsJSON() = 0;
[[nodiscord]] virtual bool IsValidNode(nlohmann::json& node) = 0;
};
}
#endif // LUNARIUM_JSON_SERIALIZABLE_H_

@ -7,6 +7,7 @@
******************************************************************************/
#include "world.h"
#include <LunariumConfig.h>
#include <world/world.h>
@ -33,18 +34,24 @@ namespace lunarium { namespace editor
return OpRes::OK();
}
OpRes World::LoadFromJSON(nlohmann::json& node)
OpRes World::Deserialize(nlohmann::json& node)
{
// TODO: Implement World::LoadFromJSON
// Create the lunarium::World Object here
// Replace the one created in the constructor
#if !BUILD_NO_EDITOR // Only does this when this is an editor build
#endif
return OpRes::OK();
}
OpRes World::SaveToJSON(nlohmann::json& node)
OpRes World::Serialize(nlohmann::json& node)
{
// TODO: Implement World::SaveToJSON
// Store the entities UUID - the Entity class will serialize itself
#if !BUILD_NO_EDITOR // Only does this when this is an editor build
#endif
return OpRes::OK();
}
@ -54,4 +61,15 @@ namespace lunarium { namespace editor
return true;
}
nlohmann::json World::AsJSON()
{
#if !BUILD_NO_EDITOR // Only does this when this is an editor build
nlohmann::json node;
return node;
#endif
return nlohmann::json();
}
}}

@ -133,7 +133,7 @@ namespace lunarium { namespace editor
pAsset->mLocation = std::filesystem::path(asset["Location"].get<std::string>());
// Load type specific data
if (Failed(pAsset->LoadFromJSON(asset).LogIfFailed(Editor::LogCat).LogIfFailed(Editor::LogCat)))
if (Failed(pAsset->Deserialize(asset).LogIfFailed(Editor::LogCat).LogIfFailed(Editor::LogCat)))
{
return OpRes::Fail("Could not load asset type specific data for asset with ID: %llu, File: %s",
pAsset->GetID(), pAsset->GetFileLocation().filename().string().c_str());
@ -184,7 +184,7 @@ namespace lunarium { namespace editor
// TODO: This needs to be a relative path! (Relative to the project root)
asset["Location"] = pAsset->GetFileLocation().string().c_str();
if (Failed(pAsset->SaveToJSON(asset).LogIfFailed(Editor::LogCat).LogIfFailed(Editor::LogCat)))
if (Failed(pAsset->Serialize(asset).LogIfFailed(Editor::LogCat).LogIfFailed(Editor::LogCat)))
{
return OpRes::Fail("Could not save asset meta data for file: %s", pAsset->GetFileLocation().string().c_str());
}

@ -11,14 +11,15 @@
#include "definitions.h"
#include "content_manager.h"
#include <utils/op_res.h>
#include <assets/serializing/json_serializable.h>
#include <filesystem>
#include <string>
#include <utils/op_res.h>
namespace lunarium { namespace editor
{
class EditorAsset
class EditorAsset : public JSONSerializable
{
public:
EditorAsset(AssetType type);
@ -29,8 +30,10 @@ namespace lunarium { namespace editor
bool GetIsTrashed() const;
[[nodiscard]] virtual OpRes LoadRawFile() = 0;
[[nodiscard]] virtual OpRes LoadFromJSON(nlohmann::json& node) = 0;
[[nodiscard]] virtual OpRes SaveToJSON(nlohmann::json& node) = 0;
// [[nodiscard]] virtual OpRes LoadFromJSON(nlohmann::json& node) = 0;
//[[nodiscard]] virtual OpRes SaveToJSON(nlohmann::json& node) = 0;
private:
friend class ContentManager;
@ -43,7 +46,7 @@ namespace lunarium { namespace editor
protected:
std::filesystem::path mAssetDir;
[[nodiscord]] virtual bool IsValidNode(nlohmann::json& node) = 0;
// [[nodiscord]] virtual bool IsValidNode(nlohmann::json& node) = 0;
private: // DISABLE COPY
EditorAsset(const EditorAsset&) = delete;

@ -37,8 +37,10 @@ namespace lunarium { namespace editor
return OpRes::OK();
}
OpRes TileSet::LoadFromJSON(nlohmann::json& node)
{
OpRes TileSet::Deserialize(nlohmann::json& node)
{
#if !BUILD_NO_EDITOR // Only does this when this is an editor build
// Load Image
mSetImage = FileLoaders::LoadImage(mAssetDir / GetFileLocation());
if (!mSetImage)
@ -57,20 +59,40 @@ namespace lunarium { namespace editor
mNumTiles.Width = node["NumTilesCol"].get<int>();
mNumTiles.Height = node["NumTilesRow"].get<int>();
#endif
return OpRes::OK();
}
OpRes TileSet::SaveToJSON(nlohmann::json& node)
OpRes TileSet::Serialize(nlohmann::json& node)
{
#if !BUILD_NO_EDITOR // Only does this when this is an editor build
node["TileSetID"] = mTileSetID;
node["TileSizeWidth"] = mTileSize.Width;
node["TileSizeHeight"] = mTileSize.Height;
node["NumTilesCol"] = mNumTiles.Width;
node["NumTilesRow"] = mNumTiles.Height;
#endif
return OpRes::OK();
}
nlohmann::json TileSet::AsJSON()
{
nlohmann::json node;
#if !BUILD_NO_EDITOR // Only does this when this is an editor build
node["TileSetID"] = mTileSetID;
node["TileSizeWidth"] = mTileSize.Width;
node["TileSizeHeight"] = mTileSize.Height;
node["NumTilesCol"] = mNumTiles.Width;
node["NumTilesRow"] = mNumTiles.Height;
#endif
return node;
}
bool TileSet::IsValidNode(nlohmann::json& node)
{
if (node["TileSetID"].is_null()) { return false; }

@ -24,8 +24,10 @@ namespace lunarium { namespace editor
// Load the raw asset file from the internal location
OpRes LoadRawFile();
OpRes LoadFromJSON(nlohmann::json& node);
OpRes SaveToJSON(nlohmann::json& node);
OpRes Serialize(nlohmann::json& node);
OpRes Deserialize(nlohmann::json& node);
bool IsValidNode(nlohmann::json& node);
nlohmann::json AsJSON();
void SetTileSetID(int id);
int GetTileSetID() const;
@ -47,7 +49,6 @@ namespace lunarium { namespace editor
private:
[[nodiscord]] virtual bool IsValidNode(nlohmann::json& node);
};
}}

@ -28,8 +28,10 @@ namespace lunarium { namespace editor
~World();
[[nodiscard]] virtual OpRes LoadRawFile();
[[nodiscard]] virtual OpRes LoadFromJSON(nlohmann::json& node);
[[nodiscard]] virtual OpRes SaveToJSON(nlohmann::json& node);
[[nodiscard]] virtual OpRes Serialize(nlohmann::json& node);
[[nodiscard]] virtual OpRes Deserialize(nlohmann::json& node);
[[nodiscord]] virtual bool IsValidNode(nlohmann::json& node);
[[nodiscard]] virtual nlohmann::json AsJSON();
lunarium::World* GetWorld();
@ -38,7 +40,6 @@ namespace lunarium { namespace editor
private:
[[nodiscord]] virtual bool IsValidNode(nlohmann::json& node);
private: // DISABLED

@ -15,7 +15,7 @@
namespace lunarium
{
BinaryFileBuffer::BinaryFileBuffer()
: mbIsLoaded(false), mpData(nullptr), mFileSize(0), mReadPos(0), mFileName("")
: mbIsLoaded(false), mpBuffer(nullptr), mFileSize(0), mBufferPos(0), mFileName("")
{
}
@ -24,6 +24,43 @@ namespace lunarium
Unload();
}
bool BinaryFileBuffer::NewFile(int reserve_size)
{
if (mbIsLoaded)
{
Unload();
}
mpBuffer = new unsigned char[reserve_size];
mFileSize = reserve_size;
mbIsLoaded = true;
return true;
}
bool BinaryFileBuffer::WriteFile(const char* filename, bool include_extra_bytes)
{
std::ofstream ofs(filename, std::ios_base::binary | std::ios_base::trunc);
if (!ofs.is_open())
{
return false;
}
// Only writing up to the buffer pos because the rest will be garbage data
int write_size = mBufferPos;
if (include_extra_bytes)
{
// Unless the user says otherwise
write_size = mFileSize;
}
ofs.write((const char*)mpBuffer, write_size);
ofs.close();
ofs.clear();
mFileName = filename;
return true;
}
bool BinaryFileBuffer::LoadFile(const char * filename)
{
if (mbIsLoaded)
@ -43,9 +80,9 @@ namespace lunarium
ifs.seekg(0, std::ios_base::beg);
mFileSize = end - start;
mpData = new unsigned char[mFileSize];
mpBuffer = new unsigned char[mFileSize];
ifs.read((char*)mpData, mFileSize);
ifs.read((char*)mpBuffer, mFileSize);
ifs.close();
ifs.clear();
@ -60,12 +97,12 @@ namespace lunarium
if (!mbIsLoaded)
return;
delete[] mpData;
mpData = nullptr;
delete[] mpBuffer;
mpBuffer = nullptr;
mFileSize = 0;
mFileName = "";
mReadPos = 0;
mBufferPos = 0;
mbIsLoaded = false;
}
@ -86,29 +123,130 @@ namespace lunarium
const unsigned char* BinaryFileBuffer::GetBuffer() const
{
return mpData;
return mpBuffer;
}
/////////////////////////////////////////////////////////////////////
// READ METHODS
/////////////////////////////////////////////////////////////////////
bool BinaryFileBuffer::Read(char * buffer, int numBytes)
{
if (!mbIsLoaded || mReadPos >= mFileSize)
if (!mbIsLoaded || mBufferPos >= mFileSize)
return false;
memcpy(buffer, &mpBuffer[mBufferPos], numBytes);
mBufferPos += numBytes;
return true;
}
int BinaryFileBuffer::ReadInt()
{
int value = 0;
Read((char*)&value, sizeof(int));
return value;
}
short BinaryFileBuffer::ReadShort()
{
short value = 0;
Read((char*)&value, sizeof(short));
return value;
}
char BinaryFileBuffer::ReadByte()
{
char value = 0;
Read((char*)&value, sizeof(char));
return value;
}
unsigned int BinaryFileBuffer::ReadUInt()
{
unsigned int value = 0;
Read((char*)&value, sizeof(unsigned int));
return value;
}
unsigned short BinaryFileBuffer::ReadUShort()
{
unsigned short value = 0;
Read((char*)&value, sizeof(unsigned short));
return value;
}
unsigned char BinaryFileBuffer::ReadUByte()
{
unsigned char value = 0;
Read((char*)&value, sizeof(unsigned char));
return value;
}
/////////////////////////////////////////////////////////////////////
// WRITE METHODS
/////////////////////////////////////////////////////////////////////
bool BinaryFileBuffer::Write(char* buffer, int num_bytes)
{
if (!mbIsLoaded)
{
return false;
}
memcpy(buffer, &mpData[mReadPos], numBytes);
mReadPos += numBytes;
if (mBufferPos + num_bytes >= mFileSize)
{
// Reserve more space
int new_size = mFileSize * 2 + num_bytes; // adding num_bytes to make sure the write will fit
unsigned char* new_buffer = new unsigned char[new_size];
memcpy(new_buffer, mpBuffer, mFileSize);
delete[] mpBuffer;
mpBuffer = new_buffer;
mFileSize = new_size;
}
memcpy(&mpBuffer[mBufferPos], buffer, num_bytes);
mBufferPos += num_bytes;
return true;
}
void BinaryFileBuffer::WriteInt(int value)
{
Write((char*)&value, sizeof(int));
}
void BinaryFileBuffer::WriteShort(short value)
{
Write((char*)&value, sizeof(short));
}
void BinaryFileBuffer::WriteByte(char value)
{
Write((char*)&value, sizeof(char));
}
void BinaryFileBuffer::WriteUInt(unsigned int value)
{
Write((char*)&value, sizeof(unsigned int));
}
void BinaryFileBuffer::WriteUShort(unsigned short value)
{
Write((char*)&value, sizeof(unsigned short));
}
void BinaryFileBuffer::WriteUByte(unsigned char value)
{
Write((char*)&value, sizeof(unsigned char));
}
void BinaryFileBuffer::SeekTo(int pos)
{
mReadPos = pos;
mBufferPos = pos;
if (mReadPos < 0)
mReadPos = 0;
if (mBufferPos < 0)
mBufferPos = 0;
if (mReadPos >= mFileSize)
mReadPos = mFileSize - 1;
if (mBufferPos >= mFileSize)
mBufferPos = mFileSize - 1;
}
}

@ -21,6 +21,10 @@ namespace lunarium
BinaryFileBuffer();
~BinaryFileBuffer();
/// Create a new file buffer of the given starting size
/// This will clear out any existing buffer
bool NewFile(int reserve_size);
bool WriteFile(const char* filename, bool include_extra_bytes = false);
bool LoadFile(const char* filename);
void Unload();
bool IsLoaded() const;
@ -29,6 +33,21 @@ namespace lunarium
const unsigned char* GetBuffer() const;
bool Read(char* buffer, int numBytes);
int ReadInt();
short ReadShort();
char ReadByte();
unsigned int ReadUInt();
unsigned short ReadUShort();
unsigned char ReadUByte();
bool Write(char* buffer, int num_bytes);
void WriteInt(int value);
void WriteShort(short value);
void WriteByte(char value);
void WriteUInt(unsigned int value);
void WriteUShort(unsigned short value);
void WriteUByte(unsigned char value);
void SeekTo(int pos);
private:
@ -36,8 +55,8 @@ namespace lunarium
bool mbIsLoaded;
std::string mFileName;
int mFileSize;
unsigned char* mpData;
int mReadPos;
unsigned char* mpBuffer;
int mBufferPos;
};
}

@ -13,13 +13,10 @@
#include <utils/logger.h>
#include <entt/entt.hpp>
#include <world/world.h>
#include <assets/serializing/json_serializable.h>
namespace nlohmann
{
class json;
}
namespace lunarium
namespace lunarium // TODO: : public JSONSerializable
{
class Entity
{

Loading…
Cancel
Save