Improved online performance for canvases with many components
This commit is contained in:
parent
8a36bc4b6d
commit
b6a25280e6
16 changed files with 406 additions and 183 deletions
|
|
@ -23,6 +23,7 @@
|
|||
#include "../MainProgram.hpp"
|
||||
#include <Helpers/Logger.hpp>
|
||||
#include <Helpers/Parallel.hpp>
|
||||
#include <cereal/types/unordered_set.hpp>
|
||||
|
||||
DrawingProgram::DrawingProgram(World& initWorld):
|
||||
world(initWorld),
|
||||
|
|
@ -52,15 +53,9 @@ DrawingProgram::DrawingProgram(World& initWorld):
|
|||
};
|
||||
components.clientEraseCallback = [&](const CollabListType::ObjectInfoPtr& c) {
|
||||
compCache.erase_component(c);
|
||||
delayedUpdateTransformComponents.erase(c->obj);
|
||||
delayedUpdateComponents.erase(c->obj);
|
||||
updateableComponents.erase(c->obj);
|
||||
};
|
||||
components.clientEraseSetCallback = [&](const std::unordered_set<CollabListType::ObjectInfoPtr>& comps) {
|
||||
for(auto& c : comps) {
|
||||
delayedUpdateTransformComponents.erase(c->obj);
|
||||
updateableComponents.erase(c->obj);
|
||||
}
|
||||
};
|
||||
components.clientInsertOrderedVectorCallback = [&](const std::vector<CollabListType::ObjectInfoPtr>& comps) {
|
||||
for(auto& c : comps)
|
||||
components.clientInsertCallback(c);
|
||||
|
|
@ -75,10 +70,10 @@ void DrawingProgram::init_client_callbacks() {
|
|||
bool isTemp;
|
||||
ServerClientID id;
|
||||
message(isTemp, id);
|
||||
std::shared_ptr<DrawComponent>* compPtr = components.get_item_by_id(id);
|
||||
if(!compPtr)
|
||||
auto objPtr = components.get_item_by_id(id);
|
||||
if(!objPtr)
|
||||
return;
|
||||
std::shared_ptr<DrawComponent>& comp = *compPtr;
|
||||
std::shared_ptr<DrawComponent>& comp = objPtr->obj;
|
||||
float dur = std::chrono::duration_cast<std::chrono::duration<float>>(std::chrono::steady_clock::now() - comp->lastUpdateTime).count();
|
||||
if(dur > CLIENT_DRAWCOMP_DELAY_TIMER_DURATION){
|
||||
comp->delayedUpdatePtr = nullptr;
|
||||
|
|
@ -91,31 +86,22 @@ void DrawingProgram::init_client_callbacks() {
|
|||
else {
|
||||
comp->delayedUpdatePtr = DrawComponent::allocate_comp_type(comp->get_type());
|
||||
message(*comp->delayedUpdatePtr);
|
||||
delayedUpdateTransformComponents.emplace(comp);
|
||||
delayedUpdateComponents.emplace(comp);
|
||||
}
|
||||
});
|
||||
world.con.client_add_recv_callback(CLIENT_TRANSFORM_COMPONENT, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
bool isTemp;
|
||||
ServerClientID id;
|
||||
message(isTemp, id);
|
||||
std::shared_ptr<DrawComponent>* compPtr = components.get_item_by_id(id);
|
||||
if(!compPtr)
|
||||
message(id);
|
||||
auto objPtr = components.get_item_by_id(id);
|
||||
if(!objPtr)
|
||||
return;
|
||||
std::shared_ptr<DrawComponent>& comp = *compPtr;
|
||||
float dur = std::chrono::duration_cast<std::chrono::duration<float>>(std::chrono::steady_clock::now() - comp->lastTransformTime).count();
|
||||
if(dur > CLIENT_DRAWCOMP_DELAY_TIMER_DURATION){
|
||||
comp->delayedCoordinateSpace = nullptr;
|
||||
message(comp->coords);
|
||||
if(!isTemp)
|
||||
comp->finalize_update(*this); // No need to update draw data during transformation
|
||||
}
|
||||
else {
|
||||
comp->delayedCoordinateSpace = std::make_shared<CoordSpaceHelper>();
|
||||
message(*comp->delayedCoordinateSpace);
|
||||
delayedUpdateTransformComponents.emplace(comp);
|
||||
}
|
||||
if(selection.is_selected(objPtr)) // Whatever transformation we're doing right now will overwrite this transformation, so we can ignore this message
|
||||
return;
|
||||
std::shared_ptr<DrawComponent>& comp = objPtr->obj;
|
||||
message(comp->coords);
|
||||
comp->finalize_update(*this); // No need to update draw data during transformation
|
||||
});
|
||||
world.con.client_add_recv_callback(CLIENT_PLACE_COMPONENT, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
world.con.client_add_recv_callback(CLIENT_PLACE_SINGLE_COMPONENT, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
uint64_t insertPosition;
|
||||
DrawComponentType type;
|
||||
message(insertPosition, type);
|
||||
|
|
@ -126,17 +112,42 @@ void DrawingProgram::init_client_callbacks() {
|
|||
if(didntExistPreviously)
|
||||
newObj->final_update(*this);
|
||||
});
|
||||
world.con.client_add_recv_callback(CLIENT_ERASE_COMPONENT, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
ServerClientID cToRemove;
|
||||
message(cToRemove);
|
||||
components.server_erase(cToRemove);
|
||||
world.con.client_add_recv_callback(CLIENT_PLACE_MANY_COMPONENTS, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
std::vector<CollabListType::ObjectInfoPtr> sortedPlacedComponents;
|
||||
|
||||
SendOrderedComponentVectorOp a{&sortedPlacedComponents};
|
||||
message(a);
|
||||
|
||||
std::vector<bool> didntExistPreviously = components.server_insert_ordered_vector(sortedPlacedComponents);
|
||||
if(sortedPlacedComponents.size() >= DrawingProgramCache::MINIMUM_COMPONENTS_TO_START_REBUILD) {
|
||||
parallel_loop_container(sortedPlacedComponents, [&](const auto& c){
|
||||
c->obj->final_update(*this, false);
|
||||
});
|
||||
force_rebuild_cache();
|
||||
}
|
||||
else {
|
||||
for(size_t i = 0; i < sortedPlacedComponents.size(); i++) {
|
||||
if(didntExistPreviously[i])
|
||||
sortedPlacedComponents[i]->obj->final_update(*this);
|
||||
}
|
||||
}
|
||||
});
|
||||
world.con.client_add_recv_callback(CLIENT_ERASE_SINGLE_COMPONENT, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
ServerClientID idToErase;
|
||||
message(idToErase);
|
||||
components.server_erase(idToErase);
|
||||
});
|
||||
world.con.client_add_recv_callback(CLIENT_ERASE_MANY_COMPONENTS, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
std::unordered_set<ServerClientID> idsToErase;
|
||||
message(idsToErase);
|
||||
components.server_erase_set(idsToErase);
|
||||
});
|
||||
}
|
||||
|
||||
void DrawingProgram::check_delayed_update_transform_timers() {
|
||||
std::erase_if(delayedUpdateTransformComponents, [&](auto& comp) {
|
||||
void DrawingProgram::check_delayed_update_timers() {
|
||||
std::erase_if(delayedUpdateComponents, [&](auto& comp) {
|
||||
comp->check_timers(*this);
|
||||
return !comp->delayedUpdatePtr && !comp->delayedCoordinateSpace;
|
||||
return !comp->delayedUpdatePtr;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -352,11 +363,26 @@ void DrawingProgram::update() {
|
|||
if(controls.leftClickReleased)
|
||||
controls.leftClickReleased = false;
|
||||
|
||||
check_delayed_update_transform_timers();
|
||||
check_delayed_update_timers();
|
||||
check_updateable_components();
|
||||
|
||||
compCache.update();
|
||||
selection.update();
|
||||
|
||||
if(controls.selectedTool == TOOL_ERASER)
|
||||
compCache.test_rebuild_dont_include_set_dont_include_nodes(components.client_list(), eraserTool.erasedComponents, eraserTool.erasedBVHNodes);
|
||||
else if(controls.selectedTool == TOOL_RECTSELECT)
|
||||
compCache.test_rebuild_dont_include_set(components.client_list(), selection.get_selected_set());
|
||||
else
|
||||
compCache.test_rebuild(components.client_list());
|
||||
}
|
||||
|
||||
void DrawingProgram::force_rebuild_cache() {
|
||||
if(controls.selectedTool == TOOL_ERASER)
|
||||
compCache.test_rebuild_dont_include_set_dont_include_nodes(components.client_list(), eraserTool.erasedComponents, eraserTool.erasedBVHNodes, true);
|
||||
else if(controls.selectedTool == TOOL_RECTSELECT)
|
||||
compCache.test_rebuild_dont_include_set(components.client_list(), selection.get_selected_set(), true);
|
||||
else
|
||||
compCache.test_rebuild(components.client_list(), true);
|
||||
}
|
||||
|
||||
void DrawingProgram::drag_drop_update() {
|
||||
|
|
@ -448,7 +474,7 @@ void DrawingProgram::initialize_draw_data(cereal::PortableBinaryInputArchive& a)
|
|||
parallel_loop_all_components([&](const auto& c){
|
||||
c->obj->final_update(*this, false);
|
||||
});
|
||||
compCache.force_rebuild(components.client_list());
|
||||
compCache.test_rebuild(components.client_list(), true);
|
||||
}
|
||||
|
||||
void DrawingProgram::add_undo_place_component(uint64_t placement, const std::shared_ptr<DrawComponent>& comp) {
|
||||
|
|
@ -476,15 +502,17 @@ void DrawingProgram::add_undo_place_components(uint64_t placement, const std::ve
|
|||
world.undo.push(UndoManager::UndoRedoPair{
|
||||
[&, comps]() {
|
||||
bool toRet = true;
|
||||
std::unordered_set<ServerClientID> idsToErase;
|
||||
for(auto& c : comps) {
|
||||
if(!c->collabListInfo.lock())
|
||||
toRet = false;
|
||||
else {
|
||||
idsToErase.emplace(c->collabListInfo.lock()->id);
|
||||
ServerClientID compID;
|
||||
c->client_send_erase(*this);
|
||||
components.client_erase(c, compID);
|
||||
}
|
||||
}
|
||||
DrawComponent::client_send_erase_set(*this, idsToErase);
|
||||
reset_tools();
|
||||
return toRet;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -55,14 +55,16 @@ class DrawingProgram {
|
|||
CollabListType components;
|
||||
|
||||
std::unordered_set<std::shared_ptr<DrawComponent>> updateableComponents;
|
||||
std::unordered_set<std::shared_ptr<DrawComponent>> delayedUpdateTransformComponents;
|
||||
std::unordered_set<std::shared_ptr<DrawComponent>> delayedUpdateComponents;
|
||||
|
||||
Vector4f* get_foreground_color_ptr();
|
||||
private:
|
||||
|
||||
void check_delayed_update_transform_timers();
|
||||
void check_delayed_update_timers();
|
||||
void check_updateable_components();
|
||||
|
||||
void force_rebuild_cache();
|
||||
|
||||
std::atomic<bool> addFileInNextFrame = false;
|
||||
std::pair<std::string, Vector2f> addFileInfo;
|
||||
|
||||
|
|
|
|||
|
|
@ -49,9 +49,45 @@ void DrawingProgramCache::clear_own_cached_surfaces() {
|
|||
});
|
||||
}
|
||||
|
||||
void DrawingProgramCache::update() {
|
||||
if(!disableRefresh && unsortedComponents.size() >= 1000 && (std::chrono::steady_clock::now() - lastBvhBuildTime) >= std::chrono::seconds(5))
|
||||
force_rebuild(drawP.components.client_list());
|
||||
bool DrawingProgramCache::check_if_rebuild_should_occur() {
|
||||
return (unsortedComponents.size() >= MINIMUM_COMPONENTS_TO_START_REBUILD && (std::chrono::steady_clock::now() - lastBvhBuildTime) >= std::chrono::seconds(5));
|
||||
}
|
||||
|
||||
void DrawingProgramCache::test_rebuild(const std::vector<CollabListType::ObjectInfoPtr>& comps, bool force) {
|
||||
if(force || check_if_rebuild_should_occur())
|
||||
force_rebuild(comps);
|
||||
}
|
||||
|
||||
void DrawingProgramCache::test_rebuild_dont_include_set(const std::vector<CollabListType::ObjectInfoPtr>& comps, const std::unordered_set<CollabListType::ObjectInfoPtr>& objsToNotInclude, bool force) {
|
||||
if(force || check_if_rebuild_should_occur())
|
||||
force_rebuild_dont_include_objs(comps, objsToNotInclude);
|
||||
}
|
||||
|
||||
void DrawingProgramCache::test_rebuild_dont_include_set_dont_include_nodes(const std::vector<CollabListType::ObjectInfoPtr>& comps, const std::unordered_set<CollabListType::ObjectInfoPtr>& objsToNotInclude, const std::unordered_set<std::shared_ptr<DrawingProgramCacheBVHNode>>& nodesToNotInclude, bool force) {
|
||||
if(force || check_if_rebuild_should_occur()) {
|
||||
auto objsToNotIncludeNew = objsToNotInclude;
|
||||
move_components_from_bvh_nodes_to_set(objsToNotIncludeNew, nodesToNotInclude);
|
||||
force_rebuild_dont_include_objs(comps, objsToNotIncludeNew);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawingProgramCache::move_components_from_bvh_nodes_to_set(std::unordered_set<CollabListType::ObjectInfoPtr>& s, const std::unordered_set<std::shared_ptr<DrawingProgramCacheBVHNode>>& bvhNodes) {
|
||||
for(auto& b : bvhNodes)
|
||||
move_components_from_bvh_node_to_set(s, b);
|
||||
}
|
||||
|
||||
void DrawingProgramCache::move_components_from_bvh_node_to_set(std::unordered_set<CollabListType::ObjectInfoPtr>& s, const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode) {
|
||||
for(auto& c : bvhNode->components)
|
||||
s.emplace(c);
|
||||
for(auto& p : bvhNode->children)
|
||||
move_components_from_bvh_node_to_set(s, p);
|
||||
}
|
||||
|
||||
void DrawingProgramCache::force_rebuild_dont_include_objs(std::vector<CollabListType::ObjectInfoPtr> componentsToBuild, const std::unordered_set<CollabListType::ObjectInfoPtr>& objsToNotInclude) {
|
||||
std::erase_if(componentsToBuild, [&objsToNotInclude](auto& c) {
|
||||
return objsToNotInclude.contains(c);
|
||||
});
|
||||
build(componentsToBuild);
|
||||
}
|
||||
|
||||
void DrawingProgramCache::force_rebuild(const std::vector<CollabListType::ObjectInfoPtr>& componentsToBuild) {
|
||||
|
|
@ -151,7 +187,7 @@ void DrawingProgramCache::build_bvh_node(const std::shared_ptr<DrawingProgramCac
|
|||
|
||||
build_bvh_node_coords_and_resolution(*bvhNode);
|
||||
|
||||
if(components.size() < 100) {
|
||||
if(components.size() < MAXIMUM_COMPONENTS_IN_SINGLE_NODE) {
|
||||
bvhNode->components = components;
|
||||
for(auto& c : bvhNode->components)
|
||||
c->obj->parentBvhNode = bvhNode;
|
||||
|
|
|
|||
|
|
@ -33,16 +33,24 @@ class DrawingProgramCache {
|
|||
DrawingProgramCache(DrawingProgram& initDrawP);
|
||||
~DrawingProgramCache();
|
||||
|
||||
static std::unordered_set<std::shared_ptr<DrawingProgramCacheBVHNode>> nodesWithCachedSurfaces;
|
||||
bool disableRefresh = false;
|
||||
static constexpr size_t MINIMUM_COMPONENTS_TO_START_REBUILD = 1000;
|
||||
static constexpr size_t MAXIMUM_COMPONENTS_IN_SINGLE_NODE = 100;
|
||||
|
||||
static std::unordered_set<std::shared_ptr<DrawingProgramCacheBVHNode>> nodesWithCachedSurfaces;
|
||||
|
||||
bool check_if_rebuild_should_occur();
|
||||
void test_rebuild(const std::vector<CollabListType::ObjectInfoPtr>& comps, bool force = false);
|
||||
void test_rebuild_dont_include_set(const std::vector<CollabListType::ObjectInfoPtr>& comps, const std::unordered_set<CollabListType::ObjectInfoPtr>& objsToNotInclude, bool force = false);
|
||||
void test_rebuild_dont_include_set_dont_include_nodes(const std::vector<CollabListType::ObjectInfoPtr>& comps, const std::unordered_set<CollabListType::ObjectInfoPtr>& objsToNotInclude, const std::unordered_set<std::shared_ptr<DrawingProgramCacheBVHNode>>& nodesToNotInclude, bool force = false);
|
||||
|
||||
static void move_components_from_bvh_nodes_to_set(std::unordered_set<CollabListType::ObjectInfoPtr>& s, const std::unordered_set<std::shared_ptr<DrawingProgramCacheBVHNode>>& bvhNodes);
|
||||
static void move_components_from_bvh_node_to_set(std::unordered_set<CollabListType::ObjectInfoPtr>& s, const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode);
|
||||
|
||||
void update();
|
||||
void erase_component(const CollabListType::ObjectInfoPtr& c);
|
||||
void add_component(const CollabListType::ObjectInfoPtr& c);
|
||||
void refresh_all_draw_cache(const DrawData& drawData);
|
||||
void traverse_bvh_run_function(const SCollision::AABB<WorldScalar>& aabb, std::function<bool(const std::shared_ptr<DrawingProgramCacheBVHNode>& node, const std::vector<CollabListType::ObjectInfoPtr>& components)> f);
|
||||
void traverse_bvh_erase_function(const SCollision::AABB<WorldScalar>& aabb, std::function<bool(const std::shared_ptr<DrawingProgramCacheBVHNode>& node, std::vector<CollabListType::ObjectInfoPtr>& components)> f);
|
||||
void force_rebuild(const std::vector<CollabListType::ObjectInfoPtr>& componentsToBuild);
|
||||
// Run before actually updating the component
|
||||
void preupdate_component(const CollabListType::ObjectInfoPtr& c);
|
||||
void invalidate_cache_before_pos(uint64_t placementToInvalidateAt);
|
||||
|
|
@ -53,6 +61,9 @@ class DrawingProgramCache {
|
|||
const std::chrono::steady_clock::time_point& get_last_bvh_build_time() const;
|
||||
void clear_own_cached_surfaces();
|
||||
private:
|
||||
void force_rebuild_dont_include_objs(std::vector<CollabListType::ObjectInfoPtr> componentsToBuild, const std::unordered_set<CollabListType::ObjectInfoPtr>& objsToNotInclude);
|
||||
void force_rebuild(const std::vector<CollabListType::ObjectInfoPtr>& componentsToBuild);
|
||||
|
||||
bool traverse_bvh_erase_function_recursive(const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode, const SCollision::AABB<WorldScalar>& aabb, std::function<bool(const std::shared_ptr<DrawingProgramCacheBVHNode>& node, std::vector<CollabListType::ObjectInfoPtr>& components)> f);
|
||||
void build_bvh_node_coords_and_resolution(DrawingProgramCacheBVHNode& node);
|
||||
void refresh_draw_cache(const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode, const DrawData& drawData);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ DrawingProgramSelection::DrawingProgramSelection(DrawingProgram& initDrawP):
|
|||
drawP(initDrawP)
|
||||
{}
|
||||
|
||||
const std::unordered_set<CollabListType::ObjectInfoPtr>& DrawingProgramSelection::get_selected_set() {
|
||||
return selectedSet;
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection<float>& cC) {
|
||||
auto cCWorld = drawP.world.drawData.cam.c.collider_to_world<SCollision::ColliderCollection<WorldScalar>, SCollision::ColliderCollection<float>>(cC);
|
||||
|
||||
|
|
@ -73,19 +77,26 @@ void DrawingProgramSelection::deselect_all() {
|
|||
parallel_loop_container(a, [&](auto& obj) {
|
||||
obj->obj->coords = selectionTransformCoords.other_coord_space_from_this_space(obj->obj->coords);
|
||||
obj->obj->final_update(drawP, false);
|
||||
obj->obj->client_send_transform(drawP);
|
||||
});
|
||||
selectedSet.clear();
|
||||
cache.clear();
|
||||
selectionTransformCoords = CoordSpaceHelper();
|
||||
drawP.compCache.force_rebuild(drawP.components.client_list());
|
||||
drawP.force_rebuild_cache();
|
||||
transformOpHappening = TransformOperation::NONE;
|
||||
}
|
||||
}
|
||||
|
||||
bool DrawingProgramSelection::is_selected(const CollabListType::ObjectInfoPtr& objToCheck) {
|
||||
return selectedSet.contains(objToCheck);
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::update() {
|
||||
if(is_something_selected()) {
|
||||
if(cache.get_unsorted_component_list().size() >= 1000 && (std::chrono::steady_clock::now() - cache.get_last_bvh_build_time()) >= std::chrono::seconds(5))
|
||||
cache.force_rebuild(std::vector<CollabListType::ObjectInfoPtr>(selectedSet.begin(), selectedSet.end()));
|
||||
|
||||
if(cache.check_if_rebuild_should_occur())
|
||||
cache.test_rebuild(std::vector<CollabListType::ObjectInfoPtr>(selectedSet.begin(), selectedSet.end()), true);
|
||||
|
||||
if(drawP.world.main.input.key(InputManager::KEY_DRAW_UNSELECT).pressed)
|
||||
deselect_all();
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ class DrawingProgramSelection {
|
|||
void draw_gui(SkCanvas* canvas, const DrawData& drawData);
|
||||
bool is_something_selected();
|
||||
bool mouse_collided_with_selection();
|
||||
bool is_selected(const CollabListType::ObjectInfoPtr& objToCheck);
|
||||
const std::unordered_set<CollabListType::ObjectInfoPtr>& get_selected_set();
|
||||
private:
|
||||
bool mouse_collided_with_selection_aabb();
|
||||
bool mouse_collided_with_scale_point();
|
||||
|
|
|
|||
|
|
@ -22,16 +22,17 @@ void EraserTool::gui_toolbox() {
|
|||
|
||||
void EraserTool::reset_tool() {
|
||||
if(!erasedComponents.empty()) {
|
||||
for(auto& bvhNode : erasedBVHNodes)
|
||||
move_erased_components_from_bvh_nodes_recursive(bvhNode);
|
||||
DrawingProgramCache::move_components_from_bvh_nodes_to_set(erasedComponents, erasedBVHNodes);
|
||||
|
||||
std::unordered_set<ServerClientID> idsToErase;
|
||||
for(auto& c : erasedComponents)
|
||||
c->obj->client_send_erase(drawP);
|
||||
idsToErase.emplace(c->id);
|
||||
DrawComponent::client_send_erase_set(drawP, idsToErase);
|
||||
drawP.components.client_erase_set(erasedComponents);
|
||||
|
||||
drawP.world.undo.push(UndoManager::UndoRedoPair{
|
||||
[&, erasedCompVal = erasedComponents]() {
|
||||
std::vector<CollabListType::ObjectInfoPtr> sortedObjects(erasedCompVal.begin(), erasedCompVal.end());
|
||||
[&, erasedComponents = erasedComponents]() {
|
||||
std::vector<CollabListType::ObjectInfoPtr> sortedObjects(erasedComponents.begin(), erasedComponents.end());
|
||||
std::sort(sortedObjects.begin(), sortedObjects.end(), [](auto& a, auto& b) {
|
||||
return a->pos < b->pos;
|
||||
});
|
||||
|
|
@ -41,27 +42,27 @@ void EraserTool::reset_tool() {
|
|||
return false;
|
||||
|
||||
drawP.components.client_insert_ordered_vector(sortedObjects);
|
||||
|
||||
for(auto& comp : sortedObjects)
|
||||
comp->obj->client_send_place(drawP);
|
||||
DrawComponent::client_send_place_many(drawP, sortedObjects);
|
||||
|
||||
drawP.reset_tools();
|
||||
|
||||
return true;
|
||||
},
|
||||
[&, erasedCompVal = erasedComponents]() {
|
||||
for(auto& comp : erasedCompVal)
|
||||
[&, erasedComponents = erasedComponents]() {
|
||||
for(auto& comp : erasedComponents)
|
||||
if(!comp->obj->collabListInfo.lock())
|
||||
return false;
|
||||
|
||||
for(auto& comp : erasedCompVal)
|
||||
comp->obj->client_send_erase(drawP);
|
||||
std::unordered_set<ServerClientID> idsToErase;
|
||||
for(auto& c : erasedComponents)
|
||||
idsToErase.emplace(c->id);
|
||||
|
||||
drawP.components.client_erase_set(erasedCompVal);
|
||||
DrawComponent::client_send_erase_set(drawP, idsToErase);
|
||||
drawP.components.client_erase_set(erasedComponents);
|
||||
|
||||
drawP.reset_tools();
|
||||
|
||||
drawP.compCache.force_rebuild(drawP.components.client_list());
|
||||
drawP.force_rebuild_cache();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -69,7 +70,6 @@ void EraserTool::reset_tool() {
|
|||
}
|
||||
erasedComponents.clear();
|
||||
erasedBVHNodes.clear();
|
||||
drawP.compCache.disableRefresh = false;
|
||||
}
|
||||
|
||||
void EraserTool::tool_update() {
|
||||
|
|
@ -82,8 +82,6 @@ void EraserTool::tool_update() {
|
|||
SCollision::generate_wide_line(cC, prevMousePos, drawP.world.main.input.mouse.pos, drawP.controls.relativeWidth * 2.0f, true);
|
||||
auto cCWorld = drawP.world.drawData.cam.c.collider_to_world<SCollision::ColliderCollection<WorldScalar>, SCollision::ColliderCollection<float>>(cC);
|
||||
|
||||
drawP.compCache.disableRefresh = true;
|
||||
|
||||
drawP.compCache.traverse_bvh_erase_function(cCWorld.bounds, [&](const auto& bvhNode, auto& comps) {
|
||||
if(bvhNode &&
|
||||
SCollision::collide(cC, drawP.world.drawData.cam.c.to_space(bvhNode->bounds.min)) &&
|
||||
|
|
@ -109,13 +107,6 @@ void EraserTool::tool_update() {
|
|||
reset_tool();
|
||||
}
|
||||
|
||||
void EraserTool::move_erased_components_from_bvh_nodes_recursive(const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode) {
|
||||
for(auto& c : bvhNode->components)
|
||||
erasedComponents.emplace(c);
|
||||
for(auto& p : bvhNode->children)
|
||||
move_erased_components_from_bvh_nodes_recursive(p);
|
||||
}
|
||||
|
||||
void EraserTool::draw(SkCanvas* canvas, const DrawData& drawData) {
|
||||
if(!drawData.main->toolbar.io->hoverObstructed) {
|
||||
SkColor4f c = drawP.world.main.canvasTheme.toolFrontColor;
|
||||
|
|
|
|||
|
|
@ -12,11 +12,10 @@ class EraserTool {
|
|||
void tool_update();
|
||||
void reset_tool();
|
||||
void draw(SkCanvas* canvas, const DrawData& drawData);
|
||||
private:
|
||||
|
||||
std::unordered_set<CollabListType::ObjectInfoPtr> erasedComponents;
|
||||
std::unordered_set<std::shared_ptr<DrawingProgramCacheBVHNode>> erasedBVHNodes;
|
||||
|
||||
void move_erased_components_from_bvh_nodes_recursive(const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode);
|
||||
private:
|
||||
|
||||
DrawingProgram& drawP;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,13 +35,11 @@ void RectSelectTool::gui_toolbox() {
|
|||
void RectSelectTool::reset_tool() {
|
||||
drawP.selection.deselect_all();
|
||||
controls = RectSelectControls();
|
||||
drawP.compCache.disableRefresh = false;
|
||||
}
|
||||
|
||||
void RectSelectTool::tool_update() {
|
||||
switch(controls.selectionMode) {
|
||||
case 0: {
|
||||
drawP.compCache.disableRefresh = false;
|
||||
if(drawP.controls.leftClick) {
|
||||
if(drawP.selection.is_something_selected()) {
|
||||
if(!drawP.selection.mouse_collided_with_selection())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue