[niepce] library: added sync interface



commit 1fb1fb970b8cf5a848b6f691f5ce798beda0d028
Author: Hubert Figuière <hub figuiere net>
Date:   Sun Nov 12 10:30:35 2017 -0500

    library: added sync interface
    
    - add keyword create command
    - make a create label command sync
    - fix undo create label using the sync command

 src/engine/library/commands.rs       |   11 +++++++++--
 src/engine/library/op.rs             |    4 +++-
 src/libraryclient/clientimpl.rs      |   33 +++++++++++++++++++++++++++++++--
 src/libraryclient/clientinterface.rs |   11 +++++++++++
 src/libraryclient/libraryclient.rs   |   20 +++++++++++++++++++-
 src/niepce/ui/dialogs/editlabels.cpp |    5 +----
 6 files changed, 74 insertions(+), 10 deletions(-)
---
diff --git a/src/engine/library/commands.rs b/src/engine/library/commands.rs
index 02d2510..2ce9cb5 100644
--- a/src/engine/library/commands.rs
+++ b/src/engine/library/commands.rs
@@ -27,6 +27,7 @@ use engine::db::library::{
     Managed
 };
 use engine::db::filebundle::FileBundle;
+use engine::db::keyword::Keyword;
 use engine::db::label::Label;
 use engine::db::libfolder::LibFolder;
 use super::notification::Notification as LibNotification;
@@ -151,6 +152,12 @@ pub fn cmd_count_folder(lib: &Library, folder_id: LibraryId) -> bool {
     true
 }
 
