GridManager now works on net objects
This commit is contained in:
parent
67507a9a39
commit
ceafbf8bb6
20 changed files with 214 additions and 222 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include "Helpers/NetworkingObjects/NetObjPtr.decl.hpp"
|
||||
#include "NetObjPtr.hpp"
|
||||
|
||||
namespace NetworkingObjects {
|
||||
|
|
@ -27,4 +28,10 @@ namespace NetworkingObjects {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
template <typename T> void generic_serialized_class_send_update_to_all(const NetworkingObjects::NetObjPtr<T>& o) {
|
||||
o.send_update_to_all(RELIABLE_COMMAND_CHANNEL, [](const NetworkingObjects::NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(*o);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ namespace NetworkingObjects {
|
|||
}
|
||||
|
||||
template <typename T> friend class NetObjPtr;
|
||||
template <typename T> friend class NetObjWeakPtr;
|
||||
|
||||
struct SingleObjectData {
|
||||
NetTypeIDType netTypeID;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ namespace NetworkingObjects {
|
|||
static uint32_t erase(const NetObjPtr<NetObjOrderedList<T>>& l, const NetObjPtr<T>& p) {
|
||||
return l->erase_by_ptr(l, p);
|
||||
}
|
||||
virtual bool contains(const NetObjPtr<T>& p) const = 0;
|
||||
virtual uint32_t size() const = 0;
|
||||
virtual const NetObjPtr<T>& at(uint32_t index) const = 0;
|
||||
virtual bool empty() const = 0;
|
||||
|
|
@ -83,6 +84,9 @@ namespace NetworkingObjects {
|
|||
template <typename T> class NetObjOrderedListServer : public NetObjOrderedList<T> {
|
||||
public:
|
||||
NetObjOrderedListServer() {}
|
||||
virtual bool contains(const NetObjPtr<T>& p) const override {
|
||||
return idToDataMap.contains(p.get_net_id());
|
||||
}
|
||||
virtual uint32_t size() const override {
|
||||
return data.size();
|
||||
}
|
||||
|
|
@ -159,8 +163,11 @@ namespace NetworkingObjects {
|
|||
uint32_t constructedSize;
|
||||
a(constructedSize);
|
||||
data.clear();
|
||||
for(uint32_t i = 0; i < constructedSize; i++)
|
||||
idToDataMap.clear();
|
||||
for(uint32_t i = 0; i < constructedSize; i++) {
|
||||
data.emplace_back(std::make_shared<NetObjOrderedListObjectInfo<T>>(l.get_obj_man()->template read_create_message<T>(a, c), static_cast<uint32_t>(data.size()), false));
|
||||
idToDataMap.emplace(data.back()->obj.get_net_id(), data.back());
|
||||
}
|
||||
// Dont send the object data to all clients in the constructor, as the function that called read_create_message is also the one that will decide where to send the data of the constructed object
|
||||
// Example: the INSERT_SINGLE command in read_update, if it was inserting another NetObjOrderedList, would first construct the list using read_create_message, then it will call insert() to send it to clients
|
||||
}
|
||||
|
|
@ -190,6 +197,9 @@ namespace NetworkingObjects {
|
|||
template <typename T> class NetObjOrderedListClient : public NetObjOrderedList<T> {
|
||||
public:
|
||||
NetObjOrderedListClient() {}
|
||||
virtual bool contains(const NetObjPtr<T>& p) const override {
|
||||
return clientIdToDataMap.contains(p.get_net_id());
|
||||
}
|
||||
virtual uint32_t size() const override {
|
||||
return clientData.size();
|
||||
}
|
||||
|
|
@ -273,9 +283,14 @@ namespace NetworkingObjects {
|
|||
a(constructedSize);
|
||||
clientData.clear();
|
||||
serverData.clear();
|
||||
for(uint32_t i = 0; i < constructedSize; i++)
|
||||
serverIdToDataMap.clear();
|
||||
clientIdToDataMap.clear();
|
||||
for(uint32_t i = 0; i < constructedSize; i++) {
|
||||
serverData.emplace_back(std::make_shared<NetObjOrderedListObjectInfo<T>>(l.get_obj_man()->template read_create_message<T>(a, nullptr), static_cast<uint32_t>(serverData.size()), false));
|
||||
serverIdToDataMap.emplace(serverData.back()->obj.get_net_id(), serverData.back());
|
||||
}
|
||||
clientData = serverData;
|
||||
clientIdToDataMap = serverIdToDataMap;
|
||||
}
|
||||
virtual void read_update(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) override {
|
||||
ObjPtrOrderedListCommand_StoC c;
|
||||
|
|
|
|||
|
|
@ -21,10 +21,12 @@ namespace NetworkingObjects {
|
|||
std::strong_ordering operator<=>(const NetObjPtr<T>& rhs) const;
|
||||
void send_client_update(const std::string& channel, std::function<void(const NetObjPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void send_server_update_to_all_clients(const std::string& channel, std::function<void(const NetObjPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void send_update_to_all(const std::string& channel, std::function<void(const NetObjPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void write_create_message(cereal::PortableBinaryOutputArchive& a) const;
|
||||
private:
|
||||
friend class NetObjManager;
|
||||
template <typename S> friend class NetObjPtr;
|
||||
template <typename S> friend class NetObjWeakPtr;
|
||||
|
||||
NetObjPtr(NetObjManager* initObjMan, NetObjID initID, const std::shared_ptr<T>& initPtr);
|
||||
NetObjManager* objMan;
|
||||
|
|
|
|||
|
|
@ -89,6 +89,13 @@ namespace NetworkingObjects {
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T> void NetObjPtr<T>::send_update_to_all(const std::string& channel, std::function<void(const NetObjPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
if(objMan->is_server())
|
||||
send_server_update_to_all_clients(channel, sendUpdateFunc);
|
||||
else
|
||||
send_client_update(channel, sendUpdateFunc);
|
||||
}
|
||||
|
||||
template <typename T> void NetObjPtr<T>::write_create_message(cereal::PortableBinaryOutputArchive& a) const {
|
||||
a(id);
|
||||
objMan->typeList->get_type_index_data<T>(objMan->isServer).writeConstructorFunc(this->cast<void>(), a);
|
||||
|
|
|
|||
63
include/Helpers/NetworkingObjects/NetObjWeakPtr.hpp
Normal file
63
include/Helpers/NetworkingObjects/NetObjWeakPtr.hpp
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#pragma once
|
||||
#include "NetObjID.hpp"
|
||||
#include "NetObjManager.hpp"
|
||||
#include "NetObjPtr.decl.hpp"
|
||||
|
||||
namespace NetworkingObjects {
|
||||
template <typename T> class NetObjWeakPtr {
|
||||
public:
|
||||
NetObjWeakPtr():
|
||||
objMan(nullptr),
|
||||
id({0, 0})
|
||||
{}
|
||||
NetObjWeakPtr(const NetObjWeakPtr& other):
|
||||
objMan(other.objMan),
|
||||
id(other.id)
|
||||
{}
|
||||
NetObjWeakPtr(const NetObjPtr<T>& other):
|
||||
objMan(other.objMan),
|
||||
id(other.id)
|
||||
{}
|
||||
NetObjWeakPtr& operator=(const NetObjWeakPtr& other) {
|
||||
objMan = other.objMan;
|
||||
id = other.id;
|
||||
}
|
||||
template <typename S> NetObjWeakPtr<S> cast() const {
|
||||
return NetObjWeakPtr<S>(objMan, id);
|
||||
}
|
||||
bool expired() const {
|
||||
if(!objMan)
|
||||
return true;
|
||||
auto it = objMan->objectData.find(id);
|
||||
return it == objMan->objectData.end();
|
||||
}
|
||||
NetObjPtr<T> lock() const {
|
||||
auto it = objMan->objectData.find(id);
|
||||
if(it == objMan->objectData.end())
|
||||
return NetObjPtr<T>();
|
||||
else
|
||||
return NetObjPtr<T>(objMan, id, std::static_pointer_cast<T>(it->second.p));
|
||||
}
|
||||
NetObjManager* get_obj_man() const {
|
||||
return objMan;
|
||||
}
|
||||
NetObjID get_net_id() const {
|
||||
return id;
|
||||
}
|
||||
bool operator!=(const NetObjWeakPtr<T>& rhs) const {
|
||||
return objMan != rhs.objMan || id != rhs.id;
|
||||
}
|
||||
bool operator==(const NetObjWeakPtr<T>& rhs) const {
|
||||
return objMan == rhs.objMan && id == rhs.id;
|
||||
}
|
||||
private:
|
||||
NetObjWeakPtr(NetObjManager* initObjMan, NetObjID initID):
|
||||
objMan(initObjMan),
|
||||
id(initID)
|
||||
{}
|
||||
|
||||
template <typename S> friend class NetObjPtr;
|
||||
NetObjManager* objMan;
|
||||
NetObjID id;
|
||||
};
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
#include "../World.hpp"
|
||||
#include "../MainProgram.hpp"
|
||||
#include "Helpers/FileDownloader.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjWeakPtr.hpp"
|
||||
#include "Helpers/StringHelpers.hpp"
|
||||
#include "LassoSelectTool.hpp"
|
||||
#include <Helpers/Logger.hpp>
|
||||
|
|
@ -283,9 +284,9 @@ void DrawingProgram::tool_options_gui() {
|
|||
}
|
||||
}
|
||||
|
||||
void DrawingProgram::modify_grid(ServerClientID gridToModifyID) {
|
||||
void DrawingProgram::modify_grid(const NetworkingObjects::NetObjPtr<WorldGrid>& gridToModify) {
|
||||
std::unique_ptr<GridModifyTool> newTool(std::make_unique<GridModifyTool>(*this));
|
||||
newTool->set_grid_id(gridToModifyID);
|
||||
newTool->set_grid(gridToModify);
|
||||
switch_to_tool_ptr(std::move(newTool));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "../DrawData.hpp"
|
||||
#include "DrawingProgramCache.hpp"
|
||||
#include "GridModifyTool.hpp"
|
||||
#include <Helpers/NetworkingObjects/NetObjPtr.hpp>
|
||||
#include "PanCanvasTool.hpp"
|
||||
#include "ZoomCanvasTool.hpp"
|
||||
#include "cereal/archives/portable_binary.hpp"
|
||||
|
|
@ -63,7 +64,7 @@ class DrawingProgram {
|
|||
|
||||
void clear_draw_cache();
|
||||
|
||||
void modify_grid(ServerClientID gridToModifyID);
|
||||
void modify_grid(const NetworkingObjects::NetObjPtr<WorldGrid>& gridToModify);
|
||||
|
||||
private:
|
||||
std::optional<std::chrono::steady_clock::time_point> badFrametimeTimePoint;
|
||||
|
|
|
|||
|
|
@ -2,18 +2,21 @@
|
|||
#include "DrawingProgram.hpp"
|
||||
#include "../MainProgram.hpp"
|
||||
#include "../DrawData.hpp"
|
||||
#include <Helpers/NetworkingObjects/NetObjWeakPtr.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjGenericSerializedClass.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
using namespace NetworkingObjects;
|
||||
|
||||
GridModifyTool::GridModifyTool(DrawingProgram& initDrawP):
|
||||
DrawingProgramToolBase(initDrawP)
|
||||
{
|
||||
}
|
||||
|
||||
void GridModifyTool::set_grid_id(ServerClientID newGridID) {
|
||||
gridID = newGridID;
|
||||
auto gridFoundIt = drawP.world.gridMan.grids.find(gridID);
|
||||
if(gridFoundIt != drawP.world.gridMan.grids.end()) {
|
||||
WorldGrid& g = gridFoundIt->second;
|
||||
void GridModifyTool::set_grid(const NetObjPtr<WorldGrid>& newGrid) {
|
||||
grid = newGrid;
|
||||
if(drawP.world.gridMan.grids->contains(grid)) {
|
||||
WorldGrid& g = *grid;
|
||||
oldGrid = g;
|
||||
CoordSpaceHelper newCam;
|
||||
newCam.inverseScale = g.size / WorldScalar(WorldGrid::GRID_UNIT_PIXEL_SIZE);
|
||||
|
|
@ -31,9 +34,8 @@ void GridModifyTool::gui_toolbox() {
|
|||
Toolbar& t = drawP.world.main.toolbar;
|
||||
t.gui.push_id("Grid modify tool");
|
||||
t.gui.text_label_centered("Edit Grid");
|
||||
auto gridFoundIt = drawP.world.gridMan.grids.find(gridID);
|
||||
if(gridFoundIt != drawP.world.gridMan.grids.end()) {
|
||||
WorldGrid& g = gridFoundIt->second;
|
||||
if(drawP.world.gridMan.grids->contains(grid)) {
|
||||
WorldGrid& g = *grid;
|
||||
t.gui.input_text_field("grid name", "Name", &g.name);
|
||||
t.gui.checkbox_field("Visible", "Visible", &g.visible);
|
||||
t.gui.checkbox_field("Display in Front", "Display in front of canvas", &g.displayInFront);
|
||||
|
|
@ -83,9 +85,8 @@ bool GridModifyTool::right_click_popup_gui(Vector2f popupPos) {
|
|||
}
|
||||
|
||||
void GridModifyTool::tool_update() {
|
||||
auto gridFoundIt = drawP.world.gridMan.grids.find(gridID);
|
||||
if(gridFoundIt != drawP.world.gridMan.grids.end()) {
|
||||
WorldGrid& g = gridFoundIt->second;
|
||||
if(drawP.world.gridMan.grids->contains(grid)) {
|
||||
WorldGrid& g = *grid;
|
||||
switch(selectionMode) {
|
||||
case 0:
|
||||
if(drawP.controls.leftClick) {
|
||||
|
|
@ -145,9 +146,8 @@ bool GridModifyTool::prevent_undo_or_redo() {
|
|||
}
|
||||
|
||||
void GridModifyTool::draw(SkCanvas* canvas, const DrawData& drawData) {
|
||||
auto gridFoundIt = drawP.world.gridMan.grids.find(gridID);
|
||||
if(gridFoundIt != drawP.world.gridMan.grids.end()) {
|
||||
WorldGrid& g = gridFoundIt->second;
|
||||
if(drawP.world.gridMan.grids->contains(grid)) {
|
||||
WorldGrid& g = *grid;
|
||||
if(g.bounds.has_value()) {
|
||||
const auto& b = g.bounds.value();
|
||||
Vector2f bMin = drawP.world.drawData.cam.c.to_space(b.min);
|
||||
|
|
@ -178,5 +178,5 @@ void GridModifyTool::draw(SkCanvas* canvas, const DrawData& drawData) {
|
|||
}
|
||||
|
||||
void GridModifyTool::switch_tool(DrawingProgramToolType newTool) {
|
||||
drawP.world.gridMan.send_grid_info(oldGrid, gridID);
|
||||
NetworkingObjects::generic_serialized_class_send_update_to_all<WorldGrid>(grid);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
#pragma once
|
||||
#include "DrawingProgramToolBase.hpp"
|
||||
#include "../WorldGrid.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjPtr.hpp"
|
||||
|
||||
class DrawingProgram;
|
||||
|
||||
class GridModifyTool : public DrawingProgramToolBase {
|
||||
public:
|
||||
GridModifyTool(DrawingProgram& initDrawP);
|
||||
void set_grid_id(ServerClientID newGridID);
|
||||
void set_grid(const NetworkingObjects::NetObjPtr<WorldGrid>& newGrid);
|
||||
virtual DrawingProgramToolType get_type() override;
|
||||
virtual void gui_toolbox() override;
|
||||
virtual bool right_click_popup_gui(Vector2f popupPos) override;
|
||||
|
|
@ -17,6 +18,6 @@ class GridModifyTool : public DrawingProgramToolBase {
|
|||
virtual void switch_tool(DrawingProgramToolType newTool) override;
|
||||
private:
|
||||
WorldGrid oldGrid;
|
||||
ServerClientID gridID;
|
||||
NetworkingObjects::NetObjPtr<WorldGrid> grid;
|
||||
unsigned selectionMode = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "GridManager.hpp"
|
||||
#include "Helpers/Networking/NetLibrary.hpp"
|
||||
#include "Server/CommandList.hpp"
|
||||
#include "SharedTypes.hpp"
|
||||
#include "World.hpp"
|
||||
|
|
@ -6,166 +7,87 @@
|
|||
#include <algorithm>
|
||||
|
||||
GridManager::GridManager(World& w):
|
||||
world(w) {}
|
||||
|
||||
void GridManager::init_client_callbacks() {
|
||||
world.con.client_add_recv_callback(CLIENT_SET_GRID, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
ServerClientID gID;
|
||||
message(gID);
|
||||
auto& g = grids[gID];
|
||||
message(g);
|
||||
changed = true;
|
||||
});
|
||||
world.con.client_add_recv_callback(CLIENT_REMOVE_GRID, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
ServerClientID gID;
|
||||
message(gID);
|
||||
grids.erase(gID);
|
||||
changed = true;
|
||||
});
|
||||
world(w) {
|
||||
if(w.netObjMan.is_server())
|
||||
grids = w.netObjMan.make_obj<NetworkingObjects::NetObjOrderedList<WorldGrid>>();
|
||||
}
|
||||
|
||||
ServerClientID GridManager::add_default_grid(const std::string& newName) {
|
||||
ServerClientID newID = world.get_new_id();
|
||||
WorldGrid g;
|
||||
g.name = newName;
|
||||
g.color = color_mul_alpha(convert_vec4<Vector4f>(world.canvasTheme.toolFrontColor), 0.4f);
|
||||
g.size = world.drawData.cam.c.inverseScale * WorldScalar(WorldGrid::GRID_UNIT_PIXEL_SIZE);
|
||||
g.offset = world.drawData.cam.c.pos + world.drawData.cam.c.dir_from_space(world.main.window.size.cast<float>() * 0.5f);
|
||||
grids[newID] = g;
|
||||
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, newID, g);
|
||||
void GridManager::add_default_grid(const std::string& newName) {
|
||||
if(grids) {
|
||||
WorldGrid g;
|
||||
g.name = newName;
|
||||
g.color = color_mul_alpha(convert_vec4<Vector4f>(world.canvasTheme.toolFrontColor), 0.4f);
|
||||
g.size = world.drawData.cam.c.inverseScale * WorldScalar(WorldGrid::GRID_UNIT_PIXEL_SIZE);
|
||||
g.offset = world.drawData.cam.c.pos + world.drawData.cam.c.dir_from_space(world.main.window.size.cast<float>() * 0.5f);
|
||||
NetworkingObjects::NetObjPtr<WorldGrid> gridPtr = grids->emplace_back_direct(grids, g);
|
||||
|
||||
changed = true;
|
||||
|
||||
world.undo.push({[&world = world, &changed = changed, &grids = grids, newID]() {
|
||||
grids.erase(newID);
|
||||
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_REMOVE_GRID, newID);
|
||||
changed = true;
|
||||
return true;
|
||||
},
|
||||
[&world = world, &changed = changed, &grids = grids, g, newID]() {
|
||||
grids[newID] = g;
|
||||
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, newID, g);
|
||||
changed = true;
|
||||
return true;
|
||||
}});
|
||||
|
||||
return newID;
|
||||
}
|
||||
|
||||
void GridManager::send_grid_info(WorldGrid oldGrid, ServerClientID gridID) {
|
||||
auto gridFoundIt = grids.find(gridID);
|
||||
if(gridFoundIt != grids.end()) {
|
||||
WorldGrid& g = gridFoundIt->second;
|
||||
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, gridID, g);
|
||||
|
||||
world.undo.push({[&world = world, &changed = changed, &grids = grids, gridID, oldGrid]() {
|
||||
auto gridFoundIt = grids.find(gridID);
|
||||
if(gridFoundIt == grids.end())
|
||||
return false;
|
||||
gridFoundIt->second = oldGrid;
|
||||
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, gridID, oldGrid);
|
||||
changed = true;
|
||||
uint32_t pos = grids->size() - 1;
|
||||
world.undo.push({[&grids = grids, gridPtr](){
|
||||
grids->erase(grids, gridPtr);
|
||||
return true;
|
||||
},
|
||||
[&world = world, &changed = changed, &grids = grids, gridID, g]() {
|
||||
auto gridFoundIt = grids.find(gridID);
|
||||
if(gridFoundIt == grids.end())
|
||||
return false;
|
||||
gridFoundIt->second = g;
|
||||
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, gridID, g);
|
||||
changed = true;
|
||||
[&grids = grids, gridPtr, pos]() {
|
||||
grids->insert_and_send_create(grids, pos, gridPtr);
|
||||
return true;
|
||||
}});
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GridManager::remove_grid(ServerClientID idToRemove) {
|
||||
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_REMOVE_GRID, idToRemove);
|
||||
changed = true;
|
||||
auto it = grids.find(idToRemove);
|
||||
if(it == grids.end())
|
||||
return;
|
||||
|
||||
WorldGrid g = it->second;
|
||||
grids.erase(it);
|
||||
|
||||
world.undo.push({[&world = world, &changed = changed, &grids = grids, idToRemove, g]() {
|
||||
grids[idToRemove] = g;
|
||||
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, idToRemove, g);
|
||||
changed = true;
|
||||
return true;
|
||||
},
|
||||
[&world = world, &changed = changed, &grids = grids, idToRemove]() {
|
||||
grids.erase(idToRemove);
|
||||
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_REMOVE_GRID, idToRemove);
|
||||
changed = true;
|
||||
return true;
|
||||
}});
|
||||
}
|
||||
|
||||
const std::vector<ServerClientID>& GridManager::sorted_grid_ids() {
|
||||
if(changed) {
|
||||
sortedGridIDs.clear();
|
||||
for(auto& [k, v] : grids)
|
||||
sortedGridIDs.emplace_back(k);
|
||||
std::sort(sortedGridIDs.begin(), sortedGridIDs.end(), [&](ServerClientID a, ServerClientID b) {
|
||||
std::string nameA = grids[a].get_display_name();
|
||||
std::string nameB = grids[b].get_display_name();
|
||||
bool namesEqual = nameA == nameB;
|
||||
return (!namesEqual && std::lexicographical_compare(nameA.begin(), nameA.end(), nameB.begin(), nameB.end())) || (namesEqual && a < b);
|
||||
});
|
||||
changed = false;
|
||||
void GridManager::remove_grid(uint32_t indexToRemove) {
|
||||
if(grids) {
|
||||
NetworkingObjects::NetObjPtr<WorldGrid> gridPtr = grids->erase(grids, indexToRemove);
|
||||
world.undo.push({[&grids = grids, gridPtr, indexToRemove]() {
|
||||
grids->insert_and_send_create(grids, indexToRemove, gridPtr);
|
||||
return true;
|
||||
},
|
||||
[&grids = grids, gridPtr](){
|
||||
grids->erase(grids, gridPtr);
|
||||
return true;
|
||||
}});
|
||||
}
|
||||
return sortedGridIDs;
|
||||
}
|
||||
|
||||
ClientPortionID GridManager::get_max_id(ServerPortionID serverID) const {
|
||||
ClientPortionID maxClientID = 0;
|
||||
for(auto& p : grids) {
|
||||
if(p.first.first == serverID)
|
||||
maxClientID = std::max(maxClientID, p.first.second);
|
||||
}
|
||||
return maxClientID;
|
||||
}
|
||||
|
||||
void GridManager::draw_back(SkCanvas* canvas, const DrawData& drawData) {
|
||||
auto& sortedGridIDS = sorted_grid_ids();
|
||||
for(ServerClientID id : sortedGridIDS) {
|
||||
if(!grids[id].displayInFront)
|
||||
grids[id].draw(*this, canvas, drawData);
|
||||
if(grids) {
|
||||
for(uint32_t i = 0; i < grids->size(); i++) {
|
||||
if(!grids->at(i)->displayInFront)
|
||||
grids->at(i)->draw(*this, canvas, drawData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GridManager::draw_front(SkCanvas* canvas, const DrawData& drawData) {
|
||||
auto& sortedGridIDS = sorted_grid_ids();
|
||||
for(ServerClientID id : sortedGridIDS) {
|
||||
if(grids[id].displayInFront)
|
||||
grids[id].draw(*this, canvas, drawData);
|
||||
if(grids) {
|
||||
for(uint32_t i = 0; i < grids->size(); i++) {
|
||||
if(grids->at(i)->displayInFront)
|
||||
grids->at(i)->draw(*this, canvas, drawData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GridManager::draw_coordinates(SkCanvas* canvas, const DrawData& drawData) {
|
||||
auto& sortedGridIDS = sorted_grid_ids();
|
||||
Vector2f axisOffset{0.0f, 0.0f};
|
||||
for(ServerClientID id : sortedGridIDS) {
|
||||
auto& g = grids[id];
|
||||
if(g.coordinatesWillBeDrawn && g.coordinatesAxisOnBounds) {
|
||||
grids[id].draw_coordinates(canvas, drawData, axisOffset);
|
||||
g.coordinatesWillBeDrawn = false;
|
||||
if(grids) {
|
||||
Vector2f axisOffset{0.0f, 0.0f};
|
||||
for(uint32_t i = 0; i < grids->size(); i++) {
|
||||
auto& g = grids->at(i);
|
||||
if(g->coordinatesWillBeDrawn && g->coordinatesAxisOnBounds) {
|
||||
g->draw_coordinates(canvas, drawData, axisOffset);
|
||||
g->coordinatesWillBeDrawn = false;
|
||||
}
|
||||
}
|
||||
for(uint32_t i = 0; i < grids->size(); i++) {
|
||||
auto& g = grids->at(i);
|
||||
if(g->coordinatesWillBeDrawn && !g->coordinatesAxisOnBounds)
|
||||
g->draw_coordinates(canvas, drawData, axisOffset);
|
||||
g->coordinatesWillBeDrawn = false;
|
||||
}
|
||||
}
|
||||
for(ServerClientID id : sortedGridIDS) {
|
||||
auto& g = grids[id];
|
||||
if(g.coordinatesWillBeDrawn && !g.coordinatesAxisOnBounds)
|
||||
grids[id].draw_coordinates(canvas, drawData, axisOffset);
|
||||
g.coordinatesWillBeDrawn = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GridManager::scale_up(const WorldScalar& scaleUpAmount) {
|
||||
for(auto& [id, g] : grids) {
|
||||
g.scale_up(scaleUpAmount);
|
||||
if(grids) {
|
||||
for(uint32_t i = 0; i < grids->size(); i++) {
|
||||
grids->at(i)->scale_up(scaleUpAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,38 +1,37 @@
|
|||
#pragma once
|
||||
#include "Helpers/NetworkingObjects/NetObjPtr.decl.hpp"
|
||||
#include "WorldGrid.hpp"
|
||||
#include <Helpers/NetworkingObjects/NetObjOrderedList.hpp>
|
||||
|
||||
class World;
|
||||
|
||||
class GridManager {
|
||||
public:
|
||||
GridManager(World& w);
|
||||
void init_client_callbacks();
|
||||
|
||||
ServerClientID add_default_grid(const std::string& newName);
|
||||
void add_default_grid(const std::string& newName);
|
||||
|
||||
template <typename Archive> void save(Archive& a) const {
|
||||
a(grids);
|
||||
a(grids->size());
|
||||
for(uint32_t i = 0; i < grids->size(); i++)
|
||||
a(*grids->at(i));
|
||||
}
|
||||
|
||||
template <typename Archive> void load(Archive& a) {
|
||||
a(grids);
|
||||
changed = true;
|
||||
uint32_t newSize = grids->size();
|
||||
for(uint32_t i = 0; i < newSize; i++) {
|
||||
WorldGrid b;
|
||||
a(b);
|
||||
grids->emplace_back_direct(grids, b);
|
||||
}
|
||||
}
|
||||
|
||||
void send_grid_info(WorldGrid oldGrid, ServerClientID gridID);
|
||||
void remove_grid(ServerClientID idToRemove);
|
||||
void remove_grid(uint32_t indexToRemove);
|
||||
void draw_back(SkCanvas* canvas, const DrawData& drawData);
|
||||
void draw_front(SkCanvas* canvas, const DrawData& drawData);
|
||||
void draw_coordinates(SkCanvas* canvas, const DrawData& drawData);
|
||||
void scale_up(const WorldScalar& scaleUpAmount);
|
||||
|
||||
ClientPortionID get_max_id(ServerPortionID serverID) const;
|
||||
|
||||
const std::vector<ServerClientID>& sorted_grid_ids();
|
||||
|
||||
std::unordered_map<ServerClientID, WorldGrid> grids;
|
||||
NetworkingObjects::NetObjPtr<NetworkingObjects::NetObjOrderedList<WorldGrid>> grids;
|
||||
World& world;
|
||||
private:
|
||||
bool changed = true;
|
||||
std::vector<ServerClientID> sortedGridIDs;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ MainProgram::MainProgram():
|
|||
NetworkingObjects::register_ordered_list_class<std::string>(*netObjectTypeList);
|
||||
NetworkingObjects::register_generic_serialized_class<Bookmark>(*netObjectTypeList);
|
||||
NetworkingObjects::register_ordered_list_class<Bookmark>(*netObjectTypeList);
|
||||
NetworkingObjects::register_generic_serialized_class<WorldGrid>(*netObjectTypeList);
|
||||
NetworkingObjects::register_ordered_list_class<WorldGrid>(*netObjectTypeList);
|
||||
|
||||
displayName = Random::get().alphanumeric_str(10);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ enum ServerCommands : MessageCommandType {
|
|||
SERVER_NEW_RESOURCE_DATA,
|
||||
SERVER_CHAT_MESSAGE,
|
||||
SERVER_CANVAS_COLOR,
|
||||
SERVER_SET_GRID,
|
||||
SERVER_REMOVE_GRID,
|
||||
SERVER_CANVAS_SCALE
|
||||
};
|
||||
|
||||
|
|
@ -43,8 +41,6 @@ enum ClientCommands : MessageCommandType {
|
|||
CLIENT_NEW_RESOURCE_DATA,
|
||||
CLIENT_CHAT_MESSAGE,
|
||||
CLIENT_CANVAS_COLOR,
|
||||
CLIENT_SET_GRID,
|
||||
CLIENT_REMOVE_GRID,
|
||||
CLIENT_CANVAS_SCALE
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID):
|
|||
data.idToComponentMap.emplace(data.components.back()->id, data.components.back());
|
||||
}
|
||||
data.canvasScale = world.canvasScale;
|
||||
data.grids = world.gridMan.grids;
|
||||
data.resources = world.rMan.resource_list();
|
||||
data.canvasBackColor = convert_vec3<Vector3f>(world.canvasTheme.backColor);
|
||||
|
||||
|
|
@ -75,6 +74,7 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID):
|
|||
cereal::PortableBinaryOutputArchive a(*ss);
|
||||
a(CLIENT_INITIAL_DATA, isDirectConnect, newClient.serverID, newClient.cursorColor, newClient.displayName, newClient.camCoords, newClient.windowSize, fileDisplayName, clients, data);
|
||||
world.bMan.bookmarks.write_create_message(a);
|
||||
world.gridMan.grids.write_create_message(a);
|
||||
}
|
||||
netServer->send_string_stream_to_client(client, RELIABLE_COMMAND_CHANNEL, ss);
|
||||
for(auto& [id, rData] : data.resources) {
|
||||
|
|
@ -229,24 +229,6 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID):
|
|||
message(chatMessage);
|
||||
netServer->send_items_to_all_clients_except(client, RELIABLE_COMMAND_CHANNEL, CLIENT_CHAT_MESSAGE, client->customID, chatMessage);
|
||||
});
|
||||
netServer->add_recv_callback(SERVER_SET_GRID, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
|
||||
ServerClientID gID;
|
||||
message(gID);
|
||||
WorldGrid& g = data.grids[gID];
|
||||
message(g);
|
||||
|
||||
auto& c = clients[client->customID];
|
||||
if(c.canvasScale < data.canvasScale)
|
||||
g.scale_up(FixedPoint::pow_int(CANVAS_SCALE_UP_STEP, data.canvasScale - c.canvasScale));
|
||||
|
||||
netServer->send_items_to_all_clients(RELIABLE_COMMAND_CHANNEL, CLIENT_SET_GRID, gID, g);
|
||||
});
|
||||
netServer->add_recv_callback(SERVER_REMOVE_GRID, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
|
||||
ServerClientID gID;
|
||||
message(gID);
|
||||
data.grids.erase(gID);
|
||||
netServer->send_items_to_all_clients(RELIABLE_COMMAND_CHANNEL, CLIENT_REMOVE_GRID, gID);
|
||||
});
|
||||
netServer->add_recv_callback(SERVER_CANVAS_COLOR, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
|
||||
message(data.canvasBackColor);
|
||||
netServer->send_items_to_all_clients(RELIABLE_COMMAND_CHANNEL, CLIENT_CANVAS_COLOR, data.canvasBackColor);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ void ServerData::save(cereal::PortableBinaryOutputArchive& a) const {
|
|||
a((uint64_t)components.size());
|
||||
for(uint64_t i = 0; i < components.size(); i++)
|
||||
a(components[i]->get_type(), components[i]->id, components[i]->coords, *components[i]);
|
||||
a(grids);
|
||||
}
|
||||
|
||||
void ServerData::load(cereal::PortableBinaryInputArchive& a) {
|
||||
|
|
@ -21,12 +20,9 @@ void ServerData::load(cereal::PortableBinaryInputArchive& a) {
|
|||
components.emplace_back(newComp);
|
||||
idToComponentMap.emplace(newComp->id, newComp);
|
||||
}
|
||||
a(grids);
|
||||
}
|
||||
|
||||
void ServerData::scale_up(const WorldScalar& scaleUpAmount) {
|
||||
for(auto& [n, g] : grids)
|
||||
g.scale_up(scaleUpAmount);
|
||||
for(auto& c : components)
|
||||
c->scale_up(scaleUpAmount);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ class ServerData {
|
|||
std::vector<std::shared_ptr<DrawComponent>> components;
|
||||
std::unordered_map<ServerClientID, std::shared_ptr<DrawComponent>> idToComponentMap;
|
||||
std::unordered_map<ServerClientID, ResourceData> resources;
|
||||
std::unordered_map<ServerClientID, WorldGrid> grids;
|
||||
uint64_t canvasScale = 0;
|
||||
Vector3f canvasBackColor;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "Helpers/ConvertVec.hpp"
|
||||
#include "Helpers/FileDownloader.hpp"
|
||||
#include "Helpers/Networking/NetLibrary.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjGenericSerializedClass.hpp"
|
||||
#include "MainProgram.hpp"
|
||||
#include "GUIStuff/Elements/Element.hpp"
|
||||
#include "GUIStuff/GUIManager.hpp"
|
||||
|
|
@ -708,13 +709,12 @@ void Toolbar::grid_menu(bool justOpened) {
|
|||
gui.obstructing_window();
|
||||
gui.text_label_centered("Grids");
|
||||
float entryHeight = 25.0f;
|
||||
if(main.world->gridMan.sorted_grid_ids().empty())
|
||||
if(main.world->gridMan.grids->empty())
|
||||
gui.text_label_centered("No grids yet...");
|
||||
ServerClientID toDelete{0, 0};
|
||||
gui.scroll_bar_many_entries_area("grid menu entries", entryHeight, main.world->gridMan.sorted_grid_ids().size(), true, [&](size_t i, bool isListHovered) {
|
||||
ServerClientID gridID = main.world->gridMan.sorted_grid_ids()[i];
|
||||
WorldGrid& grid = main.world->gridMan.grids[gridID];
|
||||
bool selectedEntry = gridID == gridMenu.gridSelected;
|
||||
uint32_t toDelete = std::numeric_limits<uint32_t>::max();
|
||||
gui.scroll_bar_many_entries_area("grid menu entries", entryHeight, main.world->gridMan.grids->size(), true, [&](size_t i, bool isListHovered) {
|
||||
auto& grid = main.world->gridMan.grids->at(i);
|
||||
bool selectedEntry = gridMenu.selectedGrid == i;
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(entryHeight)},
|
||||
|
|
@ -724,7 +724,7 @@ void Toolbar::grid_menu(bool justOpened) {
|
|||
},
|
||||
.backgroundColor = selectedEntry ? convert_vec4<Clay_Color>(io->theme->backColor1) : convert_vec4<Clay_Color>(io->theme->backColor2)
|
||||
}) {
|
||||
gui.text_label(grid.get_display_name());
|
||||
gui.text_label(grid->get_display_name());
|
||||
bool miniButtonClicked = false;
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
|
|
@ -734,32 +734,31 @@ void Toolbar::grid_menu(bool justOpened) {
|
|||
.layoutDirection = CLAY_LEFT_TO_RIGHT
|
||||
}
|
||||
}) {
|
||||
if(gui.svg_icon_button_transparent("visibility eye", grid.visible ? "data/icons/eyeopen.svg" : "data/icons/eyeclose.svg", false, entryHeight, false)) {
|
||||
if(gui.svg_icon_button_transparent("visibility eye", grid->visible ? "data/icons/eyeopen.svg" : "data/icons/eyeclose.svg", false, entryHeight, false)) {
|
||||
miniButtonClicked = true;
|
||||
WorldGrid oldGrid = grid;
|
||||
grid.visible = !grid.visible;
|
||||
main.world->gridMan.send_grid_info(oldGrid, gridID);
|
||||
grid->visible = !grid->visible;
|
||||
NetworkingObjects::generic_serialized_class_send_update_to_all<WorldGrid>(grid);
|
||||
}
|
||||
if(gui.svg_icon_button_transparent("edit pencil", "data/icons/pencil.svg", false, entryHeight, false)) {
|
||||
miniButtonClicked = true;
|
||||
main.world->drawProg.modify_grid(gridID);
|
||||
main.world->drawProg.modify_grid(grid);
|
||||
stop_displaying_grid_menu();
|
||||
}
|
||||
if(gui.svg_icon_button_transparent("delete trash", "data/icons/trash.svg", false, entryHeight, false)) {
|
||||
miniButtonClicked = true;
|
||||
toDelete = gridID;
|
||||
toDelete = i;
|
||||
}
|
||||
}
|
||||
if(Clay_Hovered() && io->mouse.leftClick && isListHovered && !miniButtonClicked) {
|
||||
gridMenu.gridSelected = gridID;
|
||||
gridMenu.selectedGrid = i;
|
||||
if(io->mouse.leftClick >= 2) {
|
||||
main.world->drawProg.modify_grid(gridID);
|
||||
main.world->drawProg.modify_grid(grid);
|
||||
stop_displaying_grid_menu();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if(toDelete != ServerClientID{0, 0})
|
||||
if(toDelete != std::numeric_limits<uint32_t>::max())
|
||||
main.world->gridMan.remove_grid(toDelete);
|
||||
gui.left_to_right_line_layout([&]() {
|
||||
bool addByEnter = false;
|
||||
|
|
@ -767,7 +766,8 @@ void Toolbar::grid_menu(bool justOpened) {
|
|||
addByEnter = s.selected && io->key.enter;
|
||||
});
|
||||
if(gui.svg_icon_button("grid add button", "data/icons/plus.svg", false, GUIStuff::GUIManager::SMALL_BUTTON_SIZE) || (addByEnter && !gridMenu.newName.empty())) {
|
||||
main.world->drawProg.modify_grid(main.world->gridMan.add_default_grid(gridMenu.newName));
|
||||
main.world->gridMan.add_default_grid(gridMenu.newName);
|
||||
main.world->drawProg.modify_grid(main.world->gridMan.grids->at(main.world->gridMan.grids->size() - 1));
|
||||
stop_displaying_grid_menu();
|
||||
}
|
||||
});
|
||||
|
|
@ -782,7 +782,7 @@ void Toolbar::grid_menu(bool justOpened) {
|
|||
void Toolbar::stop_displaying_grid_menu() {
|
||||
gridMenu.newName.clear();
|
||||
gridMenu.popupOpen = false;
|
||||
gridMenu.gridSelected = ServerClientID{0, 0};
|
||||
gridMenu.selectedGrid = std::numeric_limits<uint32_t>::max();
|
||||
}
|
||||
|
||||
void Toolbar::bookmark_menu(bool justOpened) {
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ class Toolbar {
|
|||
struct GridMenu {
|
||||
bool popupOpen = false;
|
||||
std::string newName;
|
||||
ServerClientID gridSelected = {0, 0};
|
||||
uint32_t selectedGrid = std::numeric_limits<uint32_t>::max();
|
||||
} gridMenu;
|
||||
|
||||
bool useNativeFilePicker = true;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ World::World(MainProgram& initMain, OpenWorldInfo& worldInfo):
|
|||
|
||||
drawProg.init_client_callbacks();
|
||||
rMan.init_client_callbacks();
|
||||
gridMan.init_client_callbacks();
|
||||
init_client_callbacks();
|
||||
con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_INITIAL_DATA, displayName, false);
|
||||
}
|
||||
|
|
@ -87,8 +86,8 @@ void World::init_client_callbacks() {
|
|||
set_canvas_background_color(newBackColor, false);
|
||||
message(canvasScale);
|
||||
drawProg.initialize_draw_data(message);
|
||||
message(gridMan);
|
||||
bMan.bookmarks = netObjMan.read_create_message<NetworkingObjects::NetObjOrderedList<Bookmark>>(message, nullptr);
|
||||
gridMan.grids = netObjMan.read_create_message<NetworkingObjects::NetObjOrderedList<WorldGrid>>(message, nullptr);
|
||||
}
|
||||
nextClientID = get_max_id(ownID);
|
||||
clientStillConnecting = false;
|
||||
|
|
@ -284,7 +283,6 @@ void World::start_hosting(const std::string& initNetSource, const std::string& s
|
|||
con.init_local_p2p(*this, serverLocalID);
|
||||
drawProg.init_client_callbacks();
|
||||
rMan.init_client_callbacks();
|
||||
gridMan.init_client_callbacks();
|
||||
init_client_callbacks();
|
||||
con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_INITIAL_DATA, displayName, true, drawData.cam.c, main.window.size.cast<float>().eval());
|
||||
conType = CONNECTIONTYPE_SERVER;
|
||||
|
|
@ -374,7 +372,7 @@ void World::load_from_file(const std::filesystem::path& filePathToLoadFrom, std:
|
|||
}
|
||||
|
||||
ClientPortionID World::get_max_id(ServerPortionID serverID) {
|
||||
return std::max(std::max(rMan.get_max_id(serverID), drawProg.get_max_id(serverID)), gridMan.get_max_id(serverID));
|
||||
return std::max(rMan.get_max_id(serverID), drawProg.get_max_id(serverID));
|
||||
}
|
||||
|
||||
void World::save_file(cereal::PortableBinaryOutputArchive& a) const {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue