binary serialization of a universe

This commit is contained in:
Mikulas Florek 2014-11-26 22:40:37 +01:00
parent 867a0a312f
commit bb45bab48a
23 changed files with 255 additions and 399 deletions

View file

@ -90,48 +90,42 @@ namespace Lumix
}
virtual void serialize(JsonSerializer& serializer) override
virtual void serialize(Blob& serializer) override
{
serializer.serialize("count", m_animables.size());
serializer.beginArray("animables");
serializer.write((int32_t)m_animables.size());
for (int i = 0; i < m_animables.size(); ++i)
{
serializer.serializeArrayItem(m_animables[i].m_manual);
serializer.serializeArrayItem(m_animables[i].m_renderable.entity.index);
serializer.serializeArrayItem(m_animables[i].m_time);
serializer.serializeArrayItem(m_animables[i].m_is_free);
serializer.serializeArrayItem(m_animables[i].m_animation ? m_animables[i].m_animation->getPath().c_str() : "");
serializer.write(m_animables[i].m_manual);
serializer.write(m_animables[i].m_renderable.entity.index);
serializer.write(m_animables[i].m_time);
serializer.write(m_animables[i].m_is_free);
serializer.write(m_animables[i].m_animation ? m_animables[i].m_animation->getPath().c_str() : "");
}
serializer.endArray();
}
virtual void deserialize(JsonSerializer& serializer) override
virtual void deserialize(Blob& serializer) override
{
int count;
serializer.deserialize("count", count, 0);
serializer.deserializeArrayBegin("animables");
int32_t count;
serializer.read(count);
m_animables.resize(count);
for (int i = 0; i < count; ++i)
{
serializer.deserializeArrayItem(m_animables[i].m_manual, false);
int entity_index;
serializer.deserializeArrayItem(entity_index, 0);
Entity e(&m_universe, entity_index);
m_animables[i].m_entity = e;
Component renderable = m_render_scene->getRenderable(e);
serializer.read(m_animables[i].m_manual);
serializer.read(m_animables[i].m_entity.index);
m_animables[i].m_entity.universe = &m_universe;
Component renderable = m_render_scene->getRenderable(m_animables[i].m_entity);
if (renderable.isValid())
{
m_animables[i].m_renderable = renderable;
}
serializer.deserializeArrayItem(m_animables[i].m_time, 0);
serializer.deserializeArrayItem(m_animables[i].m_is_free, true);
serializer.read(m_animables[i].m_time);
serializer.read(m_animables[i].m_is_free);
char path[LUMIX_MAX_PATH];
serializer.deserializeArrayItem(path, sizeof(path), "");
serializer.readString(path, sizeof(path));
m_animables[i].m_animation = path[0] == '\0' ? NULL : loadAnimation(path);
m_universe.addComponent(e, ANIMABLE_HASH, this, i);
m_universe.addComponent(m_animables[i].m_entity, ANIMABLE_HASH, this, i);
}
serializer.deserializeArrayEnd();
}

View file

@ -64,12 +64,25 @@ namespace Lumix
((unsigned char*)data)[i] = 0;
return false;
}
memcpy(data, ((char*)m_data) + m_pos, size);
if (size)
{
memcpy(data, ((char*)m_data) + m_pos, size);
}
m_pos += size;
return true;
}
void Blob::write(const char* string)
void Blob::readString(char* out, int max_size)
{
int32_t size;
read(size);
ASSERT(size <= max_size);
read(out, size < max_size ? size : max_size);
}
void Blob::writeString(const char* string)
{
int32_t size = (int32_t)strlen(string) + 1;

View file

@ -15,9 +15,10 @@ namespace Lumix
Blob(const Blob& rhs, IAllocator& allocator);
void operator =(const Blob& rhs);
void reserve(int size) { m_buffer.reserve(size); }
void create(const void* data, int size) { m_data = data; m_size = size; m_pos = 0; }
virtual void write(const void* data, int32_t size);
virtual bool read(void* data, int32_t size);
void write(const void* data, int32_t size);
bool read(void* data, int32_t size);
const uint8_t* getBuffer() const { return &m_buffer[0]; }
int getBufferSize() const { return m_size; }
void flush() { m_size = 0; }
@ -25,7 +26,8 @@ namespace Lumix
template <class T>
void write(T value) { write(&value, sizeof(T)); }
void write(const char* string);
void writeString(const char* string);
void readString(char* out, int max_size);
template <class T>
void read(T& value) { read(&value, sizeof(T)); }

View file

@ -235,65 +235,56 @@ namespace Lumix
}
virtual void serialize(JsonSerializer& serializer) override
virtual void serialize(Blob& serializer) override
{
serializer.serialize("templates_count", (int32_t)m_template_names.size());
serializer.beginArray("template_names");
serializer.write((int32_t)m_template_names.size());
for (int i = 0, c = m_template_names.size(); i < c; ++i)
{
serializer.serializeArrayItem(m_template_names[i].c_str());
serializer.write(m_template_names[i].c_str());
}
serializer.endArray();
serializer.serialize("instance_count", (int32_t)m_instances.size());
serializer.beginArray("instances");
serializer.write((int32_t)m_instances.size());
for (int i = 0; i < m_instances.size(); ++i)
{
serializer.serializeArrayItem(m_instances.getKey(i));
serializer.write(m_instances.getKey(i));
Array<Entity>& entities = m_instances.at(i);
serializer.serializeArrayItem((int32_t)entities.size());
serializer.write((int32_t)entities.size());
for (int j = 0, c = entities.size(); j < c; ++j)
{
serializer.serializeArrayItem(entities[j].index);
serializer.write(entities[j].index);
}
}
serializer.endArray();
}
virtual void deserialize(JsonSerializer& serializer) override
virtual void deserialize(Blob& serializer) override
{
m_template_names.clear();
m_instances.clear();
int32_t count;
serializer.deserialize("templates_count", count, 0);
serializer.deserializeArrayBegin("template_names");
serializer.read(count);
for (int i = 0; i < count; ++i)
{
const int MAX_NAME_LENGTH = 50;
char name[MAX_NAME_LENGTH];
serializer.deserializeArrayItem(name, MAX_NAME_LENGTH, "");
serializer.readString(name, MAX_NAME_LENGTH);
m_template_names.push(string(name, m_editor.getAllocator()));
}
serializer.deserializeArrayEnd();
serializer.deserialize("instance_count", count, 0);
serializer.deserializeArrayBegin("instances");
serializer.read(count);
for (int i = 0; i < count; ++i)
{
uint32_t hash;
serializer.deserializeArrayItem(hash, 0);
serializer.read(hash);
int32_t instances_per_template;
serializer.deserializeArrayItem(instances_per_template, 0);
serializer.read(instances_per_template);
m_instances.insert(hash, Array<Entity>(m_editor.getAllocator()));
Array<Entity>& entities = m_instances.get(hash);
for (int j = 0; j < instances_per_template; ++j)
{
int32_t entity_index;
serializer.deserializeArrayItem(entity_index, 0);
serializer.read(entity_index);
entities.push(Entity(m_universe, entity_index));
}
}
serializer.deserializeArrayEnd();
m_updated.invoke();
}

