Allow signals to be blocked and resumed, and so make sure that a set
[dcpomatic.git] / src / lib / content.h
index eafadd3ecbfd6d39404c0cccdad370a4ea8ad052..f2fecddf063df96a2546fffb66cd82722922aa13 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2021 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 
 */
 
+
 /** @file  src/lib/content.h
  *  @brief Content class.
  */
 
+
 #ifndef DCPOMATIC_CONTENT_H
 #define DCPOMATIC_CONTENT_H
 
-#include "types.h"
-#include "signaller.h"
-#include "dcpomatic_time.h"
+
 #include "change_signaller.h"
+#include "dcpomatic_time.h"
+#include "signaller.h"
 #include "user_property.h"
+#include "text_type.h"
 #include <libcxml/cxml.h>
 #include <boost/filesystem.hpp>
 #include <boost/signals2.hpp>
@@ -47,6 +50,9 @@ namespace cxml {
 class Job;
 class Film;
 class AtmosContent;
+class AudioContent;
+class TextContent;
+class VideoContent;
 
 class ContentProperty
 {
@@ -59,19 +65,23 @@ public:
        static int const VIDEO_FRAME_RATE;
 };
 
+
 /** @class Content
  *  @brief A piece of content represented by one or more files on disk.
  */
-class Content : public std::enable_shared_from_this<Content>, public Signaller, public boost::noncopyable
+class Content : public std::enable_shared_from_this<Content>, public Signaller
 {
 public:
        explicit Content ();
        Content (dcpomatic::DCPTime);
        Content (boost::filesystem::path);
        Content (cxml::ConstNodePtr);
-       Content (std::vector<std::shared_ptr<Content> >);
+       Content (std::vector<std::shared_ptr<Content>>);
        virtual ~Content () {}
 
+       Content (Content const&) = delete;
+       Content& operator= (Content const&) = delete;
+
        /** Examine the content to establish digest, frame rates and any other
         *  useful metadata.
         *  @param job Job to use to report progress, or 0.
@@ -146,7 +156,7 @@ public:
                return _position;
        }
 
-       void set_trim_start (dcpomatic::ContentTime);
+       void set_trim_start(std::shared_ptr<const Film> film, dcpomatic::ContentTime);
 
        dcpomatic::ContentTime trim_start () const {
                boost::mutex::scoped_lock lm (_mutex);
@@ -165,6 +175,10 @@ public:
                return position() + length_after_trim(film);
        }
 
+       dcpomatic::DCPTimePeriod period(std::shared_ptr<const Film> film) const {
+               return { position(), end(film) };
+       }
+
        dcpomatic::DCPTime length_after_trim (std::shared_ptr<const Film> film) const;
 
        boost::optional<double> video_frame_rate () const {
@@ -172,7 +186,7 @@ public:
                return _video_frame_rate;
        }
 
-       void set_video_frame_rate (double r);
+       void set_video_frame_rate(std::shared_ptr<const Film> film, double r);
        void unset_video_frame_rate ();
 
        double active_video_frame_rate (std::shared_ptr<const Film> film) const;
@@ -185,17 +199,24 @@ public:
 
        std::string calculate_digest () const;
 
-       /* CHANGE_TYPE_PENDING and CHANGE_TYPE_CANCELLED may be emitted from any thread; CHANGE_TYPE_DONE always from GUI thread */
+       virtual bool can_be_played () const {
+               return true;
+       }
+
+       /* ChangeType::PENDING and ChangeType::CANCELLED may be emitted from any thread; ChangeType::DONE always from GUI thread */
        boost::signals2::signal<void (ChangeType, std::weak_ptr<Content>, int, bool)> Change;
 
        std::shared_ptr<VideoContent> video;
        std::shared_ptr<AudioContent> audio;
-       std::list<std::shared_ptr<TextContent> > text;
+       std::vector<std::shared_ptr<TextContent>> text;
        std::shared_ptr<AtmosContent> atmos;
 
        std::shared_ptr<TextContent> only_text () const;
        std::shared_ptr<TextContent> text_of_original_type (TextType type) const;
 
+       /** @return true if this content has changed since it was last examined */
+       bool changed () const;
+
 protected:
 
        virtual void add_properties (std::shared_ptr<const Film> film, std::list<UserProperty> &) const;
@@ -212,7 +233,8 @@ private:
        friend struct best_dcp_frame_rate_test_single;
        friend struct best_dcp_frame_rate_test_double;
        friend struct audio_sampling_rate_test;
-       template<class, class> friend class ChangeSignaller;
+       friend struct subtitle_font_id_change_test2;
+       template<class, class> friend class ChangeSignalDespatcher;
 
        void signal_change (ChangeType, int);
 
@@ -229,11 +251,12 @@ private:
         *  else (either some video happening at the same time, or the rate of the DCP).
         */
        boost::optional<double> _video_frame_rate;
-       bool _change_signals_frequent;
+       bool _change_signals_frequent = false;
 };
 
 
 typedef ChangeSignaller<Content, int> ContentChangeSignaller;
+typedef ChangeSignalDespatcher<Content, int> ContentChangeSignalDespatcher;
 
 
 #endif