]> git.sesse.net Git - casparcg/blob - core/monitor/monitor.h
Use ScheduledFrameCompleted callback for audio scheduling in addition to video schedu...
[casparcg] / core / monitor / monitor.h
1 /*
2 * Copyright 2013 Sveriges Television AB http://casparcg.com/
3 *
4 * This file is part of CasparCG (www.casparcg.com).
5 *
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * CasparCG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Author: Robert Nagy, ronag89@gmail.com
20 */
21 #pragma once
22
23 #include <common/memory.h>
24 #include <common/assert.h>
25
26 #include <boost/variant.hpp>
27 #include <boost/chrono/duration.hpp>
28
29 #include <cstdint>
30 #include <string>
31 #include <vector>
32
33 namespace caspar { namespace core { namespace monitor {
34                 
35 typedef boost::variant<bool, 
36                                            std::int32_t, 
37                                            std::int64_t, 
38                                            float, 
39                                            double, 
40                                            std::string,
41                                            std::wstring,
42                                            std::vector<std::int8_t>> data_t;
43
44 class message
45 {
46 public:
47
48         message(std::string path, std::vector<data_t> data = std::vector<data_t>())
49                 : path_(std::move(path))
50                 , data_ptr_(std::make_shared<std::vector<data_t>>(std::move(data)))
51         {
52                 CASPAR_ASSERT(path.empty() || path[0] == '/');
53         }
54         
55         message(std::string path, spl::shared_ptr<std::vector<data_t>> data_ptr)
56                 : path_(std::move(path))
57                 , data_ptr_(std::move(data_ptr))
58         {
59                 CASPAR_ASSERT(path.empty() || path[0] == '/');
60         }
61
62         const std::string& path() const
63         {
64                 return path_;
65         }
66
67         const std::vector<data_t>& data() const
68         {
69                 return *data_ptr_;
70         }
71
72         message propagate(const std::string& path) const
73         {
74                 return message(path + path_, data_ptr_);
75         }
76
77         template<typename T>
78         message& operator%(T&& data)
79         {
80                 data_ptr_->push_back(std::forward<T>(data));
81                 return *this;
82         }
83
84 private:
85         std::string                                                             path_;
86         spl::shared_ptr<std::vector<data_t>>    data_ptr_;
87 };
88
89 struct sink
90 {
91         virtual ~sink() { }
92
93         virtual void propagate(const message& msg) = 0;
94 };
95
96 class subject : public sink
97 {
98 private:
99         std::weak_ptr<sink> parent_;
100         const std::string path_;
101 public:
102         subject(std::string path = "")
103                 : path_(std::move(path))
104         {
105                 CASPAR_ASSERT(path.empty() || path[0] == '/');
106         }
107
108         void attach_parent(spl::shared_ptr<sink> parent)
109         {
110                 parent_ = std::move(parent);
111         }
112
113         void detach_parent()
114         {
115                 parent_.reset();
116         }
117
118         subject& operator<<(const message& msg)
119         {
120                 propagate(msg);
121
122                 return *this;
123         }
124
125         virtual void propagate(const message& msg) override
126         {
127                 auto parent = parent_.lock();
128
129                 if (parent)
130                         parent->propagate(msg.propagate(path_));
131         }
132 };
133
134 }}}