+
+void
+JobManager::drop ()
+{
+ delete _instance;
+ _instance = 0;
+}
+
+void
+JobManager::analyse_audio (
+ shared_ptr<const Film> film,
+ shared_ptr<const Playlist> playlist,
+ bool from_zero,
+ boost::signals2::connection& connection,
+ function<void()> ready
+ )
+{
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+
+ BOOST_FOREACH (shared_ptr<Job> i, _jobs) {
+ shared_ptr<AnalyseAudioJob> a = dynamic_pointer_cast<AnalyseAudioJob> (i);
+ if (a && a->path() == film->audio_analysis_path(playlist)) {
+ i->when_finished (connection, ready);
+ return;
+ }
+ }
+ }
+
+ shared_ptr<AnalyseAudioJob> job;
+
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+
+ job.reset (new AnalyseAudioJob (film, playlist, from_zero));
+ connection = job->Finished.connect (ready);
+ _jobs.push_back (job);
+ _empty_condition.notify_all ();
+ }
+
+ emit (boost::bind (boost::ref (JobAdded), weak_ptr<Job> (job)));
+}
+
+void
+JobManager::increase_priority (shared_ptr<Job> job)
+{
+ bool changed = false;
+
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+ list<shared_ptr<Job> >::iterator last = _jobs.end ();
+ for (list<shared_ptr<Job> >::iterator i = _jobs.begin(); i != _jobs.end(); ++i) {
+ if (*i == job && last != _jobs.end()) {
+ swap (*i, *last);
+ changed = true;
+ break;
+ }
+ last = i;
+ }
+ }
+
+ if (changed) {
+ priority_changed ();
+ }
+}
+
+void
+JobManager::priority_changed ()
+{
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+
+ bool first = true;
+ BOOST_FOREACH (shared_ptr<Job> i, _jobs) {
+ if (first) {
+ if (i->is_new ()) {
+ i->start ();
+ } else if (i->paused_by_priority ()) {
+ i->resume ();
+ }
+ first = false;
+ } else {
+ if (i->running ()) {
+ i->pause_by_priority ();
+ }
+ }
+ }
+ }
+
+ emit (boost::bind (boost::ref (JobsReordered)));
+}
+
+void
+JobManager::decrease_priority (shared_ptr<Job> job)
+{
+ bool changed = false;
+
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+ for (list<shared_ptr<Job> >::iterator i = _jobs.begin(); i != _jobs.end(); ++i) {
+ list<shared_ptr<Job> >::iterator next = i;
+ ++next;
+ if (*i == job && next != _jobs.end()) {
+ swap (*i, *next);
+ changed = true;
+ break;
+ }
+ }
+ }
+
+ if (changed) {
+ priority_changed ();
+ }
+}
+
+void
+JobManager::pause ()
+{
+ boost::mutex::scoped_lock lm (_mutex);
+
+ if (_paused) {
+ return;
+ }
+
+ BOOST_FOREACH (shared_ptr<Job> i, _jobs) {
+ if (i->pause_by_user()) {
+ _paused_job = i;
+ }
+ }
+
+ _paused = true;
+}
+
+void
+JobManager::resume ()
+{
+ boost::mutex::scoped_lock lm (_mutex);
+ if (!_paused) {
+ return;
+ }
+
+ if (_paused_job) {
+ _paused_job->resume ();
+ }
+
+ _paused_job.reset ();
+ _paused = false;
+}