converted player module to use list tracker
Stefan Schuermans

Stefan Schuermans commited on 2011-12-11 13:03:52
Showing 4 changed files, with 199 additions and 159 deletions.

... ...
@@ -13,8 +13,11 @@
13 13
 #include "Directory.h"
14 14
 #include "File.h"
15 15
 #include "Module.h"
16
+#include "ListTracker.h"
17
+#include "ListTracker_impl.h"
16 18
 #include "OutStreamFile.h"
17 19
 #include "Player.h"
20
+#include "PlayerMovie.h"
18 21
 #include "StreamMgr.h"
19 22
 #include "Time.h"
20 23
 #include "TimeCallee.h"
... ...
@@ -31,13 +34,15 @@ Player::Player(CallMgr &callMgr, StreamMgr &streamMgr,
31 34
                const Directory &dirBase):
32 35
   Module(callMgr, streamMgr, dirBase),
33 36
   m_fileOutStream(dirBase.getFile("outstream"), streamMgr),
34
-  m_dirPlaylist(dirBase.getSubdir("playlist")),
37
+  m_playlistTracker(*this, dirBase.getSubdir("playlist")),
35 38
   m_curValid(false),
36
-  m_curEntry(m_playlist.begin()),
37
-  m_curFrame(0)
39
+  m_curEntry(m_playlistTracker.m_list.begin()),
40
+  m_curFrame(0),
41
+  m_curChange(false)
38 42
 {
39 43
   // load playlist
40
-  updatePlaylistFull();
44
+  m_playlistTracker.init();
45
+  checkCurChanged();
41 46
 }
42 47
 
43 48
 /// virtual destructor
... ...
@@ -47,10 +52,7 @@ Player::~Player()
47 52
   m_callMgr.cancelTimeCall(this);
48 53
 
49 54
   // free all movies
50
-  while (!m_playlist.empty()) {
51
-    m_playlist.back().freeMovie();
52
-    m_playlist.pop_back();
53
-  }
55
+  m_playlistTracker.clear();
54 56
 }
55 57
 
56 58
 /// check for update of configuration
... ...
@@ -62,11 +64,9 @@ void Player::updateConfig()
62 64
     sendFrame();
63 65
   }
64 66
 
65
-  // playlist update (directory modified -> full, otherwise -> light)
66
-  if (m_dirPlaylist.checkModified())
67
-    updatePlaylistFull();
68
-  else
69
-    updatePlaylistLight();
67
+  // playlist update
68
+  m_playlistTracker.updateConfig();
69
+  checkCurChanged();
70 70
 }
71 71
 
72 72
 /// callback when requested time reached
... ...
@@ -86,105 +86,19 @@ void Player::timeCall()
86 86
   procFrame();
87 87
 }
88 88
 
89
-/// light update of playlist, i.e. stat all files in current playlist
90
-void Player::updatePlaylistLight()
89
+/// check if current movie changed and react
90
+void Player::checkCurChanged()
91 91
 {
92
-  // walk through all files in playlist and check for modification
93
-  Playlist::iterator itEntry = m_playlist.begin();
94
-  bool               bCurChg = false;
95
-  while (itEntry != m_playlist.end()) {
96
-
97
-    // movie changed
98
-    if (itEntry->m_file.checkModified()) {
99
-      // check if changed movie is current movie
100
-      if (itEntry == m_curEntry) {
101
-        // advance current movie to next movie
102
-        ++m_curEntry;
103
-        bCurChg = true;
104
-      }
105
-      // re-load entry
106
-      itEntry->freeMovie();
107
-      if (!itEntry->loadMovie()) {
108
-        // loading movie failed -> remove entry
109
-        itEntry = m_playlist.erase(itEntry);
110
-        // do not advance to next file
111
-        continue;
112
-      }
113
-    }
114
-
115
-    // advance to next file
116
-    ++itEntry;
92
+  // current movie changed
93
+  if (m_curChange) {
94
+    m_curChange = false;
117 95
 
118
-  } // while itEntry
119
-
120
-  // current movie entry changed
121
-  if (bCurChg) {
122 96
     // go to begin of new current movie and start playing now
123 97
     m_curFrame = 0;
124 98
     m_nextTime = Time::now();
125 99
     procFrame();
126
-  }
127
-}
128
-
129
-/// full update of playlist, i.e. scan files in playlist directory
130
-void Player::updatePlaylistFull()
131
-{
132
-  // get list of files in playlist directory
133
-  typedef std::list<std::string> Filelist;
134
-  Filelist curFiles;
135
-  m_dirPlaylist.getEntries(Directory::TypeFile, curFiles);
136
-
137
-  // walk through current playlist and file list simultaneously
138
-  bool                     bWasEmpty = m_playlist.empty();
139
-  Filelist::const_iterator itFile    = curFiles.begin();
140
-  Playlist::iterator       itEntry   = m_playlist.begin();
141
-  bool                     bCurChg   = false;
142
-  while (itFile != curFiles.end() || itEntry != m_playlist.end()) {
143
-
144
-    // new movie inserted
145
-    if (itEntry == m_playlist.end() ||
146
-        (itFile != curFiles.end() && *itFile < itEntry->m_name)) {
147
-      // load movie
148
-      Entry entry(*itFile, m_dirPlaylist.getFile(*itFile));
149
-      if (entry.loadMovie())
150
-        // insert playlist entry
151
-        m_playlist.insert(itEntry, entry);
152
-      // advance to next file
153
-      ++itFile;
154
-    }
155
-
156
-    // movie removed
157
-    // movie changed (=> remove and re-insert in next iteration)
158
-    else if (itFile == curFiles.end() || *itFile > itEntry->m_name ||
159
-             itEntry->m_file.checkModified()) {
160
-      // check if movie to remove is current movie
161
-      if (itEntry == m_curEntry) {
162
-        // advance current movie to next movie
163
-        ++m_curEntry;
164
-        bCurChg = true;
165
-      }
166
-      // remove entry
167
-      itEntry->freeMovie();
168
-      itEntry = m_playlist.erase(itEntry);
169
-      // do not advance to next file
170
-    }
171 100
 
172
-    // movie stayed in playlist and did not change
173
-    else {
174
-      // advance to next file and next entry
175
-      ++itFile;
176
-      ++itEntry;
177
-    }
178
-
179
-  } // while itFile itEntry
180
-
181
-  // current movie entry changed - or - playlist was empty and is not now
182
-  if (bCurChg || (bWasEmpty && !m_playlist.empty())) {
183
-    // go to begin of new current movie and start playing now
184
-    m_curFrame = 0;
185
-    m_nextTime = Time::now();
186
-    procFrame();
187
-  }
101
+  } // if (m_curChange)
188 102
 }
189 103
 
190 104
 /// process current frame
... ...
@@ -196,8 +110,8 @@ void Player::procFrame()
196 110
   bool wrapped = false;
