Ver Fonte

Merge branch 'settings-manager-scale'

darkfi há 1 ano atrás
pai
commit
73c2dbd8e5

+ 31 - 16
bin/app/src/app/mod.rs

@@ -34,10 +34,9 @@ use crate::{
     error::Error,
     expr::Op,
     gfx::{GraphicsEventPublisherPtr, RenderApi, Vertex},
-    plugin::{self, PluginObject},
+    plugin::{self, PluginObject, PluginSettings},
     prop::{
-        Property, PropertyAtomicGuard, PropertyBool, PropertyStr, PropertySubType, PropertyType,
-        Role,
+        Property, PropertyAtomicGuard, PropertyBool, PropertyStr, PropertySubType, PropertyType, PropertyValue, Role
     },
     scene::{Pimpl, SceneNode as SceneNode3, SceneNodePtr, SceneNodeType as SceneNodeType3, Slot},
     text::TextShaperPtr,
@@ -48,12 +47,13 @@ use crate::{
 mod node;
 use node::create_darkirc;
 mod schema;
-use schema::{get_window_scale_filename, settings};
+use schema::{get_settingsdb_path, get_window_scale_filename, settings};
 
 macro_rules! d { ($($arg:tt)*) => { debug!(target: "app", $($arg)*); } }
 macro_rules! t { ($($arg:tt)*) => { trace!(target: "app", $($arg)*); } }
 macro_rules! i { ($($arg:tt)*) => { info!(target: "app", $($arg)*); } }
 macro_rules! w { ($($arg:tt)*) => { warn!(target: "app", $($arg)*); } }
+macro_rules! e { ($($arg:tt)*) => { error!(target: "app", $($arg)*); } }
 
 //fn print_type_of<T>(_: &T) {
 //    println!("{}", std::any::type_name::<T>())
@@ -157,8 +157,18 @@ impl App {
 
     /// Does not require miniquad to be init. Created the scene graph tree / schema and all
     /// the objects.
-    pub async fn setup(&self) {
+    pub async fn setup(&self) -> Result<Option<i32>, Error> {
         t!("App::setup()");
+
+        let db_path = get_settingsdb_path();
+        let db = match sled::open(&db_path) {
+            Ok(db) => db,
+            Err(err) => {
+                e!("Sled database '{}' failed to open: {err}!", db_path.display());
+                return Err(Error::SledDbErr);
+            }
+        };
+
         let atom = &mut PropertyAtomicGuard::new();
 
         let mut window = SceneNode3::new("window", SceneNodeType3::Window);
@@ -167,12 +177,21 @@ impl App {
         prop.set_array_len(2);
         window.add_property(prop).unwrap();
 
-        let mut prop = Property::new("scale", PropertyType::Float32, PropertySubType::Pixel);
-        prop.set_defaults_f32(vec![1.]).unwrap();
-        window.add_property(prop).unwrap();
 
-        let window = window.setup(|me| Window::new(me, self.render_api.clone())).await;
+        let setting_root = Arc::new(SceneNode3::new("setting", SceneNodeType3::SettingRoot));
+        let settings_tree = db.open_tree("settings").unwrap();
+        let settings = PluginSettings {
+            setting_root: setting_root.clone(),
+            sled_tree: settings_tree,
+        };
+
+        settings.add_setting("scale", PropertyValue::Float32(1.));
+        settings.load_settings();
+        let window = window.setup(|me| Window::new(me, self.render_api.clone(), setting_root.clone())).await;
+
         self.sg_root.clone().link(window.clone());
+        self.sg_root.clone().link(setting_root.clone());
+
         schema::make(&self, window.clone()).await;
 
         d!("Schema loaded");
@@ -186,7 +205,9 @@ impl App {
         #[cfg(not(feature = "enable-plugins"))]
         w!("Plugins are disabled in this build");
 
-        settings::make(&self, window).await;
+        settings::make(&self, window, self.ex.clone()).await;
+
+        Ok(None)
     }
 
     #[cfg(feature = "enable-plugins")]
@@ -330,12 +351,6 @@ impl App {
         prop.clone().set_f32(atom, Role::App, 0, screen_width);
         prop.clone().set_f32(atom, Role::App, 1, screen_height);
 
-        let mut window_scale = 1.;
-        if let Ok(mut file) = File::open(get_window_scale_filename()) {
-            window_scale = Decodable::decode(&mut file).unwrap();
-        }
-        window_node.set_property_f32(atom, Role::App, "scale", window_scale).unwrap();
-
         drop(atom);
 
         // Access drawable in window node and call draw()

+ 1 - 1
bin/app/src/app/schema/chat.rs

@@ -190,7 +190,7 @@ pub async fn make(
     emoji_meshes: emoji_picker::EmojiMeshesPtr,
     is_first_time: bool,
 ) {
-    let window_scale = PropertyFloat32::wrap(&window, Role::Internal, "scale", 0).unwrap();
+    let window_scale = PropertyFloat32::wrap(&app.sg_root.clone().lookup_node("/setting/scale").unwrap(), Role::Internal, "value", 0).unwrap();
     let atom = &mut PropertyAtomicGuard::new();
 
     let mut cc = Compiler::new();

+ 1 - 1
bin/app/src/app/schema/menu.rs

@@ -77,7 +77,7 @@ mod ui_consts {
 use ui_consts::*;
 
 pub async fn make(app: &App, window: SceneNodePtr) {
-    let window_scale = PropertyFloat32::wrap(&window, Role::Internal, "scale", 0).unwrap();
+    let window_scale = PropertyFloat32::wrap(&app.sg_root.clone().lookup_node("/setting/scale").unwrap(), Role::Internal, "value", 0).unwrap();
     let atom = &mut PropertyAtomicGuard::new();
 
     let mut cc = Compiler::new();

+ 15 - 7
bin/app/src/app/schema/mod.rs

@@ -80,6 +80,10 @@ mod ui_consts {
     pub fn get_window_scale_filename() -> PathBuf {
         get_appdata_path().join("window_scale")
     }
+
+    pub fn get_settingsdb_path() -> PathBuf {
+        get_appdata_path().join("settings")
+    }
 }
 
 #[cfg(not(target_os = "android"))]
@@ -99,6 +103,10 @@ mod desktop_paths {
     pub fn get_window_scale_filename() -> PathBuf {
         dirs::cache_dir().unwrap().join("darkfi/app/window_scale")
     }
+
+    pub fn get_settingsdb_path() -> PathBuf {
+        dirs::cache_dir().unwrap().join("darkfi/app/settings")
+    }
 }
 
 #[cfg(feature = "emulate-android")]
@@ -143,11 +151,11 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     node.set_property_u32(atom, Role::App, "priority", 10).unwrap();
     let (slot, recvr) = Slot::new("zoom_out_pressed");
     node.register("shortcut", slot).unwrap();
-    let window_scale = PropertyFloat32::wrap(&window, Role::App, "scale", 0).unwrap();
+    let window_scale = app.sg_root.clone().lookup_node("/setting/scale").unwrap();
     let window_scale2 = window_scale.clone();
     let listen_zoom = app.ex.spawn(async move {
         while let Ok(_) = recvr.recv().await {
-            let scale = 0.9 * window_scale2.get();
+            let scale = 0.9 * window_scale2.get_property_f32("value").unwrap();
 
             let filename = get_window_scale_filename();
             if let Some(parent) = filename.parent() {
@@ -158,7 +166,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
             }
 
             let atom = &mut PropertyAtomicGuard::new();
-            window_scale2.set(atom, scale);
+            window_scale2.set_property_f32(atom, Role::User, "value", scale);
         }
     });
     app.tasks.lock().unwrap().push(listen_zoom);
@@ -174,7 +182,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     let window_scale2 = window_scale.clone();
     let listen_zoom = app.ex.spawn(async move {
         while let Ok(_) = recvr.recv().await {
-            let scale = 1.1 * window_scale2.get();
+            let scale = 1.1 * window_scale2.get_property_f32("value").unwrap();
 
             let filename = get_window_scale_filename();
             if let Some(parent) = filename.parent() {
@@ -185,7 +193,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
             }
 
             let atom = &mut PropertyAtomicGuard::new();
-            window_scale2.set(atom, scale);
+            window_scale2.set_property_f32(atom, Role::User, "value", scale);
         }
     });
     app.tasks.lock().unwrap().push(listen_zoom);
@@ -201,7 +209,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
             let distance: f32 = deserialize(&data).unwrap();
             // Dampen it a little
             let r = (distance - 1.) / 2. + 1.;
-            let scale = r * window_scale.get();
+            let scale = r * window_scale.get_property_f32("value").unwrap();
 
             let filename = get_window_scale_filename();
             if let Some(parent) = filename.parent() {
@@ -212,7 +220,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
             }
 
             let atom = &mut PropertyAtomicGuard::new();
-            window_scale.set(atom, scale);
+            window_scale.set_property_f32(atom, Role::User, "value", scale);
         }
     });
     app.tasks.lock().unwrap().push(listen_zoom);

+ 19 - 7
bin/app/src/app/schema/settings.rs

@@ -29,14 +29,13 @@ use crate::{
     },
     expr::{self, Compiler},
     prop::{
-        PropertyAtomicGuard, PropertyFloat32, PropertyStr, Property, PropertyValue, Role,
+        Property, PropertyAtomicGuard, PropertyFloat32, PropertyStr, PropertyValue, Role
     },
     scene::{SceneNodePtr, Slot},
     shape,
     ui::{
-        Button, EditBox, Layer, ShapeVertex, Text, VectorArt,
-        VectorShape,
-    },
+        Button, EditBox, Layer, OnModify, ShapeVertex, Text, VectorArt, VectorShape
+    }, ExecutorPtr,
 };
 
 use super::{ColorScheme, CHANNELS, COLOR_SCHEME};
@@ -121,11 +120,11 @@ impl Setting {
     }
 }
 
-pub async fn make(app: &App, window: SceneNodePtr) {
+pub async fn make(app: &App, window: SceneNodePtr, ex: ExecutorPtr) {
     let mut cc = Compiler::new();
     cc.add_const_f32("BORDER_RIGHT_SCALE", BORDER_RIGHT_SCALE);
     cc.add_const_f32("X_RATIO", 1./3.);
-    let window_scale = PropertyFloat32::wrap(&window, Role::Internal, "scale", 0).unwrap();
+    let window_scale = PropertyFloat32::wrap(&app.sg_root.clone().lookup_node("/setting/scale").unwrap(), Role::Internal, "value", 0).unwrap();
     let atom = &mut PropertyAtomicGuard::new();
 
     // Main view
@@ -246,6 +245,19 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     // Create a BTreeMap to store settings
     let mut settings_map: BTreeMap<String, Arc<Setting>> = BTreeMap::new();
 
+    // Get the app settings
+    let app_setting_root = app.sg_root.clone().lookup_node("/setting").unwrap();
+    for setting in app_setting_root.get_children().iter() {
+        let name = ["app", &setting.name.clone()].join(".");
+        settings_map.insert(
+            name.clone(),
+            Arc::new(Setting {
+                name,
+                node: setting.clone(),
+            }),
+        );
+    }
+
     // Get the settings from all plugins
     let sg_root_children = app.sg_root.clone().get_children();
     let plugin_node = sg_root_children.iter().find(|node| node.name == "plugin");
@@ -255,7 +267,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
             let setting_root = plugin_children.iter().find(|node| node.name == "setting");
             if let Some(sroot) = setting_root {
                 for setting in sroot.get_children().iter() {
-                    let name = vec![plugin.name.clone(), setting.name.clone()].join(".");
+                    let name = [plugin.name.clone(), setting.name.clone()].join(".");
                     settings_map.insert(
                         name.clone(),
                         Arc::new(Setting {

+ 1 - 1
bin/app/src/app/schema/test.rs

@@ -62,7 +62,7 @@ use ui_consts::*;
 pub async fn make(app: &App, window: SceneNodePtr) {
     let atom = &mut PropertyAtomicGuard::new();
 
-    let window_scale = PropertyFloat32::wrap(&window, Role::Internal, "scale", 0).unwrap();
+    let window_scale = PropertyFloat32::wrap(&app.sg_root.clone().lookup_node("/setting/scale").unwrap(), Role::Internal, "value", 0).unwrap();
 
     let mut cc = Compiler::new();
 

+ 7 - 17
bin/app/src/plugin/darkirc.rs

@@ -184,7 +184,7 @@ impl DarkIrc {
         let node_ref = &node.upgrade().unwrap();
         let nick = PropertyStr::wrap(node_ref, Role::Internal, "nick", 0).unwrap();
 
-        let mut setting_root = Arc::new(SceneNode::new("setting", SceneNodeType::SettingRoot));
+        let setting_root = Arc::new(SceneNode::new("setting", SceneNodeType::SettingRoot));
         node_ref.clone().link(setting_root.clone());
 
         i!("Starting DarkIRC backend");
@@ -236,23 +236,10 @@ impl DarkIrc {
         p2p_settings.p2p_datastore = p2p_datastore_path().into_os_string().into_string().ok();
         p2p_settings.hostlist = hostlist_path().into_os_string().into_string().ok();
 
-        let node_outbound_connect_timeout = settings.add_setting("net.outbound_connect_timeout", PropertyValue::Uint32(p2p_settings.outbound_connect_timeout as u32)).unwrap();
-        let node_channel_handshake_timeout = settings.add_setting("net.channel_handshake_timeout", PropertyValue::Uint32(p2p_settings.channel_handshake_timeout as u32)).unwrap();
-        let node_channel_heartbeat_interval = settings.add_setting("net.channel_heartbeat_interval", PropertyValue::Uint32(p2p_settings.channel_heartbeat_interval as u32)).unwrap();
-        let node_outbound_peer_discovery_cooloff_time = settings.add_setting("net.outbound_peer_discovery_cooloff_time", PropertyValue::Uint32(p2p_settings.outbound_peer_discovery_cooloff_time as u32)).unwrap();
-        let node_slot_preference_strict = settings.add_setting("net.slot_preference_strict", PropertyValue::Bool(p2p_settings.slot_preference_strict)).unwrap();
-        let node_transport_mixing = settings.add_setting("net.transport_mixing", PropertyValue::Bool(p2p_settings.transport_mixing)).unwrap();
-        let node_localnet = settings.add_setting("net.localnet", PropertyValue::Bool(p2p_settings.localnet)).unwrap();
+        settings.add_p2p_settings(&p2p_settings);
 
         settings.load_settings();
-
-        p2p_settings.outbound_connect_timeout = node_outbound_connect_timeout.get_property_u32("value").unwrap() as u64;
-        p2p_settings.channel_handshake_timeout = node_channel_handshake_timeout.get_property_u32("value").unwrap() as u64;
-        p2p_settings.channel_heartbeat_interval = node_channel_heartbeat_interval.get_property_u32("value").unwrap() as u64;
-        p2p_settings.outbound_peer_discovery_cooloff_time = node_outbound_peer_discovery_cooloff_time.get_property_u32("value").unwrap() as u64;
-        p2p_settings.slot_preference_strict = node_slot_preference_strict.get_property_bool("value").unwrap();
-        p2p_settings.transport_mixing = node_transport_mixing.get_property_bool("value").unwrap();
-        p2p_settings.localnet = node_localnet.get_property_bool("value").unwrap();
+        settings.update_p2p_settings(&mut p2p_settings);
 
         let p2p = match P2p::new(p2p_settings.clone(), ex.clone()).await {
             Ok(p2p) => p2p,
@@ -512,7 +499,10 @@ impl DarkIrc {
 
     async fn apply_settings(self_: Arc<Self>) {
         self_.settings.save_settings();
-        i!("TODO: Apply darkirc settings");
+
+        let p2p_settings = self_.p2p.settings();
+        let mut write_guard = p2p_settings.write().await;
+        self_.settings.update_p2p_settings(&mut write_guard);
     }
 }
 

+ 45 - 5
bin/app/src/plugin/mod.rs

@@ -24,6 +24,8 @@ use crate::ExecutorPtr;
 pub mod darkirc;
 pub use darkirc::{DarkIrc, DarkIrcPtr};
 
+use darkfi::net::Settings as NetSettings;
+
 use sled_overlay::sled;
 use crate::{
     scene::{MethodCallSub, Pimpl, SceneNode, SceneNodeType, SceneNodePtr, SceneNodeWeak},
@@ -38,11 +40,11 @@ pub trait PluginObject {
 }
 
 pub struct PluginSettings {
-    setting_root: SceneNodePtr,
-    sled_tree: sled::Tree,
+    pub setting_root: SceneNodePtr,
+    pub sled_tree: sled::Tree,
 }
 impl PluginSettings {
-    fn add_setting(&self, name: &str, default: PropertyValue) -> Option<SceneNodePtr> {
+    pub fn add_setting(&self, name: &str, default: PropertyValue) -> Option<SceneNodePtr> {
         let atom = &mut PropertyAtomicGuard::new();
         let node = match default {
             PropertyValue::Bool(b) => {
@@ -99,7 +101,7 @@ impl PluginSettings {
     }
 
     // For all settings, copy the value from sled into the setting node's value property
-    fn load_settings(&self) {
+    pub fn load_settings(&self) {
         let atom = &mut PropertyAtomicGuard::new();
         for setting_node in self.setting_root.get_children().iter() {
             if setting_node.typ != SceneNodeType::Setting {
@@ -151,7 +153,7 @@ impl PluginSettings {
     }
 
     // Save all settings to sled
-    fn save_settings(&self) {
+    pub fn save_settings(&self) {
         for setting_node in self.setting_root.get_children().iter() {
             if setting_node.typ != SceneNodeType::Setting {
                 continue;
@@ -176,4 +178,42 @@ impl PluginSettings {
             }
         }
     }
+
+    pub fn get_setting(&self, name: &str) -> Option<SceneNodePtr> {
+        self.setting_root.clone().get_children().iter().find(|node| node.typ == SceneNodeType::Setting && node.name == name).cloned()
+    }
+
+    pub fn add_p2p_settings(&self, p2p_settings: &NetSettings) {
+        self.add_setting("net.outbound_connections", PropertyValue::Uint32(p2p_settings.outbound_connections as u32));
+        self.add_setting("net.inbound_connections", PropertyValue::Uint32(p2p_settings.inbound_connections as u32));
+        self.add_setting("net.outbound_connect_timeout", PropertyValue::Uint32(p2p_settings.outbound_connect_timeout as u32));
+        self.add_setting("net.channel_handshake_timeout", PropertyValue::Uint32(p2p_settings.channel_handshake_timeout as u32));
+        self.add_setting("net.channel_heartbeat_interval", PropertyValue::Uint32(p2p_settings.channel_heartbeat_interval as u32));
+        self.add_setting("net.outbound_peer_discovery_cooloff_time", PropertyValue::Uint32(p2p_settings.outbound_peer_discovery_cooloff_time as u32));
+        self.add_setting("net.transport_mixing", PropertyValue::Bool(p2p_settings.transport_mixing));
+        self.add_setting("net.localnet", PropertyValue::Bool(p2p_settings.localnet));
+        self.add_setting("net.greylist_refinery_interval", PropertyValue::Uint32(p2p_settings.greylist_refinery_interval as u32));
+        self.add_setting("net.white_connect_percent", PropertyValue::Uint32(p2p_settings.white_connect_percent as u32));
+        self.add_setting("net.gold_connect_count", PropertyValue::Uint32(p2p_settings.gold_connect_count as u32));
+        self.add_setting("net.slot_preference_strict", PropertyValue::Bool(p2p_settings.slot_preference_strict));
+        self.add_setting("net.time_with_no_connections", PropertyValue::Uint32(p2p_settings.time_with_no_connections as u32));
+    }
+
+    // Update a NetSettings from settings in the node tree
+    pub fn update_p2p_settings(&self, p2p_settings: &mut NetSettings) {
+        p2p_settings.outbound_connections = self.get_setting("net.outbound_connections").unwrap().get_property_u32("value").unwrap() as usize;
+        p2p_settings.inbound_connections = self.get_setting("net.inbound_connections").unwrap().get_property_u32("value").unwrap() as usize;
+        p2p_settings.outbound_connect_timeout = self.get_setting("net.outbound_connect_timeout").unwrap().get_property_u32("value").unwrap() as u64;
+        p2p_settings.channel_handshake_timeout = self.get_setting("net.channel_handshake_timeout").unwrap().get_property_u32("value").unwrap() as u64;
+        p2p_settings.channel_heartbeat_interval = self.get_setting("net.channel_heartbeat_interval").unwrap().get_property_u32("value").unwrap() as u64;
+        p2p_settings.outbound_peer_discovery_cooloff_time = self.get_setting("net.outbound_peer_discovery_cooloff_time").unwrap().get_property_u32("value").unwrap() as u64;
+        p2p_settings.transport_mixing = self.get_setting("net.transport_mixing").unwrap().get_property_bool("value").unwrap();
+        p2p_settings.localnet = self.get_setting("net.localnet").unwrap().get_property_bool("value").unwrap();
+        p2p_settings.greylist_refinery_interval = self.get_setting("net.greylist_refinery_interval").unwrap().get_property_u32("value").unwrap() as u64;
+        p2p_settings.white_connect_percent = self.get_setting("net.white_connect_percent").unwrap().get_property_u32("value").unwrap() as usize;
+        p2p_settings.gold_connect_count = self.get_setting("net.gold_connect_count").unwrap().get_property_u32("value").unwrap() as usize;
+        p2p_settings.slot_preference_strict = self.get_setting("net.slot_preference_strict").unwrap().get_property_bool("value").unwrap();
+        p2p_settings.time_with_no_connections = self.get_setting("net.time_with_no_connections").unwrap().get_property_u32("value").unwrap() as u64;
+    }
+
 }

+ 3 - 2
bin/app/src/ui/win.rs

@@ -53,12 +53,13 @@ pub struct Window {
 }
 
 impl Window {
-    pub async fn new(node: SceneNodeWeak, render_api: RenderApi) -> Pimpl {
+    pub async fn new(node: SceneNodeWeak, render_api: RenderApi, setting_root: SceneNodePtr) -> Pimpl {
         t!("Window::new()");
 
         let node_ref = &node.upgrade().unwrap();
         let screen_size = PropertyDimension::wrap(node_ref, Role::Internal, "screen_size").unwrap();
-        let scale = PropertyFloat32::wrap(node_ref, Role::Internal, "scale", 0).unwrap();
+        let scale_ = PropertyFloat32::wrap(&setting_root.clone().lookup_node("/scale").unwrap(), Role::Internal, "value", 0);
+        let scale = scale_.unwrap();
 
         let self_ = Arc::new(Self { node, tasks: OnceLock::new(), screen_size, scale, render_api });