diff --git a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp index 17e15be..f0d3b0e 100644 --- a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp +++ b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp @@ -16,23 +16,16 @@ namespace NetworkingObjects { ERASE_SINGLE }; - template class NetObjOrderedListObjectInfo { - public: - NetObjOrderedListObjectInfo(const NetObjPtr& initObj, uint32_t initPos, bool initSyncIgnore): - obj(initObj), - pos(initPos), - syncIgnore(initSyncIgnore) - {} - uint32_t get_pos() const { return pos; } - const NetObjPtr& get_obj() const { return obj; } - private: - NetObjPtr obj; - uint32_t pos; - bool syncIgnore; - template friend class NetObjOrderedList; - template friend class NetObjOrderedListServer; - template friend class NetObjOrderedListClient; - template friend void set_positions_for_object_info_vector(std::vector>>& v, uint32_t i); + template struct NetObjOrderedListObjectInfo { + NetObjOrderedListObjectInfo(const NetObjPtr& iObj, uint32_t iPos, bool iSyncIgnore): + obj(iObj), + pos(iPos), + syncIgnore(iSyncIgnore) + {} + NetObjOrderedListObjectInfo() = delete; + NetObjPtr obj; + uint32_t pos; + bool syncIgnore; }; template using NetObjOrderedListObjectInfoPtr = std::shared_ptr>; @@ -51,29 +44,26 @@ namespace NetworkingObjects { l->insert(l, l->size(), newObj); return newObj; } - static NetObjPtr push_back_and_send_create(const NetObjPtr>& l, const NetObjPtr& newObj) { + static void push_back_and_send_create(const NetObjPtr>& l, const NetObjPtr& newObj) { l->insert(l, l->size(), newObj); - return newObj; } - static NetObjPtr insert_and_send_create(const NetObjPtr>& l, uint32_t posToInsertAt, const NetObjPtr& newObj) { + static void insert_and_send_create(const NetObjPtr>& l, uint32_t posToInsertAt, const NetObjPtr& newObj) { l->insert(l, posToInsertAt, newObj); - return newObj; } - static void erase(const NetObjPtr>& l, uint32_t indexToErase) { - l->erase_by_index(l, indexToErase); + static NetObjPtr erase(const NetObjPtr>& l, uint32_t indexToErase) { + return l->erase_by_index(l, indexToErase); } - static void erase(const NetObjPtr>& l, const NetObjOrderedListObjectInfoPtr& p) { - l->erase_by_index(l, p->pos); + static uint32_t erase(const NetObjPtr>& l, const NetObjPtr& p) { + return l->erase_by_ptr(l, p); } virtual uint32_t size() const = 0; - virtual const std::vector>& get_data() const = 0; - virtual const NetObjOrderedListObjectInfoPtr& info_at(uint32_t index) const = 0; virtual const NetObjPtr& at(uint32_t index) const = 0; virtual bool empty() const = 0; virtual ~NetObjOrderedList() {} protected: virtual void insert(const NetObjPtr>& l, uint32_t posToInsertAt, const NetObjPtr& newObj) = 0; - virtual void erase_by_index(const NetObjPtr>& l, uint32_t indexToErase) = 0; + virtual NetObjPtr erase_by_index(const NetObjPtr>& l, uint32_t indexToErase) = 0; + virtual uint32_t erase_by_ptr(const NetObjPtr>& l, const NetObjPtr& p) = 0; virtual void write_constructor(const NetObjPtr>& l, cereal::PortableBinaryOutputArchive& a) = 0; virtual void read_update(const NetObjPtr>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) = 0; virtual void read_constructor(const NetObjPtr>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) = 0; @@ -96,12 +86,6 @@ namespace NetworkingObjects { virtual uint32_t size() const override { return data.size(); } - virtual const std::vector>& get_data() const override { - return data; - } - virtual const NetObjOrderedListObjectInfoPtr& info_at(uint32_t index) const override { - return data[index]; - } virtual const NetObjPtr& at(uint32_t index) const override { return data[index]->obj; } @@ -137,17 +121,34 @@ namespace NetworkingObjects { }); set_positions_for_object_info_vector(data, actualPosToInsertAt); } - virtual void erase_by_index(const NetObjPtr>& l, uint32_t indexToErase) override { + virtual NetObjPtr erase_by_index(const NetObjPtr>& l, uint32_t indexToErase) override { if(data.empty()) - return; + return {}; indexToErase = std::min(indexToErase, data.size() - 1); l.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [indexToErase](const NetObjPtr>&, cereal::PortableBinaryOutputArchive& a) { a(ObjPtrOrderedListCommand_StoC::ERASE_SINGLE, indexToErase); }); NetObjID idToErase = data[indexToErase]->obj.get_net_id(); + NetObjPtr toRet = data[indexToErase]->obj; data.erase(data.begin() + indexToErase); idToDataMap.erase(idToErase); set_positions_for_object_info_vector(data, indexToErase); + return toRet; + } + virtual uint32_t erase_by_ptr(const NetObjPtr>& l, const NetObjPtr& p) override { + if(data.empty()) + return std::numeric_limits::max(); + auto it = idToDataMap.find(p.get_net_id()); + if(it == idToDataMap.end()) + return std::numeric_limits::max(); + uint32_t indexToErase = it->second->pos; + data.erase(data.begin() + indexToErase); + idToDataMap.erase(it); + l.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [indexToErase](const NetObjPtr>&, cereal::PortableBinaryOutputArchive& a) { + a(ObjPtrOrderedListCommand_StoC::ERASE_SINGLE, indexToErase); + }); + set_positions_for_object_info_vector(data, indexToErase); + return indexToErase; } virtual void write_constructor(const NetObjPtr>& l, cereal::PortableBinaryOutputArchive& a) override { a(static_cast(data.size())); @@ -192,12 +193,6 @@ namespace NetworkingObjects { virtual uint32_t size() const override { return clientData.size(); } - virtual const std::vector>& get_data() const override { - return clientData; - } - virtual const NetObjOrderedListObjectInfoPtr& info_at(uint32_t index) const override { - return clientData[index]; - } virtual const NetObjPtr& at(uint32_t index) const override { return clientData[index]->obj; } @@ -236,11 +231,11 @@ namespace NetworkingObjects { }); set_positions_for_object_info_vector(clientData, actualPosToInsertAt); } - virtual void erase_by_index(const NetObjPtr>& l, uint32_t indexToErase) override { + virtual NetObjPtr erase_by_index(const NetObjPtr>& l, uint32_t indexToErase) override { if(clientData.empty()) - return; + return {}; indexToErase = std::min(indexToErase, clientData.size() - 1); - auto& p = clientData[indexToErase]; + auto p = clientData[indexToErase]; l.send_client_update(RELIABLE_COMMAND_CHANNEL, [&p](const NetObjPtr>&, cereal::PortableBinaryOutputArchive& a) { a(ObjPtrOrderedListCommand_CtoS::ERASE_SINGLE, p->obj.get_net_id()); }); @@ -249,6 +244,24 @@ namespace NetworkingObjects { clientIdToDataMap.erase(p->obj.get_net_id()); clientData.erase(clientData.begin() + iToErase); set_positions_for_object_info_vector(clientData, iToErase); + return p->obj; + } + virtual uint32_t erase_by_ptr(const NetObjPtr>& l, const NetObjPtr& p) override { + if(clientData.empty()) + return std::numeric_limits::max(); + auto it = clientIdToDataMap.find(p.get_net_id()); + if(it == clientIdToDataMap.end()) + return std::numeric_limits::max(); + l.send_client_update(RELIABLE_COMMAND_CHANNEL, [&p](const NetObjPtr>&, cereal::PortableBinaryOutputArchive& a) { + a(ObjPtrOrderedListCommand_CtoS::ERASE_SINGLE, p.get_net_id()); + }); + it->second->syncIgnore = true; + uint32_t iToErase = it->second->pos; + auto toRet = clientData[iToErase]; + clientIdToDataMap.erase(it); + clientData.erase(clientData.begin() + iToErase); + set_positions_for_object_info_vector(clientData, iToErase); + return iToErase; } virtual void write_constructor(const NetObjPtr>& l, cereal::PortableBinaryOutputArchive& a) override { a(static_cast(clientData.size())); diff --git a/src/BookmarkManager.cpp b/src/BookmarkManager.cpp index acffaea..3635fd3 100644 --- a/src/BookmarkManager.cpp +++ b/src/BookmarkManager.cpp @@ -13,16 +13,36 @@ void Bookmark::scale_up(const WorldScalar& scaleUpAmount) { BookmarkManager::BookmarkManager(World& w): world(w) { + // NOTE: Should find a way for bookmarks added from the network to take into account the client's canvasScale + // Have the canvasScale variable come with the ClientData object, and the grid scale commands can be part of + // the client data class if(w.netObjMan.is_server()) bookmarks = w.netObjMan.make_obj>(); } void BookmarkManager::add_bookmark(const std::string& name) { - NetworkingObjects::NetObjPtr a = bookmarks->emplace_back_direct(bookmarks, Bookmark{name, world.drawData.cam.c, world.main.window.size.cast()}); + NetworkingObjects::NetObjPtr bookmarkPtr = bookmarks->emplace_back_direct(bookmarks, Bookmark{name, world.drawData.cam.c, world.main.window.size.cast()}); + uint32_t pos = bookmarks->size() - 1; + world.undo.push({[&bookmarks = bookmarks, bookmarkPtr](){ + bookmarks->erase(bookmarks, bookmarkPtr); + return true; + }, + [&bookmarks = bookmarks, bookmarkPtr, pos]() { + bookmarks->insert_and_send_create(bookmarks, pos, bookmarkPtr); + return true; + }}); } void BookmarkManager::remove_bookmark(uint32_t bookmarkIndex) { - bookmarks->erase(bookmarks, bookmarkIndex); + NetworkingObjects::NetObjPtr bookmarkPtr = bookmarks->erase(bookmarks, bookmarkIndex); + world.undo.push({[&bookmarks = bookmarks, bookmarkPtr, bookmarkIndex]() { + bookmarks->insert_and_send_create(bookmarks, bookmarkIndex, bookmarkPtr); + return true; + }, + [&bookmarks = bookmarks, bookmarkPtr](){ + bookmarks->erase(bookmarks, bookmarkPtr); + return true; + }}); } void BookmarkManager::jump_to_bookmark(uint32_t bookmarkIndex) {