merge LoaderQueue into Loader

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@21755 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2007-11-24 00:02:58 +00:00
parent 502125671a
commit 2e79520f6b
4 changed files with 135 additions and 180 deletions

View File

@ -315,8 +315,6 @@ liblyxgraphics_la_SOURCES = \
graphics/GraphicsLoader.cpp \
graphics/GraphicsParams.cpp \
graphics/GraphicsParams.h \
graphics/LoaderQueue.h \
graphics/LoaderQueue.cpp \
graphics/GraphicsTypes.h \
graphics/GraphicsTypes.cpp \
graphics/PreviewImage.h \

View File

@ -15,19 +15,152 @@
#include "GraphicsCacheItem.h"
#include "GraphicsImage.h"
#include "GraphicsParams.h"
#include "LoaderQueue.h"
#include "GraphicsCache.h"
#include "debug.h"
#include "support/Timeout.h"
#include <boost/bind.hpp>
#include <set>
#include <queue>
using std::string;
using std::endl;
using std::list;
namespace lyx {
namespace graphics {
using support::FileName;
namespace graphics {
/////////////////////////////////////////////////////////////////////
//
// LoaderQueue
//
/////////////////////////////////////////////////////////////////////
class LoaderQueue {
public:
/// Use this to request that the item is loaded.
void touch(Cache::ItemPtr const & item);
/// Query whether the clock is ticking.
bool running() const;
///get the and only instance of the class
static LoaderQueue & get();
private:
/// This class is a singleton class... use LoaderQueue::get() instead
LoaderQueue();
/// The in-progress loading queue (elements are unique here).
std::list<Cache::ItemPtr> cache_queue_;
/// Used to make the insertion of new elements faster.
std::set<Cache::ItemPtr> cache_set_;
/// Newly touched elements go here. loadNext moves them to cache_queue_
std::queue<Cache::ItemPtr> bucket_;
///
Timeout timer;
///
bool running_;
/** This is the 'threaded' method, that does the loading in the
* background.
*/
void loadNext();
///
void startLoader();
///
void stopLoader();
};
//static int s_numimages_ = 5;
//static int s_millisecs_ = 500;
static int s_numimages_ = 10;
static int s_millisecs_ = 500;
LoaderQueue & LoaderQueue::get()
{
static LoaderQueue singleton;
return singleton;
}
void LoaderQueue::loadNext()
{
LYXERR(Debug::GRAPHICS, "LoaderQueue: "
<< cache_queue_.size() << " items in the queue");
int counter = s_numimages_;
while (cache_queue_.size() && counter--) {
Cache::ItemPtr ptr = cache_queue_.front();
cache_set_.erase(ptr);
cache_queue_.pop_front();
if (ptr->status() == WaitingToLoad)
ptr->startLoading();
}
if (cache_queue_.size()) {
startLoader();
} else {
stopLoader();
}
}
LoaderQueue::LoaderQueue() : timer(s_millisecs_, Timeout::ONETIME),
running_(false)
{
timer.timeout.connect(boost::bind(&LoaderQueue::loadNext, this));
}
void LoaderQueue::startLoader()
{
LYXERR(Debug::GRAPHICS, "LoaderQueue: waking up");
running_ = true ;
timer.setTimeout(s_millisecs_);
timer.start();
}
void LoaderQueue::stopLoader()
{
timer.stop();
running_ = false ;
LYXERR(Debug::GRAPHICS, "LoaderQueue: I'm going to sleep");
}
bool LoaderQueue::running() const
{
return running_ ;
}
void LoaderQueue::touch(Cache::ItemPtr const & item)
{
if (! cache_set_.insert(item).second) {
list<Cache::ItemPtr>::iterator
it = cache_queue_.begin();
list<Cache::ItemPtr>::iterator
end = cache_queue_.end();
it = std::find(it, end, item);
if (it != end)
cache_queue_.erase(it);
}
cache_queue_.push_front(item);
if (!running_)
startLoader();
}
/////////////////////////////////////////////////////////////////////
//
// GraphicsLoader
//
/////////////////////////////////////////////////////////////////////
typedef boost::shared_ptr<Image> ImagePtr;

View File

@ -1,108 +0,0 @@
/**
* \file LoaderQueue.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Alfredo Braunstein
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "LoaderQueue.h"
#include "GraphicsCacheItem.h"
#include "debug.h"
#include <boost/bind.hpp>
using std::endl;
using std::list;
namespace lyx {
namespace graphics {
//static int s_numimages_ = 5;
//static int s_millisecs_ = 500;
static int s_numimages_ = 10;
static int s_millisecs_ = 500;
LoaderQueue & LoaderQueue::get()
{
static LoaderQueue singleton;
return singleton;
}
void LoaderQueue::loadNext()
{
LYXERR(Debug::GRAPHICS, "LoaderQueue: "
<< cache_queue_.size() << " items in the queue");
int counter = s_numimages_;
while (cache_queue_.size() && counter--) {
Cache::ItemPtr ptr = cache_queue_.front();
cache_set_.erase(ptr);
cache_queue_.pop_front();
if (ptr->status() == WaitingToLoad)
ptr->startLoading();
}
if (cache_queue_.size()) {
startLoader();
} else {
stopLoader();
}
}
LoaderQueue::LoaderQueue() : timer(s_millisecs_, Timeout::ONETIME),
running_(false)
{
timer.timeout.connect(boost::bind(&LoaderQueue::loadNext, this));
}
void LoaderQueue::startLoader()
{
LYXERR(Debug::GRAPHICS, "LoaderQueue: waking up");
running_ = true ;
timer.setTimeout(s_millisecs_);
timer.start();
}
void LoaderQueue::stopLoader()
{
timer.stop();
running_ = false ;
LYXERR(Debug::GRAPHICS, "LoaderQueue: I'm going to sleep");
}
bool LoaderQueue::running() const
{
return running_ ;
}
void LoaderQueue::touch(Cache::ItemPtr const & item)
{
if (! cache_set_.insert(item).second) {
list<Cache::ItemPtr>::iterator
it = cache_queue_.begin();
list<Cache::ItemPtr>::iterator
end = cache_queue_.end();
it = std::find(it, end, item);
if (it != end)
cache_queue_.erase(it);
}
cache_queue_.push_front(item);
if (!running_)
startLoader();
}
} // namespace graphics
} // namespace lyx

View File

@ -1,68 +0,0 @@
// -*- C++ -*-
/**
* \file LoaderQueue.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Alfredo Braunstein
*
* Full author contact details are available in file CREDITS.
*
* This implements a threaded service queue which loads images on background.
* In order to request an image loading you call touch() with the pointer to
* the cached image. Then it will try to satisfy the request as soon as
* posible (that's it: after finishing an eventual loading on progress)
* touch() returns inmediately, in order not tu disrupt the flow of the main
* thread.
* The service thread is the method loadNext(). It's actually not a thread,
* but implemented with a timer that comes back every x msec.
*/
#ifndef LOADERQUEUE_H
#define LOADERQUEUE_H
#include "GraphicsCache.h"
#include "support/Timeout.h"
#include <set>
#include <queue>
namespace lyx {
namespace graphics {
class LoaderQueue {
public:
/// Use this to request that the item is loaded.
void touch(Cache::ItemPtr const & item);
/// Query whether the clock is ticking.
bool running() const;
///get the and only instance of the class
static LoaderQueue & get();
private:
/// This class is a singleton class... use LoaderQueue::get() instead
LoaderQueue();
/// The in-progress loading queue (elements are unique here).
std::list<Cache::ItemPtr> cache_queue_;
/// Used to make the insertion of new elements faster.
std::set<Cache::ItemPtr> cache_set_;
/// Newly touched elements go here. loadNext moves them to cache_queue_
std::queue<Cache::ItemPtr> bucket_;
///
Timeout timer;
///
bool running_;
/** This is the 'threaded' method, that does the loading in the
* background.
*/
void loadNext();
///
void startLoader();
///
void stopLoader();
};
} // namespace graphics
} // namespace lyx
#endif // LOADERQUEUE_H