#include "GraphicsCache.h"
#include "support/debug.h"
+#include "support/lassert.h"
#include "support/Timeout.h"
-#include "support/bind.h"
-
-#include <set>
+#include <list>
#include <queue>
+#include <memory>
+#include <set>
using namespace std;
using namespace lyx::support;
namespace lyx {
+
namespace graphics {
static int const s_millisecs_ = 500;
-// FIXME THREAD
LoaderQueue & LoaderQueue::get()
{
static LoaderQueue singleton;
LoaderQueue::LoaderQueue() : timer(s_millisecs_, Timeout::ONETIME),
- running_(false)
+ running_(false)
{
- timer.timeout.connect(bind(&LoaderQueue::loadNext, this));
+ // Disconnected when this is destroyed
+ timer.timeout.connect([this](){ loadNext(); });
}
void LoaderQueue::startLoader()
{
LYXERR(Debug::GRAPHICS, "LoaderQueue: waking up");
- running_ = true ;
+ running_ = true;
timer.setTimeout(s_millisecs_);
timer.start();
}
//
/////////////////////////////////////////////////////////////////////
-typedef shared_ptr<Image> ImagePtr;
+typedef std::shared_ptr<Image> ImagePtr;
-class Loader::Impl : public boost::signals::trackable {
+class Loader::Impl {
+ friend class Loader;
public:
///
- Impl();
+ Impl(FileName const & doc_file);
///
~Impl();
///
///
Params const & params() const { return params_; }
+ ///
+ FileName doc_file_;
/// The loading status of the image.
ImageStatus status_;
/** Must store a copy of the cached item to ensure that it is not
/// We modify a local copy of the image once it is loaded.
ImagePtr image_;
/// This signal is emitted when the image loading status changes.
- boost::signal<void()> signal_;
- /// The connection of the signal StatusChanged
- boost::signals::connection sc_;
+ signal<void()> signal_;
+ /// The connection of the signal statusChanged
+ scoped_connection connection_;
double displayPixelRatio() const
{
};
-Loader::Loader()
- : pimpl_(new Impl)
+Loader::Loader(FileName const & doc_file)
+ : pimpl_(new Impl(doc_file))
{}
-Loader::Loader(FileName const & file, bool display)
- : pimpl_(new Impl)
+Loader::Loader(FileName const & doc_file, FileName const & file, bool display)
+ : pimpl_(new Impl(doc_file))
{
reset(file, display);
}
-Loader::Loader(FileName const & file, Params const & params)
- : pimpl_(new Impl)
+Loader::Loader(FileName const & doc_file, FileName const & file, Params const & params)
+ : pimpl_(new Impl(doc_file))
{
reset(file, params);
}
+Loader::Loader(FileName const & doc_file, Loader const & other)
+ : pimpl_(new Impl(doc_file))
+{
+ Params const & params = other.pimpl_->params();
+ reset(params.filename, params);
+}
+
+
Loader::Loader(Loader const & other)
- : pimpl_(new Impl)
+ : pimpl_(new Impl(other.pimpl_->doc_file_))
{
Params const & params = other.pimpl_->params();
reset(params.filename, params);
Loader & Loader::operator=(Loader const & other)
{
+ LASSERT(false, /**/);
if (this != &other) {
+ delete pimpl_;
+ pimpl_ = new Impl(other.pimpl_->doc_file_);
Params const & params = other.pimpl_->params();
reset(params.filename, params);
}
void Loader::startLoading() const
{
- if (pimpl_->status_ != WaitingToLoad || !pimpl_->cached_item_)
+ if (pimpl_->status_ != WaitingToLoad || !pimpl_->cached_item_
+ || pimpl_->cached_item_->status() == Converting)
return;
pimpl_->startLoading();
}
-void Loader::reload() const
+void Loader::reload() const
{
pimpl_->cached_item_->startLoading();
}
}
-unsigned long Loader::checksum() const
+void Loader::checkModifiedAsync() const
{
if (!pimpl_->cached_item_)
- return 0;
+ return;
- return pimpl_->cached_item_->checksum();
+ pimpl_->cached_item_->checkModifiedAsync();
}
}
-boost::signals::connection Loader::connect(slot_type const & slot) const
+connection Loader::connect(slot const & slot) const
{
return pimpl_->signal_.connect(slot);
}
}
-Loader::Impl::Impl()
- : status_(WaitingToLoad)
+Loader::Impl::Impl(FileName const & doc_file)
+ : doc_file_(doc_file), status_(WaitingToLoad)
{
}
continue_monitoring = cached_item_->monitoring();
// cached_item_ is going to be reset, so the connected
// signal needs to be disconnected.
- sc_.disconnect();
+ try {
+ // This can in theory throw a BufferException
+ connection_.disconnect();
+ } catch (...) {
+ LYXERR(Debug::GRAPHICS, "Unable to disconnect signal.");
+ }
cached_item_.reset();
if (status_ != Converting) {
Cache::get().remove(old_file);
Cache & gc = Cache::get();
if (!gc.inCache(file))
- gc.add(file);
+ gc.add(file, doc_file_);
// We /must/ make a local copy of this.
cached_item_ = gc.item(file);
if (continue_monitoring && !cached_item_->monitoring())
cached_item_->startMonitoring();
- sc_ = cached_item_->connect(bind(&Impl::statusChanged, this));
+ // This is a scoped connection
+ connection_ = cached_item_->connect([this](){ statusChanged(); });
}
if (idx != string::npos && idx > 3) {
if (filename.substr(idx - 3, 3) == "@2x") {
params_.pixel_ratio = 2.0;
- } else if (cached_item_->filename().extension() == "svgz") {
- params_.pixel_ratio = 4.0;
- } else if (cached_item_->filename().extension() == "svg") {
- params_.pixel_ratio = 4.0;
}
}
}