+pub fn cmd_add_keyword(lib: &Library, keyword: &str) -> LibraryId {
+    let id = lib.make_keyword(keyword);
+    lib.notify(Box::new(LibNotification::AddedKeyword(Keyword::new(id, keyword))));
+    id
+}
+
 pub fn cmd_query_keyword_content(lib: &Library, keyword_id: LibraryId) -> bool {
     if let Some(fl) = lib.get_keyword_content(keyword_id) {
         let mut content = unsafe { Content::new(keyword_id) };
@@ -193,13 +200,13 @@ pub fn cmd_list_all_labels(lib: &Library) -> bool {
     false
 }
 
-pub fn cmd_create_label(lib: &Library, name: &str, colour: &str) -> bool {
+pub fn cmd_create_label(lib: &Library, name: &str, colour: &str) -> LibraryId {
     let id = lib.add_label(name, colour);
     if id != -1 {
         let l = Label::new(id, name, colour);
         lib.notify(Box::new(LibNotification::AddedLabel(l)));
     }
-    true
+    id
 }
 
 pub fn cmd_delete_label(lib: &Library, label_id: LibraryId) -> bool {
diff --git a/src/engine/library/op.rs b/src/engine/library/op.rs
index 6863530..0bd652d 100644
--- a/src/engine/library/op.rs
+++ b/src/engine/library/op.rs
@@ -21,9 +21,11 @@ use std::sync::Arc;
 
 use engine::db::Library;
 
+// When we can use a FnOnce here, we should.
+type Function = Fn(&Library) -> bool + Send + Sync + 'static;
 
 pub struct Op {
-    op: Arc<Fn(&Library) -> bool + Send + Sync + 'static>
+    op: Arc<Function>
 }
 
 impl Op {
diff --git a/src/libraryclient/clientimpl.rs b/src/libraryclient/clientimpl.rs
index 770db97..89ab2f1 100644
--- a/src/libraryclient/clientimpl.rs
+++ b/src/libraryclient/clientimpl.rs
@@ -20,6 +20,7 @@
 use std::collections::VecDeque;
 use std::path::PathBuf;
 use std::sync;
+use std::sync::mpsc;
 use std::sync::atomic;
 use std::thread;
 
@@ -28,7 +29,7 @@ use engine::db::{Library, LibraryId};
 use engine::db::library::Managed;
 use engine::library::op::Op;
 use engine::library::commands;
-use super::clientinterface::ClientInterface;
+use super::clientinterface::{ClientInterface,ClientInterfaceSync};
 use root::eng::NiepceProperties as Np;
 
 pub struct ClientImpl {
@@ -173,7 +174,7 @@ impl ClientInterface for ClientImpl {
     }
     fn create_label(&mut self, name: String, colour: String) {
         self.schedule_op(move |lib| {
-            commands::cmd_create_label(&lib, &name, &colour)
+            commands::cmd_create_label(&lib, &name, &colour) != 0
         });
     }
     fn delete_label(&mut self, label_id: LibraryId) {
@@ -212,3 +213,31 @@ impl ClientInterface for ClientImpl {
         });
     }
 }
+
+
+impl ClientInterfaceSync for ClientImpl {
+
+    fn create_label_sync(&mut self, name: String, colour: String) -> LibraryId {
+        // can't use futures::sync::oneshot
+        let (tx, rx) = mpsc::sync_channel::<LibraryId>(1);
+
+        self.schedule_op(move |lib| {
+            tx.send(commands::cmd_create_label(&lib, &name, &colour)).unwrap();
+            true
+        });
+
+        rx.recv().unwrap()
+    }
+
+    fn create_keyword_sync(&mut self, keyword: String) -> LibraryId {
+        // can't use futures::sync::oneshot
+        let (tx, rx) = mpsc::sync_channel::<LibraryId>(1);
+
+        self.schedule_op(move |lib| {
+            tx.send(commands::cmd_add_keyword(&lib, &keyword)).unwrap();
+            true
+        });
+
+        rx.recv().unwrap()
+    }
+}
diff --git a/src/libraryclient/clientinterface.rs b/src/libraryclient/clientinterface.rs
index dea5249..8a1ddbb 100644
--- a/src/libraryclient/clientinterface.rs
+++ b/src/libraryclient/clientinterface.rs
@@ -60,3 +60,14 @@ pub trait ClientInterface {
     /// @param manage true if imports have to be managed
     fn import_from_directory(&mut self, dir: String, files: Vec<String>, manage: Managed);
 }
+
+/// Sync client interface
+pub trait ClientInterfaceSync {
+
+    /// Create a keyword. Return the id for the keyword.
+    /// If the keyword already exists, return its `LibraryId`.
+    fn create_keyword_sync(&mut self, keyword: String) -> LibraryId;
+
+    /// Create a label. Return the id of the newly created labal.
+    fn create_label_sync(&mut self, name: String, colour: String) -> LibraryId;
+}
diff --git a/src/libraryclient/libraryclient.rs b/src/libraryclient/libraryclient.rs
index 2dfe99e..6390fa0 100644
--- a/src/libraryclient/libraryclient.rs
+++ b/src/libraryclient/libraryclient.rs
@@ -24,7 +24,7 @@ use std::sync::Arc;
 
 use fwk::base::PropertyValue;
 use super::clientimpl::ClientImpl;
-use super::clientinterface::ClientInterface;
+use super::clientinterface::{ClientInterface,ClientInterfaceSync};
 use engine::db::LibraryId;
 use engine::db::library::Managed;
 use root::fwk::FileList;
@@ -139,6 +139,16 @@ impl ClientInterface for LibraryClient {
 
 }
 
+impl ClientInterfaceSync for LibraryClient {
+    fn create_keyword_sync(&mut self, keyword: String) -> LibraryId {
+        self.pimpl.create_keyword_sync(keyword)
+    }
+
+    fn create_label_sync(&mut self, name: String, colour: String) -> LibraryId {
+        self.pimpl.create_label_sync(name, colour)
+    }
+}
+
 #[no_mangle]
 pub extern "C" fn libraryclient_new(path: *const c_char, notif_id: u64) -> *mut LibraryClientWrapper {
     let dir = PathBuf::from(&*unsafe { CStr::from_ptr(path) }.to_string_lossy());
@@ -229,6 +239,14 @@ pub extern "C" fn libraryclient_create_label(client: &mut LibraryClientWrapper,
 }
 
 #[no_mangle]
+pub extern "C" fn libraryclient_create_label_sync(
+    client: &mut LibraryClientWrapper, s: *const c_char, c: *const c_char) -> LibraryId {
+    let name = unsafe { CStr::from_ptr(s) }.to_string_lossy();
+    let colour = unsafe { CStr::from_ptr(c) }.to_string_lossy();
+    client.unwrap_mut().create_label_sync(String::from(name), String::from(colour))
+}
+
+#[no_mangle]
 pub extern "C" fn libraryclient_delete_label(client: &mut LibraryClientWrapper,
                                              label_id: LibraryId) {
     client.unwrap_mut().delete_label(label_id);
diff --git a/src/niepce/ui/dialogs/editlabels.cpp b/src/niepce/ui/dialogs/editlabels.cpp
index b1e57a1..aa5fb67 100644
--- a/src/niepce/ui/dialogs/editlabels.cpp
+++ b/src/niepce/ui/dialogs/editlabels.cpp
@@ -134,11 +134,8 @@ void EditLabels::update_labels(int /*response*/)
             } else {
                 undo->new_command<int>(
                     [libclient, new_name, new_colour] () {
-                        ffi::libraryclient_create_label(
+                        return ffi::libraryclient_create_label_sync(
                             libclient->client(), new_name.c_str(), new_colour.c_str());
-                        return 0; // XXX this is wrong. This was wrong before/
-                        // We need to figure out how to get he new label id to be able
-                        // To cancel it.
                     },
                     [libclient] (int label) {
                         ffi::libraryclient_delete_label(libclient->client(), label);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]