Transforms are now sent over network

This commit is contained in:
Yousef Khadadeh 2025-12-31 11:42:16 +03:00
parent 08513646bf
commit ebe4d8e60a
8 changed files with 65 additions and 16 deletions

View file

@ -9,7 +9,8 @@ enum ServerCommands : MessageCommandType {
SERVER_UPDATE_NETWORK_OBJECT,
SERVER_UPDATE_MANY_NETWORK_OBJECTS,
SERVER_NEW_RESOURCE_ID,
SERVER_NEW_RESOURCE_DATA
SERVER_NEW_RESOURCE_DATA,
SERVER_TRANSFORM_MANY_COMPONENTS
};
enum ClientCommands : MessageCommandType {
@ -19,7 +20,8 @@ enum ClientCommands : MessageCommandType {
CLIENT_UPDATE_NETWORK_OBJECT,
CLIENT_UPDATE_MANY_NETWORK_OBJECTS,
CLIENT_NEW_RESOURCE_ID,
CLIENT_NEW_RESOURCE_DATA
CLIENT_NEW_RESOURCE_DATA,
CLIENT_TRANSFORM_MANY_COMPONENTS
};
// Arbitrary value. Higher scale up values lead to less scale up events (which can cause stuttering), but leads to larger numbers overall, which can cause a tiny bit of lag and increased memory usage

View file

@ -1,4 +1,5 @@
#include "DrawingProgram.hpp"
#include "Helpers/Networking/NetLibrary.hpp"
#include "Tools/DrawingProgramToolBase.hpp"
#include <include/core/SkPaint.h>
#include <include/core/SkVertices.h>
@ -8,6 +9,7 @@
#include "Tools/GridModifyTool.hpp"
#include "../InputManager.hpp"
#include "../SharedTypes.hpp"
#include "../CommandList.hpp"
#include <memory>
#include <optional>
#include <Helpers/ConvertVec.hpp>
@ -29,6 +31,7 @@
#include "../CanvasComponents/ImageCanvasComponent.hpp"
#include "Layers/DrawingProgramLayer.hpp"
#include "Layers/DrawingProgramLayerListItem.hpp"
#include <Helpers/Parallel.hpp>
#include "Tools/EraserTool.hpp"
@ -62,6 +65,47 @@ void DrawingProgram::read_components_client(cereal::PortableBinaryInputArchive&
drawCache.build({});
}
void DrawingProgram::init_server_callbacks() {
world.netServer->add_recv_callback(SERVER_TRANSFORM_MANY_COMPONENTS, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
std::vector<std::pair<NetworkingObjects::NetObjID, CoordSpaceHelper>> transforms;
message(transforms);
process_transform_message(transforms);
world.netServer->send_items_to_all_clients(RELIABLE_COMMAND_CHANNEL, CLIENT_TRANSFORM_MANY_COMPONENTS, transforms);
});
}
void DrawingProgram::init_client_callbacks() {
world.con.client_add_recv_callback(CLIENT_TRANSFORM_MANY_COMPONENTS, [&](cereal::PortableBinaryInputArchive& message) {
std::vector<std::pair<NetworkingObjects::NetObjID, CoordSpaceHelper>> transforms;
message(transforms);
process_transform_message(transforms);
});
}
void DrawingProgram::process_transform_message(const std::vector<std::pair<NetworkingObjects::NetObjID, CoordSpaceHelper>>& transforms) {
for(auto& [id, coords] : transforms) {
auto objPtr = world.netObjMan.get_obj_temporary_ref_from_id<CanvasComponentContainer>(id);
if(!objPtr || selection.is_selected(&(*objPtr->objInfo))) // Whatever transformation we're doing right now will overwrite this transformation, so we can ignore this message
return;
if(objPtr->coords == coords)
return;
objPtr->coords = coords;
objPtr->commit_transform(*this);
}
}
void DrawingProgram::send_transforms_for(const std::vector<CanvasComponentContainer::ObjInfo*>& objsToSendTransformsFor) {
if(world.netObjMan.is_connected()) {
std::vector<std::pair<NetworkingObjects::NetObjID, CoordSpaceHelper>> transforms;
for(auto& obj : objsToSendTransformsFor)
transforms.emplace_back(obj->obj.get_net_id(), obj->obj->coords);
if(world.netObjMan.is_server())
world.netServer->send_items_to_all_clients(RELIABLE_COMMAND_CHANNEL, CLIENT_TRANSFORM_MANY_COMPONENTS, transforms);
else
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, CLIENT_TRANSFORM_MANY_COMPONENTS, transforms);
}
}
void DrawingProgram::toolbar_gui() {
Toolbar& t = world.main.toolbar;
t.gui.push_id("Drawing Program Toolbar GUI");

View file

@ -32,7 +32,8 @@ class DrawingProgram {
void draw(SkCanvas* canvas, const DrawData& drawData);
void write_components_server(cereal::PortableBinaryOutputArchive& a);
void read_components_client(cereal::PortableBinaryInputArchive& a);
void init_server_callbacks();
void init_client_callbacks();
void add_file_to_canvas_by_path(const std::filesystem::path& filePath, Vector2f dropPos, bool addInSameThread);
void add_file_to_canvas_by_data(const std::string& fileName, std::string_view fileBuffer, Vector2f dropPos);
@ -52,7 +53,10 @@ class DrawingProgram {
void invalidate_cache_at_component(CanvasComponentContainer::ObjInfo* objToCheck);
void preupdate_component(CanvasComponentContainer::ObjInfo* objToCheck);
void send_transforms_for(const std::vector<CanvasComponentContainer::ObjInfo*>& objsToSendTransformsFor);
private:
void process_transform_message(const std::vector<std::pair<NetworkingObjects::NetObjID, CoordSpaceHelper>>& transforms);
void drag_drop_update();
void add_file_to_canvas_by_path_execute(const std::filesystem::path& filePath, Vector2f dropPos);
void check_updateable_components();

View file

@ -161,21 +161,11 @@ bool DrawingProgramSelection::mouse_collided_with_rotate_handle_point() {
void DrawingProgramSelection::commit_transform_selection() {
auto selectedSetTemp = selectedSet;
std::vector<CanvasComponentContainer::ObjInfo*> a(selectedSet.begin(), selectedSet.end());
std::vector<std::pair<CanvasComponentContainer::ObjInfo*, CoordSpaceHelper>> transformsFrom;
for(auto& transformedObj : a)
transformsFrom.emplace_back(transformedObj, transformedObj->obj->coords);
for(auto& comp : a) {
for(auto& comp : selectedSet) {
comp->obj->coords = selectionTransformCoords.other_coord_space_from_this_space(comp->obj->coords);
comp->obj->commit_transform(drawP);
}
std::vector<std::pair<CanvasComponentContainer::ObjInfo*, CoordSpaceHelper>> transformsTo;
std::vector<std::pair<NetworkingObjects::NetObjID, CoordSpaceHelper>> transformsToSend;
for(auto& transformedObj : a) {
transformsToSend.emplace_back(transformedObj->obj.get_net_id(), transformedObj->obj->coords);
transformsTo.emplace_back(transformedObj, transformedObj->obj->coords);
}
//DrawComponent::client_send_transform_many(drawP, transformsToSend);
drawP.send_transforms_for(selectedSet);
reset_all();
set_to_selection(selectedSetTemp);

View file

@ -33,6 +33,12 @@ uint32_t DrawingProgramLayerManager::edited_layer_component_count() {
return editingLayer.lock()->get_layer().components->size();
}
uint32_t DrawingProgramLayerManager::total_component_count() {
if(layerTreeRoot)
return layerTreeRoot->get_component_count();
return 0;
}
CanvasComponentContainer::ObjInfoIterator DrawingProgramLayerManager::get_edited_layer_end_iterator() {
return editingLayer.lock()->get_layer().components->end();
}

View file

@ -39,6 +39,7 @@ class DrawingProgramLayerManager {
bool layer_tree_root_exists();
const DrawingProgramLayerListItem& get_layer_root();
uint32_t total_component_count();
CanvasComponentContainer::ObjInfo* add_component_to_layer_being_edited(CanvasComponentContainer* newObj);
std::vector<CanvasComponentContainer::ObjInfoIterator> add_many_components_to_layer_being_edited(const std::vector<std::pair<CanvasComponentContainer::ObjInfoIterator, CanvasComponentContainer*>>& newObjs);

View file

@ -1228,7 +1228,7 @@ void Toolbar::performance_metrics() {
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.get_layer_root().get_component_count()));
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());

View file

@ -126,6 +126,7 @@ void World::init_net_obj_type_list() {
void World::init_server_callbacks() {
rMan.init_server_callbacks();
drawProg.init_server_callbacks();
netServer->add_recv_callback(SERVER_INITIAL_DATA, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
ClientData::InitStruct newClientData;
newClientData.cursorColor = get_random_cursor_color();
@ -170,6 +171,7 @@ void World::init_server_callbacks() {
void World::init_client_callbacks() {
rMan.init_client_callbacks();
drawProg.init_client_callbacks();
con.client_add_recv_callback(CLIENT_INITIAL_DATA, [&](cereal::PortableBinaryInputArchive& message) {
std::string fileDisplayName;
NetworkingObjects::NetObjID clientDataObjID;