197 111
   while (true) {
198 112
     // playlist finished -> re-start from beginning
199
-    while (m_curEntry == m_playlist.end()) {
200
-      m_curEntry = m_playlist.begin();
113
+    while (m_curEntry == m_playlistTracker.m_list.end()) {
114
+      m_curEntry = m_playlistTracker.m_list.begin();
201 115
       m_curFrame = 0;
202 116
       // detect empty playlist or playlist with only empty movies
203 117
       if (wrapped) {
... ...
@@ -209,7 +123,7 @@ void Player::procFrame()
209 123
     if (!m_curValid)
210 124
       break;
211 125
     // movie not yet finished -> done
212
-    if (m_curFrame < BlinkenMovieGetFrameCnt(m_curEntry->m_pMovie))
126
+    if (m_curFrame < BlinkenMovieGetFrameCnt(m_curEntry->m_pObj->m_pMovie))
213 127
       break;
214 128
     // movie finished -> next movie
215 129
     ++m_curEntry;
... ...
@@ -223,7 +137,7 @@ void Player::procFrame()
223 137
   if (m_curValid) {
224 138
     // calculate time for next frame
225 139
     stBlinkenFrame *pFrame =
226
-      BlinkenMovieGetFrame(m_curEntry->m_pMovie, m_curFrame);
140
+      BlinkenMovieGetFrame(m_curEntry->m_pObj->m_pMovie, m_curFrame);
227 141
     Time duration;
228 142
     duration.fromMs(BlinkenFrameGetDuration(pFrame));
229 143
     m_nextTime += duration;
... ...
@@ -238,7 +152,7 @@ void Player::sendFrame()
238 152
   // frame avalable -> send it
239 153
   if (m_curValid) {
240 154
     stBlinkenFrame *pFrame =
241
-      BlinkenMovieGetFrame(m_curEntry->m_pMovie, m_curFrame);
155
+      BlinkenMovieGetFrame(m_curEntry->m_pObj->m_pMovie, m_curFrame);
242 156
     m_fileOutStream.setFrame(pFrame);
243 157
   }
244 158
   // no frame available -> send this information
... ...
@@ -246,34 +160,5 @@ void Player::sendFrame()
246 160
     m_fileOutStream.setFrame(NULL);
247 161
 }
248 162
 
249
-/* #################
250
-   # Player::Entry #
251
-   ################# */
252
-
253
-/// constructor
254
-Player::Entry::Entry(const std::string &name, const File &file):
255
-  m_name(name),
256
-  m_file(file),
257
-  m_pMovie(NULL)
258
-{
259
-}
260
-
261
-/// load movie from current file
262
-bool Player::Entry::loadMovie()
263
-{
264
-  freeMovie();
265
-  m_pMovie = BlinkenMovieLoad(m_file.getPath().c_str());
266
-  return m_pMovie;
267
-}
268
-
269
-/// free current movie
270
-void Player::Entry::freeMovie()
271
-{
272
-  if (m_pMovie) {
273
-    BlinkenMovieFree(m_pMovie);
274
-    m_pMovie = NULL;
275
-  }
276
-}
277
-
278 163
 } // namespace Blinker
279 164
 
... ...
@@ -15,6 +15,7 @@
15 15
 #include "Directory.h"
16 16
 #include "File.h"
17 17
 #include "Module.h"
18
+#include "ListTracker.h"
18 19
 #include "OutStreamFile.h"
19 20
 #include "StreamMgr.h"
20 21
 #include "Time.h"
... ...
@@ -26,18 +27,14 @@ namespace Blinker {
26 27
 class Player: public Module, public TimeCallee
27 28
 {
28 29
 protected:
29
-  /// playlist entry
30
-  struct Entry {
31
-    std::string     m_name;    ///< name of playlist entry
32
-    File            m_file;    ///< file object (to check for updates)
33
-    stBlinkenMovie *m_pMovie;  ///< movie object
34
-    Entry(const std::string &name, const File &file); ///< constructor
35
-    bool loadMovie(); ///< load movie from current file
36
-    void freeMovie(); ///< free current movie
37
-  };
38
-
39
-  /// playlist
40
-  typedef std::list<Entry> Playlist;
30
+  /// movie in playlist
31
+  class Movie;
32
+
33
+  /// playlist tracker
34
+  typedef ListTracker<Player, Movie, File> PlaylistTracker;
35
+
36
+  /// playlist iterator
37
+  typedef PlaylistTracker::ListIt PlaylistIt;
41 38
 
42 39
 public:
43 40
   /**
... ...
@@ -66,11 +63,8 @@ public:
66 63
   virtual void timeCall();
67 64
 
68 65
 protected:
69
-  /// light update of playlist, i.e. stat all files in current playlist
70
-  void updatePlaylistLight();
71
-
72
-  /// full update of playlist, i.e. scan files in playlist directory
73
-  void updatePlaylistFull();
66
+  /// check if current movie changed and react
67
+  void checkCurChanged();
74 68
 
75 69
   /// process current frame
76 70
   void procFrame();
... ...
@@ -80,11 +74,11 @@ protected:
80 74
 
81 75
 protected:
82 76
   OutStreamFile   m_fileOutStream;   ///< output stream name file
83
-  Directory                m_dirPlaylist;   ///< playlist directory
84
-  Playlist                 m_playlist;      ///< current playlist
77
+  PlaylistTracker m_playlistTracker; ///< current playlist
85 78
   bool            m_curValid;        ///< if there is a current frame
86
-  Playlist::const_iterator m_curEntry;      ///< current playlist entry
79
+  PlaylistIt      m_curEntry;        ///< current playlist entry
87 80
   int             m_curFrame;        ///< current frame in movie
81
+  bool            m_curChange;       ///< current movie changed
88 82
   Time            m_nextTime;        ///< when to show next frame
89 83
 }; // class Player
90 84
 
... ...
@@ -0,0 +1,90 @@
1
+/* Blinker
2
+   Copyright 2011 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 <string>
7
+
8
+#include <BlinkenLib/BlinkenFrame.h>
9
+#include <BlinkenLib/BlinkenMovie.h>
10
+
11
+#include "File.h"
12
+#include "Player.h"
13
+#include "PlayerMovie.h"
14
+
15
+namespace Blinker {
16
+
17
+/**
18
+ * @brief constructor
19
+ * @param[in] player owning player module
20
+ * @param[in] name name of movie
21
+ * @param[in] file movie file
22
+ */
23
+Player::Movie::Movie(Player &player, const std::string &name,
24
+                     const File &file):
25
+  m_player(player),
26
+  m_name(name),
27
+  m_file(file),
28
+  m_pMovie(NULL)
29
+{
30
+  load();
31
+  ifOnlyGoHere();
32
+}
33
+
34
+/// destructor
35
+Player::Movie::~Movie()
36
+{
37
+  ifCurGoNext();
38
+  free();
39
+}
40
+
41
+/// check for update of configuration
42
+void Player::Movie::updateConfig()
43
+{
44
+  // movie file was modified
45
+  if (m_file.checkModified()) {
46
+    ifCurGoNext();
47
+    load();
48
+    ifOnlyGoHere();
49
+  }
50
+}
51
+
52
+/// load movie from current file
53
+void Player::Movie::load()
54
+{
55
+  free();
56
+  m_pMovie = BlinkenMovieLoad(m_file.getPath().c_str());
57
+}
58
+
59
+/// free current movie
60
+void Player::Movie::free()
61
+{
62
+  if (m_pMovie) {
63
+    BlinkenMovieFree(m_pMovie);
64
+    m_pMovie = NULL;
65
+  }
66
+}
67
+
68
+/// if this is the only movie in playlist go to begin of this movie
69
+void Player::Movie::ifOnlyGoHere()
70
+{
71
+  /* The implementation of ListTracker will first set up the entry and then
72
+     insert it into the list. Thus, we are the only movie if we see an empty
73
+     playlist here. */
74
+  if (m_player.m_playlistTracker.m_list.empty() && m_pMovie) {
75
+    m_player.m_curEntry = m_player.m_playlistTracker.m_list.begin();
76
+    m_player.m_curChange = true;
77
+  }
78
+}
79
+
80
+/// if this is current movie go to begin of next movie
81
+void Player::Movie::ifCurGoNext()
82
+{
83
+  if (m_player.m_curEntry->m_pObj == this) {
84
+    ++m_player.m_curEntry;
85
+    m_player.m_curChange = true;
86
+  }
87
+}
88
+
89
+} // namespace Blinker
90
+
... ...
@@ -0,0 +1,71 @@
1
+/* Blinker
2
+   Copyright 2011 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 PLAYERMOVIE_H
7
+#define PLAYERMOVIE_H
8
+
9
+#include <string>
10
+
11
+#include <BlinkenLib/BlinkenFrame.h>
12
+#include <BlinkenLib/BlinkenMovie.h>
13
+
14
+#include "File.h"
15
+#include "Player.h"
16
+
17
+namespace Blinker {
18
+
19
+/// movie in player's playlist
20
+class Player::Movie
21
+{
22
+public:
23
+  /**
24
+   * @brief constructor
25
+   * @param[in] player owning player module
26
+   * @param[in] name name of movie
27
+   * @param[in] file movie file
28
+   */
29
+  Movie(Player &player, const std::string &name,
30
+        const File &file);
31
+
32
+  /// destructor
33
+  ~Movie();
34
+
35
+private:
36
+  /// copy constructor disabled
37
+  Movie(const Movie &that);
38
+
39
+  /// assignment operator disabled
40
+  const Movie & operator=(const Movie &that);
41
+
42
+public:
43
+  /// check for update of configuration
44
+  void updateConfig();
45
+
46
+protected:
47
+  /// load movie from current file
48
+  void load();
49
+
50
+  /// free current movie
51
+  void free();
52
+
53
+  /// if this is the only movie in playlist go to begin of this movie
54
+  void ifOnlyGoHere();
55
+
56
+  /// if this is current movie go to begin of next movie
57
+  void ifCurGoNext();
58
+
59
+protected:
60
+  Player         &m_player; ///< owning player module
61
+  std::string    m_name;    ///< name of movie
62
+  File           m_file;    ///< movie file
63
+
64
+public:
65
+  stBlinkenMovie *m_pMovie; ///< loaded movie object
66
+}; // class Player::Movie
67
+
68
+} // namespace Blinker
69
+
70
+#endif // #ifndef PLAYERMOVIE_H
71
+
0 72