removed json

This commit is contained in:
Mikulas Florek 2019-06-21 18:49:30 +02:00
parent 9b399880ad
commit 55f36731df
23 changed files with 97 additions and 2119 deletions

View file

@ -24,6 +24,9 @@
namespace Lumix
{
class Animation;
class Engine;
class Universe;
enum class AnimationSceneVersion
{
@ -41,12 +44,6 @@ static const ComponentType CONTROLLER_TYPE = Reflection::getComponentType("anim_
static const ComponentType SHARED_CONTROLLER_TYPE = Reflection::getComponentType("shared_anim_controller");
class Animation;
class Engine;
class JsonSerializer;
class Universe;
struct AnimationSceneImpl final : public AnimationScene
{
friend struct AnimationSystemImpl;

View file

@ -12,6 +12,9 @@
namespace Lumix
{
class Animation;
class Engine;
class Universe;
enum class AnimationSceneVersion
{
@ -64,12 +67,6 @@ struct AnimSetProperty : public Reflection::IEnumProperty
};
class Animation;
class Engine;
class JsonSerializer;
class Universe;
template <typename T>
struct AnimResourceManager final : public ResourceManager
{

View file

@ -94,8 +94,6 @@ struct BeginGroupCommand final : IEditorCommand
bool execute() override { return true; }
void undo() override { ASSERT(false); }
void serialize(JsonSerializer& serializer) override {}
void deserialize(JsonDeserializer& serializer) override {}
bool merge(IEditorCommand& command) override { ASSERT(false); return false; }
const char* getType() override { return "begin_group"; }
};
@ -108,8 +106,6 @@ struct EndGroupCommand final : IEditorCommand
bool execute() override { return true; }
void undo() override { ASSERT(false); }
void serialize(JsonSerializer& serializer) override {}
void deserialize(JsonDeserializer& serializer) override {}
bool merge(IEditorCommand& command) override { ASSERT(false); return false; }
const char* getType() override { return "end_group"; }
@ -155,19 +151,6 @@ struct MoveAnimNodeCommand : IEditorCommand
}
void serialize(JsonSerializer& serializer) override
{
// TODO
ASSERT(false);
}
void deserialize(JsonDeserializer& serializer) override
{
// TODO
ASSERT(false);
}
ControllerResource& m_controller;
int m_node_uid;
ImVec2 m_new_pos;
@ -215,19 +198,6 @@ struct CreateAnimNodeCommand : IEditorCommand
bool merge(IEditorCommand& command) override { return false; }
void serialize(JsonSerializer& serializer) override
{
// TODO
ASSERT(false);
}
void deserialize(JsonDeserializer& serializer) override
{
// TODO
ASSERT(false);
}
ControllerResource& m_controller;
int m_container_uid;
int m_node_uid;
@ -281,17 +251,6 @@ struct DestroyAnimEdgeCommand : IEditorCommand
bool merge(IEditorCommand& command) override { return false; }
void serialize(JsonSerializer& serializer) override
{
ASSERT(false);
}
void deserialize(JsonDeserializer& serializer) override
{
ASSERT(false);
}
ControllerResource& m_controller;
int m_edge_uid;
int m_from_uid;
@ -350,19 +309,6 @@ struct DestroyNodeCommand : IEditorCommand
bool merge(IEditorCommand& command) override { return false; }
void serialize(JsonSerializer& serializer) override
{
// TODO
ASSERT(false);
}
void deserialize(JsonDeserializer& serializer) override
{
// TODO
ASSERT(false);
}
ControllerResource& m_controller;
int m_node_uid;
OutputMemoryStream m_original_values;
@ -404,19 +350,6 @@ struct CreateAnimEdgeCommand : IEditorCommand
bool merge(IEditorCommand& command) override { return false; }
void serialize(JsonSerializer& serializer) override
{
// TODO
ASSERT(false);
}
void deserialize(JsonDeserializer& serializer) override
{
// TODO
ASSERT(false);
}
ControllerResource& m_controller;
int m_from_uid;
int m_to_uid;

View file

@ -11,10 +11,10 @@
#include "engine/crc32.h"
#include "engine/engine.h"
#include "engine/hash_map.h"
#include "engine/json_serializer.h"
#include "engine/log.h"
#include "engine/os.h"
#include "engine/reflection.h"
#include "engine/serializer.h"
#include "engine/universe/universe.h"
#include "imgui/imgui.h"
#include "renderer/model.h"
@ -169,10 +169,13 @@ struct PropertyAnimationAssetBrowserPlugin : AssetBrowser::IPlugin
void savePropertyAnimation(PropertyAnimation& anim)
{
if (IOutputStream* file = m_app.getAssetBrowser().beginSaveResource(anim))
if (OutputMemoryStream* file = m_app.getAssetBrowser().beginSaveResource(anim))
{
bool success = true;
JsonSerializer serializer(*file, anim.getPath());
struct : ISaveEntityGUIDMap {
EntityGUID get(EntityPtr entity) override { ASSERT(false); return INVALID_ENTITY_GUID; }
} dummy_map;
TextSerializer serializer(*file, dummy_map);
if (!anim.save(serializer))
{
success = false;

View file

@ -304,8 +304,6 @@ struct SetCommand : PathCommand<RootGetter>
this->root_getter().accept(v);
}
void serialize(JsonSerializer& serializer) override { ASSERT(false); }
void deserialize(JsonDeserializer& serializer) override { ASSERT(false); }
const char* getType() override { return "set_property"; }
@ -370,8 +368,6 @@ struct AddArrayItemCommand : PathCommand<RootGetter>
this->root_getter().accept(v);
}
void serialize(JsonSerializer& serializer) override { ASSERT(false); }
void deserialize(JsonDeserializer& serializer) override { ASSERT(false); }
const char* getType() override { return "add_array_item"; }
bool merge(IEditorCommand& command) override { return false; }
@ -585,8 +581,6 @@ struct RemoveArrayItemCommand : PathCommand<RootGetter>
this->root_getter().accept(v);
}
void serialize(JsonSerializer& serializer) override { ASSERT(false); }
void deserialize(JsonDeserializer& serializer) override { ASSERT(false); }
const char* getType() override { return "remove_array_item"; }
bool merge(IEditorCommand& command) override { return false; }

View file

@ -1,9 +1,9 @@
#include "animation/property_animation.h"
#include "engine/crc32.h"
#include "engine/allocator.h"
#include "engine/json_serializer.h"
#include "engine/log.h"
#include "engine/reflection.h"
#include "engine/serializer.h"
namespace Lumix
@ -28,28 +28,22 @@ PropertyAnimation::Curve& PropertyAnimation::addCurve()
}
bool PropertyAnimation::save(JsonSerializer& serializer)
bool PropertyAnimation::save(TextSerializer& serializer)
{
if (!isReady()) return false;
serializer.beginArray();
serializer.write("count", curves.size());
for (Curve& curve : curves)
{
serializer.beginObject();
serializer.serialize("component", Reflection::getComponent(curve.cmp_type)->name);
serializer.serialize("property", curve.property->name);
serializer.beginArray("keys");
serializer.write("component", Reflection::getComponent(curve.cmp_type)->name);
serializer.write("property", curve.property->name);
serializer.write("keys_count", curve.frames.size());
for (int i = 0; i < curve.frames.size(); ++i)
{
serializer.beginObject();
serializer.serialize("frame", curve.frames[i]);
serializer.serialize("value", curve.values[i]);
serializer.endObject();
serializer.write("frame", curve.frames[i]);
serializer.write("value", curve.values[i]);
}
serializer.endArray();
serializer.endObject();
}
serializer.endArray();
return true;
}
@ -58,82 +52,30 @@ bool PropertyAnimation::save(JsonSerializer& serializer)
bool PropertyAnimation::load(u64 size, const u8* mem)
{
InputMemoryStream file(mem, size);
JsonDeserializer serializer(file, getPath(), m_allocator);
if (serializer.isError()) return false;
struct : ILoadEntityGUIDMap {
EntityPtr get(EntityGUID guid) override { ASSERT(false); return INVALID_ENTITY; }
} dummy_map;
TextDeserializer serializer(file, dummy_map);
serializer.deserializeArrayBegin();
while (!serializer.isArrayEnd())
{
serializer.nextArrayItem();
int count;
serializer.read(&count);
for (int i = 0; i < count; ++i) {
Curve& curve = curves.emplace(m_allocator);
serializer.deserializeObjectBegin();
u32 prop_hash = 0;
while (!serializer.isObjectEnd())
{
char tmp[32];
serializer.deserializeLabel(tmp, lengthOf(tmp));
if (equalIStrings(tmp, "component"))
{
serializer.deserialize(tmp, lengthOf(tmp), "");
curve.cmp_type = Reflection::getComponentType(tmp);
}
else if (equalIStrings(tmp, "property"))
{
serializer.deserialize(tmp, lengthOf(tmp), "");
prop_hash = crc32(tmp);
}
else if (equalIStrings(tmp, "keys"))
{
serializer.deserializeArrayBegin();
while (!serializer.isArrayEnd())
{
serializer.nextArrayItem();
serializer.deserializeObjectBegin();
while (!serializer.isObjectEnd())
{
serializer.deserializeLabel(tmp, lengthOf(tmp));
if (equalIStrings(tmp, "frame"))
{
int frame;
serializer.deserialize(frame, 0);
curve.frames.push(frame);
}
else if (equalIStrings(tmp, "value"))
{
float value;
serializer.deserialize(value, 0);
curve.values.push(value);
}
else
{
logError("Animation") << "Unknown key " << tmp;
curves.clear();
return false;
}
}
if (curve.values.size() != curve.frames.size())
{
logError("Animation") << "Key without " << (curve.values.size() < curve.frames.size() ? "value" : "frame");
curves.clear();
return false;
}
serializer.deserializeObjectEnd();
}
serializer.deserializeArrayEnd();
}
else
{
logError("Animation") << "Unknown key " << tmp;
curves.clear();
return false;
}
char tmp[32];
serializer.read(tmp, lengthOf(tmp));
curve.cmp_type = Reflection::getComponentType(tmp);
serializer.read(tmp, lengthOf(tmp));
u32 prop_hash = crc32(tmp);
int keys_count;
serializer.read(&keys_count);
curve.frames.resize(keys_count);
curve.values.resize(keys_count);
for (int j = 0; j < keys_count; ++j) {
serializer.read(&curve.frames[i]);
serializer.read(&curve.values[i]);
}
serializer.deserializeObjectEnd();
curve.property = Reflection::getProperty(curve.cmp_type, prop_hash);
}
serializer.deserializeArrayEnd();
return true;
}

View file

@ -7,7 +7,7 @@ namespace Lumix
{
class JsonSerializer;
struct TextSerializer;
namespace Reflection { struct PropertyBase; }
@ -29,7 +29,7 @@ public:
ResourceType getType() const override { return TYPE; }
Curve& addCurve();
bool save(JsonSerializer& serializer);
bool save(TextSerializer& serializer);
IAllocator& m_allocator;
Array<Curve> curves;

View file

@ -593,33 +593,34 @@ bool AssetBrowser::resourceInput(const char* label, const char* str_id, char* bu
}
IOutputStream* AssetBrowser::beginSaveResource(Resource& resource)
OutputMemoryStream* AssetBrowser::beginSaveResource(Resource& resource)
{
// use temporary because otherwise the resource is reloaded during saving
StaticString<MAX_PATH_LENGTH> tmp_path(resource.getPath().c_str(), ".tmp");
OS::OutputFile* f = LUMIX_NEW(m_app.getWorldEditor().getAllocator(), OS::OutputFile);
FileSystem& fs = m_app.getWorldEditor().getEngine().getFileSystem();
if (!fs.open(tmp_path, f))
{
LUMIX_DELETE(m_app.getWorldEditor().getAllocator(), f);
logError("Editor") << "Could not save file " << resource.getPath().c_str();
return nullptr;
}
return f;
IAllocator& allocator = m_app.getWorldEditor().getAllocator();
return LUMIX_NEW(allocator, OutputMemoryStream)(allocator);
}
void AssetBrowser::endSaveResource(Resource& resource, IOutputStream& file, bool success)
void AssetBrowser::endSaveResource(Resource& resource, OutputMemoryStream& stream, bool success)
{
static_cast<OS::OutputFile&>(file).close();
LUMIX_DELETE(m_app.getWorldEditor().getAllocator(), &file);
if (!success) return;
FileSystem& fs = m_app.getWorldEditor().getEngine().getFileSystem();
// use temporary because otherwise the resource is reloaded during saving
StaticString<MAX_PATH_LENGTH> tmp_path(resource.getPath().c_str(), ".tmp");
OS::OutputFile f;
if (!fs.open(tmp_path, &f))
{
LUMIX_DELETE(m_app.getWorldEditor().getAllocator(), &stream);
logError("Editor") << "Could not save file " << resource.getPath().c_str();
return;
}
f.write(stream.getData(), stream.getPos());
f.close();
LUMIX_DELETE(m_app.getWorldEditor().getAllocator(), &stream);
auto& engine = m_app.getWorldEditor().getEngine();
StaticString<MAX_PATH_LENGTH> src_full_path;
StaticString<MAX_PATH_LENGTH> dest_full_path;
StaticString<MAX_PATH_LENGTH> tmp_path(resource.getPath().c_str(), ".tmp");
src_full_path.data[0] = 0;
dest_full_path.data[0] = 0;
src_full_path << engine.getFileSystem().getBasePath() << tmp_path;

View file

@ -13,11 +13,12 @@
namespace Lumix
{
class Material;
class WorldEditor;
struct Action;
class FileSystemWatcher;
class Material;
class OutputMemoryStream;
class StudioApp;
class WorldEditor;
class LUMIX_EDITOR_API AssetBrowser
@ -52,8 +53,8 @@ public:
void openInExternalEditor(Resource* resource) const;
void openInExternalEditor(const char* path) const;
bool resourceList(char* buf, int max_size, ResourceType type, float height) const;
IOutputStream* beginSaveResource(Resource& resource);
void endSaveResource(Resource& resource, IOutputStream& file, bool success);
OutputMemoryStream* beginSaveResource(Resource& resource);
void endSaveResource(Resource& resource, OutputMemoryStream& file, bool success);
public:
bool m_is_open;

View file

@ -5,18 +5,12 @@ namespace Lumix
{
class JsonDeserializer;
class JsonSerializer;
struct IEditorCommand
{
virtual ~IEditorCommand() {}
virtual bool execute() = 0;
virtual void undo() = 0;
virtual void serialize(JsonSerializer& serializer) = 0;
virtual void deserialize(JsonDeserializer& serializer) = 0;
virtual const char* getType() = 0;
virtual bool merge(IEditorCommand& command) = 0;
};

View file

@ -9,7 +9,6 @@
#include "engine/engine.h"
#include "engine/hash_map.h"
#include "engine/iplugin.h"
#include "engine/json_serializer.h"
#include "engine/log.h"
#include "engine/math.h"
#include "engine/os.h"
@ -145,36 +144,6 @@ class PrefabSystemImpl final : public PrefabSystem
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("position_x", position.x);
serializer.serialize("position_y", position.y);
serializer.serialize("position_z", position.z);
serializer.serialize("rotation_x", rotation.x);
serializer.serialize("rotation_y", rotation.y);
serializer.serialize("rotation_z", rotation.z);
serializer.serialize("rotation_w", rotation.w);
serializer.serialize("scale", scale);
serializer.serialize("path", prefab->getPath().c_str());
}
void deserialize(JsonDeserializer& serializer) override
{
serializer.deserialize("position_x", position.x, 0);
serializer.deserialize("position_y", position.y, 0);
serializer.deserialize("position_z", position.z, 0);
serializer.deserialize("rotation_x", rotation.x, 0);
serializer.deserialize("rotation_y", rotation.y, 0);
serializer.deserialize("rotation_z", rotation.z, 0);
serializer.deserialize("rotation_w", rotation.w, 0);
serializer.deserialize("scale", scale, 0);
char path[MAX_PATH_LENGTH];
serializer.deserialize("path_hash", path, lengthOf(path), "");
prefab = editor.getEngine().getResourceManager().load<PrefabResource>(Path(path));
}
const char* getType() override
{
return "instantiate_prefab";

View file

@ -1057,26 +1057,6 @@ public:
}
void loadAndExecuteCommands()
{
char filename[MAX_PATH_LENGTH];
if (OS::getOpenFilename(filename, lengthOf(filename), "JSON files\0*.json\0", nullptr))
{
m_editor->executeUndoStack(Path(filename));
}
}
void saveUndoStack()
{
char filename[MAX_PATH_LENGTH];
if (OS::getSaveFilename(filename, lengthOf(filename), "JSON files\0*.json\0", "json"))
{
m_editor->saveUndoStack(Path(filename));
}
}
void removeAction(Action* action) override
{
m_actions.eraseItem(action);
@ -1284,8 +1264,6 @@ public:
doMenuItem(*getAction("toggleMeasure"), true);
doMenuItem(*getAction("snapDown"), is_any_entity_selected);
doMenuItem(*getAction("autosnapDown"), true);
if (ImGui::MenuItem("Save commands")) saveUndoStack();
if (ImGui::MenuItem("Load commands")) loadAndExecuteCommands();
doMenuItem(*getAction("pack_data"), true);
ImGui::EndMenu();
}
@ -2219,18 +2197,12 @@ public:
}
void executeUndoStack(const char* path) { m_editor->executeUndoStack(Path(path)); }
void saveUniverseAs(const char* basename, bool save_path) { m_editor->saveUniverse(basename, save_path); }
void saveUniverse() { save(); }
bool runTest(const char* dir, const char* name) { return m_editor->runTest(dir, name); }
void createLua()
{
lua_State* L = m_engine->getState();
@ -2253,8 +2225,6 @@ public:
REGISTER_FUNCTION(newUniverse);
REGISTER_FUNCTION(saveUniverse);
REGISTER_FUNCTION(saveUniverseAs);
REGISTER_FUNCTION(runTest);
REGISTER_FUNCTION(executeUndoStack);
REGISTER_FUNCTION(exitWithCode);
REGISTER_FUNCTION(exitGameMode);

View file

@ -13,7 +13,6 @@
#include "engine/file_system.h"
#include "engine/geometry.h"
#include "engine/iplugin.h"
#include "engine/json_serializer.h"
#include "engine/log.h"
#include "engine/math.h"
#include "engine/os.h"
@ -65,8 +64,6 @@ struct BeginGroupCommand final : public IEditorCommand
bool execute() override { return true; }
void undo() override { ASSERT(false); }
void serialize(JsonSerializer& serializer) override {}
void deserialize(JsonDeserializer& serializer) override {}
bool merge(IEditorCommand& command) override { ASSERT(false); return false; }
const char* getType() override { return "begin_group"; }
};
@ -79,8 +76,6 @@ struct EndGroupCommand final : public IEditorCommand
bool execute() override { return true; }
void undo() override { ASSERT(false); }
void serialize(JsonSerializer& serializer) override {}
void deserialize(JsonDeserializer& serializer) override {}
bool merge(IEditorCommand& command) override { ASSERT(false); return false; }
const char* getType() override { return "end_group"; }
@ -108,28 +103,6 @@ public:
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("name", m_new_name.c_str());
serializer.serialize("entity", m_entity);
}
void deserialize(JsonDeserializer& serializer) override
{
char name[100];
serializer.deserialize("name", name, sizeof(name), "");
m_new_name = name;
serializer.deserialize("entity", m_entity, INVALID_ENTITY);
if (m_entity.isValid()) {
m_old_name = m_editor.getUniverse()->getEntityName((EntityRef)m_entity);
}
else {
m_old_name = "";
}
}
bool execute() override
{
if (m_entity.isValid()) {
@ -244,55 +217,6 @@ public:
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("count", m_entities.size());
serializer.beginArray("entities");
for (int i = 0; i < m_entities.size(); ++i)
{
serializer.serializeArrayItem(m_entities[i]);
serializer.serializeArrayItem(m_new_positions[i].x);
serializer.serializeArrayItem(m_new_positions[i].y);
serializer.serializeArrayItem(m_new_positions[i].z);
serializer.serializeArrayItem(m_new_rotations[i].x);
serializer.serializeArrayItem(m_new_rotations[i].y);
serializer.serializeArrayItem(m_new_rotations[i].z);
serializer.serializeArrayItem(m_new_rotations[i].w);
}
serializer.endArray();
}
void deserialize(JsonDeserializer& serializer) override
{
Universe* universe = m_editor.getUniverse();
int count;
serializer.deserialize("count", count, 0);
m_entities.resize(count);
m_new_positions.resize(count);
m_new_rotations.resize(count);
m_old_positions.resize(count);
m_old_rotations.resize(count);
serializer.deserializeArrayBegin("entities");
for (int i = 0; i < m_entities.size(); ++i)
{
serializer.deserializeArrayItem(m_entities[i], INVALID_ENTITY);
serializer.deserializeArrayItem(m_new_positions[i].x, 0);
serializer.deserializeArrayItem(m_new_positions[i].y, 0);
serializer.deserializeArrayItem(m_new_positions[i].z, 0);
serializer.deserializeArrayItem(m_new_rotations[i].x, 0);
serializer.deserializeArrayItem(m_new_rotations[i].y, 0);
serializer.deserializeArrayItem(m_new_rotations[i].z, 0);
serializer.deserializeArrayItem(m_new_rotations[i].w, 0);
if(m_entities[i].isValid()) {
m_old_positions[i] = universe->getPosition((EntityRef)m_entities[i]);
m_old_rotations[i] = universe->getRotation((EntityRef)m_entities[i]);
}
}
serializer.deserializeArrayEnd();
}
bool execute() override
{
Universe* universe = m_editor.getUniverse();
@ -413,47 +337,6 @@ public:
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("count", m_entities.size());
serializer.beginArray("entities");
for (int i = 0; i < m_entities.size(); ++i)
{
serializer.serializeArrayItem(m_entities[i]);
serializer.serializeArrayItem(m_new_positions[i].x);
serializer.serializeArrayItem(m_new_positions[i].y);
serializer.serializeArrayItem(m_new_positions[i].z);
}
serializer.endArray();
}
void deserialize(JsonDeserializer& serializer) override
{
Universe* universe = m_editor.getUniverse();
int count;
serializer.deserialize("count", count, 0);
m_entities.resize(count);
m_new_positions.resize(count);
m_old_positions.resize(count);
serializer.deserializeArrayBegin("entities");
for (int i = 0; i < m_entities.size(); ++i)
{
serializer.deserializeArrayItem(m_entities[i], INVALID_ENTITY);
serializer.deserializeArrayItem(m_new_positions[i].x, 0);
serializer.deserializeArrayItem(m_new_positions[i].y, 0);
serializer.deserializeArrayItem(m_new_positions[i].z, 0);
if (m_entities[i].isValid()) {
m_old_positions[i] = universe->getPosition((EntityRef)m_entities[i]);
}
else {
m_old_positions[i] = DVec3(0);
}
}
serializer.deserializeArrayEnd();
}
bool execute() override
{
Universe* universe = m_editor.getUniverse();
@ -567,51 +450,6 @@ public:
}
void serialize(JsonSerializer& serializer) override
{
serializer.beginArray("new_scales");
for (int i = 0; i < m_new_scales.size(); ++i)
{
serializer.serializeArrayItem(m_new_scales[i]);
}
serializer.endArray();
serializer.beginArray("entities");
for (int i = 0; i < m_entities.size(); ++i)
{
serializer.serializeArrayItem(m_entities[i]);
}
serializer.endArray();
}
void deserialize(JsonDeserializer& serializer) override
{
Universe* universe = m_editor.getUniverse();
serializer.deserializeArrayBegin("new_scales");
while (!serializer.isArrayEnd())
{
float scale;
serializer.deserializeArrayItem(scale, 1);
m_new_scales.push(scale);
}
serializer.deserializeArrayEnd();
serializer.deserializeArrayBegin("entities");
while (!serializer.isArrayEnd())
{
EntityPtr entity;
serializer.deserializeArrayItem(entity, INVALID_ENTITY);
m_entities.push(entity);
if (entity.isValid()) {
m_old_scales.push(universe->getScale((EntityRef)entity));
}
else {
m_old_scales.push(1);
}
}
serializer.deserializeArrayEnd();
}
bool execute() override
{
Universe* universe = m_editor.getUniverse();
@ -760,30 +598,6 @@ public:
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("inedx", m_index);
serializer.serialize("entity_index", m_component.entity);
serializer.serialize("component_type", Reflection::getComponentTypeHash(m_component.type));
serializer.serialize("property_name_hash", crc32(m_property->name));
}
void deserialize(JsonDeserializer& serializer) override
{
serializer.deserialize("inedx", m_index, 0);
serializer.deserialize("entity_index", m_component.entity, INVALID_ENTITY);
u32 hash;
serializer.deserialize("component_type", hash, 0);
m_component.type = Reflection::getComponentTypeFromHash(hash);
m_component.scene = m_editor.getUniverse()->getScene(m_component.type);
u32 property_name_hash;
serializer.deserialize("property_name_hash", property_name_hash, 0);
m_property =
static_cast<const Reflection::IArrayProperty*>(Reflection::getProperty(m_component.type, property_name_hash));
}
bool execute() override
{
m_property->removeItem(m_component, m_index);
@ -833,29 +647,6 @@ public:
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("inedx", m_index);
serializer.serialize("entity_index", m_component.entity);
serializer.serialize("component_type", Reflection::getComponentTypeHash(m_component.type));
serializer.serialize("property_name_hash", crc32(m_property->name));
}
void deserialize(JsonDeserializer& serializer) override
{
serializer.deserialize("inedx", m_index, 0);
serializer.deserialize("entity_index", m_component.entity, INVALID_ENTITY);
u32 hash;
serializer.deserialize("component_type", hash, 0);
m_component.type = Reflection::getComponentTypeFromHash(hash);
m_component.scene = m_editor.getUniverse()->getScene(m_component.type);
u32 property_name_hash;
serializer.deserialize("property_name_hash", property_name_hash, 0);
m_property = (const Reflection::IArrayProperty*)Reflection::getProperty(m_component.type, property_name_hash);
}
bool execute() override
{
m_property->addItem(m_component, -1);
@ -942,55 +733,6 @@ public:
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("index", m_index);
serializer.beginArray("entities");
for (EntityPtr entity : m_entities)
{
serializer.serializeArrayItem(entity);
}
serializer.endArray();
serializer.serialize("component_type", Reflection::getComponentTypeHash(m_component_type));
serializer.beginArray("data");
for (int i = 0; i < m_new_value.getPos(); ++i)
{
serializer.serializeArrayItem((int)((const u8*)m_new_value.getData())[i]);
}
serializer.endArray();
serializer.serialize("property_name_hash", crc32(m_property->name));
}
void deserialize(JsonDeserializer& serializer) override
{
serializer.deserialize("index", m_index, 0);
serializer.deserializeArrayBegin("entities");
while (!serializer.isArrayEnd())
{
EntityPtr entity;
serializer.deserializeArrayItem(entity, INVALID_ENTITY);
m_entities.push(entity);
}
serializer.deserializeArrayEnd();
u32 hash;
serializer.deserialize("component_type", hash, 0);
m_component_type = Reflection::getComponentTypeFromHash(hash);
serializer.deserializeArrayBegin("data");
m_new_value.clear();
while (!serializer.isArrayEnd())
{
int data;
serializer.deserializeArrayItem(data, 0);
m_new_value.write((u8)data);
}
serializer.deserializeArrayEnd();
u32 property_name_hash;
serializer.deserialize("property_name_hash", property_name_hash, 0);
m_property = Reflection::getProperty(m_component_type, property_name_hash);
}
bool execute() override
{
InputMemoryStream blob(m_new_value);
@ -1098,37 +840,6 @@ private:
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("component_type", Reflection::getComponentTypeHash(m_type));
serializer.beginArray("entities");
for (int i = 0; i < m_entities.size(); ++i)
{
serializer.serializeArrayItem(m_entities[i]);
}
serializer.endArray();
}
void deserialize(JsonDeserializer& serializer) override
{
u32 hash;
serializer.deserialize("component_type", hash, 0);
m_type = Reflection::getComponentTypeFromHash(hash);
m_entities.clear();
serializer.deserializeArrayBegin("entities");
while (!serializer.isArrayEnd())
{
EntityPtr e;
serializer.deserializeArrayItem(e, INVALID_ENTITY);
if (e.isValid()) {
m_entities.push((EntityRef)e);
}
}
serializer.deserializeArrayEnd();
}
bool merge(IEditorCommand&) override { return false; }
@ -1188,20 +899,6 @@ private:
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("parent", m_parent);
serializer.serialize("child", m_child);
}
void deserialize(JsonDeserializer& serializer) override
{
serializer.deserialize("parent", m_parent, INVALID_ENTITY);
serializer.deserialize("child", m_child, INVALID_ENTITY);
}
bool merge(IEditorCommand& cmd) override {
auto& c = (MakeParentCommand&)cmd;
@ -1291,60 +988,6 @@ private:
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("count", m_entities.size());
serializer.beginArray("entities");
for (int i = 0; i < m_entities.size(); ++i)
{
serializer.serializeArrayItem(m_entities[i]);
serializer.serializeArrayItem(m_transformations[i].pos.x);
serializer.serializeArrayItem(m_transformations[i].pos.y);
serializer.serializeArrayItem(m_transformations[i].pos.z);
serializer.serializeArrayItem(m_transformations[i].rot.x);
serializer.serializeArrayItem(m_transformations[i].rot.y);
serializer.serializeArrayItem(m_transformations[i].rot.z);
serializer.serializeArrayItem(m_transformations[i].rot.w);
serializer.serializeArrayItem(m_transformations[i].scale);
}
serializer.endArray();
}
void deserialize(JsonDeserializer& serializer) override
{
int count;
serializer.deserialize("count", count, 0);
serializer.deserializeArrayBegin("entities");
m_entities.reserve(count);
m_transformations.reserve(count);
for (int i = 0; i < count; ++i) {
EntityPtr e;
serializer.deserializeArrayItem(e, INVALID_ENTITY);
if(e.isValid()) {
m_entities.push((EntityRef)e);
Transform tr = m_transformations.emplace();
serializer.deserializeArrayItem(tr.pos.x, 0);
serializer.deserializeArrayItem(tr.pos.y, 0);
serializer.deserializeArrayItem(tr.pos.z, 0);
serializer.deserializeArrayItem(tr.rot.x, 0);
serializer.deserializeArrayItem(tr.rot.y, 0);
serializer.deserializeArrayItem(tr.rot.z, 0);
serializer.deserializeArrayItem(tr.rot.w, 1);
if (serializer.isArrayEnd())
{
tr.scale = 1;
}
else
{
serializer.deserializeArrayItem(tr.scale, 1);
}
}
}
serializer.deserializeArrayEnd();
}
bool execute() override
{
Universe* universe = m_editor.getUniverse();
@ -1536,37 +1179,6 @@ private:
}
void serialize(JsonSerializer& serializer) override
{
serializer.beginArray("entities");
for (EntityRef entity : m_entities)
{
serializer.serializeArrayItem(entity);
}
serializer.endArray();
serializer.serialize("component_type", Reflection::getComponentTypeHash(m_cmp_type));
}
void deserialize(JsonDeserializer& serializer) override
{
serializer.deserializeArrayBegin("entities");
while (!serializer.isArrayEnd())
{
EntityPtr entity;
serializer.deserializeArrayItem(entity, INVALID_ENTITY);
if(entity.isValid()) {
m_entities.push((EntityRef)entity);
}
}
serializer.deserializeArrayEnd();
u32 hash;
serializer.deserialize("component_type", hash, 0);
m_cmp_type = Reflection::getComponentTypeFromHash(hash);
}
void undo() override
{
ComponentUID cmp;
@ -1665,22 +1277,6 @@ private:
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("pos_x", m_position.x);
serializer.serialize("pos_y", m_position.y);
serializer.serialize("pos_z", m_position.z);
}
void deserialize(JsonDeserializer& serializer) override
{
serializer.deserialize("pos_x", m_position.x, 0);
serializer.deserialize("pos_y", m_position.y, 0);
serializer.deserialize("pos_z", m_position.z, 0);
}
void undo() override
{
if(m_entity.isValid()) {
@ -3534,34 +3130,6 @@ public:
}
void saveUndoStack(const Path& path) override
{
if (m_undo_stack.empty()) return;
OS::OutputFile file;
if (file.open(path.c_str()))
{
JsonSerializer serializer(file, path);
serializer.beginObject();
serializer.beginArray("commands");
for (int i = 0; i < m_undo_stack.size(); ++i)
{
serializer.beginObject();
serializer.serialize("undo_command_type", m_undo_stack[i]->getType());
m_undo_stack[i]->serialize(serializer);
serializer.endObject();
}
serializer.endArray();
serializer.endObject();
file.close();
}
else
{
logError("Editor") << "Could not save commands to " << path;
}
}
IEditorCommand* createEditorCommand(u32 command_type) override
{
int index = m_editor_command_creators.find(command_type);
@ -3579,46 +3147,6 @@ public:
}
bool executeUndoStack(const Path& path) override
{
destroyUndoStack();
m_undo_index = -1;
FileSystem& fs = m_engine->getFileSystem();
OS::InputFile file;
if (fs.open(path.c_str(), &file))
{
JsonDeserializer serializer(file, path, m_allocator);
serializer.deserializeObjectBegin();
serializer.deserializeArrayBegin("commands");
while (!serializer.isArrayEnd())
{
serializer.nextArrayItem();
serializer.deserializeObjectBegin();
char type_name[256];
serializer.deserialize("undo_command_type", type_name, lengthOf(type_name), "");
IEditorCommand* command = createEditorCommand(crc32(type_name));
if (!command)
{
logError("Editor") << "Unknown command " << type_name << " in " << path;
destroyUndoStack();
m_undo_index = -1;
file.close();
return false;
}
command->deserialize(serializer);
while (fs.hasWork()) fs.updateAsyncTransactions();
executeCommand(command);
serializer.deserializeObjectEnd();
}
serializer.deserializeArrayEnd();
serializer.deserializeObjectEnd();
file.close();
return true;
}
return false;
}
void setTopView() override
{
m_go_to_parameters.m_is_active = true;
@ -3678,88 +3206,6 @@ public:
}
bool runTest(const char* dir, const char* name) override
{
FileSystem& fs = m_engine->getFileSystem();
while (fs.hasWork()) fs.updateAsyncTransactions();
newUniverse();
Path undo_stack_path(dir, name, ".json");
executeUndoStack(undo_stack_path);
OutputMemoryStream blob0(m_allocator);
OutputMemoryStream blob1(m_allocator);
Universe& tpl_universe = m_engine->createUniverse(true);
PrefabSystem* prefab_system = PrefabSystem::create(*this);
EntityGUIDMap entity_guid_map(m_allocator);
bool is_same = deserialize(tpl_universe, "unit_tests/editor", name, *prefab_system, entity_guid_map, m_allocator);
if (!is_same) goto end;
if (getEntitiesCount(tpl_universe) != getEntitiesCount(*m_universe))
{
is_same = false;
goto end;
}
for (EntityPtr e_ptr = tpl_universe.getFirstEntity(); e_ptr.isValid(); e_ptr = tpl_universe.getNextEntity((EntityRef)e_ptr))
{
const EntityRef e = (EntityRef)e_ptr;
EntityGUID guid = entity_guid_map.get(e);
EntityPtr other_entity_ptr = m_entity_map.get(guid);
if (!other_entity_ptr.isValid())
{
is_same = false;
goto end;
}
EntityRef other_entity = (EntityRef)other_entity_ptr;
for (ComponentUID cmp = tpl_universe.getFirstComponent(e); cmp.isValid(); cmp = tpl_universe.getNextComponent(cmp))
{
if (!m_universe->hasComponent(other_entity, cmp.type))
{
is_same = false;
goto end;
}
ComponentUID other_cmp = m_universe->getComponent(other_entity, cmp.type);
const Reflection::ComponentBase* base = Reflection::getComponent(cmp.type);
struct : Reflection::ISimpleComponentVisitor
{
void visitProperty(const Reflection::PropertyBase& prop) override
{
blob0->clear();
blob1->clear();
prop.getValue(cmp, index, *blob0);
prop.getValue(other_cmp, index, *blob1);
if (blob0->getPos() != blob1->getPos()
|| compareMemory(blob0->getData(), blob1->getData(), blob0->getPos()) != 0)
{
*is_same = false;
}
}
int index = -1;
bool* is_same;
ComponentUID cmp;
ComponentUID other_cmp;
OutputMemoryStream* blob0;
OutputMemoryStream* blob1;
} visitor;
visitor.is_same = &is_same;
visitor.cmp = cmp;
visitor.other_cmp = other_cmp;
visitor.blob0 = &blob0;
visitor.blob1 = &blob1;
base->visit(visitor);
if (!is_same) goto end;
}
}
end:
m_engine->destroyUniverse(tpl_universe);
PrefabSystem::destroy(prefab_system);
return is_same;
}
private:
enum class MouseMode
{
@ -3867,43 +3313,6 @@ public:
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("pos_x", m_position.x);
serializer.serialize("pos_y", m_position.y);
serializer.serialize("pos_z", m_position.z);
serializer.serialize("identity", m_identity);
serializer.serialize("size", (int)m_copy_buffer.getPos());
serializer.beginArray("data");
for (int i = 0; i < m_copy_buffer.getPos(); ++i)
{
serializer.serializeArrayItem((i32)((const u8*)m_copy_buffer.getData())[i]);
}
serializer.endArray();
}
void deserialize(JsonDeserializer& serializer) override
{
serializer.deserialize("pos_x", m_position.x, 0);
serializer.deserialize("pos_y", m_position.y, 0);
serializer.deserialize("pos_z", m_position.z, 0);
serializer.deserialize("identity", m_identity, false);
int size;
serializer.deserialize("size", size, 0);
serializer.deserializeArrayBegin("data");
m_copy_buffer.clear();
m_copy_buffer.reserve(size);
for (int i = 0; i < size; ++i)
{
i32 data;
serializer.deserializeArrayItem(data, 0);
m_copy_buffer.write((u8)data);
}
serializer.deserializeArrayEnd();
}
bool execute() override
{
struct Map : ILoadEntityGUIDMap {

View file

@ -175,9 +175,6 @@ public:
virtual void makeRelative(char* relative, int max_size, const char* absolute) const = 0;
virtual void makeAbsolute(char* absolute, int max_size, const char* relative) const = 0;
virtual void saveUndoStack(const Path& path) = 0;
virtual bool executeUndoStack(const Path& path) = 0;
virtual bool runTest(const char* dir, const char* name) = 0;
virtual void registerEditorCommandCreator(const char* command_type, EditorCommandCreator) = 0;
virtual bool isGameMode() const = 0;
virtual void setMouseSensitivity(float x, float y) = 0;

View file

@ -1,946 +0,0 @@
#include "json_serializer.h"
#include "engine/allocator.h"
#include "engine/file_system.h"
#include "engine/log.h"
#include "engine/math.h"
#include "engine/path.h"
#include "engine/stream.h"
#include "engine/string.h"
#include <cstdlib>
namespace Lumix
{
void JsonDeserializer::logError(const char* msg)
{
m_is_error = true;
const char* c = m_data;
int line = 0;
int column = 0;
while (c < m_token)
{
if (*c == '\n')
{
++line;
column = 0;
}
++column;
++c;
}
Lumix::logError("serializer") << m_path << "(line " << (line + 1) << ", column " << column << "): " << msg;
}
struct ErrorProxy {
ErrorProxy(JsonDeserializer& deserializer)
: deserializer(deserializer)
, msg(deserializer.m_allocator)
{}
~ErrorProxy() {
deserializer.logError(msg.c_str());
}
String& log() { return msg; }
String msg;
JsonDeserializer& deserializer;
};
JsonSerializer::JsonSerializer(IOutputStream& file, const Path& path)
: m_file(file)
{
m_is_first_in_block = true;
}
JsonDeserializer::JsonDeserializer(IInputStream& file,
const Path& path,
IAllocator& allocator)
: m_file(file)
, m_allocator(allocator)
{
m_is_error = false;
copyString(m_path, path.c_str());
m_is_first_in_block = true;
m_data = nullptr;
m_is_string_token = false;
m_data_size = (int)file.size();
if (file.getBuffer() != nullptr)
{
m_data = (const char*)file.getBuffer();
m_own_data = false;
}
else
{
int size = (int)m_file.size();
char* data = (char*)m_allocator.allocate(size);
m_own_data = true;
file.read(data, m_data_size);
m_data = data;
}
m_token = m_data;
m_token_size = 0;
deserializeToken();
}
JsonDeserializer::~JsonDeserializer()
{
if (m_own_data) m_allocator.deallocate((void*)m_data);
}
#pragma region serialization
void JsonSerializer::serialize(const char* label, EntityPtr value)
{
serialize(label, value.index);
}
void JsonSerializer::serialize(const char* label, unsigned int value)
{
writeBlockComma();
char tmp[20];
writeString(label);
toCString(value, tmp, 20);
m_file.write(" : ", stringLength(" : "));
m_file.write(tmp, stringLength(tmp));
m_is_first_in_block = false;
}
void JsonSerializer::serialize(const char* label, u16 value)
{
writeBlockComma();
char tmp[20];
writeString(label);
toCString(value, tmp, 20);
m_file.write(" : ", stringLength(" : "));
m_file.write(tmp, stringLength(tmp));
m_is_first_in_block = false;
}
void JsonSerializer::serialize(const char* label, float value)
{
writeBlockComma();
char tmp[20];
writeString(label);
toCString(value, tmp, 20, 8);
m_file.write(" : ", stringLength(" : "));
m_file.write(tmp, stringLength(tmp));
m_is_first_in_block = false;
}
void JsonSerializer::serialize(const char* label, double value)
{
writeBlockComma();
char tmp[20];
writeString(label);
toCString(value, tmp, 40, 16);
m_file.write(" : ", stringLength(" : "));
m_file.write(tmp, stringLength(tmp));
m_is_first_in_block = false;
}
void JsonSerializer::serialize(const char* label, int value)
{
writeBlockComma();
char tmp[20];
writeString(label);
toCString(value, tmp, 20);
m_file.write(" : ", stringLength(" : "));
m_file.write(tmp, stringLength(tmp));
m_is_first_in_block = false;
}
void JsonSerializer::serialize(const char* label, const Path& value)
{
writeBlockComma();
writeString(label);
m_file.write(" : \"", 4);
m_file.write(value.c_str(), value.length());
m_file.write("\"", 1);
m_is_first_in_block = false;
}
void JsonSerializer::serialize(const char* label, const char* value)
{
writeBlockComma();
writeString(label);
m_file.write(" : \"", 4);
if (value == nullptr)
{
m_file.write("", 1);
}
else
{
m_file.write(value, stringLength(value));
}
m_file.write("\"", 1);
m_is_first_in_block = false;
}
void JsonSerializer::serialize(const char* label, bool value)
{
writeBlockComma();
writeString(label);
m_file.write(value ? " : true" : " : false", value ? 7 : 8);
m_is_first_in_block = false;
}
void JsonSerializer::beginObject()
{
writeBlockComma();
m_file.write("{", 1);
m_is_first_in_block = true;
}
void JsonSerializer::beginObject(const char* label)
{
writeBlockComma();
writeString(label);
m_file.write(" : {", 4);
m_is_first_in_block = true;
}
void JsonSerializer::endObject()
{
m_file.write("}", 1);
m_is_first_in_block = false;
}
void JsonSerializer::beginArray(const char* label)
{
writeBlockComma();
writeString(label);
m_file.write(" : [", 4);
m_is_first_in_block = true;
}
void JsonSerializer::beginArray()
{
writeBlockComma();
m_file.write("[", 1);
m_is_first_in_block = true;
}
void JsonSerializer::endArray()
{
m_file.write("]", 1);
m_is_first_in_block = false;
}
void JsonSerializer::serializeArrayItem(const char* value)
{
writeBlockComma();
writeString(value);
m_is_first_in_block = false;
}
/*void JsonSerializer::serializeArrayItem(string& value)
{
writeBlockComma();
writeString(value.c_str() ? value.c_str() : "");
m_is_first_in_block = false;
}*/
void JsonSerializer::serializeArrayItem(unsigned int value)
{
writeBlockComma();
char tmp[20];
toCString(value, tmp, 20);
m_file.write(tmp, stringLength(tmp));
m_is_first_in_block = false;
}
void JsonSerializer::serializeArrayItem(EntityPtr value)
{
serializeArrayItem(value.index);
}
void JsonSerializer::serializeArrayItem(int value)
{
writeBlockComma();
char tmp[20];
toCString(value, tmp, 20);
m_file.write(tmp, stringLength(tmp));
m_is_first_in_block = false;
}
void JsonSerializer::serializeArrayItem(i64 value)
{
writeBlockComma();
char tmp[30];
toCString(value, tmp, 30);
m_file.write(tmp, stringLength(tmp));
m_is_first_in_block = false;
}
void JsonSerializer::serializeArrayItem(float value)
{
writeBlockComma();
char tmp[20];
toCString(value, tmp, 20, 8);
m_file.write(tmp, stringLength(tmp));
m_is_first_in_block = false;
}
void JsonSerializer::serializeArrayItem(double value)
{
writeBlockComma();
char tmp[20];
toCString(value, tmp, 40, 16);
m_file.write(tmp, stringLength(tmp));
m_is_first_in_block = false;
}
void JsonSerializer::serializeArrayItem(bool value)
{
writeBlockComma();
m_file.write(value ? "true" : "false", value ? 4 : 5);
m_is_first_in_block = false;
}
#pragma endregion
#pragma region deserialization
bool JsonDeserializer::isNextBoolean() const
{
if (m_is_string_token) return false;
if (m_token_size == 4 && compareStringN(m_token, "true", 4) == 0) return true;
if (m_token_size == 5 && compareStringN(m_token, "false", 5) == 0) return true;
return false;
}
void JsonDeserializer::deserialize(const char* label, EntityPtr& value, EntityPtr default_value)
{
deserialize(label, value.index, default_value.index);
}
void JsonDeserializer::deserialize(bool& value, bool default_value)
{
value = !m_is_string_token ? m_token_size == 4 && (compareStringN(m_token, "true", 4) == 0)
: default_value;
deserializeToken();
}
void JsonDeserializer::deserialize(float& value, float default_value)
{
if (!m_is_string_token)
{
value = tokenToFloat();
}
else
{
value = default_value;
}
deserializeToken();
}
void JsonDeserializer::deserialize(double& value, double default_value)
{
if (!m_is_string_token)
{
value = tokenToDouble();
}
else
{
value = default_value;
}
deserializeToken();
}
void JsonDeserializer::deserialize(i32& value, i32 default_value)
{
if (m_is_string_token || !fromCString(m_token, m_token_size, &value))
{
value = default_value;
}
deserializeToken();
}
void JsonDeserializer::deserialize(const char* label, Path& value, const Path& default_value)
{
deserializeLabel(label);
if (!m_is_string_token)
{
value = default_value;
}
else
{
char tmp[MAX_PATH_LENGTH];
int size = minimum(lengthOf(tmp) - 1, m_token_size);
copyMemory(tmp, m_token, size);
tmp[size] = '\0';
value = tmp;
deserializeToken();
}
}
void JsonDeserializer::deserialize(Path& value, const Path& default_value)
{
if (!m_is_string_token)
{
value = default_value;
}
else
{
char tmp[MAX_PATH_LENGTH];
int size = minimum(lengthOf(tmp) - 1, m_token_size);
copyMemory(tmp, m_token, size);
tmp[size] = '\0';
value = tmp;
deserializeToken();
}
}
void JsonDeserializer::deserialize(char* value, int max_length, const char* default_value)
{
if (!m_is_string_token)
{
copyString(value, max_length, default_value);
}
else
{
int size = minimum(max_length - 1, m_token_size);
copyMemory(value, m_token, size);
value[size] = '\0';
deserializeToken();
}
}
void JsonDeserializer::deserialize(const char* label, float& value, float default_value)
{
deserializeLabel(label);
if (!m_is_string_token)
{
value = tokenToFloat();
deserializeToken();
}
else
{
value = default_value;
}
}
void JsonDeserializer::deserialize(const char* label, double& value, double default_value)
{
deserializeLabel(label);
if (!m_is_string_token)
{
value = tokenToDouble();
deserializeToken();
}
else
{
value = default_value;
}
}
void JsonDeserializer::deserialize(const char* label, u32& value, u32 default_value)
{
deserializeLabel(label);
if (m_is_string_token || !fromCString(m_token, m_token_size, &value))
{
value = default_value;
}
else
{
deserializeToken();
}
}
void JsonDeserializer::deserialize(const char* label, u16& value, u16 default_value)
{
deserializeLabel(label);
if (m_is_string_token || !fromCString(m_token, m_token_size, &value))
{
value = default_value;
}
else
{
deserializeToken();
}
}
bool JsonDeserializer::isObjectEnd()
{
if (m_token == m_data + m_data_size)
{
logError("Unexpected end of file while looking for the end of an object.");
return true;
}
return (!m_is_string_token && m_token_size == 1 && m_token[0] == '}');
}
void JsonDeserializer::deserialize(const char* label, i32& value, i32 default_value)
{
deserializeLabel(label);
if (m_is_string_token || !fromCString(m_token, m_token_size, &value))
{
value = default_value;
}
deserializeToken();
}
void JsonDeserializer::deserialize(const char* label,
char* value,
int max_length,
const char* default_value)
{
deserializeLabel(label);
if (!m_is_string_token)
{
copyString(value, max_length, default_value);
}
else
{
int size = minimum(max_length - 1, m_token_size);
copyMemory(value, m_token, size);
value[size] = '\0';
deserializeToken();
}
}
void JsonDeserializer::deserializeArrayBegin(const char* label)
{
deserializeLabel(label);
expectToken('[');
m_is_first_in_block = true;
deserializeToken();
}
void JsonDeserializer::expectToken(char expected_token)
{
if (m_is_string_token || m_token_size != 1 || m_token[0] != expected_token)
{
char tmp[2];
tmp[0] = expected_token;
tmp[1] = 0;
ErrorProxy(*this).log().cat("Unexpected token \"")
.cat(StringView(m_token, m_token_size))
.cat("\", expected ")
.cat(tmp)
.cat(".");
deserializeToken();
}
}
void JsonDeserializer::deserializeArrayBegin()
{
expectToken('[');
m_is_first_in_block = true;
deserializeToken();
}
void JsonDeserializer::deserializeRawString(char* buffer, int max_length)
{
int size = minimum(max_length - 1, m_token_size);
copyMemory(buffer, m_token, size);
buffer[size] = '\0';
deserializeToken();
}
void JsonDeserializer::nextArrayItem()
{
if (!m_is_first_in_block)
{
expectToken(',');
deserializeToken();
}
}
bool JsonDeserializer::isArrayEnd()
{
if (m_token == m_data + m_data_size)
{
logError("Unexpected end of file while looking for the end of an array.");
return true;
}
return (!m_is_string_token && m_token_size == 1 && m_token[0] == ']');
}
void JsonDeserializer::deserializeArrayEnd()
{
expectToken(']');
m_is_first_in_block = false;
deserializeToken();
}
void JsonDeserializer::deserializeArrayItem(char* value, int max_length, const char* default_value)
{
deserializeArrayComma();
if (m_is_string_token)
{
int size = minimum(max_length - 1, m_token_size);
copyMemory(value, m_token, size);
value[size] = '\0';
deserializeToken();
}
else
{
ErrorProxy(*this).log().cat("Unexpected token \"")
.cat(StringView(m_token, m_token_size))
.cat("\", expected string.");
deserializeToken();
copyString(value, max_length, default_value);
}
}
void JsonDeserializer::deserializeArrayItem(EntityPtr& value, EntityPtr default_value)
{
deserializeArrayItem(value.index, default_value.index);
}
void JsonDeserializer::deserializeArrayItem(u32& value, u32 default_value)
{
deserializeArrayComma();
if (m_is_string_token || !fromCString(m_token, m_token_size, &value))
{
value = default_value;
}
deserializeToken();
}
void JsonDeserializer::deserializeArrayItem(i32& value, i32 default_value)
{
deserializeArrayComma();
if (m_is_string_token || !fromCString(m_token, m_token_size, &value))
{
value = default_value;
}
deserializeToken();
}
void JsonDeserializer::deserializeArrayItem(i64& value, i64 default_value)
{
deserializeArrayComma();
if (m_is_string_token || !fromCString(m_token, m_token_size, &value))
{
value = default_value;
}
deserializeToken();
}
void JsonDeserializer::deserializeArrayItem(float& value, float default_value)
{
deserializeArrayComma();
if (m_is_string_token)
{
value = default_value;
}
else
{
value = tokenToFloat();
}
deserializeToken();
}
void JsonDeserializer::deserializeArrayItem(double& value, double default_value)
{
deserializeArrayComma();
if (m_is_string_token)
{
value = default_value;
}
else
{
value = tokenToDouble();
}
deserializeToken();
}
void JsonDeserializer::deserializeArrayItem(bool& value, bool default_value)
{
deserializeArrayComma();
if (m_is_string_token)
{
value = default_value;
}
else
{
value = m_token_size == 4 && compareStringN("true", m_token, m_token_size) == 0;
}
deserializeToken();
}
void JsonDeserializer::deserialize(const char* label, bool& value, bool default_value)
{
deserializeLabel(label);
if (!m_is_string_token)
{
value = m_token_size == 4 && compareStringN("true", m_token, 4) == 0;
}
else
{
value = default_value;
}
deserializeToken();
}
static bool isDelimiter(char c)
{
return c == '\t' || c == '\n' || c == ' ' || c == '\r';
}
void JsonDeserializer::deserializeArrayComma()
{
if (m_is_first_in_block)
{
m_is_first_in_block = false;
}
else
{
expectToken(',');
deserializeToken();
}
}
static bool isSingleCharToken(char c)
{
return c == ',' || c == '[' || c == ']' || c == '{' || c == '}' || c == ':';
}
void JsonDeserializer::deserializeToken()
{
m_token += m_token_size;
if (m_is_string_token)
{
++m_token;
}
while (m_token < m_data + m_data_size && isDelimiter(*m_token))
{
++m_token;
}
if (*m_token == '/' && m_token < m_data + m_data_size - 1 && m_token[1] == '/')
{
m_token_size = int((m_data + m_data_size) - m_token);
m_is_string_token = false;
}
else if (*m_token == '"')
{
++m_token;
m_is_string_token = true;
const char* token_end = m_token;
while (token_end < m_data + m_data_size && *token_end != '"')
{
++token_end;
}
if (token_end == m_data + m_data_size)
{
logError("Unexpected end of file while looking for \".");
m_token_size = 0;
}
else
{
m_token_size = int(token_end - m_token);
}
}
else if (isSingleCharToken(*m_token))
{
m_is_string_token = false;
m_token_size = 1;
}
else
{
m_is_string_token = false;
const char* token_end = m_token;
while (token_end < m_data + m_data_size && !isDelimiter(*token_end) &&
!isSingleCharToken(*token_end))
{
++token_end;
}
m_token_size = int(token_end - m_token);
}
}
void JsonDeserializer::deserializeObjectBegin()
{
m_is_first_in_block = true;
expectToken('{');
deserializeToken();
}
void JsonDeserializer::deserializeObjectEnd()
{
expectToken('}');
m_is_first_in_block = false;
deserializeToken();
}
void JsonDeserializer::deserializeLabel(char* label, int max_length)
{
if (!m_is_first_in_block)
{
expectToken(',');
deserializeToken();
}
else
{
m_is_first_in_block = false;
}
if (!m_is_string_token)
{
ErrorProxy(*this).log() .cat("Unexpected token \"")
.cat(StringView(m_token, m_token_size))
.cat("\", expected string.");
deserializeToken();
}
copyNString(label, max_length, m_token, m_token_size);
deserializeToken();
expectToken(':');
deserializeToken();
}
void JsonSerializer::writeString(const char* str)
{
m_file.write("\"", 1);
if (str)
{
m_file.write(str, stringLength(str));
}
m_file.write("\"", 1);
}
void JsonSerializer::writeBlockComma()
{
if (!m_is_first_in_block)
{
m_file.write(",\n", 2);
}
}
void JsonDeserializer::deserializeLabel(const char* label)
{
if (!m_is_first_in_block)
{
expectToken(',');
deserializeToken();
}
else
{
m_is_first_in_block = false;
}
if (!m_is_string_token)
{
ErrorProxy(*this).log().cat("Unexpected token \"")
.cat(StringView(m_token, m_token_size))
.cat("\", expected string.");
deserializeToken();
}
if (compareStringN(label, m_token, m_token_size) != 0)
{
ErrorProxy(*this).log().cat("Unexpected label \"")
.cat(StringView(m_token, m_token_size))
.cat("\", expected \"")
.cat(label)
.cat("\".");
deserializeToken();
}
deserializeToken();
if (m_is_string_token || m_token_size != 1 || m_token[0] != ':')
{
ErrorProxy(*this).log().cat("Unexpected label \"")
.cat(StringView(m_token, m_token_size))
.cat("\", expected \"")
.cat(label)
.cat("\".");
deserializeToken();
}
deserializeToken();
}
#pragma endregion
float JsonDeserializer::tokenToFloat()
{
char tmp[64];
int size = minimum((int)sizeof(tmp) - 1, m_token_size);
copyMemory(tmp, m_token, size);
tmp[size] = '\0';
return (float)atof(tmp);
}
float JsonDeserializer::tokenToDouble()
{
char tmp[64];
int size = minimum((int)sizeof(tmp) - 1, m_token_size);
copyMemory(tmp, m_token, size);
tmp[size] = '\0';
return (float)atof(tmp);
}
} // namespace Lumix

View file

@ -1,131 +0,0 @@
#pragma once
#include "engine/lumix.h"
namespace Lumix
{
struct IAllocator;
struct IInputStream;
struct IOutputStream;
class Path;
class LUMIX_ENGINE_API JsonSerializer
{
public:
JsonSerializer(IOutputStream& file, const Path& path);
void operator=(const JsonSerializer&) = delete;
JsonSerializer(const JsonSerializer&) = delete;
void serialize(const char* label, EntityPtr value);
void serialize(const char* label, u32 value);
void serialize(const char* label, u16 value);
void serialize(const char* label, float value);
void serialize(const char* label, double value);
void serialize(const char* label, i32 value);
void serialize(const char* label, const char* value);
void serialize(const char* label, const Path& value);
void serialize(const char* label, bool value);
void beginObject();
void beginObject(const char* label);
void endObject();
void beginArray();
void beginArray(const char* label);
void endArray();
void serializeArrayItem(EntityPtr value);
void serializeArrayItem(u32 value);
void serializeArrayItem(i32 value);
void serializeArrayItem(i64 value);
void serializeArrayItem(float value);
void serializeArrayItem(double value);
void serializeArrayItem(bool value);
void serializeArrayItem(const char* value);
private:
float tokenToFloat();
float tokenToDouble();
void writeString(const char* str);
void writeBlockComma();
private:
bool m_is_first_in_block;
IOutputStream& m_file;
};
class LUMIX_ENGINE_API JsonDeserializer
{
friend struct ErrorProxy;
public:
JsonDeserializer(IInputStream& file, const Path& path, IAllocator& allocator);
void operator=(const JsonDeserializer&) = delete;
JsonDeserializer(const JsonDeserializer&) = delete;
~JsonDeserializer();
void deserialize(const char* label, EntityPtr& value, EntityPtr default_value);
void deserialize(const char* label, u32& value, u32 default_value);
void deserialize(const char* label, u16& value, u16 default_value);
void deserialize(const char* label, float& value, float default_value);
void deserialize(const char* label, double& value, double default_value);
void deserialize(const char* label, i32& value, i32 default_value);
void deserialize(const char* label, char* value, int max_length, const char* default_value);
void deserialize(const char* label, Path& value, const Path& default_value);
void deserialize(const char* label, bool& value, bool default_value);
void deserialize(char* value, int max_length, const char* default_value);
void deserialize(Path& path, const Path& default_value);
void deserialize(bool& value, bool default_value);
void deserialize(float& value, float default_value);
void deserialize(double& value, double default_value);
void deserialize(i32& value, i32 default_value);
void deserializeArrayBegin(const char* label);
void deserializeArrayBegin();
void deserializeArrayEnd();
bool isArrayEnd();
void deserializeArrayItem(EntityPtr& value, EntityPtr default_value);
void deserializeArrayItem(u32& value, u32 default_value);
void deserializeArrayItem(i32& value, i32 default_value);
void deserializeArrayItem(i64& value, i64 default_value);
void deserializeArrayItem(float& value, float default_value);
void deserializeArrayItem(double& value, double default_value);
void deserializeArrayItem(bool& value, bool default_value);
void deserializeArrayItem(char* value, int max_length, const char* default_value);
void deserializeObjectBegin();
void deserializeObjectEnd();
void deserializeLabel(char* label, int max_length);
void deserializeRawString(char* buffer, int max_length);
void nextArrayItem();
bool isNextBoolean() const;
bool isObjectEnd();
bool isError() const { return m_is_error; }
private:
void deserializeLabel(const char* label);
void deserializeToken();
void deserializeArrayComma();
float tokenToFloat();
float tokenToDouble();
void expectToken(char expected_token);
void logError(const char* msg);
private:
bool m_is_first_in_block;
IInputStream& m_file;
const char* m_token;
int m_token_size;
bool m_is_string_token;
char m_path[MAX_PATH_LENGTH];
IAllocator& m_allocator;
const char* m_data;
int m_data_size;
bool m_own_data;
bool m_is_error;
};
} // namespace Lumix

View file

@ -10,7 +10,6 @@ namespace Lumix
class Engine;
class InputMemoryStream;
struct IPlugin;
class JsonSerializer;
class OutputMemoryStream;
class Universe;
template <typename T> class Array;

View file

@ -6,13 +6,13 @@
#include "engine/crc32.h"
#include "engine/engine.h"
#include "engine/geometry.h"
#include "engine/json_serializer.h"
#include "engine/log.h"
#include "engine/math.h"
#include "engine/os.h"
#include "engine/path.h"
#include "engine/plugin_manager.h"
#include "engine/reflection.h"
#include "engine/serializer.h"
#include "engine/universe/universe.h"
#include "gui/gui_scene.h"
#include "gui/sprite.h"
@ -181,9 +181,12 @@ struct SpritePlugin final : public AssetBrowser::IPlugin
void saveSprite(Sprite& sprite)
{
if (IOutputStream* file = app.getAssetBrowser().beginSaveResource(sprite))
if (OutputMemoryStream* file = app.getAssetBrowser().beginSaveResource(sprite))
{
JsonSerializer serializer(*file, sprite.getPath());
struct : ISaveEntityGUIDMap {
EntityGUID get(EntityPtr entity) override { return INVALID_ENTITY_GUID; }
} dummy_map;
TextSerializer serializer(*file, dummy_map);
bool success = true;
if (!sprite.save(serializer))
{

View file

@ -1,7 +1,7 @@
#include "sprite.h"
#include "engine/json_serializer.h"
#include "engine/log.h"
#include "engine/resource_manager.h"
#include "engine/serializer.h"
#include "engine/stream.h"
#include "renderer/texture.h"
@ -47,18 +47,16 @@ void Sprite::setTexture(const Path& path)
}
bool Sprite::save(JsonSerializer& serializer)
bool Sprite::save(TextSerializer& serializer)
{
if (!isReady()) return false;
serializer.beginObject();
serializer.serialize("type", type == PATCH9 ? "patch9" : "simple");
serializer.serialize("top", top);
serializer.serialize("bottom", bottom);
serializer.serialize("left", left);
serializer.serialize("right", right);
serializer.serialize("texture", m_texture ? m_texture->getPath().c_str() : "");
serializer.endObject();
serializer.write("type", type == PATCH9 ? "patch9" : "simple");
serializer.write("top", top);
serializer.write("bottom", bottom);
serializer.write("left", left);
serializer.write("right", right);
serializer.write("texture", m_texture ? m_texture->getPath().c_str() : "");
return true;
}
@ -67,45 +65,20 @@ bool Sprite::save(JsonSerializer& serializer)
bool Sprite::load(u64 size, const u8* mem)
{
InputMemoryStream file(mem, size);
JsonDeserializer serializer(file, getPath(), m_allocator);
serializer.deserializeObjectBegin();
while (!serializer.isObjectEnd())
{
char tmp[32];
serializer.deserializeLabel(tmp, lengthOf(tmp));
if (equalIStrings(tmp, "type"))
{
serializer.deserialize(tmp, lengthOf(tmp), "");
type = equalIStrings(tmp, "patch9") ? PATCH9 : SIMPLE;
}
else if (equalIStrings(tmp, "top"))
{
serializer.deserialize(top, 0);
}
else if (equalIStrings(tmp, "bottom"))
{
serializer.deserialize(bottom, 0);
}
else if (equalIStrings(tmp, "left"))
{
serializer.deserialize(left, 0);
}
else if (equalIStrings(tmp, "right"))
{
serializer.deserialize(right, 0);
}
else if (equalIStrings(tmp, "texture"))
{
char texture_path[MAX_PATH_LENGTH];
serializer.deserialize(texture_path, lengthOf(texture_path), "");
ResourceManagerHub& mng = m_resource_manager.getOwner();
m_texture = texture_path[0] != '\0' ? mng.load<Texture>(Path(texture_path)) : nullptr;
}
else
{
logError("gui") << "Unknown label " << tmp << " in " << getPath();
}
}
struct : ILoadEntityGUIDMap {
EntityPtr get(EntityGUID guid) override { ASSERT(false); return INVALID_ENTITY; }
} dummy_map;
TextDeserializer serializer(file, dummy_map);
char tmp[MAX_PATH_LENGTH];
serializer.read(tmp, lengthOf(tmp));
type = equalStrings(tmp, "simple") ? SIMPLE : PATCH9;
serializer.read(&top);
serializer.read(&bottom);
serializer.read(&left);
serializer.read(&right);
serializer.read(tmp, lengthOf(tmp));
ResourceManagerHub& mng = m_resource_manager.getOwner();
m_texture = tmp[0] != '\0' ? mng.load<Texture>(Path(tmp)) : nullptr;
return true;
}

View file

@ -8,8 +8,8 @@ namespace Lumix
{
class JsonSerializer;
class Renderer;
struct TextSerializer;
class Texture;
@ -28,7 +28,7 @@ public:
void unload() override;
bool load(u64 size, const u8* mem) override;
bool save(JsonSerializer& serializer);
bool save(TextSerializer& serializer);
void setTexture(const Path& path);
Texture* getTexture() const { return m_texture; }

View file

@ -11,7 +11,6 @@
#include "engine/engine.h"
#include "engine/file_system.h"
#include "engine/allocator.h"
#include "engine/json_serializer.h"
#include "engine/log.h"
#include "engine/lua_wrapper.h"
#include "engine/os.h"
@ -60,15 +59,6 @@ struct PropertyGridPlugin final : public PropertyGrid::IPlugin
}
void serialize(JsonSerializer& serializer) override { serializer.serialize("entity", entity); }
void deserialize(JsonDeserializer& serializer) override
{
serializer.deserialize("entity", entity, INVALID_ENTITY);
}
const char* getType() override { return "add_script"; }
@ -116,22 +106,6 @@ struct PropertyGridPlugin final : public PropertyGrid::IPlugin
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("entity", entity);
serializer.serialize("scr_index", scr_index);
serializer.serialize("up", up);
}
void deserialize(JsonDeserializer& serializer) override
{
serializer.deserialize("entity", entity, INVALID_ENTITY);
serializer.deserialize("scr_index", scr_index, 0);
serializer.deserialize("up", up, false);
}
const char* getType() override { return "move_script"; }
@ -186,20 +160,6 @@ struct PropertyGridPlugin final : public PropertyGrid::IPlugin
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("entity", entity);
serializer.serialize("scr_index", scr_index);
}
void deserialize(JsonDeserializer& serializer) override
{
serializer.deserialize("entity", entity, INVALID_ENTITY);
serializer.deserialize("scr_index", scr_index, 0);
}
const char* getType() override { return "remove_script"; }
@ -283,30 +243,6 @@ struct PropertyGridPlugin final : public PropertyGrid::IPlugin
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("entity", entity);
serializer.serialize("script_index", script_index);
serializer.serialize("property_name", property_name.c_str());
serializer.serialize("value", value.c_str());
serializer.serialize("old_value", old_value.c_str());
}
void deserialize(JsonDeserializer& serializer) override
{
serializer.deserialize("entity", entity, INVALID_ENTITY);
serializer.deserialize("script_index", script_index, 0);
char buf[256];
serializer.deserialize("property_name", buf, lengthOf(buf), "");
property_name = buf;
serializer.deserialize("value", buf, lengthOf(buf), "");
value = buf;
serializer.deserialize("old_value", buf, lengthOf(buf), "");
old_value = buf;
}
const char* getType() override { return "set_script_property"; }

View file

@ -11,7 +11,6 @@
#include "engine/file_system.h"
#include "engine/geometry.h"
#include "engine/job_system.h"
#include "engine/json_serializer.h"
#include "engine/log.h"
#include "engine/lua_wrapper.h"
#include "engine/lumix.h"
@ -214,7 +213,7 @@ struct MaterialPlugin final : AssetBrowser::IPlugin, AssetCompiler::IPlugin
void saveMaterial(Material* material)
{
if (IOutputStream* file = m_app.getAssetBrowser().beginSaveResource(*material)) {
if (OutputMemoryStream* file = m_app.getAssetBrowser().beginSaveResource(*material)) {
bool success = true;
if (!material->save(*file))
{

View file

@ -7,7 +7,6 @@
#include "engine/crc32.h"
#include "engine/engine.h"
#include "engine/geometry.h"
#include "engine/json_serializer.h"
#include "engine/log.h"
#include "engine/os.h"
#include "engine/path_utils.h"
@ -16,6 +15,7 @@
#include "engine/profiler.h"
#include "engine/reflection.h"
#include "engine/resource_manager.h"
#include "engine/serializer.h"
#include "engine/universe/universe.h"
#include "imgui/imgui.h"
#include "physics/physics_scene.h"
@ -108,68 +108,6 @@ struct PaintTerrainCommand final : public IEditorCommand
}
void serialize(JsonSerializer& serializer) override
{
serializer.serialize("type", (int)m_action_type);
serializer.serialize("texture_idx", m_texture_idx);
serializer.serialize("grass_mask", m_grass_mask);
serializer.beginArray("items");
for (int i = 0; i < m_items.size(); ++i)
{
serializer.serializeArrayItem(m_items[i].m_amount);
serializer.serializeArrayItem(m_items[i].m_local_pos.x);
serializer.serializeArrayItem(m_items[i].m_local_pos.z);
serializer.serializeArrayItem(m_items[i].m_radius);
serializer.serializeArrayItem(m_items[i].m_color.x);
serializer.serializeArrayItem(m_items[i].m_color.y);
serializer.serializeArrayItem(m_items[i].m_color.z);
}
serializer.endArray();
serializer.beginArray("mask");
for (int i = 0; i < m_mask.size(); ++i)
{
serializer.serializeArrayItem((bool)m_mask[i]);
}
serializer.endArray();
}
void deserialize(JsonDeserializer& serializer) override
{
m_items.clear();
int action_type;
serializer.deserialize("type", action_type, 0);
m_action_type = (TerrainEditor::ActionType)action_type;
serializer.deserialize("texture_idx", m_texture_idx, 0);
serializer.deserialize("grass_mask", m_grass_mask, 0);
serializer.deserializeArrayBegin("items");
while (!serializer.isArrayEnd())
{
Item& item = m_items.emplace();
serializer.deserializeArrayItem(item.m_amount, 0);
serializer.deserializeArrayItem(item.m_local_pos.x, 0);
serializer.deserializeArrayItem(item.m_local_pos.z, 0);
serializer.deserializeArrayItem(item.m_radius, 0);
serializer.deserializeArrayItem(item.m_color.x, 0);
serializer.deserializeArrayItem(item.m_color.y, 0);
serializer.deserializeArrayItem(item.m_color.z, 0);
}
serializer.deserializeArrayEnd();
serializer.deserializeArrayBegin("mask");
m_mask.clear();
int i = 0;
while (!serializer.isArrayEnd())
{
bool b;
serializer.deserialize(b, true);
m_mask[i] = b;
++i;
}
serializer.deserializeArrayEnd();
}
bool execute() override
{
if (m_new_data.empty())