View file

@ -10,7 +10,7 @@
namespace Lumix
{
class JsonSerializer;
class Blob;
class WorldEditor;
class LUMIX_ENGINE_API EntityTemplateSystem
@ -20,8 +20,8 @@ namespace Lumix
static void destroy(EntityTemplateSystem* system);
virtual ~EntityTemplateSystem() {}
virtual void serialize(JsonSerializer& serializer) = 0;
virtual void deserialize(JsonSerializer& serializer) = 0;
virtual void serialize(Blob& serializer) = 0;
virtual void deserialize(Blob& serializer) = 0;
virtual void createTemplateFromEntity(const char* name, const Entity& entity) = 0;
virtual uint32_t getTemplate(const Entity& entity) = 0;
virtual const Array<Entity>& getInstances(uint32_t template_name_hash) = 0;

View file

@ -1182,18 +1182,20 @@ struct WorldEditorImpl : public WorldEditor
g_log_info.log("editor") << "saving universe " << path.c_str() << "...";
FS::FileSystem& fs = m_engine->getFileSystem();
FS::IFile* file = fs.open(fs.getDefaultDevice(), path, FS::Mode::OPEN_OR_CREATE | FS::Mode::WRITE);
save(*file, path.c_str());
save(*file);
fs.close(file);
m_universe_path = path;
}
void save(FS::IFile& file, const char* path)
void save(FS::IFile& file)
{
JsonSerializer serializer(m_allocator, file, JsonSerializer::WRITE, path);
m_engine->serialize(serializer);
m_template_system->serialize(serializer);
Blob blob(m_allocator);
blob.reserve(1 << 20);
m_engine->serialize(blob);
m_template_system->serialize(blob);
g_log_info.log("editor") << "universe saved";
file.write(blob.getBuffer(), blob.getBufferSize());
}
@ -1386,7 +1388,7 @@ struct WorldEditorImpl : public WorldEditor
else
{
m_game_mode_file = m_engine->getFileSystem().open("memory", "", FS::Mode::WRITE);
save(*m_game_mode_file, "GameMode");
save(*m_game_mode_file);
m_is_game_mode = true;
}
}
@ -1396,7 +1398,7 @@ struct WorldEditorImpl : public WorldEditor
{
m_is_game_mode = false;
m_game_mode_file->seek(FS::SeekMode::BEGIN, 0);
load(*m_game_mode_file, "GameMode");
load(*m_game_mode_file);
m_engine->getFileSystem().close(m_game_mode_file);
m_game_mode_file = NULL;
}
@ -1541,7 +1543,7 @@ struct WorldEditorImpl : public WorldEditor
ASSERT(success);
if (success)
{
resetAndLoad(*file, "unknown map"); /// TODO file path
resetAndLoad(*file);
}
fs.close(file);
@ -1568,14 +1570,16 @@ struct WorldEditorImpl : public WorldEditor
g_log_info.log("editor") << "universe created";
}
void load(FS::IFile& file, const char* path)
void load(FS::IFile& file)
{
ASSERT(file.getBuffer());
m_components.clear();
m_components.reserve(5000);
g_log_info.log("editor") << "parsing universe...";
JsonSerializer serializer(m_allocator, file, JsonSerializer::READ, path);
m_engine->deserialize(serializer);
m_template_system->deserialize(serializer);
Blob blob(m_allocator);
blob.create(file.getBuffer(), file.size());
m_engine->deserialize(blob);
m_template_system->deserialize(blob);
m_camera = static_cast<RenderScene*>(m_engine->getScene(crc32("renderer")))->getCameraInSlot("editor").entity;
g_log_info.log("editor") << "universe parsed";
@ -1642,11 +1646,11 @@ struct WorldEditorImpl : public WorldEditor
}
}
void resetAndLoad(FS::IFile& file, const char* path)
void resetAndLoad(FS::IFile& file)
{
destroyUniverse();
createUniverse(false);
load(file, path);
load(file);
}

View file

@ -1,7 +1,7 @@
#include "core/lumix.h"
#include "engine/engine.h"
#include "core/blob.h"
#include "core/crc32.h"
#include "core/input_system.h"
#include "core/log.h"
@ -280,7 +280,7 @@ namespace Lumix
}
virtual void serialize(JsonSerializer& serializer) override
virtual void serialize(Blob& serializer) override
{
m_universe->serialize(serializer);
m_hierarchy->serialize(serializer);
@ -293,7 +293,7 @@ namespace Lumix
}
virtual void deserialize(JsonSerializer& serializer) override
virtual void deserialize(Blob& serializer) override
{
m_universe->deserialize(serializer);
m_hierarchy->deserialize(serializer);

View file

@ -18,6 +18,7 @@ namespace Lumix
class Manager;
}
class Blob;
class EditorServer;
class InputSystem;
class IPlugin;
@ -58,8 +59,8 @@ namespace Lumix
virtual const char* getBasePath() const = 0;
virtual void update(bool is_game_running) = 0;
virtual void serialize(JsonSerializer& serializer) = 0;
virtual void deserialize(JsonSerializer& serializer) = 0;
virtual void serialize(Blob& serializer) = 0;
virtual void deserialize(Blob& serializer) = 0;
virtual float getFPS() const = 0;
virtual float getLastTimeDelta() = 0;

View file

@ -7,9 +7,9 @@
namespace Lumix
{
class Blob;
class Engine;
class IPlugin;
class JsonSerializer;
class Universe;
@ -20,8 +20,8 @@ namespace Lumix
virtual Component createComponent(uint32_t, const Entity&) = 0;
virtual void destroyComponent(const Component& component) = 0;
virtual void serialize(JsonSerializer& serializer) = 0;
virtual void deserialize(JsonSerializer& serializer) = 0;
virtual void serialize(Blob& serializer) = 0;
virtual void deserialize(Blob& serializer) = 0;
virtual IPlugin& getPlugin() const = 0;
virtual void update(float time_delta) = 0;
};
@ -34,8 +34,8 @@ namespace Lumix
virtual bool create() = 0;
virtual void destroy() = 0;
virtual void serialize(JsonSerializer&) {}
virtual void deserialize(JsonSerializer&) {}
virtual void serialize(Blob&) {}
virtual void deserialize(Blob&) {}
virtual void update(float) {}
virtual const char* getName() const = 0;
virtual void sendMessage(const char*) {};

View file

@ -31,7 +31,7 @@ namespace Lumix
}
void PluginManager::serialize(JsonSerializer& serializer)
void PluginManager::serialize(Blob& serializer)
{
PluginManagerImpl::PluginList& plugins = m_impl->m_plugins;
for(int i = 0, c = plugins.size(); i < c; ++i)
@ -41,7 +41,7 @@ namespace Lumix
}
void PluginManager::deserialize(JsonSerializer& serializer)
void PluginManager::deserialize(Blob& serializer)
{
PluginManagerImpl::PluginList& plugins = m_impl->m_plugins;
for(int i = 0, c = plugins.size(); i < c; ++i)

View file

@ -8,6 +8,7 @@
namespace Lumix
{
class Blob;
class Engine;
class IPlugin;
class JsonSerializer;
@ -23,8 +24,8 @@ namespace Lumix
IPlugin* load(const char* path);
void addPlugin(IPlugin* plugin);
void update(float dt);
void serialize(JsonSerializer& serializer);
void deserialize(JsonSerializer& serializer);
void serialize(Blob& serializer);
void deserialize(Blob& serializer);
IPlugin* getPlugin(const char* name);
const Array<IPlugin*>& getPlugins() const;

View file

@ -1,6 +1,7 @@
#include "render_scene.h"
#include "core/array.h"
#include "core/blob.h"
#include "core/crc32.h"
#include "core/FS/file_system.h"
#include "core/FS/ifile.h"
@ -252,101 +253,51 @@ namespace Lumix
}
}
void serializeCameras(JsonSerializer& serializer)
void serializeCameras(Blob& serializer)
{
serializer.serialize("camera_count", m_cameras.size());
serializer.beginArray("cameras");
for (int i = 0; i < m_cameras.size(); ++i)
{
serializer.serializeArrayItem(m_cameras[i].m_is_free);
serializer.serializeArrayItem(m_cameras[i].m_far);
serializer.serializeArrayItem(m_cameras[i].m_near);
serializer.serializeArrayItem(m_cameras[i].m_fov);
serializer.serializeArrayItem(m_cameras[i].m_is_active);
serializer.serializeArrayItem(m_cameras[i].m_width);
serializer.serializeArrayItem(m_cameras[i].m_height);
serializer.serializeArrayItem(m_cameras[i].m_entity.index);
serializer.serializeArrayItem(m_cameras[i].m_slot);
}
serializer.endArray();
serializer.write((int32_t)m_cameras.size());
serializer.write(&m_cameras[0], sizeof(m_cameras[0]) * m_cameras.size());
}
void serializeLights(JsonSerializer& serializer)
void serializeLights(Blob& serializer)
{
serializer.serialize("light_count", m_lights.size());
serializer.beginArray("lights");
for (int i = 0; i < m_lights.size(); ++i)
{
serializer.serializeArrayItem(m_lights[i].m_entity.index);
serializer.serializeArrayItem((int32_t)m_lights[i].m_type);
serializer.serializeArrayItem(m_lights[i].m_is_free);
serializer.serializeArrayItem(m_lights[i].m_diffuse_color.x);
serializer.serializeArrayItem(m_lights[i].m_diffuse_color.y);
serializer.serializeArrayItem(m_lights[i].m_diffuse_color.z);
serializer.serializeArrayItem(m_lights[i].m_diffuse_color.w);
serializer.serializeArrayItem(m_lights[i].m_diffuse_intensity);
serializer.serializeArrayItem(m_lights[i].m_ambient_color.x);
serializer.serializeArrayItem(m_lights[i].m_ambient_color.y);
serializer.serializeArrayItem(m_lights[i].m_ambient_color.z);
serializer.serializeArrayItem(m_lights[i].m_ambient_color.w);
serializer.serializeArrayItem(m_lights[i].m_ambient_intensity);
serializer.serializeArrayItem(m_lights[i].m_fog_color.x);
serializer.serializeArrayItem(m_lights[i].m_fog_color.y);
serializer.serializeArrayItem(m_lights[i].m_fog_color.z);
serializer.serializeArrayItem(m_lights[i].m_fog_color.w);
serializer.serializeArrayItem(m_lights[i].m_fog_density);
}
serializer.endArray();
serializer.write((int32_t)m_lights.size());
serializer.write(&m_lights[0], sizeof(m_lights[0]) * m_lights.size());
}
void serializeRenderables(JsonSerializer& serializer)
void serializeRenderables(Blob& serializer)
{
serializer.serialize("renderable_count", m_renderables.size());
serializer.beginArray("renderables");
serializer.write((int32_t)m_renderables.size());
for (int i = 0; i < m_renderables.size(); ++i)
{
serializer.serializeArrayItem(m_renderables[i]->m_is_always_visible);
serializer.serializeArrayItem(m_renderables[i]->m_component_index);
serializer.serializeArrayItem(m_renderables[i]->m_entity.index);
serializer.serializeArrayItem(m_culling_system->getLayerMask(i));
if (m_renderables[i]->m_model)
{
serializer.serializeArrayItem(m_renderables[i]->m_model->getPath().c_str());
}
else
{
serializer.serializeArrayItem("");
}
serializer.serializeArrayItem(m_renderables[i]->m_scale);
const Matrix& mtx = m_renderables[i]->m_matrix;
for (int j = 0; j < 16; ++j)
{
serializer.serializeArrayItem((&mtx.m11)[j]);
}
serializer.write(m_renderables[i]->m_is_always_visible);
serializer.write(m_renderables[i]->m_component_index);
serializer.write(m_renderables[i]->m_entity.index);
serializer.write(m_renderables[i]->m_scale);
serializer.write(m_culling_system->getLayerMask(i));
serializer.write(&m_renderables[i]->m_matrix.m11, sizeof(Matrix));
serializer.write(m_renderables[i]->m_model ? m_renderables[i]->m_model->getPath().c_str() : "");
}
serializer.endArray();
}
void serializeTerrains(JsonSerializer& serializer)
void serializeTerrains(Blob& serializer)
{
serializer.serialize("terrain_count", m_terrains.size());
serializer.beginArray("terrains");
serializer.write((int32_t)m_terrains.size());
for (int i = 0; i < m_terrains.size(); ++i)
{
if(m_terrains[i])
{
serializer.serializeArrayItem(true);
serializer.write(true);
m_terrains[i]->serialize(serializer);
}
else
{
serializer.serializeArrayItem(false);
serializer.write(false);
}
}
serializer.endArray();
}
virtual void serialize(JsonSerializer& serializer) override
virtual void serialize(Blob& serializer) override
{
serializeCameras(serializer);
serializeRenderables(serializer);
@ -354,38 +305,26 @@ namespace Lumix
serializeTerrains(serializer);
}
void deserializeCameras(JsonSerializer& serializer)
void deserializeCameras(Blob& serializer)
{
int32_t size;
serializer.deserialize("camera_count", size, 0);
serializer.deserializeArrayBegin("cameras");
serializer.read(size);
m_cameras.resize(size);
serializer.read(&m_cameras[0], sizeof(m_cameras[0]) * size);
for (int i = 0; i < size; ++i)
{
serializer.deserializeArrayItem(m_cameras[i].m_is_free, true);
serializer.deserializeArrayItem(m_cameras[i].m_far, 0.01f);
serializer.deserializeArrayItem(m_cameras[i].m_near, 1000.0f);
serializer.deserializeArrayItem(m_cameras[i].m_fov, 60.0f);
serializer.deserializeArrayItem(m_cameras[i].m_is_active, false);
serializer.deserializeArrayItem(m_cameras[i].m_width, 800);
serializer.deserializeArrayItem(m_cameras[i].m_height, 600);
m_cameras[i].m_aspect = m_cameras[i].m_width / m_cameras[i].m_height;
serializer.deserializeArrayItem(m_cameras[i].m_entity.index, 0);
m_cameras[i].m_entity.universe = &m_universe;
serializer.deserializeArrayItem(m_cameras[i].m_slot, Camera::MAX_SLOT_LENGTH, "main");
if(!m_cameras[i].m_is_free)
{
m_universe.addComponent(m_cameras[i].m_entity, CAMERA_HASH, this, i);
}
}
serializer.deserializeArrayEnd();
}
void deserializeRenderables(JsonSerializer& serializer)
void deserializeRenderables(Blob& serializer)
{
int32_t size = 0;
serializer.deserialize("renderable_count", size, 0);
serializer.deserializeArrayBegin("renderables");
serializer.read(size);
for(int i = size; i < m_renderables.size(); ++i)
{
setModel(i, NULL);
@ -399,73 +338,48 @@ namespace Lumix
for (int i = 0; i < size; ++i)
{
m_renderables.push(m_allocator.newObject<Renderable>(m_allocator));
serializer.deserializeArrayItem(m_renderables[i]->m_is_always_visible, false);
serializer.deserializeArrayItem(m_renderables[i]->m_component_index, 0);
serializer.read(m_renderables[i]->m_is_always_visible);
serializer.read(m_renderables[i]->m_component_index);
if (m_renderables[i]->m_is_always_visible)
{
m_always_visible.push(m_renderables[i]->m_component_index);
}
serializer.deserializeArrayItem(m_renderables[i]->m_entity.index, 0);
serializer.read(m_renderables[i]->m_entity.index);
serializer.read(m_renderables[i]->m_scale);
int64_t layer_mask;
serializer.read(layer_mask);
m_renderables[i]->m_model = NULL;
m_renderables[i]->m_entity.universe = &m_universe;
int64_t layer_mask;
serializer.deserializeArrayItem(layer_mask, 1);
serializer.read(&m_renderables[i]->m_matrix.m11, sizeof(Matrix));
char path[LUMIX_MAX_PATH];
serializer.deserializeArrayItem(path, LUMIX_MAX_PATH, "");
serializer.deserializeArrayItem(m_renderables[i]->m_scale, 0);
serializer.readString(path, LUMIX_MAX_PATH);
m_culling_system->addStatic(Sphere(m_renderables[i]->m_entity.getPosition(), 1.0f));
m_culling_system->setLayerMask(i, layer_mask);
setModel(i, static_cast<Model*>(m_engine.getResourceManager().get(ResourceManager::MODEL)->load(path)));
for (int j = 0; j < 16; ++j)
{
serializer.deserializeArrayItem((&m_renderables[i]->m_matrix.m11)[j], i == j ? 1.0f : 0.0f);
}
m_universe.addComponent(m_renderables[i]->m_entity, RENDERABLE_HASH, this, i);
}
serializer.deserializeArrayEnd();
}
void deserializeLights(JsonSerializer& serializer)
void deserializeLights(Blob& serializer)
{
int32_t size = 0;
serializer.deserialize("light_count", size, 0);
serializer.deserializeArrayBegin("lights");
serializer.read(size);
m_lights.resize(size);
serializer.read(&m_lights[0], sizeof(m_lights[0]) * size);
for (int i = 0; i < size; ++i)
{
serializer.deserializeArrayItem(m_lights[i].m_entity.index, 0);
m_lights[i].m_entity.universe = &m_universe;
serializer.deserializeArrayItem((int32_t&)m_lights[i].m_type, 0);
serializer.deserializeArrayItem(m_lights[i].m_is_free, true);
serializer.deserializeArrayItem(m_lights[i].m_diffuse_color.x, 0);
serializer.deserializeArrayItem(m_lights[i].m_diffuse_color.y, 0);
serializer.deserializeArrayItem(m_lights[i].m_diffuse_color.z, 0);
serializer.deserializeArrayItem(m_lights[i].m_diffuse_color.w, 0);
serializer.deserializeArrayItem(m_lights[i].m_diffuse_intensity, 0);
serializer.deserializeArrayItem(m_lights[i].m_ambient_color.x, 0);
serializer.deserializeArrayItem(m_lights[i].m_ambient_color.y, 0);
serializer.deserializeArrayItem(m_lights[i].m_ambient_color.z, 0);
serializer.deserializeArrayItem(m_lights[i].m_ambient_color.w, 0);
serializer.deserializeArrayItem(m_lights[i].m_ambient_intensity, 0);
serializer.deserializeArrayItem(m_lights[i].m_fog_color.x, 0);
serializer.deserializeArrayItem(m_lights[i].m_fog_color.y, 0);
serializer.deserializeArrayItem(m_lights[i].m_fog_color.z, 0);
serializer.deserializeArrayItem(m_lights[i].m_fog_color.w, 0);
serializer.deserializeArrayItem(m_lights[i].m_fog_density, 0);
if(!m_lights[i].m_is_free)
{
m_universe.addComponent(m_lights[i].m_entity, LIGHT_HASH, this, i);
}
}
serializer.deserializeArrayEnd();
}
void deserializeTerrains(JsonSerializer& serializer)
void deserializeTerrains(Blob& serializer)
{
int32_t size = 0;
serializer.deserialize("terrain_count", size, 0);
serializer.deserializeArrayBegin("terrains");
serializer.read(size);
for (int i = size; i < m_terrains.size(); ++i)
{
m_allocator.deleteObject(m_terrains[i]);
@ -475,7 +389,7 @@ namespace Lumix
for (int i = 0; i < size; ++i)
{
bool exists;
serializer.deserializeArrayItem(exists, false);
serializer.read(exists);
if(exists)
{
m_terrains[i] = m_allocator.newObject<Terrain>(Entity::INVALID, *this, m_allocator);
@ -487,10 +401,9 @@ namespace Lumix
m_terrains[i] = NULL;
}
}
serializer.deserializeArrayEnd();
}
virtual void deserialize(JsonSerializer& serializer) override
virtual void deserialize(Blob& serializer) override
{
deserializeCameras(serializer);
deserializeRenderables(serializer);

View file

@ -14,7 +14,6 @@ namespace Lumix
class Frustum;
class Geometry;
class IRenderDevice;
class JsonSerializer;
class Material;
class Mesh;
class Model;

View file

@ -398,24 +398,19 @@ struct RendererImpl : public Renderer
}
}
virtual void serialize(JsonSerializer&) override
{
}
virtual void deserialize(JsonSerializer&) override
{
}
virtual void setEditorWireframe(bool is_wireframe)
{
m_is_editor_wireframe = is_wireframe;
}
virtual bool isEditorWireframe() const
{
return m_is_editor_wireframe;
}
Engine& m_engine;
Debug::Allocator m_allocator;
TextureManager m_texture_manager;

View file

@ -1,5 +1,6 @@
#include "terrain.h"
#include "core/aabb.h"
#include "core/blob.h"
#include "core/frustum.h"
#include "core/json_serializer.h"
#include "core/log.h"
@ -580,18 +581,18 @@ namespace Lumix
}
}
void Terrain::deserialize(JsonSerializer& serializer, Universe& universe, RenderScene& scene, int index)
void Terrain::deserialize(Blob& serializer, Universe& universe, RenderScene& scene, int index)
{
serializer.deserializeArrayItem(m_entity.index, 0);
serializer.read(m_entity.index);
m_entity.universe = &universe;
serializer.deserializeArrayItem(m_layer_mask, 0);
serializer.read(m_layer_mask);
char path[LUMIX_MAX_PATH];
serializer.deserializeArrayItem(path, LUMIX_MAX_PATH, "");
serializer.readString(path, LUMIX_MAX_PATH);
setMaterial(static_cast<Material*>(scene.getEngine().getResourceManager().get(ResourceManager::MATERIAL)->load(path)));
serializer.deserializeArrayItem(m_xz_scale, 0);
serializer.deserializeArrayItem(m_y_scale, 0);
int count;
serializer.deserializeArrayItem(count, 0);
serializer.read(m_xz_scale);
serializer.read(m_y_scale);
int32_t count;
serializer.read(count);
while(m_grass_types.size() > count)
{
removeGrassType(m_grass_types.size() - 1);
@ -603,29 +604,29 @@ namespace Lumix
}
for(int i = 0; i < count; ++i)
{
serializer.deserializeArrayItem(path, LUMIX_MAX_PATH, "");
serializer.deserializeArrayItem(m_grass_types[i]->m_ground, 0);
serializer.deserializeArrayItem(m_grass_types[i]->m_density, 0);
serializer.readString(path, LUMIX_MAX_PATH);
serializer.read(m_grass_types[i]->m_ground);
serializer.read(m_grass_types[i]->m_density);
setGrassTypePath(i, path);
}
universe.addComponent(m_entity, TERRAIN_HASH, &scene, index);
}
void Terrain::serialize(JsonSerializer& serializer)
void Terrain::serialize(Blob& serializer)
{
serializer.serializeArrayItem(m_entity.index);
serializer.serializeArrayItem(m_layer_mask);
serializer.serializeArrayItem(m_material ? m_material->getPath().c_str() : "");
serializer.serializeArrayItem(m_xz_scale);
serializer.serializeArrayItem(m_y_scale);
serializer.serializeArrayItem(m_grass_types.size());
serializer.write(m_entity.index);
serializer.write(m_layer_mask);
serializer.write(m_material ? m_material->getPath().c_str() : "");
serializer.write(m_xz_scale);
serializer.write(m_y_scale);
serializer.write((int32_t)m_grass_types.size());
for(int i = 0; i < m_grass_types.size(); ++i)
{
GrassType& type = *m_grass_types[i];
serializer.serializeArrayItem(type.m_grass_model ? type.m_grass_model->getPath().c_str() : "");
serializer.serializeArrayItem(type.m_ground);
serializer.serializeArrayItem(type.m_density);
serializer.write(type.m_grass_model ? type.m_grass_model->getPath().c_str() : "");
serializer.write(type.m_ground);
serializer.write(type.m_density);
}
}

View file

@ -15,7 +15,7 @@ namespace Lumix
{
class JsonSerializer;
class Blob;
class Material;
class Mesh;
class PipelineInstance;
@ -42,8 +42,8 @@ class Terrain
Mesh* m_grass_mesh;
Model* m_grass_model;
Terrain& m_terrain;
int m_ground;
int m_density;
int32_t m_ground;
int32_t m_density;
};
class GrassPatch
@ -81,8 +81,8 @@ class Terrain
void render(Renderer& renderer, PipelineInstance& pipeline, const Vec3& camera_pos);
RayCastModelHit castRay(const Vec3& origin, const Vec3& dir);
int64_t getLayerMask() const { return m_layer_mask; }
void serialize(JsonSerializer& serializer);
void deserialize(JsonSerializer& serializer, Universe& universe, RenderScene& scene, int index);
void serialize(Blob& serializer);
void deserialize(Blob& serializer, Universe& universe, RenderScene& scene, int index);
void setXZScale(float scale) { m_xz_scale = scale; }
float getXZScale() const { return m_xz_scale; }
void setYScale(float scale) { m_y_scale = scale; }

View file

@ -3,6 +3,7 @@
#include <Windows.h>
#include <PxPhysicsAPI.h>
#include "cooking/PxCooking.h"
#include "core/blob.h"
#include "core/crc32.h"
#include "core/fs/file_system.h"
#include "core/fs/ifile.h"
@ -824,7 +825,7 @@ struct PhysicsSceneImpl : public PhysicsScene
}
void serializeActor(JsonSerializer& serializer, int idx)
void serializeActor(Blob& serializer, int idx)
{
physx::PxShape* shapes;
if (m_actors[idx]->m_physx_actor->getNbShapes() == 1 && m_actors[idx]->m_physx_actor->getShapes(&shapes, 1))
@ -833,10 +834,10 @@ struct PhysicsSceneImpl : public PhysicsScene
physx::PxHeightFieldGeometry hf_geom;
if (shapes->getBoxGeometry(geom))
{
serializer.serialize("type", (int32_t)BOX);
serializer.serialize("x", geom.halfExtents.x);
serializer.serialize("y", geom.halfExtents.y);
serializer.serialize("z", geom.halfExtents.z);
serializer.write((int32_t)BOX);
serializer.write(geom.halfExtents.x);
serializer.write(geom.halfExtents.y);
serializer.write(geom.halfExtents.z);
}
else
{
@ -850,10 +851,10 @@ struct PhysicsSceneImpl : public PhysicsScene
}
void deserializeActor(JsonSerializer& serializer, int idx)
void deserializeActor(Blob& serializer, int idx)
{
ActorType type;
serializer.deserialize("type", (int32_t&)type, 0);
serializer.read((int32_t&)type);
physx::PxTransform transform;
Matrix mtx;
m_actors[idx]->m_entity.getMatrix(mtx);
@ -865,9 +866,9 @@ struct PhysicsSceneImpl : public PhysicsScene
{
case BOX:
{
serializer.deserialize("x", box_geom.halfExtents.x, 1.0f);
serializer.deserialize("y", box_geom.halfExtents.y, 1.0f);
serializer.deserialize("z", box_geom.halfExtents.z, 1.0f);
serializer.read(box_geom.halfExtents.x);
serializer.read(box_geom.halfExtents.y);
serializer.read(box_geom.halfExtents.z);
geom = &box_geom;
}
break;
@ -894,55 +895,49 @@ struct PhysicsSceneImpl : public PhysicsScene
}
virtual void serialize(JsonSerializer& serializer) override
virtual void serialize(Blob& serializer) override
{
serializer.serialize("count", m_actors.size());
serializer.beginArray("actors");
serializer.write((int32_t)m_actors.size());
for (int i = 0; i < m_actors.size(); ++i)
{
serializer.serializeArrayItem(m_actors[i]->m_source);
serializer.serializeArrayItem(isDynamic(i));
serializer.serializeArrayItem(m_actors[i]->m_entity.index);
serializer.write(m_actors[i]->m_source.c_str());
serializer.write(isDynamic(i));
serializer.write(m_actors[i]->m_entity.index);
if(m_actors[i]->m_entity.index != -1)
{
serializeActor(serializer, i);
}
}
serializer.endArray();
serializer.serialize("count", m_controllers.size());
serializer.beginArray("controllers");
serializer.write((int32_t)m_controllers.size());
for (int i = 0; i < m_controllers.size(); ++i)
{
serializer.serializeArrayItem(m_controllers[i].m_entity.index);
serializer.serializeArrayItem(m_controllers[i].m_is_free);
serializer.write(m_controllers[i].m_entity.index);
serializer.write(m_controllers[i].m_is_free);
}
serializer.endArray();
serializer.serialize("count", m_terrains.size());
serializer.beginArray("terrains");
serializer.write((int32_t)m_terrains.size());
for (int i = 0; i < m_terrains.size(); ++i)
{
if(m_terrains[i])
{
serializer.serializeArrayItem(true);
serializer.serializeArrayItem(m_terrains[i]->m_entity.index);
serializer.serializeArrayItem(m_terrains[i]->m_heightmap ? m_terrains[i]->m_heightmap->getPath().c_str() : "");
serializer.serializeArrayItem(m_terrains[i]->m_xz_scale);
serializer.serializeArrayItem(m_terrains[i]->m_y_scale);
serializer.write(true);
serializer.write(m_terrains[i]->m_entity.index);
serializer.write(m_terrains[i]->m_heightmap ? m_terrains[i]->m_heightmap->getPath().c_str() : "");
serializer.write(m_terrains[i]->m_xz_scale);
serializer.write(m_terrains[i]->m_y_scale);
}
else
{
serializer.serializeArrayItem(false);
serializer.write(false);
}
}
serializer.endArray();
}
void deserializeActors(JsonSerializer& serializer)
void deserializeActors(Blob& serializer)
{
int32_t count;
m_dynamic_actors.clear();
serializer.deserialize("count", count, 0);
serializer.read(count);
for (int i = count; i < m_actors.size(); ++i)
{
m_actors[i]->m_physx_actor->release();
@ -954,43 +949,42 @@ struct PhysicsSceneImpl : public PhysicsScene
RigidActor* actor = m_allocator.newObject<RigidActor>(m_allocator);
m_actors[i] = actor;
}
serializer.deserializeArrayBegin("actors");
for (int i = 0; i < m_actors.size(); ++i)
{
serializer.deserializeArrayItem(m_actors[i]->m_source, "");
char tmp[LUMIX_MAX_PATH];
serializer.readString(tmp, sizeof(tmp));
m_actors[i]->m_source = tmp;
bool is_dynamic;
serializer.deserializeArrayItem(is_dynamic, false);
serializer.read(is_dynamic);
if (is_dynamic)
{
m_dynamic_actors.push(m_actors[i]);
}
serializer.deserializeArrayItem(m_actors[i]->m_entity.index, 0);
serializer.read(m_actors[i]->m_entity.index);
if(m_actors[i]->m_entity.index != -1)
{
m_actors[i]->m_entity.universe = m_universe;
deserializeActor(serializer, i);
}
}
serializer.deserializeArrayEnd();
}
void deserializeControllers(JsonSerializer& serializer)
void deserializeControllers(Blob& serializer)
{
int32_t count;
serializer.deserialize("count", count, 0);
serializer.read(count);
for (int i = 0; i < m_controllers.size(); ++i)
{
m_controllers[i].m_controller->release();
}
m_controllers.clear();
serializer.deserializeArrayBegin("controllers");
for (int i = 0; i < count; ++i)
{
int index;
int32_t index;
bool is_free;
serializer.deserializeArrayItem(index, 0);
serializer.deserializeArrayItem(is_free, true);
serializer.read(index);
serializer.read(is_free);
Entity e(m_universe, index);
Controller& c = m_controllers.pushEmpty();
@ -1014,14 +1008,13 @@ struct PhysicsSceneImpl : public PhysicsScene
m_universe->addComponent(e, CONTROLLER_HASH, this, i);
}
}
serializer.deserializeArrayEnd();
}
void deserializeTerrains(JsonSerializer& serializer)
void deserializeTerrains(Blob& serializer)
{
int32_t count;
serializer.deserialize("count", count, 0);
serializer.read(count);
for (int i = count; i < m_terrains.size(); ++i)
{
m_allocator.deleteObject(m_terrains[i]);
@ -1033,11 +1026,10 @@ struct PhysicsSceneImpl : public PhysicsScene
{
m_terrains[i] = NULL;
}
serializer.deserializeArrayBegin("terrains");
for (int i = 0; i < count; ++i)
{
bool exists;
serializer.deserializeArrayItem(exists, false);
serializer.read(exists);
if(exists)
{
if(!m_terrains[i])
@ -1046,11 +1038,11 @@ struct PhysicsSceneImpl : public PhysicsScene
}
m_terrains[i]->m_scene = this;
m_terrains[i]->m_entity.universe = m_universe;
serializer.deserializeArrayItem(m_terrains[i]->m_entity.index, 0);
serializer.read(m_terrains[i]->m_entity.index);
char tmp[LUMIX_MAX_PATH];
serializer.deserializeArrayItem(tmp, LUMIX_MAX_PATH, "");
serializer.deserializeArrayItem(m_terrains[i]->m_xz_scale, 0);
serializer.deserializeArrayItem(m_terrains[i]->m_y_scale, 0);
serializer.readString(tmp, LUMIX_MAX_PATH);
serializer.read(m_terrains[i]->m_xz_scale);
serializer.read(m_terrains[i]->m_y_scale);
Component cmp(m_terrains[i]->m_entity, HEIGHTFIELD_HASH, this, i);
if (m_terrains[i]->m_heightmap == NULL || strcmp(tmp, m_terrains[i]->m_heightmap->getPath().c_str()) != 0)
@ -1060,11 +1052,10 @@ struct PhysicsSceneImpl : public PhysicsScene
m_universe->addComponent(m_terrains[i]->m_entity, HEIGHTFIELD_HASH, this, i);
}
}
serializer.deserializeArrayEnd();
}
virtual void deserialize(JsonSerializer& serializer) override
virtual void deserialize(Blob& serializer) override
{
deserializeActors(serializer);
deserializeControllers(serializer);

View file

@ -47,20 +47,19 @@ namespace Lumix
virtual IPlugin& getPlugin() const;
void deserialize(JsonSerializer& serializer) override
void deserialize(Blob& serializer) override
{
stopAll();
int count;
serializer.deserialize("count", count, 0);
serializer.deserializeArrayBegin("scripts");
int32_t count;
serializer.read(count);
m_script_entities.resize(count);
m_paths.clear();
m_paths.reserve(count);
for (int i = 0; i < m_script_entities.size(); ++i)
{
serializer.deserializeArrayItem(m_script_entities[i], 0);
serializer.read(m_script_entities[i]);
char path[LUMIX_MAX_PATH];
serializer.deserializeArrayItem(path, sizeof(path), NULL);
serializer.readString(path, sizeof(path));
m_paths.push(path);
Entity entity(&m_universe, m_script_entities[i]);
if(m_script_entities[i] != -1)
@ -68,7 +67,6 @@ namespace Lumix
m_universe.addComponent(entity, SCRIPT_HASH, this, i);
}
}
serializer.deserializeArrayEnd();
runAll();
}
@ -273,16 +271,14 @@ namespace Lumix
}
void serialize(JsonSerializer& serializer) override
void serialize(Blob& serializer) override
{
serializer.serialize("count", m_script_entities.size());
serializer.beginArray("scripts");
serializer.write((int32_t)m_script_entities.size());
for (int i = 0; i < m_script_entities.size(); ++i)
{
serializer.serializeArrayItem(m_script_entities[i]);
serializer.serializeArrayItem(m_paths[i].c_str());
serializer.write((int32_t)m_script_entities[i]);
serializer.write(m_paths[i].c_str());
}
serializer.endArray();
}
@ -318,7 +314,7 @@ namespace Lumix
IAllocator& m_allocator;
Array<RunningScript> m_running_scripts;
Array<int> m_script_entities;
Array<int32_t> m_script_entities;
Array<Path> m_paths;
Universe& m_universe;
Engine& m_engine;

View file

@ -12,8 +12,6 @@ namespace Lumix
class Engine;
class InputSystem;
class Navigation;
class Path;

View file

@ -1,5 +1,6 @@
#include "hierarchy.h"
#include "core/array.h"
#include "core/blob.h"
#include "core/hash_map.h"
#include "core/json_serializer.h"
#include "core/matrix.h"
@ -140,35 +141,31 @@ class HierarchyImpl : public Hierarchy
}
virtual void serialize(JsonSerializer& serializer) override
virtual void serialize(Blob& serializer) override
{
int size = m_parents.size();
serializer.serialize("hierarchy_size", size);
serializer.beginArray("hierarchy");
serializer.write((int32_t)size);
Parents::iterator iter = m_parents.begin(), end = m_parents.end();
while(iter != end)
{
serializer.serializeArrayItem(iter.key());
serializer.serializeArrayItem(iter.value());
serializer.write(iter.key());
serializer.write(iter.value());
++iter;
}
serializer.endArray();
}
virtual void deserialize(JsonSerializer& serializer) override
virtual void deserialize(Blob& serializer) override
{
int size;
serializer.deserialize("hierarchy_size", size, 0);
serializer.deserializeArrayBegin("hierarchy");
int32_t size;
serializer.read(size);
for(int i = 0; i < size; ++i)
{
int32_t child, parent;
serializer.deserializeArrayItem(child, 0);
serializer.deserializeArrayItem(parent, 0);
serializer.read(child);
serializer.read(parent);
setParent(Entity(&m_universe, child), Entity(&m_universe, parent));
}
serializer.deserializeArrayEnd();
}

