Fixed issue when inserting objects in client net list

This commit is contained in:
Yousef Khadadeh 2026-01-02 20:11:33 +03:00
parent 2c9908bcea
commit 92115957b2
6 changed files with 68 additions and 55 deletions

View file

@ -111,7 +111,11 @@ namespace NetworkingObjects {
virtual bool empty() const = 0;
virtual ~NetObjOrderedList() {}
protected:
virtual NetObjOrderedListIterator<T> insert_single(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, const NetObjOrderedListIterator<T> it, NetObjOwnerPtr<T> newObj) = 0;
NetObjOrderedListIterator<T> insert_single(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, const NetObjOrderedListIterator<T> it, NetObjOwnerPtr<T> newObj) {
std::vector<std::pair<NetObjOrderedListIterator<T>, NetObjOwnerPtr<T>>> toInsert;
toInsert.emplace_back(it, std::move(newObj));
return insert_ordered_list(l, clientInserting, toInsert).back();
}
virtual std::vector<NetObjOrderedListIterator<T>> insert_ordered_list(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, std::vector<std::pair<NetObjOrderedListIterator<T>, NetObjOwnerPtr<T>>>& newObj) = 0;
virtual void erase_it_list(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::vector<NetObjOrderedListIterator<T>>& itList, std::vector<NetObjOwnerPtr<T>>* erasedObjects) = 0;
virtual void write_constructor(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryOutputArchive& a) = 0;
@ -211,29 +215,6 @@ namespace NetworkingObjects {
}
}
protected:
virtual NetObjOrderedListIterator<T> insert_single(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, const NetObjOrderedListIterator<T> it, NetObjOwnerPtr<T> newObj) override {
NetworkingObjects::NetObjID idPosition;
if(it == data.begin())
idPosition = NetworkingObjects::NetObjID{0, 0};
else
idPosition = std::prev(it)->obj.get_net_id();
NetObjOrderedListIterator<T> toRet = data.emplace(it, std::move(newObj), it == data.end() ? data.size() : it->pos);
idToDataMap.emplace(toRet->obj.get_net_id(), toRet);
set_position_obj_info_list<T>(toRet, data.end());
l.send_server_update_to_all_clients_except(clientInserting, RELIABLE_COMMAND_CHANNEL, [&toRet, &idPosition](const NetObjTemporaryPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
a(ObjPtrOrderedListCommand_StoC::INSERT_LIST_CONSTRUCT, static_cast<uint32_t>(1));
a(idPosition);
toRet->obj.write_create_message(a);
});
l.send_server_update_to_client(clientInserting, RELIABLE_COMMAND_CHANNEL, [&toRet, &idPosition](const NetObjTemporaryPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
a(ObjPtrOrderedListCommand_StoC::INSERT_LIST_REFERENCE, static_cast<uint32_t>(1));
a(idPosition, toRet->obj.get_net_id());
});
this->call_insert_callback(toRet);
return toRet;
}
virtual std::vector<NetObjOrderedListIterator<T>> insert_ordered_list(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, std::vector<std::pair<NetObjOrderedListIterator<T>, NetObjOwnerPtr<T>>>& newObjs) override {
if(newObjs.empty())
return {};
@ -431,20 +412,6 @@ namespace NetworkingObjects {
}
}
protected:
virtual NetObjOrderedListIterator<T> insert_single(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, const NetObjOrderedListIterator<T> it, NetObjOwnerPtr<T> newObj) override {
NetObjOrderedListIterator<T> toRet = clientData.emplace(it, std::move(newObj), it == clientData.end() ? clientData.size() : it->pos);
clientIdToDataMap.emplace(toRet->obj.get_net_id(), toRet);
set_position_obj_info_list<T>(toRet, clientData.end());
l.send_server_update_to_all_clients_except(clientInserting, RELIABLE_COMMAND_CHANNEL, [&toRet](const NetObjTemporaryPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
a(ObjPtrOrderedListCommand_CtoS::INSERT_LIST, static_cast<uint32_t>(1));
a(toRet->pos);
toRet->obj.write_create_message(a);
});
this->call_insert_callback(toRet);
return toRet;
}
virtual std::vector<NetObjOrderedListIterator<T>> insert_ordered_list(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, std::vector<std::pair<NetObjOrderedListIterator<T>, NetObjOwnerPtr<T>>>& newObjs) override {
if(newObjs.empty())
return {};

View file

@ -151,7 +151,7 @@ void GridModifyTool::tool_update() {
}
bool GridModifyTool::prevent_undo_or_redo() {
return false;
return true;
}
void GridModifyTool::draw(SkCanvas* canvas, const DrawData& drawData) {

View file

@ -26,6 +26,9 @@ void GridManager::add_default_grid(const std::string& newName) {
gridData(initGridData),
undoID(initUndoID)
{}
const char* get_name() const override {
return "Add Grid";
}
bool undo(WorldUndoManager& undoMan) override {
std::optional<NetworkingObjects::NetObjID> toEraseID = undoMan.get_netid_from_undoid(undoID);
if(!toEraseID.has_value())
@ -64,6 +67,9 @@ void GridManager::remove_grid(uint32_t indexToRemove) {
gridData(initGridData),
undoID(initUndoID)
{}
const char* get_name() const override {
return "Remove Grid";
}
bool undo(WorldUndoManager& undoMan) override {
std::optional<NetworkingObjects::NetObjID> toInsertID = undoMan.get_netid_from_undoid(undoID);
if(toInsertID.has_value())
@ -104,6 +110,9 @@ void GridManager::finalize_grid_modify(const NetworkingObjects::NetObjTemporaryP
gridDataNew(initGridDataNew),
undoID(initUndoID)
{}
const char* get_name() const override {
return "Modify Grid";
}
bool undo(WorldUndoManager& undoMan) override {
std::optional<NetworkingObjects::NetObjID> toModifyID = undoMan.get_netid_from_undoid(undoID);
if(!toModifyID.has_value())

View file

@ -1221,25 +1221,50 @@ void Toolbar::performance_metrics() {
.sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0) },
.padding = CLAY_PADDING_ALL(io->theme->padding1),
.childGap = io->theme->childGap1,
.childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_TOP},
.layoutDirection = CLAY_TOP_TO_BOTTOM
.childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_BOTTOM},
.layoutDirection = CLAY_LEFT_TO_RIGHT
},
.backgroundColor = convert_vec4<Clay_Color>(io->theme->backColor1),
.floating = {.offset = {-10, -10}, .attachPoints = {.element = CLAY_ATTACH_POINT_RIGHT_BOTTOM, .parent = CLAY_ATTACH_POINT_RIGHT_BOTTOM}, .attachTo = CLAY_ATTACH_TO_PARENT}
}) {
std::stringstream a;
a << "FPS: " << std::fixed << std::setprecision(0) << (1.0 / main.deltaTime);
gui.text_label(a.str());
gui.text_label("Item Count: " + std::to_string(main.world->drawProg.layerMan.total_component_count()));
std::stringstream b;
b << "Coord: " << main.world->drawData.cam.c.pos.x().display_int_str(5) << ", " << main.world->drawData.cam.c.pos.y().display_int_str(5);
gui.text_label(b.str());
std::stringstream c;
c << "Zoom: " << main.world->drawData.cam.c.inverseScale.display_int_str(5);
gui.text_label(c.str());
std::stringstream d;
d << "Rotation: " << main.world->drawData.cam.c.rotation;
gui.text_label(d.str());
CLAY_AUTO_ID({
.layout = {
.sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0) },
.padding = CLAY_PADDING_ALL(io->theme->padding1),
.childGap = io->theme->childGap1,
.childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_TOP},
.layoutDirection = CLAY_TOP_TO_BOTTOM
},
.backgroundColor = convert_vec4<Clay_Color>(io->theme->backColor1),
}) {
gui.text_label("Undo queue");
std::vector<const char*> undoList = main.world->undo.get_front_undo_queue_names(10);
for(const char* u : undoList)
gui.text_label(u);
}
CLAY_AUTO_ID({
.layout = {
.sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0) },
.padding = CLAY_PADDING_ALL(io->theme->padding1),
.childGap = io->theme->childGap1,
.childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_TOP},
.layoutDirection = CLAY_TOP_TO_BOTTOM
},
.backgroundColor = convert_vec4<Clay_Color>(io->theme->backColor1),
}) {
std::stringstream a;
a << "FPS: " << std::fixed << std::setprecision(0) << (1.0 / main.deltaTime);
gui.text_label(a.str());
gui.text_label("Item Count: " + std::to_string(main.world->drawProg.layerMan.total_component_count()));
std::stringstream b;
b << "Coord: " << main.world->drawData.cam.c.pos.x().display_int_str(5) << ", " << main.world->drawData.cam.c.pos.y().display_int_str(5);
gui.text_label(b.str());
std::stringstream c;
c << "Zoom: " << main.world->drawData.cam.c.inverseScale.display_int_str(5);
gui.text_label(c.str());
std::stringstream d;
d << "Rotation: " << main.world->drawData.cam.c.rotation;
gui.text_label(d.str());
}
}
}

