[niepce] npc-engine: bind LibFile with cxx



commit 6d409f68ea0102bc22c34fdd02906938db7ec1e0
Author: Hubert Figuière <hub figuiere net>
Date:   Sat Oct 15 21:46:16 2022 -0400

    npc-engine: bind LibFile with cxx

 crates/npc-engine/build.rs                     |  1 +
 crates/npc-engine/src/db.rs                    |  1 +
 crates/npc-engine/src/db/libfile.rs            | 44 +++++++-------------------
 crates/npc-engine/src/lib.rs                   | 38 +++++++++++++++++++++-
 niepce-main/build.rs                           |  1 +
 src/engine/Makefile.am                         |  2 +-
 src/engine/db/libfile.cpp                      | 38 ----------------------
 src/engine/db/libfile.hpp                      |  3 --
 src/niepce/modules/darkroom/darkroommodule.cpp | 30 +++++++-----------
 src/niepce/modules/darkroom/darkroommodule.hpp |  6 ++--
 src/niepce/ui/imageliststore.cpp               |  6 ++--
 src/niepce/ui/imageliststore.hpp               |  4 ++-
 src/niepce/ui/moduleshell.cpp                  |  4 +--
 src/niepce/ui/selectioncontroller.cpp          | 20 ++++++------
 src/niepce/ui/selectioncontroller.hpp          |  5 ++-
 src/rust_bindings.hpp                          |  6 ++--
 16 files changed, 92 insertions(+), 117 deletions(-)
