| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- /* This file is part of DarkFi (https://dark.fi)
- *
- * Copyright (C) 2020-2025 Dyne.org foundation
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- use super::{ModifyAction, ModifyPublisher, PropertyPtr, Role};
- macro_rules! t { ($($arg:tt)*) => { trace!(target: "prop", $($arg)*); } }
- /// This schedules all property updates to happen at the end of the scope.
- /// We can therefore have fine-grained control about when property updates are
- /// propagated to the rest of the scenegraph.
- ///
- /// This way we avoid triggering draw updates mid draw, and changes are atomic.
- /// For example resizing the content view, will trigger the editbox background to
- /// redraw while a current window wide draw is in progress. Since the window draw
- /// triggered the change when we submit the draw update, it will be discarded by
- /// the editbox bg triggered update. However this update won't have the current
- /// rect and will be stale.
- ///
- /// 1. Content draw starts
- /// 2. Dependent property triggers and submits editbox bg redraw.
- /// 3. Content draw continues and now draws editbox bg with updated rect.
- /// 4. Finished content draw's editbox bg update is discarded in favour of #2.
- /// However #2 used the pre-updated rect and is now stale.
- ///
- /// We solve the above issue by batching all updates until after the draw call is finished.
- /// This also has the unintended side-effect of making draws much faster since they aren't
- /// interrupted halfway through by extra compute.
- pub struct PropertyAtomicGuard {
- updates: Vec<(PropertyPtr, Role, ModifyAction)>,
- }
- impl PropertyAtomicGuard {
- pub fn new() -> Self {
- Self { updates: vec![] }
- }
- pub(super) fn add(&mut self, prop: PropertyPtr, role: Role, action: ModifyAction) {
- self.updates.push((prop, role, action));
- }
- }
- impl Drop for PropertyAtomicGuard {
- fn drop(&mut self) {
- for (prop, role, action) in std::mem::take(&mut self.updates) {
- prop.on_modify.notify((role, action));
- }
- }
- }
|