View file

@ -122,3 +122,13 @@ std::optional<NetworkingObjects::NetObjID> WorldUndoManager::get_netid_from_undo
return std::nullopt;
return it->second;
}
std::vector<const char*> WorldUndoManager::get_front_undo_queue_names(unsigned count) {
std::vector<const char*> toRet;
for(auto& u : undoQueue | std::views::reverse) {
toRet.emplace_back(u->get_name());
if(toRet.size() == count)
return toRet;
}
return toRet;
}

View file

@ -9,6 +9,7 @@ class WorldUndoManager;
class WorldUndoAction {
public:
virtual const char* get_name() const = 0;
virtual bool undo(WorldUndoManager& undoMan) = 0;
virtual bool redo(WorldUndoManager& undoMan) = 0;
virtual void scale_up(const WorldScalar& scaleAmount);
@ -34,6 +35,7 @@ class WorldUndoManager {
UndoObjectID get_undoid_from_netid(const NetworkingObjects::NetObjID& netObjID);
void register_new_netid_to_existing_undoid(UndoObjectID existingUndoID, const NetworkingObjects::NetObjID& netObjID);
std::optional<NetworkingObjects::NetObjID> get_netid_from_undoid(UndoObjectID undoID);
std::vector<const char*> get_front_undo_queue_names(unsigned count);
World& world;
private: