[solang] Added a PhotoFactory



commit 408e4e2eaab230041223e6cda6ede1c5ef682b6c
Author: Debarshi Ray <rishi gnu org>
Date:   Sat Mar 13 10:39:42 2010 +0200

    Added a PhotoFactory
    
    Currently photos are instanciated in the database when a query returns
    a bunch of URIs and they get destructed when the last reference is
    dropped. It is possible that the same URI is represented by two
    separate instances of Photo -- one in the export queue and another
    created from the results of a new query. For consistency it is better
    to have only one Photo instance represent a particular URI at any
    time.
    
    Instances of Photo should be created using PhotoFactory::create_photo.
    The PhotoFactory is not thread-safe as we are constructing or
    destructing photos only from the main thread. The PhotoFactory keeps a
    std::map of uris and WeakPhotoPtrs. When the last PhotoPtr referring
    to a particular Photo instance is dropped the corresponding
    WeakPhotoPtr is removed from the std::map. Therefore all PhotoPtrs
    should be destructed before the PhotoFactory.
    
    Added a Thumbnailer::shutdown, which should be invoked before the
    PhotoFactory is destructed.

 src/application/application.cpp |    3 +
 src/common/Makefile.am          |    2 +
 src/common/database.cpp         |    6 ++-
 src/common/photo-factory.cpp    |   91 +++++++++++++++++++++++++++++++++++++++
 src/common/photo-factory.h      |   65 ++++++++++++++++++++++++++++
 src/common/photo.h              |    8 ++-
 src/common/thumbnailer.cpp      |    8 +++
 src/common/thumbnailer.h        |    3 +
 8 files changed, 182 insertions(+), 4 deletions(-)
---
diff --git a/src/application/application.cpp b/src/application/application.cpp
index 6c68798..ac506e0 100644
--- a/src/application/application.cpp
+++ b/src/application/application.cpp
@@ -258,6 +258,9 @@ Application::Application(int & argc, char ** & argv) throw() :
 Application::~Application() throw()
 {
     threadPool_.shutdown(false);
+
+    Thumbnailer & thumbnailer = Thumbnailer::instance();
+    thumbnailer.shutdown();
 }
 
 void
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 7794f16..04bfe40 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -65,6 +65,8 @@ libcommon_la_SOURCES = \
 	operation.h \
 	photo.cpp \
 	photo.h \
+	photo-factory.cpp \
+	photo-factory.h \
 	plugin.cpp \
 	plugin.h \
 	pixbuf-maker.cpp \
diff --git a/src/common/database.cpp b/src/common/database.cpp
index d306dd6..552e034 100644
--- a/src/common/database.cpp
+++ b/src/common/database.cpp
@@ -30,6 +30,7 @@
 #include "database.h"
 #include "exif-data.h"
 #include "photo.h"
+#include "photo-factory.h"
 #include "photo-tag.h"
 #include "tag.h"
 #include "date-photo-info.h"
@@ -293,12 +294,15 @@ void
 Database::on_async_photos(std::vector<UStringList> & result,
                           const SlotAsyncPhotos & slot) const throw()
 {
+    PhotoFactory & photo_factory = PhotoFactory::instance();
     PhotoList photos;
+
     for (std::vector<UStringList>::const_iterator it = result.begin();
          result.end() != it;
          it++)
     {
-        PhotoPtr photo(new Photo((*it)[0], (*it)[1]));
+        PhotoPtr photo = photo_factory.create_photo((*it)[0],
+                                                    (*it)[1]);
         photos.push_back(photo);
     }
 
diff --git a/src/common/photo-factory.cpp b/src/common/photo-factory.cpp
new file mode 100644
index 0000000..7e7a1e3
--- /dev/null
+++ b/src/common/photo-factory.cpp
@@ -0,0 +1,91 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
+ *
+ * Solang is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Solang is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+#include <iostream>
+#include <utility>
+
+#include "photo.h"
+#include "photo-factory.h"
+
+namespace Solang
+{
+
+PhotoFactory::PhotoFactory() throw() :
+    photos_()
+{
+}
+
+PhotoFactory::~PhotoFactory() throw()
+{
+}
+
+PhotoPtr
+PhotoFactory::create_photo(const Glib::ustring & uri,
+                           const Glib::ustring & content_type) throw()
+{
+    const PhotoMap::iterator iter = photos_.find(uri);
+
+    if (photos_.end() == iter)
+    {
+        const PhotoPtr photo(new Photo(uri, content_type),
+                             &PhotoFactory::deleter);
+        const WeakPhotoPtr weak_photo(photo);
+
+        photos_.insert(std::make_pair(uri, weak_photo));
+        return photo;
+    }
+
+    const WeakPhotoPtr weak_photo = iter->second;
+    const PhotoPtr photo = weak_photo.lock();
+    photo->set_content_type(content_type);
+
+    return photo;
+}
+
+void
+PhotoFactory::deleter(Photo * photo) throw()
+{
+    const Glib::ustring & uri = photo->get_uri();
+    PhotoFactory & photo_factory = PhotoFactory::instance();
+    PhotoMap & photos = photo_factory.get_photos();
+    PhotoMap::iterator iter = photos.find(uri);
+
+    if (photos.end() == iter)
+    {
+        std::cerr << G_STRLOC << ", " << G_STRFUNC << ": "
+                  << uri << ": Missing WeakPhotoPtr" << std::endl;
+    }
+    else
+    {
+        photos.erase(iter);
+    }
+
+    delete photo;
+}
+
+PhotoFactory::PhotoMap &
+PhotoFactory::get_photos() throw()
+{
+    return photos_;
+}
+
+} // namespace Solang
diff --git a/src/common/photo-factory.h b/src/common/photo-factory.h
new file mode 100644
index 0000000..ff80509
--- /dev/null
+++ b/src/common/photo-factory.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2010 Debarshi Ray <rishi gnu org>
+ *
+ * Solang is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Solang is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SOLANG_PHOTO_FACTORY_H
+#define SOLANG_PHOTO_FACTORY_H
+
+#include <map>
+#include <tr1/memory>
+
+#include <glibmm.h>
+
+#include "singleton.h"
+#include "types.h"
+
+namespace Solang
+{
+
+class Photo;
+
+class PhotoFactory :
+    public Singleton<PhotoFactory>
+{
+    public:
+        ~PhotoFactory() throw();
+
+        PhotoPtr
+        create_photo(const Glib::ustring & uri,
+                     const Glib::ustring & content_type) throw();
+
+    private:
+        typedef std::tr1::weak_ptr<Photo> WeakPhotoPtr;
+
+        typedef std::map<Glib::ustring, WeakPhotoPtr> PhotoMap;
+
+        friend class Singleton<PhotoFactory>;
+
+        static void
+        deleter(Photo * photo) throw();
+
+        PhotoMap &
+        get_photos() throw();
+
+        PhotoFactory() throw();
+
+        PhotoMap photos_;
+};
+
+} // namespace Solang
+
+#endif // SOLANG_PHOTO_FACTORY_H
diff --git a/src/common/photo.h b/src/common/photo.h
index 0d6fec6..feab9f7 100644
--- a/src/common/photo.h
+++ b/src/common/photo.h
@@ -54,9 +54,6 @@ class Photo :
         parse_exif_data(const UStringList & data,
                         ExifData & exif_data) throw();
 
-        Photo(const Glib::ustring & uri,
-              const Glib::ustring & content_type) throw();
-
         virtual
         ~Photo() throw();
 
@@ -125,6 +122,11 @@ class Photo :
         get_delete_action() throw();
 
     private:
+        friend class PhotoFactory;
+
+        Photo(const Glib::ustring & uri,
+              const Glib::ustring & content_type) throw();
+
         Glib::ustring uri_;
 
         Glib::ustring contentType_; //content type
diff --git a/src/common/thumbnailer.cpp b/src/common/thumbnailer.cpp
index 34746ba..73c5b56 100644
--- a/src/common/thumbnailer.cpp
+++ b/src/common/thumbnailer.cpp
@@ -158,4 +158,12 @@ Thumbnailer::signal_ready() throw()
     return ready_;
 }
 
+void
+Thumbnailer::shutdown() throw()
+{
+    notify_callbacks();
+    pendingList_.clear();
+    map_.clear();
+}
+
 } // namespace Solang
diff --git a/src/common/thumbnailer.h b/src/common/thumbnailer.h
index 836f6a4..1042eb4 100644
--- a/src/common/thumbnailer.h
+++ b/src/common/thumbnailer.h
@@ -44,6 +44,9 @@ class Thumbnailer :
         sigc::signal<void, PhotoList &> &
         signal_ready() throw();
 
+        void
+        shutdown() throw();
+
     private:
         friend class Singleton<Thumbnailer>;
 



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