implement synchronization streams and managers
Stefan Schuermans

Stefan Schuermans commited on 2014-01-03 14:54:06
Showing 13 changed files, with 777 additions and 0 deletions.

... ...
@@ -0,0 +1,92 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#include "File.h"
7
+#include "InSyncFile.h"
8
+#include "Sync.h"
9
+#include "SyncFile.h"
10
+#include "SyncMgr.h"
11
+#include "SyncRecv.h"
12
+
13
+namespace Blinker {
14
+
15
+/**
16
+ * @brief constructor from path
17
+ * @param[in] path path to file
18
+ * @param[in] syncMgr sync stream manager
19
+ */
20
+InSyncFile::InSyncFile(const std::string &path, SyncMgr &syncMgr):
21
+  SyncFile(path, syncMgr),
22
+  m_pSyncRecv(NULL)
23
+{
24
+  update();
25
+}
26
+
27
+/**
28
+ * @brief constructor from basic file
29
+ * @param[in] file basic file object
30
+ * @param[in] syncMgr sync stream manager
31
+ */
32
+InSyncFile::InSyncFile(const File &file, SyncMgr &syncMgr):
33
+  SyncFile(file, syncMgr),
34
+  m_pSyncRecv(NULL)
35
+{
36
+  update();
37
+}
38
+
39
+/// destructor
40
+InSyncFile::~InSyncFile()
41
+{
42
+  detach();
43
+  // unreferencing sync stream happens in destructor of SyncFile
44
+}
45
+
46
+/**
47
+ * @brief assignment operator
48
+ * @param[in] file basic file object
49
+ */
50
+const InSyncFile & InSyncFile::operator=(const File &file)
51
+{
52
+  detach();
53
+  SyncFile::operator=(file);
54
+  attach();
55
+  return *this;
56
+}
57
+
58
+/**
59
+ * @brief set sync stream receiver
60
+ * @param[in] pSyncRecv sync stream reciver (NULL if none)
61
+ */
62
+void InSyncFile::setSyncRecv(SyncRecv *pSyncRecv)
63
+{
64
+  detach();
65
+  m_pSyncRecv = pSyncRecv;
66
+  attach();
67
+}
68
+
69
+/// update, i.e. (re-)read file and attach to new sync stream
70
+void InSyncFile::update()
71
+{
72
+  detach();
73
+  SyncFile::update();
74
+  attach();
75
+}
76
+
77
+/// attach to sync stream
78
+void InSyncFile::attach()
79
+{
80
+  if (m_pSync && m_pSyncRecv)
81
+    m_pSync->attach(m_pSyncRecv);
82
+}
83
+
84
+/// detach from sync stream
85
+void InSyncFile::detach()
86
+{
87
+  if (m_pSync && m_pSyncRecv)
88
+    m_pSync->detach(m_pSyncRecv);
89
+}
90
+
91
+} // namespace Blinker
92
+
... ...
@@ -0,0 +1,74 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef BLINKER_INSYNCFILE_H
7
+#define BLINKER_INSYNCFILE_H
8
+
9
+#include "File.h"
10
+#include "SyncFile.h"
11
+#include "SyncMgr.h"
12
+#include "SyncRecv.h"
13
+
14
+namespace Blinker {
15
+
16
+/// setting file containting a name of an input sync stream
17
+class InSyncFile: public SyncFile
18
+{
19
+public:
20
+  /**
21
+   * @brief constructor from path
22
+   * @param[in] path path to file
23
+   * @param[in] syncMgr sync stream manager
24
+   */
25
+  InSyncFile(const std::string &path, SyncMgr &syncMgr);
26
+
27
+  /**
28
+   * @brief constructor from basic file
29
+   * @param[in] file basic file object
30
+   * @param[in] syncMgr sync stream manager
31
+   */
32
+  InSyncFile(const File &file, SyncMgr &syncMgr);
33
+
34
+  /// destructor
35
+  ~InSyncFile();
36
+
37
+  /**
38
+   * @brief assignment operator
39
+   * @param[in] file basic file object
40
+   */
41
+  const InSyncFile & operator=(const File &file);
42
+
43
+private:
44
+  /// copy constructor disabled
45
+  InSyncFile(const InSyncFile &that);
46
+
47
+  /// assignment operator disabled
48
+  const InSyncFile & operator=(const InSyncFile &that);
49
+
50
+public:
51
+  /**
52
+   * @brief set sync stream receiver
53
+   * @param[in] pSyncRecv sync stream reciver (NULL if none)
54
+   */
55
+  void setSyncRecv(SyncRecv *pSyncRecv);
56
+
57
+  /// update, i.e. (re-)read file and attach to new sync stream
58
+  void update();
59
+
60
+protected:
61
+  /// attach to sync stream
62
+  void attach();
63
+
64
+  /// detach from sync stream
65
+  void detach();
66
+
67
+protected:
68
+  SyncRecv *m_pSyncRecv; ///< sync stream receiver to attach to input sync stream
69
+}; // class InSyncFile
70
+
71
+} // namespace Blinker
72
+
73
+#endif // #ifndef BLINKER_INSYNCFILE_H
74
+
... ...
@@ -9,6 +9,7 @@
9 9
 #include "CallMgr.h"
