Added layer draw cache, and eraser works again

This commit is contained in:
Yousef Khadadeh 2025-12-28 17:34:33 +03:00
parent c2abccefc2
commit 7549ad23a1
29 changed files with 484 additions and 1434 deletions

View file

@ -8,10 +8,25 @@ void DrawingProgramLayer::draw(SkCanvas* canvas, const DrawData& drawData) const
p->obj->draw(canvas, drawData);
}
void DrawingProgramLayer::set_component_list_callbacks(DrawingProgramLayerManager& layerMan) const {
void DrawingProgramLayer::set_component_list_callbacks(DrawingProgramLayerListItem& layerListItem, DrawingProgramLayerManager& layerMan) const {
components->set_insert_callback([&](const CanvasComponentContainer::ObjInfoSharedPtr& c) {
c->obj->set_owner_obj_info(c);
c->obj->parentLayer = &layerListItem;
c->obj->commit_update(layerMan.drawP); // Run commit update on insert so that world bounds are calculated
layerMan.drawP.drawCache.add_component(c);
if(c->obj->get_comp().get_type() == CanvasComponentType::IMAGE)
layerMan.drawP.updateableComponents.emplace(c);
});
components->set_erase_callback([&](const CanvasComponentContainer::ObjInfoSharedPtr& c) {
layerMan.drawP.drawCache.erase_component(c);
layerMan.drawP.drawTool->erase_component(c);
std::erase_if(layerMan.drawP.droppedDownloadingFiles, [&c](auto& downloadingFile) {
return downloadingFile.comp == c;
});
layerMan.drawP.updateableComponents.erase(c);
});
components->set_move_callback([&](const CanvasComponentContainer::ObjInfoSharedPtr& c, uint32_t oldPos) {
layerMan.drawP.drawCache.invalidate_cache_at_aabb(c->obj->get_world_bounds());
});
}

View file

@ -8,7 +8,7 @@ class DrawingProgramLayerManager;
class DrawingProgramLayer {
public:
void draw(SkCanvas* canvas, const DrawData& drawData) const;
void set_component_list_callbacks(DrawingProgramLayerManager& layerMan) const;
void set_component_list_callbacks(DrawingProgramLayerListItem& layerListItem, DrawingProgramLayerManager& layerMan) const;
void commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan) const;
void get_flattened_component_list(std::vector<CanvasComponentContainer::ObjInfoSharedPtr>& objList) const;

View file

@ -36,7 +36,7 @@ void DrawingProgramLayerListItem::set_component_list_callbacks(DrawingProgramLay
if(folderData)
folderData->set_component_list_callbacks(layerMan);
else
layerData->set_component_list_callbacks(layerMan);
layerData->set_component_list_callbacks(*this, layerMan);
}
void DrawingProgramLayerListItem::commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan) {
@ -90,10 +90,11 @@ const std::string& DrawingProgramLayerListItem::get_name() const {
return nameData->name;
}
void DrawingProgramLayerListItem::set_alpha(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, float newAlpha) const {
void DrawingProgramLayerListItem::set_alpha(DrawingProgramLayerManager& layerMan, float newAlpha) const {
if(displayData && displayData->alpha != newAlpha) {
displayData->alpha = newAlpha;
delayedNetObjMan.send_update_to_all<DisplayData>(displayData, false);
// MUST CLEAR CACHE
layerMan.drawP.world.delayedUpdateObjectManager.send_update_to_all<DisplayData>(displayData, false);
}
}
@ -101,10 +102,11 @@ float DrawingProgramLayerListItem::get_alpha() const {
return displayData->alpha;
}
void DrawingProgramLayerListItem::set_visible(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, bool newVisible) const {
void DrawingProgramLayerListItem::set_visible(DrawingProgramLayerManager& layerMan, bool newVisible) const {
if(displayData && displayData->visible != newVisible) {
displayData->visible = newVisible;
delayedNetObjMan.send_update_to_all<DisplayData>(displayData, false);
// MUST CLEAR CACHE
layerMan.drawP.world.delayedUpdateObjectManager.send_update_to_all<DisplayData>(displayData, false);
}
}
@ -112,10 +114,11 @@ bool DrawingProgramLayerListItem::get_visible() const {
return displayData->visible;
}
void DrawingProgramLayerListItem::set_blend_mode(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, SerializedBlendMode newBlendMode) const {
void DrawingProgramLayerListItem::set_blend_mode(DrawingProgramLayerManager& layerMan, SerializedBlendMode newBlendMode) const {
if(displayData && displayData->blendMode != newBlendMode) {
displayData->blendMode = newBlendMode;
delayedNetObjMan.send_update_to_all<DisplayData>(displayData, false);
// MUST CLEAR CACHE
layerMan.drawP.world.delayedUpdateObjectManager.send_update_to_all<DisplayData>(displayData, false);
}
}
@ -133,7 +136,11 @@ void DrawingProgramLayerListItem::register_class(World& w) {
.readUpdateFuncServer = nullptr,
});
w.delayedUpdateObjectManager.register_class<NameData>(w.netObjMan);
w.delayedUpdateObjectManager.register_class<DisplayData>(w.netObjMan);
w.delayedUpdateObjectManager.register_class<DisplayData>(w.netObjMan, NetworkingObjects::DelayUpdateSerializedClassManager::CustomConstructors<DisplayData>{
.postUpdateFunc = [&](DisplayData& o) {
// MUST CLEAR CACHE
}
});
}
void DrawingProgramLayerListItem::write_constructor_func(const NetworkingObjects::NetObjTemporaryPtr<DrawingProgramLayerListItem>& o, cereal::PortableBinaryOutputArchive& a) {

View file

@ -28,13 +28,13 @@ class DrawingProgramLayerListItem {
const std::string& get_name() const;
void get_flattened_component_list(std::vector<CanvasComponentContainer::ObjInfoSharedPtr>& objList) const;
void set_alpha(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, float newAlpha) const;
void set_alpha(DrawingProgramLayerManager& layerMan, float newAlpha) const;
float get_alpha() const;
void set_visible(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, bool newVisible) const;
void set_visible(DrawingProgramLayerManager& layerMan, bool newVisible) const;
bool get_visible() const;
void set_blend_mode(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, SerializedBlendMode newBlendMode) const;
void set_blend_mode(DrawingProgramLayerManager& layerMan, SerializedBlendMode newBlendMode) const;
SerializedBlendMode get_blend_mode() const;
private:
static void write_constructor_func(const NetworkingObjects::NetObjTemporaryPtr<DrawingProgramLayerListItem>& o, cereal::PortableBinaryOutputArchive& a);

View file

@ -38,3 +38,31 @@ std::vector<CanvasComponentContainer::ObjInfoSharedPtr> DrawingProgramLayerManag
layerTreeRoot->get_flattened_component_list(toRet);
return toRet;
}
bool DrawingProgramLayerManager::layer_tree_root_exists() {
return layerTreeRoot;
}
const DrawingProgramLayerListItem& DrawingProgramLayerManager::get_layer_root() {
return *layerTreeRoot;
}
void DrawingProgramLayerManager::erase_component_set(const std::unordered_set<CanvasComponentContainer::ObjInfoSharedPtr>& compsToErase) {
std::unordered_map<DrawingProgramLayerListItem*, std::unordered_set<NetworkingObjects::NetObjID>> idsToEraseInSpecificLayers;
for(auto& c : compsToErase)
idsToEraseInSpecificLayers[c->obj->parentLayer].emplace(c->obj.get_net_id());
for(auto& [layerListItem, netObjSetToErase] : idsToEraseInSpecificLayers) {
auto& layerComponentList = layerListItem->get_layer().components;
layerComponentList->erase_unordered_set(layerComponentList, netObjSetToErase);
}
}
bool DrawingProgramLayerManager::component_passes_layer_selector(const CanvasComponentContainer::ObjInfoSharedPtr& c, LayerSelector layerSelector) {
switch(layerSelector) {
case LayerSelector::ALL_VISIBLE_LAYERS:
return c->obj->parentLayer->get_visible();
case LayerSelector::LAYER_BEING_EDITED:
return is_a_layer_being_edited() && c->obj->parentLayer == editingLayer.lock().get();
}
return false;
}

View file

@ -12,6 +12,10 @@ class DrawingProgramLayerManager {
NetworkingObjects::NetObjOwnerPtr<DrawingProgramLayerListItem> layerTreeRoot;
NetworkingObjects::NetObjWeakPtr<DrawingProgramLayerListItem> editingLayer;
public:
enum class LayerSelector {
ALL_VISIBLE_LAYERS,
LAYER_BEING_EDITED
};
DrawingProgramLayerManager(DrawingProgram& drawProg);
void init();
@ -19,6 +23,12 @@ class DrawingProgramLayerManager {
void write_components_server(cereal::PortableBinaryOutputArchive& a);
void read_components_client(cereal::PortableBinaryInputArchive& a);
bool is_a_layer_being_edited();
void erase_component_set(const std::unordered_set<CanvasComponentContainer::ObjInfoSharedPtr>& compsToErase);
bool component_passes_layer_selector(const CanvasComponentContainer::ObjInfoSharedPtr& c, LayerSelector layerSelector);
bool layer_tree_root_exists();
const DrawingProgramLayerListItem& get_layer_root();
template <typename T> CanvasComponentContainer::ObjInfoSharedPtr add_component_to_layer_being_edited(T* newObj) {
auto editLayerPtr = editingLayer.lock();
if(!editLayerPtr)

View file

@ -85,7 +85,7 @@ void DrawingProgramLayerManagerGUI::setup_list_gui(const std::string& id, bool&
gui.text_label(tempPtr->get_name());
}
if(gui.svg_icon_button_transparent("visible button", tempPtr->get_visible() ? "data/icons/eyeopen.svg" : "data/icons/eyeclose.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) {
tempPtr->set_visible(world.delayedUpdateObjectManager, !tempPtr->get_visible());
tempPtr->set_visible(layerMan, !tempPtr->get_visible());
isButtonClicked = true;
}
if(gui.svg_icon_button_transparent("delete button", "data/icons/trash.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) {
@ -178,7 +178,7 @@ void DrawingProgramLayerManagerGUI::setup_list_gui(const std::string& id, bool&
gui.input_text_field("input edit name", "Name", &nameToEdit);
tempPtr->set_name(world.delayedUpdateObjectManager, nameToEdit);
gui.slider_scalar_field("input alpha slider", "Alpha", &alphaValToEdit, 0.0f, 1.0f, 2);
tempPtr->set_alpha(world.delayedUpdateObjectManager, alphaValToEdit);
tempPtr->set_alpha(layerMan, alphaValToEdit);
gui.left_to_right_line_layout([&]() {
gui.text_label("Blend Mode");
gui.dropdown_select("input blend mode", &blendModeValToEdit, get_blend_mode_name_list(), 200.0f, [&hoveringOverDropdown]() {
@ -186,7 +186,7 @@ void DrawingProgramLayerManagerGUI::setup_list_gui(const std::string& id, bool&
hoveringOverDropdown = true;
});
});
tempPtr->set_blend_mode(world.delayedUpdateObjectManager, static_cast<SerializedBlendMode>(blendModeValToEdit));
tempPtr->set_blend_mode(layerMan, static_cast<SerializedBlendMode>(blendModeValToEdit));
}
}