From 6614ea639414caab546091841bf920fe6459cc9e Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Mon, 2 Sep 2019 18:23:09 -0400 Subject: json entity saving: cout --- src/components/Component.hpp | 16 +++++++++++++++- src/components/Light.hpp | 10 +++++++++- src/components/Name.hpp | 10 +++++++++- src/components/Player.hpp | 7 ++++++- src/components/Position.hpp | 10 +++++++++- src/components/Render.hpp | 14 +++++++++++--- src/components/Script.hpp | 5 ++++- src/components/Velocity.hpp | 10 +++++++++- src/engine.cpp | 10 ++++++++++ 9 files changed, 82 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/components/Component.hpp b/src/components/Component.hpp index 5a062bd..2928366 100644 --- a/src/components/Component.hpp +++ b/src/components/Component.hpp @@ -18,13 +18,27 @@ #ifndef COMPONENT_HPP_ #define COMPONENT_HPP_ +#include +#include + +#include #include template -class Component +class Component : public entityx::Component { public: virtual T FromLua(sol::object) = 0; + + virtual void serialize(cereal::JSONOutputArchive& ar) = 0; + virtual void serialize(cereal::JSONInputArchive& ar) = 0; + + void internal_serialize(bool save, void *ar) final { + if (save) + serialize(*reinterpret_cast(ar)); + else + serialize(*reinterpret_cast(ar)); + } }; #endif // COMPONENT_HPP_ diff --git a/src/components/Light.hpp b/src/components/Light.hpp index ee215a6..2cb0e1b 100644 --- a/src/components/Light.hpp +++ b/src/components/Light.hpp @@ -22,7 +22,7 @@ #include "Component.hpp" -struct Light : Component, entityx::Component +struct Light : Component { public: float r, g, b; @@ -49,6 +49,14 @@ public: } return *this; } + + void serialize(cereal::JSONOutputArchive& ar) final { + ar(r, g, b, strength); + } + + void serialize(cereal::JSONInputArchive& ar) final { + ar(r, g, b, strength); + } }; #endif//COMPONENT_LIGHT_HPP_ diff --git a/src/components/Name.hpp b/src/components/Name.hpp index 94b7531..b42ef46 100644 --- a/src/components/Name.hpp +++ b/src/components/Name.hpp @@ -21,7 +21,7 @@ #include "Component.hpp" #include -struct Name : Component, entityx::Component +struct Name : Component { public: std::string name; @@ -38,6 +38,14 @@ public: return *this; } + + void serialize(cereal::JSONOutputArchive& ar) final { + ar(name); + } + + void serialize(cereal::JSONInputArchive& ar) final { + ar(name); + } }; #endif // COMPONENT_NAME_HPP_ diff --git a/src/components/Player.hpp b/src/components/Player.hpp index 5c1e870..95b2a96 100644 --- a/src/components/Player.hpp +++ b/src/components/Player.hpp @@ -23,13 +23,18 @@ #include "Component.hpp" -struct Player : Component, entityx::Component +struct Player : Component { public: + char _unused; + Player FromLua([[maybe_unused]] sol::object ref) { return *this; } + + void serialize([[maybe_unused]] cereal::JSONOutputArchive& ar) final {} + void serialize([[maybe_unused]] cereal::JSONInputArchive& ar) final {} }; #endif // COMPONENT_PLAYER_HPP_ diff --git a/src/components/Position.hpp b/src/components/Position.hpp index c801998..6157265 100644 --- a/src/components/Position.hpp +++ b/src/components/Position.hpp @@ -21,7 +21,7 @@ #include "Component.hpp" -struct Position : Component, entityx::Component +struct Position : Component { public: double x, y; @@ -42,6 +42,14 @@ public: } return *this; } + + void serialize(cereal::JSONOutputArchive& ar) final { + ar(x, y); + } + + void serialize(cereal::JSONInputArchive& ar) final { + ar(x, y); + } }; #endif // COMPONENT_POSITION_HPP_ diff --git a/src/components/Render.hpp b/src/components/Render.hpp index 3f1750f..49a9588 100644 --- a/src/components/Render.hpp +++ b/src/components/Render.hpp @@ -21,7 +21,7 @@ #include "Component.hpp" #include "texture.hpp" -struct Render : Component, entityx::Component +struct Render : Component { public: Texture texture; @@ -41,9 +41,9 @@ public: if (tab["visible"].get_type() == sol::type::boolean) this->visible = tab["visible"]; if (tab["texture"].get_type() == sol::type::string) - this->texture = Texture(static_cast(tab["texture"])); + this->texture = Texture(tab.get("texture")); if (tab["normal"].get_type() == sol::type::string) - this->normal = Texture(static_cast(tab["normal"])); + this->normal = Texture(tab.get("normal")); if (tab["flipx"].get_type() == sol::type::boolean) this->flipX = tab["flipx"]; } else { @@ -53,6 +53,14 @@ public: } return *this; } + + void serialize(cereal::JSONOutputArchive& ar) final { + ar(visible, flipX); + } + + void serialize(cereal::JSONInputArchive& ar) final { + ar(visible, flipX); + } }; #endif // COMPONENT_RENDER_HPP_ diff --git a/src/components/Script.hpp b/src/components/Script.hpp index b3c89f3..178c933 100644 --- a/src/components/Script.hpp +++ b/src/components/Script.hpp @@ -21,7 +21,7 @@ #include "Component.hpp" -struct Scripted : Component, entityx::Component +struct Scripted : Component { public: sol::table caller; @@ -60,6 +60,9 @@ public: if (caller["RenderIdle"] == sol::type::function) caller["RenderIdle"](caller); } + + void serialize([[maybe_unused]] cereal::JSONOutputArchive& ar) final {} + void serialize([[maybe_unused]] cereal::JSONInputArchive& ar) final {} }; #endif // COMPONENT_SCRIPT_HPP_ diff --git a/src/components/Velocity.hpp b/src/components/Velocity.hpp index 29c0e5c..7a75706 100644 --- a/src/components/Velocity.hpp +++ b/src/components/Velocity.hpp @@ -22,7 +22,7 @@ #include "Component.hpp" -struct Velocity : Component, entityx::Component +struct Velocity : Component { public: double x, y; @@ -43,6 +43,14 @@ public: } return *this; } + + void serialize(cereal::JSONOutputArchive& ar) final { + ar(x, y); + } + + void serialize(cereal::JSONInputArchive& ar) final { + ar(x, y); + } }; #endif // COMPONENT_VELOCITY_HPP_ diff --git a/src/engine.cpp b/src/engine.cpp index 61d119a..db31b9d 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -116,6 +116,16 @@ void Engine::run(void) // Done, bring logic thread back logicThread.join(); + + cereal::JSONOutputArchive archive (std::cout); + std::string name ("entity"); + int i = 0; + for (entityx::Entity e : entities.entities_for_debugging()) { + archive.setNextName((name + std::to_string(i++)).c_str()); + archive.startNode(); + entities.entity_serialize(e, true, archive); + archive.finishNode(); + } } bool Engine::shouldRun(void) -- cgit v1.2.3 From aa7b0a92d065b4435467d482ec65dd97b03459ee Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Mon, 2 Sep 2019 18:53:21 -0400 Subject: made json names readable --- lib/entityx/entityx/Entity.h | 8 ++++++-- src/components/Light.hpp | 8 ++++++-- src/components/Name.hpp | 8 ++++++-- src/components/Player.hpp | 4 ++++ src/components/Position.hpp | 8 ++++++-- src/components/Render.hpp | 8 ++++++-- src/components/Script.hpp | 4 ++++ src/components/Velocity.hpp | 8 ++++++-- src/engine.cpp | 1 + 9 files changed, 45 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/lib/entityx/entityx/Entity.h b/lib/entityx/entityx/Entity.h index 193d581..27a8820 100644 --- a/lib/entityx/entityx/Entity.h +++ b/lib/entityx/entityx/Entity.h @@ -243,6 +243,7 @@ struct BaseComponent { void operator delete[]([[maybe_unused]] void *p) { fail(); } virtual void internal_serialize(bool save, void *ar) = 0; + virtual std::string serializeName(void) const = 0; protected: static void fail() { @@ -757,8 +758,11 @@ class EntityManager : entityx::help::NonCopyable { for (size_t i = 0; i < component_helpers_.size(); i++) { BaseComponentHelper *helper = component_helpers_[i]; if (helper && mask.test(i)) { - helper->get_component(entity)->internal_serialize(save, - static_cast(&ar)); + auto* c = helper->get_component(entity); + ar.setNextName(c->serializeName().c_str()); + ar.startNode(); + c->internal_serialize(save, static_cast(&ar)); + ar.finishNode(); } } } diff --git a/src/components/Light.hpp b/src/components/Light.hpp index 2cb0e1b..6849d7c 100644 --- a/src/components/Light.hpp +++ b/src/components/Light.hpp @@ -51,11 +51,15 @@ public: } void serialize(cereal::JSONOutputArchive& ar) final { - ar(r, g, b, strength); + ar(CEREAL_NVP(r), CEREAL_NVP(g), CEREAL_NVP(b), CEREAL_NVP(strength)); } void serialize(cereal::JSONInputArchive& ar) final { - ar(r, g, b, strength); + ar(CEREAL_NVP(r), CEREAL_NVP(g), CEREAL_NVP(b), CEREAL_NVP(strength)); + } + + std::string serializeName(void) const final { + return "Light"; } }; diff --git a/src/components/Name.hpp b/src/components/Name.hpp index b42ef46..a6a6d8a 100644 --- a/src/components/Name.hpp +++ b/src/components/Name.hpp @@ -40,11 +40,15 @@ public: } void serialize(cereal::JSONOutputArchive& ar) final { - ar(name); + ar(CEREAL_NVP(name)); } void serialize(cereal::JSONInputArchive& ar) final { - ar(name); + ar(CEREAL_NVP(name)); + } + + std::string serializeName(void) const final { + return "Name"; } }; diff --git a/src/components/Player.hpp b/src/components/Player.hpp index 95b2a96..33db1eb 100644 --- a/src/components/Player.hpp +++ b/src/components/Player.hpp @@ -35,6 +35,10 @@ public: void serialize([[maybe_unused]] cereal::JSONOutputArchive& ar) final {} void serialize([[maybe_unused]] cereal::JSONInputArchive& ar) final {} + + std::string serializeName(void) const final { + return "Player"; + } }; #endif // COMPONENT_PLAYER_HPP_ diff --git a/src/components/Position.hpp b/src/components/Position.hpp index 6157265..56e8707 100644 --- a/src/components/Position.hpp +++ b/src/components/Position.hpp @@ -44,11 +44,15 @@ public: } void serialize(cereal::JSONOutputArchive& ar) final { - ar(x, y); + ar(CEREAL_NVP(x), CEREAL_NVP(y)); } void serialize(cereal::JSONInputArchive& ar) final { - ar(x, y); + ar(CEREAL_NVP(x), CEREAL_NVP(y)); + } + + std::string serializeName(void) const final { + return "Position"; } }; diff --git a/src/components/Render.hpp b/src/components/Render.hpp index 49a9588..81ca591 100644 --- a/src/components/Render.hpp +++ b/src/components/Render.hpp @@ -55,11 +55,15 @@ public: } void serialize(cereal::JSONOutputArchive& ar) final { - ar(visible, flipX); + ar(CEREAL_NVP(visible), CEREAL_NVP(flipX)); } void serialize(cereal::JSONInputArchive& ar) final { - ar(visible, flipX); + ar(CEREAL_NVP(visible), CEREAL_NVP(flipX)); + } + + std::string serializeName(void) const final { + return "Render"; } }; diff --git a/src/components/Script.hpp b/src/components/Script.hpp index 178c933..f792750 100644 --- a/src/components/Script.hpp +++ b/src/components/Script.hpp @@ -63,6 +63,10 @@ public: void serialize([[maybe_unused]] cereal::JSONOutputArchive& ar) final {} void serialize([[maybe_unused]] cereal::JSONInputArchive& ar) final {} + + std::string serializeName(void) const final { + return "Scripted"; + } }; #endif // COMPONENT_SCRIPT_HPP_ diff --git a/src/components/Velocity.hpp b/src/components/Velocity.hpp index 7a75706..776c1dd 100644 --- a/src/components/Velocity.hpp +++ b/src/components/Velocity.hpp @@ -45,11 +45,15 @@ public: } void serialize(cereal::JSONOutputArchive& ar) final { - ar(x, y); + ar(CEREAL_NVP(x), CEREAL_NVP(y)); } void serialize(cereal::JSONInputArchive& ar) final { - ar(x, y); + ar(CEREAL_NVP(x), CEREAL_NVP(y)); + } + + std::string serializeName(void) const final { + return "Velocity"; } }; diff --git a/src/engine.cpp b/src/engine.cpp index db31b9d..539515c 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -126,6 +126,7 @@ void Engine::run(void) entities.entity_serialize(e, true, archive); archive.finishNode(); } + std::cout << std::endl; } bool Engine::shouldRun(void) -- cgit v1.2.3 From 9c9f72c29a71a1813e9bc42d57998676237b57e3 Mon Sep 17 00:00:00 2001 From: Andy Belle-Isle Date: Tue, 3 Sep 2019 02:22:39 -0400 Subject: Start working on Lua function serialization --- Scripts/init.lua | 39 ++++++++++++++++++++++++++++++++++++++- src/script.cpp | 4 +++- 2 files changed, 41 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/Scripts/init.lua b/Scripts/init.lua index 4a874b2..6d225f5 100644 --- a/Scripts/init.lua +++ b/Scripts/init.lua @@ -86,7 +86,10 @@ animal = { self.Velocity.y = 500 * math.cos(math.rad(self.counter*5)); self.counter = self.counter + 5; end, - counter = 0; + counter = 0, + TestMe = function(self) + print("Light: rgb("..self.Light.r..","..self.Light.g..","..self.Light.b..")") + end } wall = { @@ -126,3 +129,37 @@ game.spawn({ self.counter = self.counter + 5; end }); + +------------------- +-- SERIALIZING -- +------------------- + +function serial (before_ser) + binary = string.dump(before_ser) + formatted_binary = "" + for i = 1, string.len(binary) do + dec, _ = ("\\%3d"):format(binary:sub(i, i):byte()):gsub(' ', '0') + formatted_binary = formatted_binary .. dec + end + return formatted_binary +end + +function hello(herro) + print("Hello world ".. herro) +end + +--print(serial(hello)) + +local ser = string.dump(hello) +f2 = (loadstring or load)(ser) +f2("shite") + +local testPut = string.dump(animalSpawn.TestMe) +testRun = (loadstring or load)(testPut) +testRun(animalSpawn) + +--blah = load(serial(hello)) +--blah() + +--draw = loadstring("\027\076\074\001\000\009\064\109\097\105\110\046\108\117\097\084\000\000\004\000\004\000\008\009\002\002\052\000\000\000\055\000\001\000\055\000\002\000\037\001\003\000\039\002\010\000\039\003\010\000\062\000\004\001\071\000\001\000\017\104\101\108\108\111\044\032\119\111\114\108\100\010\112\114\105\110\116\013\103\114\097\112\104\105\099\115\009\108\111\118\101\001\001\001\001\001\001\001\002\000\000") +--draw() diff --git a/src/script.cpp b/src/script.cpp index fa485bc..351aae4 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -57,7 +57,7 @@ void ScriptSystem::receive([[maybe_unused]] const EntitySpawnEvent &toSpawn) int ScriptSystem::init(void) { - lua.open_libraries(sol::lib::base, sol::lib::math); + lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string); scriptExport(); doFile(); @@ -176,6 +176,8 @@ sol::table ScriptSystem::spawn(sol::object param) } if (tab["Light"] != nullptr) { + if (!e.has_component()) // Position must exist for vel. + (*toRet)["Position"] = e.assign().get(); (*toRet)["Light"] = e.assign(Light().FromLua(tab["Light"])).get(); } -- cgit v1.2.3 From 6441c3e2081abe085b98578b67253f0f3ade0ca2 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Tue, 3 Sep 2019 13:06:58 -0400 Subject: save json to file --- .gitignore | 1 + src/engine.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/.gitignore b/.gitignore index da93793..65892b3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ out .*.swp .*.swo *.o +*.json diff --git a/src/engine.cpp b/src/engine.cpp index 539515c..afd325d 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -30,6 +30,8 @@ #include "components/Position.hpp" #include "components/Velocity.hpp" +#include + using namespace std::chrono_literals; namespace cr = std::chrono; typedef std::chrono::high_resolution_clock mc; @@ -117,7 +119,8 @@ void Engine::run(void) // Done, bring logic thread back logicThread.join(); - cereal::JSONOutputArchive archive (std::cout); + std::ofstream saveFile ("save.json"); + cereal::JSONOutputArchive archive (saveFile); std::string name ("entity"); int i = 0; for (entityx::Entity e : entities.entities_for_debugging()) { @@ -126,7 +129,6 @@ void Engine::run(void) entities.entity_serialize(e, true, archive); archive.finishNode(); } - std::cout << std::endl; } bool Engine::shouldRun(void) -- cgit v1.2.3 From 752438f0be9e4940556ebcc633165cd0b9c17c6f Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Tue, 3 Sep 2019 13:35:13 -0400 Subject: json save and load, made GameState class --- src/engine.cpp | 15 +++------ src/gamestate.hpp | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 src/gamestate.hpp (limited to 'src') diff --git a/src/engine.cpp b/src/engine.cpp index afd325d..9c0b09b 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -20,6 +20,7 @@ */ #include "engine.hpp" +#include "gamestate.hpp" #include "gamerun.hpp" #include "input.hpp" #include "player.hpp" @@ -45,7 +46,9 @@ int Engine::init(void) systems.add(); systems.configure(); + // Load game script and entity data systems.system()->init(); + GameState::load("save.json", entities); return 0; } @@ -119,16 +122,8 @@ void Engine::run(void) // Done, bring logic thread back logicThread.join(); - std::ofstream saveFile ("save.json"); - cereal::JSONOutputArchive archive (saveFile); - std::string name ("entity"); - int i = 0; - for (entityx::Entity e : entities.entities_for_debugging()) { - archive.setNextName((name + std::to_string(i++)).c_str()); - archive.startNode(); - entities.entity_serialize(e, true, archive); - archive.finishNode(); - } + // Save the entities' data + GameState::save("save.json", entities); } bool Engine::shouldRun(void) diff --git a/src/gamestate.hpp b/src/gamestate.hpp new file mode 100644 index 0000000..196c6b7 --- /dev/null +++ b/src/gamestate.hpp @@ -0,0 +1,96 @@ +/** + * @file gamestate.hpp + * Provides functionality to load and save entity data to or from JSON files. + * + * Copyright (C) 2019 Clyne Sullivan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GAMELOAD_HPP_ +#define GAMELOAD_HPP_ + +#include +#include +#include + +#include + +/** + * @class GameState + * Manages save files that contain entity data. + */ +class GameState +{ +public: + /** + * Loads entity data from a JSON file into entities contained in the + * entity manager. + * + * The order of entities and the components they have must match between + * those in the manager and those in the file. + * + * @param file The file to load from + * @param entities The entity manager to load into + */ + static void load(const std::string& file, entityx::EntityManager &entities) + { + if (std::ifstream saveFile (file); saveFile.good()) { + cereal::JSONInputArchive archive (saveFile); + serializeEntities(archive, false, entities); + } + } + + /** + * Saves entity data from the entities in the provided manager into a JSON + * file, + * + * @param file The file to load from + * @param entities The entity manager to get entity data from + */ + static void save(const std::string& file, entityx::EntityManager &entities) + { + if (std::ofstream saveFile (file); saveFile.good()) { + cereal::JSONOutputArchive archive (saveFile); + serializeEntities(archive, true, entities); + } + } + +private: + /** + * Calls the serialization funciton for each entity in the given entity + * manager. + * @param archive The archive to save/load with (cereal::JSON...) + * @param save True to save data, false to load + * @param entities The entity manager to iterate through + */ + template + static void serializeEntities(Archive& archive, + bool save, + entityx::EntityManager& entities) + { + std::string name ("entity"); + int i = 0; + + for (auto entity : entities.entities_for_debugging()) { + archive.setNextName((name + std::to_string(i++)).c_str()); + archive.startNode(); + entities.entity_serialize(entity, save, archive); + archive.finishNode(); + } + } +}; + +#endif // GAMELOAD_HPP_ + -- cgit v1.2.3 From 95cc88ad5f6c2abb4890d00a57ae4ad0db030e9b Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Tue, 3 Sep 2019 13:58:38 -0400 Subject: added load message --- src/engine.cpp | 5 ++++- src/gamestate.hpp | 24 ++++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/engine.cpp b/src/engine.cpp index 9c0b09b..e959f21 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -48,7 +48,10 @@ int Engine::init(void) // Load game script and entity data systems.system()->init(); - GameState::load("save.json", entities); + if (GameState::load("save.json", entities)) { + std::cout << "Loaded from save.json. Delete the file if you don't want " + "it." << std::endl; + } return 0; } diff --git a/src/gamestate.hpp b/src/gamestate.hpp index 196c6b7..55f4e47 100644 --- a/src/gamestate.hpp +++ b/src/gamestate.hpp @@ -43,13 +43,19 @@ public: * * @param file The file to load from * @param entities The entity manager to load into + * @return True if successful load */ - static void load(const std::string& file, entityx::EntityManager &entities) + static bool load(const std::string& file, entityx::EntityManager &entities) { - if (std::ifstream saveFile (file); saveFile.good()) { + std::ifstream saveFile (file); + bool opened = saveFile.good(); + + if (opened) { cereal::JSONInputArchive archive (saveFile); - serializeEntities(archive, false, entities); + serializeEntities(archive, false, entities); } + + return opened; } /** @@ -58,13 +64,19 @@ public: * * @param file The file to load from * @param entities The entity manager to get entity data from + * @return True if successful save */ - static void save(const std::string& file, entityx::EntityManager &entities) + static bool save(const std::string& file, entityx::EntityManager &entities) { - if (std::ofstream saveFile (file); saveFile.good()) { + std::ofstream saveFile (file); + bool opened = saveFile.good(); + + if (opened) { cereal::JSONOutputArchive archive (saveFile); - serializeEntities(archive, true, entities); + serializeEntities(archive, true, entities); } + + return opened; } private: -- cgit v1.2.3