10 10
 #include "OpMgr.h"
11 11
 #include "StreamMgr.h"
12
+#include "SyncMgr.h"
12 13
 
13 14
 namespace Blinker {
14 15
 
... ...
@@ -18,6 +19,7 @@ struct Mgrs
18 19
   CallMgr   m_callMgr;   ///< call manager
19 20
   OpMgr     m_opMgr;     ///< operator connection manager
20 21
   StreamMgr m_streamMgr; ///< stream manager
22
+  SyncMgr   m_syncMgr;   ///< synchronization stream manager
21 23
 }; // struct Mgrs
22 24
 
23 25
 } // namespace Blinker
... ...
@@ -0,0 +1,70 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#include "File.h"
7
+#include "OutSyncFile.h"
8
+#include "Sync.h"
9
+#include "SyncFile.h"
10
+#include "SyncMgr.h"
11
+#include "SyncRecv.h"
12
+
13
+namespace Blinker {
14
+
15
+/**
16
+ * @brief constructor from path
17
+ * @param[in] path path to file
18
+ * @param[in] syncMgr sync stream manager
19
+ */
20
+OutSyncFile::OutSyncFile(const std::string &path, SyncMgr &syncMgr):
21
+  SyncFile(path, syncMgr)
22
+{
23
+  update();
24
+}
25
+
26
+/**
27
+ * @brief constructor from basic file
28
+ * @param[in] file basic file object
29
+ * @param[in] syncMgr sync stream manager
30
+ */
31
+OutSyncFile::OutSyncFile(const File &file, SyncMgr &syncMgr):
32
+  SyncFile(file, syncMgr)
33
+{
34
+  update();
35
+}
36
+
37
+/// destructor
38
+OutSyncFile::~OutSyncFile()
39
+{
40
+  // unreferencing sync stream happens in destructor of SyncFile
41
+}
42
+
43
+/**
44
+ * @brief assignment operator
45
+ * @param[in] file basic file object
46
+ */
47
+const OutSyncFile & OutSyncFile::operator=(const File &file)
48
+{
49
+  SyncFile::operator=(file);
50
+  return *this;
51
+}
52
+
53
+/// update, i.e. (re-)read file and reference new sync stream
54
+void OutSyncFile::update()
55
+{
56
+  SyncFile::update();
57
+}
58
+
59
+/**
60
+ * @brief send synchronization information
61
+ * @param[in] pInfo synchronization information
62
+ */
63
+void OutSyncFile::sendInfo(SyncRecv::Info &info)
64
+{
65
+  if (m_pSync)
66
+    m_pSync->sendInfo(info);
67
+}
68
+
69
+} // namespace Blinker
70
+
... ...
@@ -0,0 +1,66 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef BLINKER_OUTSYNCFILE_H
7
+#define BLINKER_OUTSYNCFILE_H
8
+
9
+#include <BlinkenLib/BlinkenFrame.h>
10
+
11
+#include "File.h"
12
+#include "SyncFile.h"
13
+#include "SyncMgr.h"
14
+#include "SyncRecv.h"
15
+
16
+namespace Blinker {
17
+
18
+/// setting file containting a name of an output sync stream
19
+class OutSyncFile: public SyncFile
20
+{
21
+public:
22
+  /**
23
+   * @brief constructor from path
24
+   * @param[in] path path to file
25
+   * @param[in] syncMgr sync stream manager
26
+   */
27
+  OutSyncFile(const std::string &path, SyncMgr &syncMgr);
28
+
29
+  /**
30
+   * @brief constructor from basic file
31
+   * @param[in] file basic file object
32
+   * @param[in] syncMgr sync stream manager
33
+   */
34
+  OutSyncFile(const File &file, SyncMgr &syncMgr);
35
+
36
+  /// destructor
37
+  ~OutSyncFile();
38
+
39
+  /**
40
+   * @brief assignment operator
41
+   * @param[in] file basic file object
42
+   */
43
+  const OutSyncFile & operator=(const File &file);
44
+
45
+private:
46
+  /// copy constructor disabled
47
+  OutSyncFile(const OutSyncFile &that);
48
+
49
+  /// assignment operator disabled
50
+  const OutSyncFile & operator=(const OutSyncFile &that);
51
+
52
+public:
53
+  /// update, i.e. (re-)read file and reference new sync stream
54
+  void update();
55
+
56
+  /**
57
+   * @brief send synchronization information
58
+   * @param[in] pInfo synchronization information
59
+   */
60
+  void sendInfo(SyncRecv::Info &info);
61
+}; // class OutSyncFile
62
+
63
+} // namespace Blinker
64
+
65
+#endif // #ifndef BLINKER_OUTSYNCFILE_H
66
+
... ...
@@ -0,0 +1,54 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#include <set>
7
+
8
+#include "Sync.h"
9
+#include "SyncRecv.h"
10
+
11
+namespace Blinker {
12
+
13
+/// constructor
14
+Sync::Sync()
15
+{
16
+}
17
+
18
+/// destructor
19
+Sync::~Sync()
20
+{
21
+}
22
+
23
+/**
24
+ * @brief attach a sync stream receiver
25
+ * @param[in] recv sync stream receiver to attach
26
+ */
27
+void Sync::attach(SyncRecv *recv)
28
+{
29
+  m_recvs.insert(recv);
30
+}
31
+
32
+/**
33
+ * @brief detach a sync stream receiver
34
+ * @param[in] recv sync stream receiver to detach
35
+ */
36
+void Sync::detach(SyncRecv *recv)
37
+{
38
+  m_recvs.erase(recv);
39
+}
40
+
41
+/**
42
+ * @brief send synchronization information
43
+ * @param[in] pInfo synchronization information
44
+ */
45
+void Sync::sendInfo(Info &info)
46
+{
47
+  // pass sync information to all receivers
48
+  Recvs::iterator it;
49
+  for (it = m_recvs.begin(); it != m_recvs.end(); ++it)
50
+    (*it)->sendInfo(m_name, info);
51
+}
52
+
53
+} // namespace Blinker
54
+
... ...
@@ -0,0 +1,65 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef BLINKER_SYNC_H
7
+#define BLINKER_SYNC_H
8
+
9
+#include <set>
10
+#include <string>
11
+
12
+#include "SyncRecv.h"
13
+
14
+namespace Blinker {
15
+
16
+/// a synchronization information sync stream
17
+class Sync
18
+{
19
+public:
20
+  /// synchronization information
21
+  typedef SyncRecv::Info Info;
22
+
23
+protected:
24
+  /// set of receivers of this sync stream
25
+  typedef std::set<SyncRecv *> Recvs;
26
+
27
+public:
28
+  /// constructor
29
+  Sync();
30
+
31
+  /// destructor
32
+  ~Sync();
33
+
34
+public:
35
+  /**
36
+   * @brief attach a sync stream receiver
37
+   * @param[in] recv sync stream receiver to attach
38
+   */
39
+  void attach(SyncRecv *recv);
40
+
41
+  /**
42
+   * @brief detach a sync stream receiver
43
+   * @param[in] recv sync stream receiver to detach
44
+   */
45
+  void detach(SyncRecv *recv);
46
+
47
+  /**
48
+   * @brief send synchronization information
49
+   * @param[in] pInfo synchronization information
50
+   */
51
+  void sendInfo(Info &info);
52
+
53
+protected:
54
+  /// sync stream name
55
+  std::string m_name;
56
+  /// receivers of this sync stream
57
+  Recvs m_recvs;
58
+
59
+friend class SyncMgr;
60
+}; // class Sync
61
+
62
+} // namespace Blinker
63
+
64
+#endif // #ifndef BLINKER_SYNC_H
65
+
... ...
@@ -0,0 +1,83 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#include "File.h"
7
+#include "NameFile.h"
8
+#include "Sync.h"
9
+#include "SyncFile.h"
10
+#include "SyncMgr.h"
11
+
12
+namespace Blinker {
13
+
14
+/**
15
+ * @brief constructor from path
16
+ * @param[in] path path to file
17
+ * @param[in] syncMgr sync stream manager
18
+ */
19
+SyncFile::SyncFile(const std::string &path, SyncMgr &syncMgr):
20
+  NameFile(path),
21
+  m_syncMgr(syncMgr),
22
+  m_pSync(NULL)
23
+{
24
+  update();
25
+}
26
+
27
+/**
28
+ * @brief constructor from basic file
29
+ * @param[in] file basic file object
30
+ * @param[in] syncMgr sync stream manager
31
+ */
32
+SyncFile::SyncFile(const File &file, SyncMgr &syncMgr):
33
+  NameFile(file),
34
+  m_syncMgr(syncMgr),
35
+  m_pSync(NULL)
36
+{
37
+  update();
38
+}
39
+
40
+/// destructor
41
+SyncFile::~SyncFile()
42
+{
43
+  unref();
44
+}
45
+
46
+/**
47
+ * @brief assignment operator
48
+ * @param[in] file basic file object
49
+ */
50
+const SyncFile & SyncFile::operator=(const File &file)
51
+{
52
+  unref();
53
+  NameFile::operator=(file);
54
+  ref();
55
+  return *this;
56
+}
57
+
58
+/// update, i.e. (re-)read file and reference new sync stream
59
+void SyncFile::update()
60
+{
61
+  unref();
62
+  NameFile::update();
63
+  ref();
64
+}
65
+
66
+/// unreference sync stream
67
+void SyncFile::unref()
68
+{
69
+  if (m_pSync) {
70
+    m_syncMgr.unrefSync(m_obj.m_str);
71
+    m_pSync = NULL;
72
+  }
73
+}
74
+
75
+/// reference sync stream
76
+void SyncFile::ref()
77
+{
78
+  if (m_valid)
79
+    m_pSync = &m_syncMgr.refSync(m_obj.m_str);
80
+}
81
+
82
+} // namespace Blinker
83
+
... ...
@@ -0,0 +1,69 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef BLINKER_SYNCFILE_H
7
+#define BLINKER_SYNCFILE_H
8
+
9
+#include "File.h"
10
+#include "NameFile.h"
11
+#include "Sync.h"
12
+#include "SyncMgr.h"
13
+
14
+namespace Blinker {
15
+
16
+/// setting file containting a name of a sync stream
17
+class SyncFile: public NameFile
18
+{
19
+public:
20
+  /**
21
+   * @brief constructor from path
22
+   * @param[in] path path to file
23
+   * @param[in] syncMgr sync stream manager
24
+   */
25
+  SyncFile(const std::string &path, SyncMgr &syncMgr);
26
+
27
+  /**
28
+   * @brief constructor from basic file
29
+   * @param[in] file basic file object
30
+   * @param[in] syncMgr sync stream manager
31
+   */
32
+  SyncFile(const File &file, SyncMgr &syncMgr);
33
+
34
+  /// destructor
35
+  ~SyncFile();
36
+
37
+  /**
38
+   * @brief assignment operator
39
+   * @param[in] file basic file object
40
+   */
41
+  const SyncFile & operator=(const File &file);
42
+
43
+private:
44
+  /// copy constructor disabled
45
+  SyncFile(const SyncFile &that);
46
+
47
+  /// assignment operator disabled
48
+  const SyncFile & operator=(const SyncFile &that);
49
+
50
+public:
51
+  /// update, i.e. (re-)read file and reference new sync stream
52
+  void update();
53
+
54
+protected:
55
+  /// unreference sync stream
56
+  void unref();
57
+
58
+  /// reference sync stream
59
+  void ref();
60
+
61
+protected:
62
+  SyncMgr &m_syncMgr; ///< sync stream manager
63
+  Sync    *m_pSync;   ///< sync stream
64
+}; // class SyncFile
65
+
66
+} // namespace Blinker
67
+
68
+#endif // #ifndef BLINKER_SYNCFILE_H
69
+
... ...
@@ -0,0 +1,67 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#include <map>
7
+#include <string>
8
+
9
+#include "Sync.h"
10
+#include "SyncMgr.h"
11
+
12
+namespace Blinker {
13
+
14
+/// constructor
15
+SyncMgr::SyncMgr()
16
+{
17
+}
18
+
19
+/// destructor
20
+SyncMgr::~SyncMgr()
21
+{
22
+}
23
+
24
+/**
25
+ * @brief reference sync stream
26
+ * @param[in] name sync stream name
27
+ * @return sync stream
28
+ *
29
+ * if the sync stream does not exists, it is created
30
+ */
31
+Sync & SyncMgr::refSync(const std::string &name)
32
+{
33
+  Entry &entry = m_syncs[name];
34
+  entry.m_sync.m_name = name;
35
+  entry.m_refCnt++;
36
+  return entry.m_sync;
37
+}
38
+
39
+/**
40
+ * @brief unreference sync stream
41
+ * @param[in] name sync stream name
42
+ *
43
+ * if the last reference is removed, the sync stream is deleted
44
+ */
45
+void SyncMgr::unrefSync(const std::string &name)
46
+{
47
+  SyncMap::iterator itSync = m_syncs.find(name);
48
+  if (itSync != m_syncs.end()) {
49
+    if (itSync->second.m_refCnt > 0)
50
+      itSync->second.m_refCnt--;
51
+    if (itSync->second.m_refCnt == 0)
52
+      m_syncs.erase(itSync);
53
+  }
54
+}
55
+
56
+/* ##################
57
+   # SyncMgr::Entry #
58
+   ################## */
59
+
60
+/// constructor
61
+SyncMgr::Entry::Entry():
62
+  m_refCnt(0)
63
+{
64
+}
65
+
66
+} // namespace Blinker
67
+
... ...
@@ -0,0 +1,70 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef BLINKER_SYNCMGR_H
7
+#define BLINKER_SYNCMGR_H
8
+
9
+#include <map>
10
+#include <string>
11
+
12
+#include "Sync.h"
13
+
14
+namespace Blinker {
15
+
16
+/// sync stream manager
17
+class SyncMgr
18
+{
19
+protected:
20
+  /// sync stream map entry
21
+  struct Entry {
22
+    Sync         m_sync; ///< the sync stream
23
+    unsigned int m_refCnt; ///< reference count
24
+    Entry(); ///< constructor
25
+  };
26
+
27
+  /// map of sync streams
28
+  typedef std::map<std::string, Entry> SyncMap;
29
+
30
+public:
31
+  /// constructor
32
+  SyncMgr();
33
+
34
+  /// destructor
35
+  ~SyncMgr();
36
+
37
+private:
38
+  /// copy constructor disabled
39
+  SyncMgr(const SyncMgr &that);
40
+
41
+  /// assignment operator disabled
42
+  const SyncMgr & operator=(const SyncMgr &that);
43
+
44
+public:
45
+  /**
46
+   * @brief reference sync stream
47
+   * @param[in] name sync stream name
48
+   * @return sync stream
49
+   *
50
+   * if the sync stream does not exists, it is created
51
+   */
52
+  Sync & refSync(const std::string &name);
53
+
54
+  /**
55
+   * @brief unreference sync stream
56
+   * @param[in] name sync stream name
57
+   *
58
+   * if the last reference is removed, the sync stream is deleted
59
+   */
60
+  void unrefSync(const std::string &name);
61
+
62
+protected:
63
+  /// map of sync streams
64
+  SyncMap m_syncs;
65
+}; // class SyncMgr
66
+
67
+} // namespace Blinker
68
+
69
+#endif // #ifndef BLINKER_SYNCMGR_H
70
+
... ...
@@ -0,0 +1,21 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#include "SyncRecv.h"
7
+
8
+namespace Blinker {
9
+
10
+/// constructor
11
+SyncRecv::SyncRecv()
12
+{
13
+}
14
+
15
+/// virtual destructor
16
+SyncRecv::~SyncRecv()
17
+{
18
+}
19
+
20
+} // namespace Blinker
21
+
... ...
@@ -0,0 +1,44 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef BLINKER_SYNCRECV_H
7
+#define BLINKER_SYNCRECV_H
8
+
9
+#include <stdint.h>
10
+#include <string>
11
+
12
+namespace Blinker {
13
+
14
+/// video sync stream receiver interface
15
+class SyncRecv
16
+{
17
+public:
18
+  /// synchronization information
19
+  struct Info {
20
+    bool        pause;  ///< if pause mode is active
21
+    std::string name;   ///< name of current piece
22
+    uint32_t    pos_ms; ///< current position within the piece in milliseconds
23
+  };
24
+
25
+public:
26
+  /// constructor
27
+  SyncRecv();
28
+
29
+  /// virtual destructor
30
+  virtual ~SyncRecv();
31
+
32
+public:
33
+  /**
34
+   * @brief send synchronization information
35
+   * @param[in] sync sync stream name
36
+   * @param[in] pInfo synchronization information
37
+   */
38
+  virtual void sendInfo(const std::string &sync, Info &info) = 0;
39
+}; // class SyncRecv
40
+
41
+} // namespace Blinker
42
+
43
+#endif // #ifndef BLINKER_SYNCRECV_H
44
+
0 45