View file

@ -9,7 +9,7 @@ namespace Lumix
{
class JsonSerializer;
class Blob;
class Hierarchy
@ -31,8 +31,8 @@ namespace Lumix
virtual void setParent(const Entity& child, const Entity& parent) = 0;
virtual Entity getParent(const Entity& child) = 0;
virtual void serialize(JsonSerializer& serializer) = 0;
virtual void deserialize(JsonSerializer& serializer) = 0;
virtual void serialize(Blob& serializer) = 0;
virtual void deserialize(Blob& serializer) = 0;
virtual Array<Child>* getChildren(const Entity& parent) = 0;
virtual DelegateList<void (const Entity&, const Entity&)>& parentSet() = 0;
};

View file

@ -1,4 +1,5 @@
#include "universe.h"
#include "core/blob.h"
#include "core/crc32.h"
#include "core/matrix.h"
#include "core/json_serializer.h"
@ -111,96 +112,55 @@ Entity Universe::getNextEntity(Entity entity)
}
void Universe::serialize(JsonSerializer& serializer)
void Universe::serialize(Blob& serializer)
{
serializer.serialize("count", m_positions.size());
serializer.beginArray("positions");
for(int i = 0; i < m_positions.size(); ++i)
{
serializer.serializeArrayItem(m_positions[i].x);
serializer.serializeArrayItem(m_positions[i].y);
serializer.serializeArrayItem(m_positions[i].z);
}
serializer.endArray();
serializer.beginArray("rotations");
for(int i = 0; i < m_rotations.size(); ++i)
{
serializer.serializeArrayItem(m_rotations[i].x);
serializer.serializeArrayItem(m_rotations[i].y);
serializer.serializeArrayItem(m_rotations[i].z);
serializer.serializeArrayItem(m_rotations[i].w);
}
serializer.endArray();
serializer.serialize("name_count", m_id_to_name_map.size());
serializer.beginArray("names");
serializer.write((int32_t)m_positions.size());
serializer.write(&m_positions[0].x, sizeof(m_positions[0]) * m_positions.size());
serializer.write(&m_rotations[0].x, sizeof(m_rotations[0]) * m_rotations.size());
serializer.write((int32_t)m_id_to_name_map.size());
for (int i = 0, c = m_id_to_name_map.size(); i < c; ++i)
{
serializer.serializeArrayItem(m_id_to_name_map.getKey(i));
serializer.serializeArrayItem(m_id_to_name_map.at(i).c_str());
serializer.write(m_id_to_name_map.getKey(i));
serializer.write(m_id_to_name_map.at(i).c_str());
}
serializer.endArray();
serializer.serialize("free_slot_count", m_free_slots.size());
serializer.beginArray("free_slots");
for(int i = 0; i < m_free_slots.size(); ++i)
serializer.write((int32_t)m_free_slots.size());
if (!m_free_slots.empty())
{
serializer.serializeArrayItem(m_free_slots[i]);
serializer.write(&m_free_slots[0], sizeof(m_free_slots[0]) * m_free_slots.size());
}
serializer.endArray();
}
void Universe::deserialize(JsonSerializer& serializer)
void Universe::deserialize(Blob& serializer)
{
int count;
serializer.deserialize("count", count, 0);
int32_t count;
serializer.read(count);
m_positions.resize(count);
m_rotations.resize(count);
serializer.deserializeArrayBegin("positions");
for(int i = 0; i < count; ++i)
{
serializer.deserializeArrayItem(m_positions[i].x, 0);
serializer.deserializeArrayItem(m_positions[i].y, 0);
serializer.deserializeArrayItem(m_positions[i].z, 0);
}
serializer.deserializeArrayEnd();
serializer.read(&m_positions[0].x, sizeof(m_positions[0]) * m_positions.size());
serializer.read(&m_rotations[0].x, sizeof(m_rotations[0]) * m_rotations.size());
serializer.deserializeArrayBegin("rotations");
for(int i = 0; i < count; ++i)
{
serializer.deserializeArrayItem(m_rotations[i].x, 0);
serializer.deserializeArrayItem(m_rotations[i].y, 0);
serializer.deserializeArrayItem(m_rotations[i].z, 0);
serializer.deserializeArrayItem(m_rotations[i].w, 1);
}
serializer.deserializeArrayEnd();
serializer.deserialize("name_count", count, 0);
serializer.deserializeArrayBegin("names");
serializer.read(count);
m_id_to_name_map.clear();
m_name_to_id_map.clear();
for (int i = 0; i < count; ++i)
{
uint32_t key;
static const int MAX_NAME_LENGTH = 50;
char name[MAX_NAME_LENGTH];
serializer.deserializeArrayItem(key, 0);
serializer.deserializeArrayItem(name, MAX_NAME_LENGTH, "");
char name[50];
serializer.read(key);
serializer.readString(name, sizeof(name));
m_id_to_name_map.insert(key, string(name, m_allocator));
m_name_to_id_map.insert(crc32(name), key);
}
serializer.deserializeArrayEnd();
serializer.deserialize("free_slot_count", count, 0);
serializer.read(count);
m_free_slots.resize(count);
serializer.deserializeArrayBegin("free_slots");
for(int i = 0; i < count; ++i)
if (!m_free_slots.empty())
{
serializer.deserializeArrayItem(m_free_slots[i], 0);
serializer.read(&m_free_slots[0], sizeof(m_free_slots[0]) * count);
}
serializer.deserializeArrayEnd();
}

View file

@ -16,8 +16,8 @@ namespace Lumix
{
class Blob;
class Event;
class JsonSerializer;
struct Matrix;
struct Quat;
class Universe;
@ -51,8 +51,8 @@ class LUMIX_ENGINE_API Universe final
Delegate<void(const Component&)>& componentAdded() { return m_component_added; }
void serialize(JsonSerializer& serializer);
void deserialize(JsonSerializer& serializer);
void serialize(Blob& serializer);
void deserialize(Blob& serializer);
private:
IAllocator& m_allocator;