mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-20 17:41:37 +00:00
Merge d346997d83 into 7e60406373
This commit is contained in:
commit
dfc9c75934
4 changed files with 35 additions and 10 deletions
|
|
@ -235,7 +235,6 @@ function SettingsPage:render()
|
||||||
description = "Editing files in Studio will sync them into the filesystem",
|
description = "Editing files in Studio will sync them into the filesystem",
|
||||||
locked = self.props.syncActive,
|
locked = self.props.syncActive,
|
||||||
lockedTooltip = "(Cannot change while currently syncing. Disconnect first.)",
|
lockedTooltip = "(Cannot change while currently syncing. Disconnect first.)",
|
||||||
tag = "unstable",
|
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
layoutOrder = layoutIncrement(),
|
layoutOrder = layoutIncrement(),
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,6 @@ function ChangeBatcher:__cycle(dt)
|
||||||
self.__onChangesFlushed(patch)
|
self.__onChangesFlushed(patch)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self.__instanceMap:unpauseAllInstances()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function ChangeBatcher:__flush()
|
function ChangeBatcher:__flush()
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ end
|
||||||
--[[
|
--[[
|
||||||
Pause updates for an instance.
|
Pause updates for an instance.
|
||||||
]]
|
]]
|
||||||
function InstanceMap:pauseInstance(instance)
|
function InstanceMap:pauseInstance(instance, duration)
|
||||||
local id = self.fromInstances[instance]
|
local id = self.fromInstances[instance]
|
||||||
|
|
||||||
-- If we don't know about this instance, ignore it.
|
-- If we don't know about this instance, ignore it.
|
||||||
|
|
@ -153,7 +153,8 @@ function InstanceMap:pauseInstance(instance)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
self.pausedUpdateInstances[instance] = true
|
-- Pause with expiration timestamp (0.6s) to ensure property replication signals settle
|
||||||
|
self.pausedUpdateInstances[instance] = os.clock() + (duration or 0.6)
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
|
|
@ -202,8 +203,13 @@ end
|
||||||
function InstanceMap:__maybeFireInstanceChanged(instance, propertyName)
|
function InstanceMap:__maybeFireInstanceChanged(instance, propertyName)
|
||||||
Log.trace("{}.{} changed", instance:GetFullName(), propertyName)
|
Log.trace("{}.{} changed", instance:GetFullName(), propertyName)
|
||||||
|
|
||||||
if self.pausedUpdateInstances[instance] then
|
local pauseExpiry = self.pausedUpdateInstances[instance]
|
||||||
|
if pauseExpiry ~= nil then
|
||||||
|
if os.clock() < pauseExpiry then
|
||||||
return
|
return
|
||||||
|
else
|
||||||
|
self.pausedUpdateInstances[instance] = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.onInstanceChanged == nil then
|
if self.onInstanceChanged == nil then
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ use crossbeam_channel::{select, Receiver, RecvError, Sender};
|
||||||
use jod_thread::JoinHandle;
|
use jod_thread::JoinHandle;
|
||||||
use memofs::{IoResultExt, Vfs, VfsEvent};
|
use memofs::{IoResultExt, Vfs, VfsEvent};
|
||||||
use rbx_dom_weak::types::{Ref, Variant};
|
use rbx_dom_weak::types::{Ref, Variant};
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
use std::{
|
use std::{
|
||||||
fs,
|
fs,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
|
|
@ -54,10 +56,12 @@ impl ChangeProcessor {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let (shutdown_sender, shutdown_receiver) = crossbeam_channel::bounded(1);
|
let (shutdown_sender, shutdown_receiver) = crossbeam_channel::bounded(1);
|
||||||
let vfs_receiver = vfs.event_receiver();
|
let vfs_receiver = vfs.event_receiver();
|
||||||
|
let recent_writes = Arc::new(Mutex::new(HashMap::new()));
|
||||||
let task = JobThreadContext {
|
let task = JobThreadContext {
|
||||||
tree,
|
tree,
|
||||||
vfs,
|
vfs,
|
||||||
message_queue,
|
message_queue,
|
||||||
|
recent_writes,
|
||||||
};
|
};
|
||||||
|
|
||||||
let job_thread = jod_thread::Builder::new()
|
let job_thread = jod_thread::Builder::new()
|
||||||
|
|
@ -111,6 +115,10 @@ struct JobThreadContext {
|
||||||
/// Whenever changes are applied to the DOM, we should push those changes
|
/// Whenever changes are applied to the DOM, we should push those changes
|
||||||
/// into this message queue to inform any connected clients.
|
/// into this message queue to inform any connected clients.
|
||||||
message_queue: Arc<MessageQueue<AppliedPatchSet>>,
|
message_queue: Arc<MessageQueue<AppliedPatchSet>>,
|
||||||
|
|
||||||
|
/// Tracks recent filesystem writes initiated by Studio client two-way sync,
|
||||||
|
/// suppressing file-watcher echo loops back into the message queue.
|
||||||
|
recent_writes: Arc<Mutex<HashMap<PathBuf, Instant>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JobThreadContext {
|
impl JobThreadContext {
|
||||||
|
|
@ -165,6 +173,18 @@ impl JobThreadContext {
|
||||||
.commit_event(&event)
|
.commit_event(&event)
|
||||||
.expect("Error applying VFS change");
|
.expect("Error applying VFS change");
|
||||||
|
|
||||||
|
// Suppress echo if this event corresponds to a write triggered by two-way sync
|
||||||
|
if let VfsEvent::Create(path) | VfsEvent::Write(path) = &event {
|
||||||
|
if let Ok(canonical_path) = self.vfs.canonicalize(path) {
|
||||||
|
let mut writes = self.recent_writes.lock().unwrap();
|
||||||
|
writes.retain(|_, time| time.elapsed() < Duration::from_secs(3));
|
||||||
|
if writes.remove(&canonical_path).is_some() {
|
||||||
|
log::trace!("Suppressing VFS echo for client-originated write: {:?}", canonical_path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For a given VFS event, we might have many changes to different parts
|
// For a given VFS event, we might have many changes to different parts
|
||||||
// of the tree. Calculate and apply all of these changes.
|
// of the tree. Calculate and apply all of these changes.
|
||||||
let applied_patches = match event {
|
let applied_patches = match event {
|
||||||
|
|
@ -258,6 +278,9 @@ impl JobThreadContext {
|
||||||
path.display(),
|
path.display(),
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
|
} else if let Ok(canonical_path) = self.vfs.canonicalize(path) {
|
||||||
|
let mut writes = self.recent_writes.lock().unwrap();
|
||||||
|
writes.insert(canonical_path, Instant::now());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log::warn!("Cannot change Source to non-string value.");
|
log::warn!("Cannot change Source to non-string value.");
|
||||||
|
|
@ -288,9 +311,8 @@ impl JobThreadContext {
|
||||||
apply_patch_set(&mut tree, patch_set)
|
apply_patch_set(&mut tree, patch_set)
|
||||||
};
|
};
|
||||||
|
|
||||||
if !applied_patch.is_empty() {
|
// Suppress pushing self-generated patch back to message queue to eliminate client echo
|
||||||
self.message_queue.push_messages(&[applied_patch]);
|
let _ = applied_patch;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue