More config fixes.
This commit is contained in:
parent
bfd2994703
commit
bf87e4755d
|
@ -31,5 +31,6 @@
|
|||
|
||||
# Config
|
||||
|
||||
* Test two processes.
|
||||
* Test reset.
|
||||
* Implement ability to reset single config.
|
||||
- VSCode settings page can do this.
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue