[niepce/lr-import: 8/20] npc-engine: remove ClientImpl
- From: Hubert Figuière <hub src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [niepce/lr-import: 8/20] npc-engine: remove ClientImpl
- Date: Mon, 20 Dec 2021 05:37:15 +0000 (UTC)
commit 48259fd069e46f2a7aa8f67460c3ff75dbf8935c
Author: Hubert Figuière <hub figuiere net>
Date: Sun Nov 14 00:52:58 2021 -0500
npc-engine: remove ClientImpl
crates/npc-engine/src/libraryclient.rs | 215 +++++++++++++----
crates/npc-engine/src/libraryclient/clientimpl.rs | 270 ----------------------
src/Makefile.am | 1 -
3 files changed, 168 insertions(+), 318 deletions(-)
---
diff --git a/crates/npc-engine/src/libraryclient.rs b/crates/npc-engine/src/libraryclient.rs
index 36958fa..e6bb2bc 100644
--- a/crates/npc-engine/src/libraryclient.rs
+++ b/crates/npc-engine/src/libraryclient.rs
@@ -17,23 +17,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-pub mod clientimpl;
pub mod clientinterface;
pub use self::clientinterface::{ClientInterface, ClientInterfaceSync};
use libc::{c_char, c_void};
+use std::collections::VecDeque;
use std::ffi::CStr;
use std::path::PathBuf;
-use std::sync::Arc;
+use std::sync;
+use std::sync::atomic;
+use std::sync::mpsc;
+use std::thread;
-use self::clientimpl::ClientImpl;
use crate::db::filebundle::FileBundle;
use crate::db::library::Managed;
use crate::db::props::NiepceProperties as Np;
-use crate::db::LibraryId;
+use crate::db::{Library, LibraryId};
use crate::db::{NiepceProperties, NiepcePropertyIdx};
+use crate::library::commands;
use crate::library::notification::{LcChannel, LibNotification};
+use crate::library::op::Op;
use npc_fwk::base::PropertyValue;
use npc_fwk::toolkit::PortableChannel;
use npc_fwk::utils::files::FileList;
@@ -41,7 +45,7 @@ use npc_fwk::utils::files::FileList;
/// Wrap the libclient Arc so that it can be passed around
/// Used in the ffi for example.
pub struct LibraryClientWrapper {
- client: Arc<LibraryClient>,
+ client: sync::Arc<LibraryClient>,
}
impl LibraryClientWrapper {
@@ -50,7 +54,7 @@ impl LibraryClientWrapper {
sender: async_channel::Sender<LibNotification>,
) -> LibraryClientWrapper {
LibraryClientWrapper {
- client: Arc::new(LibraryClient::new(dir, sender)),
+ client: sync::Arc::new(LibraryClient::new(dir, sender)),
}
}
@@ -58,20 +62,38 @@ impl LibraryClientWrapper {
/// XXX we need to unsure this is thread safe.
/// Don't hold this reference more than you need.
pub fn unwrap_mut(&mut self) -> &mut LibraryClient {
- Arc::get_mut(&mut self.client).unwrap()
+ sync::Arc::get_mut(&mut self.client).unwrap()
}
}
pub struct LibraryClient {
- pimpl: ClientImpl,
-
+ terminate: sync::Arc<atomic::AtomicBool>,
+ tasks: sync::Arc<(sync::Mutex<VecDeque<Op>>, sync::Condvar)>,
trash_id: LibraryId,
}
+impl Drop for LibraryClient {
+ fn drop(&mut self) {
+ self.stop();
+ }
+}
+
impl LibraryClient {
pub fn new(dir: PathBuf, sender: async_channel::Sender<LibNotification>) -> LibraryClient {
+ let tasks = sync::Arc::new((sync::Mutex::new(VecDeque::new()), sync::Condvar::new()));
+ let mut terminate = sync::Arc::new(atomic::AtomicBool::new(false));
+ let tasks2 = tasks.clone();
+ let terminate2 = terminate.clone();
+
+ /* let thread = */
+ thread::spawn(move || {
+ let library = Library::new(&dir, None, sender);
+ Self::main(&mut terminate, &tasks, &library);
+ });
+
LibraryClient {
- pimpl: ClientImpl::new(dir, sender),
+ terminate: terminate2,
+ tasks: tasks2,
trash_id: 0,
}
}
@@ -83,110 +105,209 @@ impl LibraryClient {
pub fn set_trash_id(&mut self, id: LibraryId) {
self.trash_id = id;
}
+
+ fn stop(&mut self) {
+ self.terminate.store(true, atomic::Ordering::Relaxed);
+ self.tasks.1.notify_one();
+ }
+
+ fn main(
+ terminate: &mut sync::Arc<atomic::AtomicBool>,
+ tasks: &sync::Arc<(sync::Mutex<VecDeque<Op>>, sync::Condvar)>,
+ library: &Library,
+ ) {
+ while !terminate.load(atomic::Ordering::Relaxed) {
+ let elem: Option<Op>;
+ {
+ let mut queue = tasks.0.lock().unwrap();
+ if !queue.is_empty() {
+ elem = queue.pop_front();
+ } else {
+ elem = None;
+ }
+ }
+
+ if let Some(op) = elem {
+ op.execute(library);
+ }
+
+ let queue = tasks.0.lock().unwrap();
+ if queue.is_empty() {
+ if let Err(err) = tasks.1.wait(queue) {
+ err_out!("queue lock poisonned: {}", err);
+ break;
+ }
+ }
+ }
+ }
+
+ pub fn schedule_op<F>(&mut self, f: F)
+ where
+ F: Fn(&Library) -> bool + Send + Sync + 'static,
+ {
+ let op = Op::new(f);
+
+ let mut queue = self.tasks.0.lock().unwrap();
+ queue.push_back(op);
+ self.tasks.1.notify_all();
+ }
}
impl ClientInterface for LibraryClient {
/// get all the keywords
fn get_all_keywords(&mut self) {
- self.pimpl.get_all_keywords();
+ self.schedule_op(move |lib| commands::cmd_list_all_keywords(&lib));
}
- fn query_keyword_content(&mut self, id: LibraryId) {
- self.pimpl.query_keyword_content(id);
+
+ fn query_keyword_content(&mut self, keyword_id: LibraryId) {
+ self.schedule_op(move |lib| commands::cmd_query_keyword_content(&lib, keyword_id));
}
+
fn count_keyword(&mut self, id: LibraryId) {
- self.pimpl.count_keyword(id);
+ self.schedule_op(move |lib| commands::cmd_count_keyword(&lib, id));
}
- /// get all the folder
+ /// get all the folders
fn get_all_folders(&mut self) {
- self.pimpl.get_all_folders();
+ self.schedule_op(move |lib| commands::cmd_list_all_folders(&lib));
}
- fn query_folder_content(&mut self, id: LibraryId) {
- self.pimpl.query_folder_content(id);
+
+ fn query_folder_content(&mut self, folder_id: LibraryId) {
+ self.schedule_op(move |lib| commands::cmd_query_folder_content(&lib, folder_id));
}
- fn count_folder(&mut self, id: LibraryId) {
- self.pimpl.count_folder(id);
+
+ fn count_folder(&mut self, folder_id: LibraryId) {
+ self.schedule_op(move |lib| commands::cmd_count_folder(&lib, folder_id));
}
fn create_folder(&mut self, name: String, path: Option<String>) {
- self.pimpl.create_folder(name, path);
+ self.schedule_op(move |lib| commands::cmd_create_folder(&lib, &name, path.clone()) != 0);
}
fn delete_folder(&mut self, id: LibraryId) {
- self.pimpl.delete_folder(id);
+ self.schedule_op(move |lib| commands::cmd_delete_folder(&lib, id));
}
/// get all the albums
fn get_all_albums(&mut self) {
- self.pimpl.get_all_albums();
+ self.schedule_op(move |lib| commands::cmd_list_all_albums(&lib));
}
/// Create an album (async)
fn create_album(&mut self, name: String, parent: LibraryId) {
- self.pimpl.create_album(name, parent);
+ self.schedule_op(move |lib| commands::cmd_create_album(&lib, &name, parent) != 0);
}
- fn request_metadata(&mut self, id: LibraryId) {
- self.pimpl.request_metadata(id);
+ fn request_metadata(&mut self, file_id: LibraryId) {
+ self.schedule_op(move |lib| commands::cmd_request_metadata(&lib, file_id));
}
+
/// set the metadata
- fn set_metadata(&mut self, id: LibraryId, meta: Np, value: &PropertyValue) {
- self.pimpl.set_metadata(id, meta, value);
+ fn set_metadata(&mut self, file_id: LibraryId, meta: Np, value: &PropertyValue) {
+ let value2 = value.clone();
+ self.schedule_op(move |lib| commands::cmd_set_metadata(&lib, file_id, meta, &value2));
}
- fn write_metadata(&mut self, id: LibraryId) {
- self.pimpl.write_metadata(id);
+ fn write_metadata(&mut self, file_id: LibraryId) {
+ self.schedule_op(move |lib| commands::cmd_write_metadata(&lib, file_id));
}
fn move_file_to_folder(&mut self, file_id: LibraryId, from: LibraryId, to: LibraryId) {
- self.pimpl.move_file_to_folder(file_id, from, to);
+ self.schedule_op(move |lib| commands::cmd_move_file_to_folder(&lib, file_id, from, to));
}
+
/// get all the labels
fn get_all_labels(&mut self) {
- self.pimpl.get_all_labels();
+ self.schedule_op(move |lib| commands::cmd_list_all_labels(&lib));
}
- fn create_label(&mut self, label: String, colour: String) {
- self.pimpl.create_label(label, colour);
+ fn create_label(&mut self, name: String, colour: String) {
+ self.schedule_op(move |lib| commands::cmd_create_label(&lib, &name, &colour) != 0);
}
- fn delete_label(&mut self, id: LibraryId) {
- self.pimpl.delete_label(id);
+ fn delete_label(&mut self, label_id: LibraryId) {
+ self.schedule_op(move |lib| commands::cmd_delete_label(&lib, label_id));
}
/// update a label
- fn update_label(&mut self, id: LibraryId, new_name: String, new_colour: String) {
- self.pimpl.update_label(id, new_name, new_colour);
+ fn update_label(&mut self, label_id: LibraryId, new_name: String, new_colour: String) {
+ self.schedule_op(move |lib| {
+ commands::cmd_update_label(&lib, label_id, &new_name, &new_colour)
+ });
}
/// tell to process the Xmp update Queue
fn process_xmp_update_queue(&mut self, write_xmp: bool) {
- self.pimpl.process_xmp_update_queue(write_xmp);
+ self.schedule_op(move |lib| commands::cmd_process_xmp_update_queue(&lib, write_xmp));
}
/// Import files from a directory
/// @param dir the directory
/// @param manage true if imports have to be managed
fn import_files(&mut self, dir: String, files: Vec<PathBuf>, manage: Managed) {
- self.pimpl.import_files(dir, files, manage);
+ self.schedule_op(move |lib| commands::cmd_import_files(&lib, &dir, &files, manage));
}
}
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 {
+ // 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_label_sync(&mut self, name: String, colour: String) -> LibraryId {
- self.pimpl.create_label_sync(name, colour)
+ 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()
}
fn create_folder_sync(&mut self, name: String, path: Option<String>) -> LibraryId {
- self.pimpl.create_folder_sync(name, path)
+ // can't use futures::sync::oneshot
+ let (tx, rx) = mpsc::sync_channel::<LibraryId>(1);
+
+ self.schedule_op(move |lib| {
+ tx.send(commands::cmd_create_folder(&lib, &name, path.clone()))
+ .unwrap();
+ true
+ });
+
+ rx.recv().unwrap()
}
fn create_album_sync(&mut self, name: String, parent: LibraryId) -> LibraryId {
- self.pimpl.create_album_sync(name, parent)
+ // can't use futures::sync::oneshot
+ let (tx, rx) = mpsc::sync_channel::<LibraryId>(1);
+
+ self.schedule_op(move |lib| {
+ tx.send(commands::cmd_create_album(&lib, &name, parent))
+ .unwrap();
+ true
+ });
+
+ rx.recv().unwrap()
}
fn add_bundle_sync(&mut self, bundle: &FileBundle, folder: LibraryId) -> LibraryId {
- self.pimpl.add_bundle_sync(bundle, folder)
+ let (tx, rx) = mpsc::sync_channel::<LibraryId>(1);
+
+ let bundle = bundle.clone();
+ self.schedule_op(move |lib| {
+ tx.send(commands::cmd_add_bundle(&lib, &bundle, folder))
+ .unwrap();
+ true
+ });
+
+ rx.recv().unwrap()
}
}
diff --git a/src/Makefile.am b/src/Makefile.am
index 6f620f7..6df7503 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -30,7 +30,6 @@ RUST_SOURCES = \
@top_srcdir@/crates/npc-engine/src/library/queriedcontent.rs \
@top_srcdir@/crates/npc-engine/src/library/thumbnail_cache.rs \
@top_srcdir@/crates/npc-engine/src/libraryclient.rs \
- @top_srcdir@/crates/npc-engine/src/libraryclient/clientimpl.rs \
@top_srcdir@/crates/npc-engine/src/libraryclient/clientinterface.rs \
@top_srcdir@/crates/npc-engine/src/lib.rs \
@top_srcdir@/crates/npc-fwk/Cargo.toml \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]