MythTV  master
MythExternControl.h
Go to the documentation of this file.
1 /* -*- Mode: c++ -*-
2  *
3  * Copyright (C) John Poet 2018
4  *
5  * This file is part of MythTV
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #ifndef _MythExternControl_H_
22 #define _MythExternControl_H_
23 
24 #include "MythExternRecApp.h"
25 
26 #include <atomic>
27 #include <vector>
28 #include <queue>
29 #include <condition_variable>
30 #include <thread>
31 
32 #include <QString>
33 
34 class MythExternControl;
35 
36 class Buffer : QObject
37 {
38  Q_OBJECT
39 
40  public:
41  enum constants {MAX_QUEUE = 500};
42 
43  Buffer(MythExternControl * parent);
44  ~Buffer(void);
45  void Start(void) {
46  m_thread = std::thread(&Buffer::Run, this);
47  }
48  void Join(void) {
49  if (m_thread.joinable())
50  m_thread.join();
51  }
52  bool Fill(const QByteArray & buffer);
53 
54  std::chrono::time_point<std::chrono::system_clock> HeartBeat(void) const
55  { return m_heartbeat; }
56 
57  protected:
58  void Run(void);
59 
60  private:
61  using block_t = std::vector<uint8_t>;
62  using stack_t = std::queue<block_t>;
63 
65 
66  std::thread m_thread;
67 
69 
70  std::chrono::time_point<std::chrono::system_clock> m_heartbeat;
71 };
72 
73 class Commands : public QObject
74 {
75  Q_OBJECT
76 
77  public:
78  Commands(MythExternControl * parent);
79  ~Commands(void);
80  void Start(void) {
81  m_thread = std::thread(&Commands::Run, this);
82  }
83  void Join(void) {
84  if (m_thread.joinable())
85  m_thread.join();
86  }
87 
88  bool SendStatus(const QString & cmd, const QString & status);
89  bool SendStatus(const QString & cmd, const QString & serial,
90  const QString & status);
91  bool ProcessCommand(const QString & cmd);
92 
93  protected:
94  void Run(void);
95  bool Open(void);
96  void Close(void);
97  void StartStreaming(const QString & serial);
98  void StopStreaming(const QString & serial, bool silent);
99  void LockTimeout(const QString & serial) const;
100  void HasTuner(const QString & serial) const;
101  void HasPictureAttributes(const QString & serial) const;
102  void SetBlockSize(const QString & serial, int blksz);
103  void TuneChannel(const QString & serial, const QString & channum);
104  void LoadChannels(const QString & serial);
105  void FirstChannel(const QString & serial);
106  void NextChannel(const QString & serial);
107 
108  private:
109  std::thread m_thread;
110 
113 };
114 
115 class MythExternControl : public QObject
116 {
117  Q_OBJECT
118 
119  friend class Buffer;
120  friend class Commands;
121 
122  public:
123  MythExternControl(void);
124  ~MythExternControl(void);
125 
126  QString Desc(void) const { return QString("%1: ").arg(m_desc); }
127 
128  void Terminate(void);
129 
130  void Error(const QString & msg);
131  void Fatal(const QString & msg);
132 
133  QString ErrorString(void) const { return m_errmsg; }
134  void ClearError(void) { m_errmsg.clear(); }
135 
136  signals:
137  void Open(void);
138  void Close(void);
139  void StartStreaming(const QString & serial);
140  void StopStreaming(const QString & serial, bool silent);
141  void LockTimeout(const QString & serial) const;
142  void HasTuner(const QString & serial) const;
143  void HasPictureAttributes(const QString & serial) const;
144  void SetBlockSize(const QString & serial, int blksz);
145  void TuneChannel(const QString & serial, const QString & channum);
146  void LoadChannels(const QString & serial);
147  void FirstChannel(const QString & serial);
148  void NextChannel(const QString & serial);
149 
150  public slots:
151  void SetDescription(const QString & desc) { m_desc = desc; }
152  void SendMessage(const QString & command, const QString & serial,
153  const QString & msg);
154  void ErrorMessage(const QString & msg);
155  void Opened(void);
156  void Done(void);
157  void Streaming(bool val);
158  void Fill(const QByteArray & buffer) { m_buffer.Fill(buffer); }
159 
160  protected:
163  QString m_desc;
164 
165  std::atomic<bool> m_run;
166  std::atomic<bool> m_commands_running;
167  std::atomic<bool> m_buffer_running;
168  std::mutex m_run_mutex;
169  std::condition_variable m_run_cond;
170  std::mutex m_msg_mutex;
171 
172  bool m_fatal;
173  QString m_errmsg;
174 
175  std::mutex m_flow_mutex;
176  std::condition_variable m_flow_cond;
177  std::atomic<bool> m_streaming;
178  std::atomic<bool> m_xon;
179  std::atomic<bool> m_ready;
180 };
181 
182 #endif
std::atomic< bool > m_run
std::atomic< bool > m_commands_running
unsigned int slots[4]
Definition: element.c:38
MythExternControl * m_parent
void Join(void)
void TuneChannel(const QString &serial, const QString &channum)
void ErrorMessage(const QString &msg)
std::condition_variable m_run_cond
void NextChannel(const QString &serial)
void Run(void)
Buffer(MythExternControl *parent)
void TuneChannel(const QString &serial, const QString &channum)
std::atomic< bool > m_buffer_running
void Fill(const QByteArray &buffer)
void StopStreaming(const QString &serial, bool silent)
bool Open(void)
bool SendStatus(const QString &cmd, const QString &status)
void Error(const QString &msg)
void LockTimeout(const QString &serial) const
bool Fill(const QByteArray &buffer)
void LoadChannels(const QString &serial)
void StopStreaming(const QString &serial, bool silent)
std::thread m_thread
QString ErrorString(void) const
void FirstChannel(const QString &serial)
void HasTuner(const QString &serial) const
void Run(void)
std::condition_variable m_flow_cond
void SetBlockSize(const QString &serial, int blksz)
void Start(void)
std::vector< uint8_t > block_t
void FirstChannel(const QString &serial)
std::thread m_thread
void HasPictureAttributes(const QString &serial) const
std::atomic< bool > m_ready
void SetBlockSize(const QString &serial, int blksz)
void SetDescription(const QString &desc)
void StartStreaming(const QString &serial)
std::chrono::time_point< std::chrono::system_clock > HeartBeat(void) const
MythExternControl * m_parent
std::atomic< bool > m_streaming
void Close(void)
void Fatal(const QString &msg)
bool ProcessCommand(const QString &cmd)
void Join(void)
void Streaming(bool val)
void HasPictureAttributes(const QString &serial) const
std::queue< block_t > stack_t
QString Desc(void) const
void HasTuner(const QString &serial) const
void Start(void)
void StartStreaming(const QString &serial)
stack_t m_data
void SendMessage(const QString &command, const QString &serial, const QString &msg)
std::chrono::time_point< std::chrono::system_clock > m_heartbeat
void NextChannel(const QString &serial)
void LoadChannels(const QString &serial)
void Close(void)
std::atomic< bool > m_xon
void LockTimeout(const QString &serial) const