More config fixes.

This commit is contained in:
Samuel Guerra 2023-06-01 16:29:11 -03:00
parent bfd2994703
commit bf87e4755d
5 changed files with 61 additions and 33 deletions

View File

@ -31,5 +31,6 @@
# Config
* Test two processes.
* Test reset.
* Implement ability to reset single config.
- VSCode settings page can do this.

View File

@ -76,11 +76,17 @@ fn app_main() {
min_width = 100;
},
separator(),
Button! {
child = Text!("Reset");
on_click = hn!(|_| {
reset_config();
})
{
let enabled = var(true);
Button! {
child = Text!("Reset");
on_click = async_hn!(enabled, |_| {
enabled.set(false);
reset_config().await;
enabled.set(true);
});
enabled;
}
},
Button! {
child = Text!("Open Another Process");
@ -124,12 +130,17 @@ fn separator() -> impl UiNode {
}
}
fn reset_config() {
async fn reset_config() {
let mut retry = false;
while retry {
CONFIG.load(NilConfig); // clear file watchers
loop {
match std::fs::remove_file("target/tmp/example.config.json") {
Ok(_) => load_config(),
Ok(_) => {
task::yield_now().await;
load_config();
}
Err(e) if matches!(e.kind(), std::io::ErrorKind::NotFound) => {
task::yield_now().await;
load_config();
}
Err(e) => {
@ -138,9 +149,13 @@ fn reset_config() {
break;
} else {
retry = true;
std::thread::sleep(50.ms());
task::deadline(50.ms()).await;
}
}
}
if !retry {
break;
}
}
}

View File

@ -14,7 +14,7 @@ use crate::{
fs_watcher::{WatchFile, WriteFile},
task,
text::Txt,
var::*,
var::{types::WeakArcVar, *},
};
mod fallback;
@ -320,15 +320,12 @@ impl Config for NilConfig {
}
struct ConfigVar<T: ConfigValue> {
var: BoxedWeakVar<T>,
var: WeakArcVar<T>,
binding: VarHandles,
}
impl<T: ConfigValue> ConfigVar<T> {
fn new_any(var: BoxedWeakVar<T>) -> Box<dyn AnyConfigVar> {
Box::new(Self {
var,
binding: VarHandles::dummy(),
})
fn new_any(var: WeakArcVar<T>, binding: VarHandles) -> Box<dyn AnyConfigVar> {
Box::new(Self { var, binding })
}
}
@ -345,7 +342,7 @@ impl ConfigVars {
if e.get().can_upgrade() {
if let Some(x) = e.get().as_any().downcast_ref::<ConfigVar<T>>() {
if let Some(var) = x.var.upgrade() {
return var;
return var.boxed();
}
} else {
tracing::error!(
@ -357,14 +354,35 @@ impl ConfigVars {
}
}
// cannot upgrade
let var = bind(e.key());
e.insert(ConfigVar::new_any(var.downgrade()));
var
let cfg = bind(e.key());
let res = var(cfg.get());
let binding = res.bind_map_bidi(
&cfg,
clmv!(cfg, |v| {
let _strong_ref = &cfg;
v.clone()
}),
Clone::clone,
);
e.insert(ConfigVar::new_any(res.downgrade(), binding));
res.boxed()
}
hash_map::Entry::Vacant(e) => {
let var = bind(e.key());
e.insert(ConfigVar::new_any(var.downgrade()));
var
let cfg = bind(e.key());
let res = var(cfg.get());
let binding = res.bind_map_bidi(
&cfg,
clmv!(cfg, |v| {
let _strong_ref = &cfg;
v.clone()
}),
Clone::clone,
);
e.insert(ConfigVar::new_any(res.downgrade(), binding));
res.boxed()
}
}
}
@ -373,11 +391,6 @@ impl ConfigVars {
///
/// If the map entry is present in the `source` the variable is updated to the new value, if not the entry
/// is inserted in the source. The variable is then bound to the source.
///
/// Note that this means the variables bound from the previous source in [`get_or_bind`] **will be reused**,
/// the previous source must be dropped before calling this method.
///
/// [`get_or_bind`]: Self::get_or_bind
pub fn rebind(&mut self, source: &mut dyn AnyConfig) {
self.0.retain(|key, wk_var| wk_var.rebind(key, source));
}
@ -409,7 +422,7 @@ impl<T: ConfigValue> AnyConfigVar for ConfigVar<T> {
match RawConfigValue::deserialize::<T>(source_var.get()) {
Ok(value) => {
let _ = var.set(value);
var.set(value);
}
Err(e) => {
// invalid data error

View File

@ -93,8 +93,7 @@ impl SwapConfig {
/// Load the config.
///
/// The previous source will be dropped. Note that some variables produced from the previous source
/// can be reused, do not set `cfg` to a source that will still be alive after `cfg` is dropped.
/// The previous source will be dropped and all active config variables are set and rebound to the new config.
pub fn load(&mut self, cfg: impl AnyConfig) {
self.replace_source(Box::new(cfg))
}

View File

@ -100,7 +100,7 @@ impl<M: ConfigMap> SyncConfig<M> {
Ok(raw) => {
// get ok
if let Some(raw) = raw {
var.set(raw);
var.set_ne(raw);
}
// else backend lost entry but did not report as error.
}