---
diff --git a/crates/npc-engine/build.rs b/crates/npc-engine/build.rs
index 257fdd72..6ce29916 100644
--- a/crates/npc-engine/build.rs
+++ b/crates/npc-engine/build.rs
@@ -32,6 +32,7 @@ fn main() {
             .exclude_item("PropertyValue")
             .exclude_item("Keyword")
             .exclude_item("Label")
+            .exclude_item("LibFile")
             // Ensure these are opaque as generics are still a problem.
             .exclude_item("NiepcePropertySet")
             .exclude_item("NiepcePropertyBag")
diff --git a/crates/npc-engine/src/db.rs b/crates/npc-engine/src/db.rs
index faa2309a..3490c02f 100644
--- a/crates/npc-engine/src/db.rs
+++ b/crates/npc-engine/src/db.rs
@@ -32,6 +32,7 @@ pub type LibraryId = i64;
 // flatten namespace a bit.
 pub use self::keyword::Keyword;
 pub use self::label::Label;
+pub use self::libfile::LibFile;
 pub use self::libfolder::LibFolder;
 pub use self::libmetadata::LibMetadata;
 pub use self::library::Library;
diff --git a/crates/npc-engine/src/db/libfile.rs b/crates/npc-engine/src/db/libfile.rs
index f2aaa18a..e4b8a89e 100644
--- a/crates/npc-engine/src/db/libfile.rs
+++ b/crates/npc-engine/src/db/libfile.rs
@@ -158,6 +158,11 @@ impl LibFile {
         self.main_file.path()
     }
 
+    // For cxx
+    pub fn path_str(&self) -> String {
+        self.path().to_string_lossy().to_string()
+    }
+
     pub fn orientation(&self) -> i32 {
         self.orientation
     }
@@ -189,6 +194,12 @@ impl LibFile {
     pub fn file_type(&self) -> FileType {
         self.file_type.to_owned()
     }
+
+    // for cxx
+    pub fn file_type_int(&self) -> i32 {
+        self.file_type.into()
+    }
+
     pub fn set_file_type(&mut self, ft: FileType) {
         self.file_type = ft;
     }
@@ -295,44 +306,11 @@ pub unsafe extern "C" fn engine_db_libfile_new(
     Box::into_raw(lf)
 }
 
-/// # Safety
-/// Dereference raw pointer.
-#[no_mangle]
-pub unsafe extern "C" fn engine_db_libfile_delete(lf: *mut LibFile) {
-    drop(Box::from_raw(lf));
-}
-
-#[no_mangle]
-pub extern "C" fn engine_db_libfile_path(obj: &mut LibFile) -> *const c_char {
-    obj.cstr = CString::new(obj.path().to_str().unwrap_or("")).unwrap();
-    obj.cstr.as_ptr()
-}
-
-#[no_mangle]
-pub extern "C" fn engine_db_libfile_id(obj: &LibFile) -> LibraryId {
-    obj.id()
-}
-
-#[no_mangle]
-pub extern "C" fn engine_db_libfile_folderid(obj: &LibFile) -> LibraryId {
-    obj.folder_id()
-}
-
-#[no_mangle]
-pub extern "C" fn engine_db_libfile_orientation(obj: &LibFile) -> i32 {
-    obj.orientation()
-}
-
 #[no_mangle]
 pub extern "C" fn engine_db_libfile_property(obj: &LibFile, idx: NiepcePropertyIdx) -> i32 {
     obj.property(Np::Index(idx))
 }
 
-#[no_mangle]
-pub extern "C" fn engine_db_libfile_file_type(obj: &LibFile) -> FileType {
-    obj.file_type()
-}
-
 #[no_mangle]
 pub extern "C" fn engine_db_libfile_set_property(
     obj: &mut LibFile,
diff --git a/crates/npc-engine/src/lib.rs b/crates/npc-engine/src/lib.rs
index 28bf1d26..37771c16 100644
--- a/crates/npc-engine/src/lib.rs
+++ b/crates/npc-engine/src/lib.rs
@@ -104,7 +104,7 @@ pub extern "C" fn eng_property_bag_set_value(
     b.set_value(key.into(), v.clone())
 }
 
-use crate::db::{Keyword, Label};
+use crate::db::{Keyword, Label, LibFile};
 
 #[cxx::bridge(namespace = "eng")]
 mod ffi {
@@ -115,6 +115,27 @@ mod ffi {
         type RgbColour = npc_fwk::base::rgbcolour::RgbColour;
     }
 
+    // This enum is only here for the purpose of binding generation.
+    #[repr(i32)]
+    /// A general type of the LibFile, cxx bindings version.
+    pub enum FileType {
+        /// Don't know
+        #[allow(dead_code)]
+        Unknown = 0,
+        /// Camera Raw
+        #[allow(dead_code)]
+        Raw = 1,
+        /// Bundle of RAW + processed. Don't assume JPEG.
+        #[allow(dead_code)]
+        RawJpeg = 2,
+        /// Processed Image
+        #[allow(dead_code)]
+        Image = 3,
+        /// Video
+        #[allow(dead_code)]
+        Video = 4,
+    }
+
     extern "Rust" {
         type Keyword;
 
@@ -132,4 +153,19 @@ mod ffi {
         fn id(&self) -> i64;
         fn clone_boxed(&self) -> Box<Label>;
     }
+
+    extern "Rust" {
+        type LibFile;
+
+        #[cxx_name = "path"]
+        fn path_str(&self) -> String;
+        fn id(&self) -> i64;
+        fn folder_id(&self) -> i64;
+        fn orientation(&self) -> i32;
+        #[cxx_name = "file_type"]
+        // The type is `FileType`.
+        fn file_type_int(&self) -> i32;
+    }
+
+    impl Box<LibFile> {}
 }
diff --git a/niepce-main/build.rs b/niepce-main/build.rs
index 9a7ad0e2..216b9413 100644
--- a/niepce-main/build.rs
+++ b/niepce-main/build.rs
@@ -25,6 +25,7 @@ fn main() {
             .include_item("ColIndex")
             .exclude_item("Managed")
             .exclude_item("NiepcePropertyIdx")
+            .exclude_item("LibFile")
             .exclude_item("FileStatus")
             .exclude_item("FileList")
             .exclude_item("RgbColour")
diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am
index 4c6baa9c..921c2bf2 100644
--- a/src/engine/Makefile.am
+++ b/src/engine/Makefile.am
@@ -19,7 +19,7 @@ TEST_LIBS =  \
 noinst_LIBRARIES = libniepceengine.a
 
 libniepceengine_a_SOURCES = \
-       db/libfile.hpp db/libfile.cpp \
+       db/libfile.hpp \
        db/label.hpp \
        db/libmetadata.hpp db/libmetadata.cpp \
        db/storage.hpp \
diff --git a/src/engine/db/libfile.hpp b/src/engine/db/libfile.hpp
index 452ea447..89a129a9 100644
--- a/src/engine/db/libfile.hpp
+++ b/src/engine/db/libfile.hpp
@@ -26,12 +26,9 @@
 
 namespace eng {
 
-typedef std::shared_ptr<LibFile> LibFilePtr;
-typedef std::weak_ptr<LibFile> LibFileWeakPtr;
 typedef std::list<LibFilePtr> LibFileList;
 typedef std::shared_ptr<LibFileList> LibFileListPtr;
 
-LibFilePtr libfile_wrap(LibFile *);
 }
 
 /*
diff --git a/src/niepce/modules/darkroom/darkroommodule.cpp b/src/niepce/modules/darkroom/darkroommodule.cpp
index b881d988..c688af0b 100644
--- a/src/niepce/modules/darkroom/darkroommodule.cpp
+++ b/src/niepce/modules/darkroom/darkroommodule.cpp
@@ -48,15 +48,15 @@ void DarkroomModule::reload_image()
     if(!m_need_reload) {
         return;
     }
-    eng::LibFilePtr file = m_imagefile.lock();
-    if(file) {
+    if (m_imagefile.has_value()) {
+        const eng::LibFilePtr& file = m_imagefile.value();
         // currently we treat RAW + JPEG as RAW.
         // TODO: have a way to actually choose the JPEG.
-        auto file_type = engine_db_libfile_file_type(file.get());
-        bool isRaw = (file_type == eng::FileType::Raw)
-            || (file_type == eng::FileType::RawJpeg);
-        std::string path = engine_db_libfile_path(file.get());
-        m_image->reload(path, isRaw, engine_db_libfile_orientation(file.get()));
+        auto file_type = file->file_type();
+        bool isRaw = (file_type == (int32_t)eng::FileType::Raw)
+            || (file_type == (int32_t)eng::FileType::RawJpeg);
+        std::string path = std::string(file->path());
+        m_image->reload(path, isRaw, file->orientation());
     }
     else {
         // reset
@@ -67,18 +67,12 @@ void DarkroomModule::reload_image()
     m_need_reload = false;
 }
 
-void DarkroomModule::set_image(const eng::LibFilePtr & file)
+void DarkroomModule::set_image(std::optional<eng::LibFilePtr>&& file)
 {
-    if(m_imagefile.expired() || (file != m_imagefile.lock())) {
-        m_imagefile = eng::LibFileWeakPtr(file);
-        m_need_reload = true;
-    }
-    else if(!static_cast<bool>(file)) {
-        m_imagefile.reset();
-        m_need_reload = true;
-    }
+    m_imagefile = std::move(file);
+    m_need_reload = true;
 
-    if(m_need_reload && m_active) {
+    if (m_need_reload && m_active) {
         reload_image();
     }
 }
@@ -138,7 +132,7 @@ void DarkroomModule::on_selected(eng::library_id_t id)
 {
     auto file = m_shell.get_selection_controller()->get_file(id);
     DBG_OUT("selection is %ld", id);
-    set_image(file);
+    set_image(std::move(file));
 }
 
 }
diff --git a/src/niepce/modules/darkroom/darkroommodule.hpp b/src/niepce/modules/darkroom/darkroommodule.hpp
index ab4deb85..6675deac 100644
--- a/src/niepce/modules/darkroom/darkroommodule.hpp
+++ b/src/niepce/modules/darkroom/darkroommodule.hpp
@@ -19,6 +19,8 @@
 
 #pragma once
 
+#include <optional>
+
 #include <gtkmm/widget.h>
 #include <gtkmm/paned.h>
 #include <gtkmm/box.h>
@@ -47,7 +49,7 @@ public:
 
     DarkroomModule(const ui::IModuleShell & shell);
 
-    void set_image(const eng::LibFilePtr & file);
+    void set_image(std::optional<eng::LibFilePtr>&& file);
 
     virtual void dispatch_action(const std::string & action_name) override;
 
@@ -72,7 +74,7 @@ private:
     Gtk::ScrolledWindow          m_canvas_scroll;
     ToolboxController::Ptr       m_toolbox_ctrl;
     Glib::RefPtr<Gio::ActionGroup> m_actionGroup;
-    eng::LibFileWeakPtr        m_imagefile;
+    std::optional<eng::LibFilePtr> m_imagefile;
     ncr::Image::Ptr              m_image;
     fwk::Dock                   *m_dock;
 
diff --git a/src/niepce/ui/imageliststore.cpp b/src/niepce/ui/imageliststore.cpp
index 515ed562..dd5df696 100644
--- a/src/niepce/ui/imageliststore.cpp
+++ b/src/niepce/ui/imageliststore.cpp
@@ -71,13 +71,13 @@ eng::library_id_t ImageListStore::get_libfile_id_at_path(const Gtk::TreeModel::P
     return ffi::npc_image_list_store_get_file_id_at_path(m_store, path.gobj());
 }
 
-eng::LibFilePtr ImageListStore::get_file(eng::library_id_t id) const
+std::optional<eng::LibFilePtr> ImageListStore::get_file(eng::library_id_t id) const
 {
     auto f = ffi::npc_image_list_store_get_file(m_store, id);
     if (f) {
-        return eng::libfile_wrap(f);
+        return std::optional(eng::LibFilePtr::from_raw(f));
     }
-    return eng::LibFilePtr();
+    return std::nullopt;
 }
 
 void ImageListStore::clear_content()
diff --git a/src/niepce/ui/imageliststore.hpp b/src/niepce/ui/imageliststore.hpp
index 37c13560..b123aeee 100644
--- a/src/niepce/ui/imageliststore.hpp
+++ b/src/niepce/ui/imageliststore.hpp
@@ -19,6 +19,8 @@
 
 #pragma once
 
+#include <optional>
+
 #include <gtkmm/liststore.h>
 
 #include "fwk/base/propertybag.hpp"
@@ -43,7 +45,7 @@ public:
     Gtk::TreeModel::Path get_path_from_id(eng::library_id_t id) const;
     Gtk::TreeModel::iterator get_iter_from_id(eng::library_id_t id) const;
     eng::library_id_t get_libfile_id_at_path(const Gtk::TreeModel::Path& path) const;
-    eng::LibFilePtr get_file(eng::library_id_t id) const;
+    std::optional<eng::LibFilePtr> get_file(eng::library_id_t id) const;
     size_t get_count() const
         { return m_store_wrap->children().size(); }
 
diff --git a/src/niepce/ui/moduleshell.cpp b/src/niepce/ui/moduleshell.cpp
index bc4604f5..fb868c9a 100644
--- a/src/niepce/ui/moduleshell.cpp
+++ b/src/niepce/ui/moduleshell.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - niepce/ui/moduleshell.cpp
  *
- * Copyright (C) 2007-2018 Hubert Figuière
+ * Copyright (C) 2007-2022 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -261,7 +261,7 @@ void ModuleShell::on_image_activated(eng::library_id_t id)
     auto store = m_selection_controller->get_list_store();
     auto libfile = store->get_file(id);
     if (libfile) {
-        m_darkroom->set_image(libfile);
+        m_darkroom->set_image(std::optional(std::move(libfile)));
         m_shell.activatePage("darkroom");
     }
 }
diff --git a/src/niepce/ui/selectioncontroller.cpp b/src/niepce/ui/selectioncontroller.cpp
index 57757ecc..0684a420 100644
--- a/src/niepce/ui/selectioncontroller.cpp
+++ b/src/niepce/ui/selectioncontroller.cpp
@@ -117,7 +117,7 @@ eng::library_id_t SelectionController::get_selection() const
     return selectable->get_selected();
 }
 
-eng::LibFilePtr SelectionController::get_file(eng::library_id_t id) const
+std::optional<eng::LibFilePtr> SelectionController::get_file(eng::library_id_t id) const
 {
     return m_imageliststore->get_file(id);
 }
@@ -264,13 +264,14 @@ void SelectionController::set_property(ffi::NiepcePropertyIdx idx, int value)
     DBG_OUT("property %u = %d", static_cast<uint32_t>(idx), value);
     eng::library_id_t selection = get_selection();
     if(selection >= 0) {
-        eng::LibFilePtr file = m_imageliststore->get_file(selection);
-        if (!file) {
+        std::optional<eng::LibFilePtr> f = m_imageliststore->get_file(selection);
+        if (!f) {
             ERR_OUT("requested file %ld not found!", selection);
             return;
         }
-        DBG_OUT("old property is %d", engine_db_libfile_property(file.get(), idx));
-        int32_t old_value = engine_db_libfile_property(file.get(), idx);
+        auto& file = f.value();
+        DBG_OUT("old property is %d", engine_db_libfile_property(&*file, idx));
+        int32_t old_value = engine_db_libfile_property(&*file, idx);
         const char *action = nullptr;
         switch(idx) {
         case ffi::NiepcePropertyIdx::NpNiepceFlagProp:
@@ -289,7 +290,7 @@ void SelectionController::set_property(ffi::NiepcePropertyIdx idx, int value)
         _set_metadata(action, selection, idx, old_value, value);
         // we need to set the property here so that undo/redo works
         // consistently.
-        engine_db_libfile_set_property(file.get(), idx, value);
+        engine_db_libfile_set_property(&*file, idx, value);
     }
 }
 
@@ -321,9 +322,10 @@ void SelectionController::move_to_trash()
         ffi::libraryclient_get_trash_id(getLibraryClient()->client());
     eng::library_id_t selection = get_selection();
     if(selection >= 0) {
-        auto file = m_imageliststore->get_file(selection);
-        if (file) {
-            eng::library_id_t from_folder = engine_db_libfile_folderid(file.get());
+        auto f = m_imageliststore->get_file(selection);
+        if (f) {
+            auto& file = f.value();
+            eng::library_id_t from_folder = file->folder_id();
             std::shared_ptr<fwk::UndoTransaction> undo =
                 fwk::Application::app()->begin_undo(_("Move to Trash"));
 
diff --git a/src/niepce/ui/selectioncontroller.hpp b/src/niepce/ui/selectioncontroller.hpp
index 4f48bf42..fbe268cf 100644
--- a/src/niepce/ui/selectioncontroller.hpp
+++ b/src/niepce/ui/selectioncontroller.hpp
@@ -20,8 +20,7 @@
 #pragma once
 
 #include <memory>
-
-#include <gtk/gtk.h>
+#include <optional>
 
 #include <sigc++/signal.h>
 
@@ -108,7 +107,7 @@ public:
      *  todo: change it to support multiple
      */
     eng::library_id_t get_selection() const;
-    eng::LibFilePtr get_file(eng::library_id_t id) const;
+    std::optional<eng::LibFilePtr> get_file(eng::library_id_t id) const;
 protected:
     virtual void _added() override;
 private:
diff --git a/src/rust_bindings.hpp b/src/rust_bindings.hpp
index f7d6f09d..6608efa8 100644
--- a/src/rust_bindings.hpp
+++ b/src/rust_bindings.hpp
@@ -37,6 +37,7 @@ typedef fwk::FileList FileList;
 typedef fwk::PropertyValue PropertyValue;
 typedef fwk::RgbColour RgbColour;
 typedef eng::Label Label;
+typedef eng::LibFile LibFile;
 typedef eng::Keyword Keyword;
 struct NiepcePropertyBag;
 struct NiepcePropertySet;
@@ -59,15 +60,14 @@ typedef ffi::NiepcePropertySet PropertySet;
 }
 
 namespace eng {
-typedef rust::Box<Label> LabelPtr;
 typedef rust::Box<Keyword> KeywordPtr;
+typedef rust::Box<Label> LabelPtr;
+typedef rust::Box<LibFile> LibFilePtr;
 
 typedef ffi::NiepcePropertyIdx Np;
 using NiepcePropertyIdx = ffi::NiepcePropertyIdx;
 typedef ffi::LibraryId library_id_t; // XXX change this to LibraryId
-typedef ffi::FileType FileType;
 typedef ffi::FileStatus FileStatus;
-typedef ffi::LibFile LibFile;
 typedef ffi::LibFolder LibFolder;
 typedef ffi::LibMetadata LibMetadata;
 typedef ffi::Managed Managed;


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