Stefan Schuermans commited on 2011-10-23 11:37:40
Showing 24 changed files, with 1441 additions and 0 deletions.
... | ... |
@@ -0,0 +1 @@ |
1 |
+example.cfg |
... | ... |
@@ -0,0 +1,39 @@ |
1 |
+SRCS=$(wildcard noarch/*.cpp) $(wildcard linux/*.cpp) |
|
2 |
+TARGET=Blinker |
|
3 |
+ |
|
4 |
+CPP=g++ |
|
5 |
+INCLUDE=-Inoarch -Ilinux |
|
6 |
+CFLAGS=-Wall -Wextra -g2 |
|
7 |
+LDFLAGS= |
|
8 |
+LIBS=-lBlinkenLib |
|
9 |
+ |
|
10 |
+SRCS_BASE=$(patsubst %.cpp,%,$(SRCS)) |
|
11 |
+DEPS=$(addsuffix .d,$(SRCS_BASE)) |
|
12 |
+OBJS=$(addsuffix .o,$(SRCS_BASE)) |
|
13 |
+ |
|
14 |
+.PHONY: all clean |
|
15 |
+.SUFFIXES: |
|
16 |
+.SECONDARY: |
|
17 |
+ |
|
18 |
+all: deps $(TARGET) |
|
19 |
+ |
|
20 |
+ifneq ($(MAKECMDGOALS),clean) |
|
21 |
+ include deps |
|
22 |
+endif |
|
23 |
+ |
|
24 |
+deps: $(DEPS) |
|
25 |
+ cat /dev/null $+ >$@ |
|
26 |
+ |
|
27 |
+%.d: %.cpp Makefile |
|
28 |
+ $(CPP) $(INCLUDE) $(CFLAGS) -M -o $@ $< |
|
29 |
+ sed -i 1s!^!$(dir $<)! $@ |
|
30 |
+ |
|
31 |
+%.o: %.cpp Makefile |
|
32 |
+ $(CPP) $(INCLUDE) $(CFLAGS) -c -o $@ $< |
|
33 |
+ |
|
34 |
+$(TARGET): $(OBJS) |
|
35 |
+ $(CPP) $(LDFLAGS) -o $@ $+ $(LIBS) |
|
36 |
+ |
|
37 |
+clean: |
|
38 |
+ rm -f deps $(DEPS) $(OBJS) $(TARGET) |
|
39 |
+ |
... | ... |
@@ -0,0 +1,89 @@ |
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 <dirent.h> |
|
7 |
+#include <string> |
|
8 |
+#include <string.h> |
|
9 |
+#include <sys/stat.h> |
|
10 |
+#include <sys/types.h> |
|
11 |
+#include <unistd.h> |
|
12 |
+ |
|
13 |
+#include "Directory.h" |
|
14 |
+#include "File.h" |
|
15 |
+ |
|
16 |
+namespace Blinker { |
|
17 |
+ |
|
18 |
+/** |
|
19 |
+ * @brief constructor from path |
|
20 |
+ * @param[in] path path to directory |
|
21 |
+ */ |
|
22 |
+Directory::Directory(const std::string &path): |
|
23 |
+ File(path) |
|
24 |
+{ |
|
25 |
+ if (m_path.empty() || m_path.at(m_path.length() - 1) != '/') |
|
26 |
+ m_path += '/'; |
|
27 |
+} |
|
28 |
+ |
|
29 |
+/** |
|
30 |
+ * @brief get list of entries in directory |
|
31 |
+ * @param[in] type type of directory entries to return |
|
32 |
+ * @param[out] entries list of directory entries |
|
33 |
+ */ |
|
34 |
+void Directory::getEntries(Type type, std::list<std::string> &entries) const |
|
35 |
+{ |
|
36 |
+ entries.clear(); |
|
37 |
+ |
|
38 |
+ if (m_path.empty()) |
|
39 |
+ return; |
|
40 |
+ DIR *dir = opendir(m_path.c_str()); |
|
41 |
+ if (!dir) |
|
42 |
+ return; |
|
43 |
+ |
|
44 |
+ struct dirent *dirent; |
|
45 |
+ while ((dirent = readdir(dir))) { |
|
46 |
+ if (strcmp(dirent->d_name, ".") && strcmp(dirent->d_name, "..") ) { |
|
47 |
+ |
|
48 |
+ struct stat s; |
|
49 |
+ if (stat((m_path + dirent->d_name).c_str(), &s)) |
|
50 |
+ continue; // cannot stat -> silently ignore |
|
51 |
+ |
|
52 |
+ bool ok = false; |
|
53 |
+ switch (type) { |
|
54 |
+ case TypeSubdir: ok = S_ISDIR(s.st_mode); break; |
|
55 |
+ case TypeFile: ok = S_ISREG(s.st_mode); break; |
|
56 |
+ } |
|
57 |
+ if (ok) |
|
58 |
+ entries.push_back(dirent->d_name); |
|
59 |
+ |
|
60 |
+ } // if ! "." && ! ".." |
|
61 |
+ } // while dirent |
|
62 |
+ |
|
63 |
+ closedir(dir); |
|
64 |
+ |
|
65 |
+ entries.sort(); |
|
66 |
+} |
|
67 |
+ |
|
68 |
+/** |
|
69 |
+ * @brief get subdirectory |
|
70 |
+ * @param[in] name of subdirectory |
|
71 |
+ * @return subdirectory object |
|
72 |
+ */ |
|
73 |
+Directory Directory::getSubdir(const std::string &name) const |
|
74 |
+{ |
|
75 |
+ return Directory(m_path + name); |
|
76 |
+} |
|
77 |
+ |
|
78 |
+/** |
|
79 |
+ * @brief get file in directory |
|
80 |
+ * @param[in] name of file |
|
81 |
+ * @return file object |
|
82 |
+ */ |
|
83 |
+File Directory::getFile(const std::string &name) const |
|
84 |
+{ |
|
85 |
+ return File(m_path + name); |
|
86 |
+} |
|
87 |
+ |
|
88 |
+} // namespace Blinker |
|
89 |
+ |
... | ... |
@@ -0,0 +1,59 @@ |
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 DIRECTORY_H |
|
7 |
+#define DIRECTORY_H |
|
8 |
+ |
|
9 |
+#include <list> |
|
10 |
+#include <string> |
|
11 |
+ |
|
12 |
+#include "File.h" |
|
13 |
+ |
|
14 |
+namespace Blinker { |
|
15 |
+ |
|
16 |
+/// information about a directory |
|
17 |
+class Directory: public File |
|
18 |
+{ |
|
19 |
+public: |
|
20 |
+ /// type of directory entries |
|
21 |
+ enum Type { |
|
22 |
+ TypeSubdir, ///< subdirectory |
|
23 |
+ TypeFile ///< file |
|
24 |
+ }; |
|
25 |
+ |
|
26 |
+public: |
|
27 |
+ /** |
|
28 |
+ * @brief constructor from path |
|
29 |
+ * @param[in] path path to directory |
|
30 |
+ */ |
|
31 |
+ Directory(const std::string &path); |
|
32 |
+ |
|
33 |
+public: |
|
34 |
+ /** |
|
35 |
+ * @brief get list of entries in directory |
|
36 |
+ * @param[in] type type of directory entries to return |
|
37 |
+ * @param[out] entries list of directory entries |
|
38 |
+ */ |
|
39 |
+ void getEntries(Type type, std::list<std::string> &entries) const; |
|
40 |
+ |
|
41 |
+ /** |
|
42 |
+ * @brief get subdirectory |
|
43 |
+ * @param[in] name of subdirectory |
|
44 |
+ * @return subdirectory object |
|
45 |
+ */ |
|
46 |
+ Directory getSubdir(const std::string &name) const; |
|
47 |
+ |
|
48 |
+ /** |
|
49 |
+ * @brief get file in directory |
|
50 |
+ * @param[in] name of file |
|
51 |
+ * @return file object |
|
52 |
+ */ |
|
53 |
+ File getFile(const std::string &name) const; |
|
54 |
+}; // class Directory |
|
55 |
+ |
|
56 |
+} // namespace Blinker |
|
57 |
+ |
|
58 |
+#endif // #ifndef DIRECTORY_H |
|
59 |
+ |
... | ... |
@@ -0,0 +1,61 @@ |
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 |
+#include <sys/stat.h> |
|
8 |
+#include <sys/types.h> |
|
9 |
+#include <unistd.h> |
|
10 |
+ |
|
11 |
+#include "File.h" |
|
12 |
+#include "Time.h" |
|
13 |
+ |
|
14 |
+namespace Blinker { |
|
15 |
+ |
|
16 |
+/** |
|
17 |
+ * @brief constructor from path |
|
18 |
+ * @param[in] path path to file |
|
19 |
+ */ |
|
20 |
+File::File(const std::string &path): |
|
21 |
+ m_path(path), |
|
22 |
+ m_lastCheck() // initialize last check to "now" |
|
23 |
+{ |
|
24 |
+} |
|
25 |
+ |
|
26 |
+/** |
|
27 |
+ * @brief get path to file |
|
28 |
+ * @return path to file |
|
29 |
+ */ |
|
30 |
+const std::string & File::getPath() |
|
31 |
+{ |
|
32 |
+ return m_path; |
|
33 |
+} |
|
34 |
+ |
|
35 |
+/** |
|
36 |
+ * @brief check if file has been modified |
|
37 |
+ * @return if file has been modified since last check |
|
38 |
+ */ |
|
39 |
+bool File::checkModified() |
|
40 |
+{ |
|
41 |
+ /* get current time before getting modification time |
|
42 |
+ for not missing any modification */ |
|
43 |
+ Time now; |
|
44 |
+ |
|
45 |
+ // get modification time |
|
46 |
+ struct stat s; |
|
47 |
+ if (stat(m_path.c_str(), &s)) |
|
48 |
+ return false; // cannot stat -> silently ignore |
|
49 |
+ Time modified(s.st_mtime); |
|
50 |
+ |
|
51 |
+ // has file been modified since last check |
|
52 |
+ bool mod = modified > m_lastCheck; |
|
53 |
+ |
|
54 |
+ // remember "now" as last check time |
|
55 |
+ m_lastCheck = now; |
|
56 |
+ |
|
57 |
+ return mod; |
|
58 |
+} |
|
59 |
+ |
|
60 |
+} // namespace Blinker |
|
61 |
+ |
... | ... |
@@ -0,0 +1,46 @@ |
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 FILE_H |
|
7 |
+#define FILE_H |
|
8 |
+ |
|
9 |
+#include <string> |
|
10 |
+ |
|
11 |
+#include "Time.h" |
|
12 |
+ |
|
13 |
+namespace Blinker { |
|
14 |
+ |
|
15 |
+/// information about a file |
|
16 |
+class File |
|
17 |
+{ |
|
18 |
+public: |
|
19 |
+ /** |
|
20 |
+ * @brief constructor from path |
|
21 |
+ * @param[in] path path to file |
|
22 |
+ */ |
|
23 |
+ File(const std::string &path); |
|
24 |
+ |
|
25 |
+public: |
|
26 |
+ /** |
|
27 |
+ * @brief get path to file |
|
28 |
+ * @return path to file |
|
29 |
+ */ |
|
30 |
+ const std::string & getPath(); |
|
31 |
+ |
|
32 |
+ /** |
|
33 |
+ * @brief check if file has been modified |
|
34 |
+ * @return if file has been modified since last check |
|
35 |
+ */ |
|
36 |
+ bool checkModified(); |
|
37 |
+ |
|
38 |
+protected: |
|
39 |
+ std::string m_path; ///< path to file |
|
40 |
+ Time m_lastCheck; ///< last time modification time was checked |
|
41 |
+}; // class File |
|
42 |
+ |
|
43 |
+} // namespace Blinker |
|
44 |
+ |
|
45 |
+#endif // #ifndef FILE_H |
|
46 |
+ |
... | ... |
@@ -0,0 +1,203 @@ |
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 <errno.h> |
|
7 |
+#include <stdint.h> |
|
8 |
+#include <sys/time.h> |
|
9 |
+#include <time.h> |
|
10 |
+ |
|
11 |
+#include "Time.h" |
|
12 |
+ |
|
13 |
+namespace Blinker { |
|
14 |
+ |
|
15 |
+const Time Time::zero(0); ///< zero time |
|
16 |
+ |
|
17 |
+/** |
|
18 |
+ * @brief get current time |
|
19 |
+ * @return current time |
|
20 |
+ */ |
|
21 |
+Time Time::now() |
|
22 |
+{ |
|
23 |
+ Time now; |
|
24 |
+ |
|
25 |
+ struct timeval tv; |
|
26 |
+ gettimeofday(&tv, NULL); |
|
27 |
+ now.m_sec = tv.tv_sec; |
|
28 |
+ now.m_ns = tv.tv_usec * 1000; |
|
29 |
+ |
|
30 |
+ return now; |
|
31 |
+} |
|
32 |
+ |
|
33 |
+/// constructor |
|
34 |
+Time::Time(): |
|
35 |
+ m_sec(0), |
|
36 |
+ m_ns(0) |
|
37 |
+{ |
|
38 |
+} |
|
39 |
+ |
|
40 |
+/** |
|
41 |
+ * @brief constructor from seconds |
|
42 |
+ * @param[in] t time in seconds |
|
43 |
+ */ |
|
44 |
+Time::Time(time_t t): |
|
45 |
+ m_sec(t), |
|
46 |
+ m_ns(0) |
|
47 |
+{ |
|
48 |
+} |
|
49 |
+ |
|
50 |
+/// comparison |
|
51 |
+//@{ |
|
52 |
+ |
|
53 |
+int Time::compare(const Time &that) const |
|
54 |
+{ |
|
55 |
+ if (m_sec < that.m_sec) |
|
56 |
+ return -1; |
|
57 |
+ if (m_sec > that.m_sec) |
|
58 |
+ return 1; |
|
59 |
+ if (m_ns < that.m_ns) |
|
60 |
+ return -1; |
|
61 |
+ if (m_ns > that.m_ns) |
|
62 |
+ return 1; |
|
63 |
+ return 0; |
|
64 |
+} |
|
65 |
+ |
|
66 |
+bool Time::operator==(const Time &that) const |
|
67 |
+{ |
|
68 |
+ return compare(that) == 0; |
|
69 |
+} |
|
70 |
+ |
|
71 |
+bool Time::operator!=(const Time &that) const |
|
72 |
+{ |
|
73 |
+ return compare(that) != 0; |
|
74 |
+} |
|
75 |
+ |
|
76 |
+bool Time::operator<(const Time &that) const |
|
77 |
+{ |
|
78 |
+ return compare(that) < 0; |
|
79 |
+} |
|
80 |
+ |
|
81 |
+bool Time::operator>(const Time &that) const |
|
82 |
+{ |
|
83 |
+ return compare(that) > 0; |
|
84 |
+} |
|
85 |
+ |
|
86 |
+bool Time::operator<=(const Time &that) const |
|
87 |
+{ |
|
88 |
+ return compare(that) <= 0; |
|
89 |
+} |
|
90 |
+ |
|
91 |
+bool Time::operator>=(const Time &that) const |
|
92 |
+{ |
|
93 |
+ return compare(that) >= 0; |
|
94 |
+} |
|
95 |
+ |
|
96 |
+//@} |
|
97 |
+ |
|
98 |
+/// arithmetic |
|
99 |
+//@{ |
|
100 |
+ |
|
101 |
+const Time & Time::operator+=(const Time &that) |
|
102 |
+{ |
|
103 |
+ m_sec += that.m_sec; |
|
104 |
+ m_ns += that.m_ns; |
|
105 |
+ fix(); |
|
106 |
+ return *this; |
|
107 |
+} |
|
108 |
+ |
|
109 |
+const Time & Time::operator-=(const Time &that) |
|
110 |
+{ |
|
111 |
+ m_sec -= that.m_sec; |
|
112 |
+ m_ns -= that.m_ns; |
|
113 |
+ fix(); |
|
114 |
+ return *this; |
|
115 |
+} |
|
116 |
+ |
|
117 |
+Time Time::operator+(const Time &that) const |
|
118 |
+{ |
|
119 |
+ Time result(*this); |
|
120 |
+ result += that; |
|
121 |
+ return result; |
|
122 |
+} |
|
123 |
+ |
|
124 |
+Time Time::operator-(const Time &that) const |
|
125 |
+{ |
|
126 |
+ Time result(*this); |
|
127 |
+ result -= that; |
|
128 |
+ return result; |
|
129 |
+} |
|
130 |
+ |
|
131 |
+//@} |
|
132 |
+ |
|
133 |
+/** |
|
134 |
+ * @brief convert from milliseconds |
|
135 |
+ * @param[in] ms milliseconds |
|
136 |
+ */ |
|
137 |
+void Time::fromMs(int ms) |
|
138 |
+{ |
|
139 |
+ if (ms >= 0) { |
|
140 |
+ m_sec = ms / 1000; |
|
141 |
+ m_ns = (ms % 1000) * 1000000; |
|
142 |
+ } else { |
|
143 |
+ m_sec = -(-ms / 1000); |
|
144 |
+ m_ns = -(-ms % 1000) * 1000000; |
|
145 |
+ } |
|
146 |
+} |
|
147 |
+ |
|
148 |
+/** |
|
149 |
+ * @brief convert to seconds |
|
150 |
+ * @return seconds |
|
151 |
+ */ |
|
152 |
+time_t Time::toSec() const |
|
153 |
+{ |
|
154 |
+ if (m_ns >= 500000000) |
|
155 |
+ return m_sec + 1; |
|
156 |
+ else if (m_ns <= 500000000) |
|
157 |
+ return m_sec - 1; |
|
158 |
+ else |
|
159 |
+ return m_sec; |
|
160 |
+} |
|
161 |
+ |
|
162 |
+/// fix internal time representation after calculation |
|
163 |
+void Time::fix() |
|
164 |
+{ |
|
165 |
+ if (m_ns >= 1000000000) { |
|
166 |
+ m_sec += m_ns / 1000000000; |
|
167 |
+ m_ns = m_ns % 1000000000; |
|
168 |
+ } else if (m_ns <= -1000000000) { |
|
169 |
+ m_sec -= -m_ns / 1000000000; |
|
170 |
+ m_ns = -(-m_ns % 1000000000); |
|
171 |
+ } |
|
172 |
+ if (m_sec > 0 && m_ns < 0) { |
|
173 |
+ m_sec -= 1; |
|
174 |
+ m_ns += 1000000000; |
|
175 |
+ } else if (m_sec < 0 && m_ns > 0) { |
|
176 |
+ m_sec += 1; |
|
177 |
+ m_ns -= 1000000000; |
|
178 |
+ } |
|
179 |
+} |
|
180 |
+ |
|
181 |
+/// sleep for duration |
|
182 |
+void Time::sleepFor() const |
|
183 |
+{ |
|
184 |
+ // do not sleep for negative time |
|
185 |
+ if (*this < zero) |
|
186 |
+ return; |
|
187 |
+ |
|
188 |
+ // sleep |
|
189 |
+ struct timespec req, rem; |
|
190 |
+ req.tv_sec = m_sec; |
|
191 |
+ req.tv_nsec = m_ns; |
|
192 |
+ while (nanosleep(&req, &rem) && errno == EINTR) |
|
193 |
+ req = rem; |
|
194 |
+} |
|
195 |
+ |
|
196 |
+/// sleep until time |
|
197 |
+void Time::sleepUntil() const |
|
198 |
+{ |
|
199 |
+ (*this - now()).sleepFor(); |
|
200 |
+} |
|
201 |
+ |
|
202 |
+} // namespace Blinker |
|
203 |
+ |
... | ... |
@@ -0,0 +1,88 @@ |
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 TIME_H |
|
7 |
+#define TIME_H |
|
8 |
+ |
|
9 |
+#include <stdint.h> |
|
10 |
+#include <time.h> |
|
11 |
+ |
|
12 |
+namespace Blinker { |
|
13 |
+ |
|
14 |
+/// time, either point in time or duration |
|
15 |
+class Time |
|
16 |
+{ |
|
17 |
+public: |
|
18 |
+ static const Time zero; ///< zero time |
|
19 |
+ |
|
20 |
+public: |
|
21 |
+ /** |
|
22 |
+ * @brief get current time |
|
23 |
+ * @return current time |
|
24 |
+ */ |
|
25 |
+ static Time now(); |
|
26 |
+ |
|
27 |
+public: |
|
28 |
+ /// constructor |
|
29 |
+ Time(); |
|
30 |
+ |
|
31 |
+ /** |
|
32 |
+ * @brief constructor from seconds |
|
33 |
+ * @param[in] t time in seconds |
|
34 |
+ */ |
|
35 |
+ Time(time_t t); |
|
36 |
+ |
|
37 |
+public: |
|
38 |
+ /// comparison |
|
39 |
+ //@{ |
|
40 |
+ int compare(const Time &that) const; |
|
41 |
+ bool operator==(const Time &that) const; |
|
42 |
+ bool operator!=(const Time &that) const; |
|
43 |
+ bool operator<(const Time &that) const; |
|
44 |
+ bool operator>(const Time &that) const; |
|
45 |
+ bool operator<=(const Time &that) const; |
|
46 |
+ bool operator>=(const Time &that) const; |
|
47 |
+ //@} |
|
48 |
+ |
|
49 |
+ /// arithmetic |
|
50 |
+ //@{ |
|
51 |
+ const Time & operator+=(const Time &that); |
|
52 |
+ const Time & operator-=(const Time &that); |
|
53 |
+ Time operator+(const Time &that) const; |
|
54 |
+ Time operator-(const Time &that) const; |
|
55 |
+ //@} |
|
56 |
+ |
|
57 |
+ /** |
|
58 |
+ * @brief convert from milliseconds |
|
59 |
+ * @param[in] ms milliseconds |
|
60 |
+ */ |
|
61 |
+ void fromMs(int ms); |
|
62 |
+ |
|
63 |
+ /** |
|
64 |
+ * @brief convert to seconds |
|
65 |
+ * @return seconds |
|
66 |
+ */ |
|
67 |
+ time_t toSec() const; |
|
68 |
+ |
|
69 |
+public: |
|
70 |
+ /// sleep for duration |
|
71 |
+ void sleepFor() const; |
|
72 |
+ |
|
73 |
+ /// sleep until time |
|
74 |
+ void sleepUntil() const; |
|
75 |
+ |
|
76 |
+protected: |
|
77 |
+ /// fix internal time representation after calculation |
|
78 |
+ void fix(); |
|
79 |
+ |
|
80 |
+protected: |
|
81 |
+ int64_t m_sec; ///< seconds |
|
82 |
+ int64_t m_ns; ///< nanoseconds |
|
83 |
+}; // class Time |
|
84 |
+ |
|
85 |
+} // namespace Blinker |
|
86 |
+ |
|
87 |
+#endif // #ifndef TIME_H |
|
88 |
+ |
... | ... |
@@ -0,0 +1,83 @@ |
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 <map> |
|
7 |
+#include <set> |
|
8 |
+ |
|
9 |
+#include "CallMgr.h" |
|
10 |
+#include "Time.h" |
|
11 |
+#include "TimeCallee.h" |
|
12 |
+ |
|
13 |
+namespace Blinker { |
|
14 |
+ |
|
15 |
+/// constructor |
|
16 |
+CallMgr::CallMgr() |
|
17 |
+{ |
|
18 |
+} |
|
19 |
+ |
|
20 |
+/// destructor |
|
21 |
+CallMgr::~CallMgr() |
|
22 |
+{ |
|
23 |
+} |
|
24 |
+ |
|
25 |
+/** |
|
26 |
+ * @brief cancel callback at certain time |
|
27 |
+ * @param[in] callee whom not to call |
|
28 |
+ */ |
|
29 |
+void CallMgr::cancelTimeCall(TimeCallee *callee) |
|
30 |
+{ |
|
31 |
+ // find time a call is registered at |
|
32 |
+ TimeCalleeMap::iterator itCallee; |
|
33 |
+ itCallee = m_timeCallees.find(callee); |
|
34 |
+ if (itCallee == m_timeCallees.end()) |
|
35 |
+ return; // no call registered |
|
36 |
+ const Time &time = itCallee->second; |
|
37 |
+ |
|
38 |
+ // remove registered call |
|
39 |
+ m_times[time].erase(callee); |
|
40 |
+ m_timeCallees.erase(itCallee); |
|
41 |
+} |
|
42 |
+ |
|
43 |
+/** |
|
44 |
+ * @brief request callback at certain time |
|
45 |
+ * @param[in] callee whom to call |
|
46 |
+ * @param[in] time when to call |
|
47 |
+ * |
|
48 |
+ * this cancels a previous time call request from callee |
|
49 |
+ */ |
|
50 |
+void CallMgr::requestTimeCall(TimeCallee *callee, const Time &time) |
|
51 |
+{ |
|
52 |
+ // cancel previous call |
|
53 |
+ cancelTimeCall(callee); |
|
54 |
+ |
|
55 |
+ // register call at new time |
|
56 |
+ m_times[time].insert(callee); |
|
57 |
+ m_timeCallees[callee] = time; |
|
58 |
+} |
|
59 |
+ |
|
60 |
+/// run call manager |
|
61 |
+void CallMgr::run() |
|
62 |
+{ |
|
63 |
+ while (!m_times.empty()) { |
|
64 |
+ |
|
65 |
+ // wait until next time is reached |
|
66 |
+ m_times.begin()->first.sleepUntil(); |
|
67 |
+ |
|
68 |
+ // get callees and remove entry from time map |
|
69 |
+ TimeCallees timeCallees = m_times.begin()->second; |
|
70 |
+ m_times.erase(m_times.begin()); |
|
71 |
+ |
|
72 |
+ // call callees |
|
73 |
+ TimeCallees::const_iterator itTC; |
|
74 |
+ for (itTC = timeCallees.begin(); itTC != timeCallees.end(); ++itTC) { |
|
75 |
+ m_timeCallees.erase(*itTC); // first remove request from callee map |
|
76 |
+ (*itTC)->timeCall(); // then call callee |
|
77 |
+ } |
|
78 |
+ |
|
79 |
+ } // while m_times |
|
80 |
+} |
|
81 |
+ |
|
82 |
+} // namespace Blinker |
|
83 |
+ |
... | ... |
@@ -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 CALLMGR_H |
|
7 |
+#define CALLMGR_H |
|
8 |
+ |
|
9 |
+#include <map> |
|
10 |
+#include <set> |
|
11 |
+ |
|
12 |
+#include "Time.h" |
|
13 |
+#include "TimeCallee.h" |
|
14 |
+ |
|
15 |
+namespace Blinker { |
|
16 |
+ |
|
17 |
+/// callback manager, calls back at certain time or events |
|
18 |
+class CallMgr |
|
19 |
+{ |
|
20 |
+protected: |
|
21 |
+ /// set of time callees to call at a certain time |
|
22 |
+ typedef std::set<TimeCallee *> TimeCallees; |
|
23 |
+ /// what set of time callees to call at a certain time |
|
24 |
+ typedef std::map<Time, TimeCallees> TimeMap; |
|
25 |
+ /// when to call a time callee |
|
26 |
+ typedef std::map<TimeCallee *, Time> TimeCalleeMap; |
|
27 |
+ |
|
28 |
+public: |
|
29 |
+ /// constructor |
|
30 |
+ CallMgr(); |
|
31 |
+ |
|
32 |
+ /// destructor |
|
33 |
+ ~CallMgr(); |
|
34 |
+ |
|
35 |
+private: |
|
36 |
+ /// copy constructor disabled |
|
37 |
+ CallMgr(const CallMgr & that); |
|
38 |
+ |
|
39 |
+ /// assignment operator disabled |
|
40 |
+ const CallMgr& operator=(const CallMgr &that); |
|
41 |
+ |
|
42 |
+public: |
|
43 |
+ /** |
|
44 |
+ * @brief cancel callback at certain time |
|
45 |
+ * @param[in] callee whom not to call |
|
46 |
+ */ |
|
47 |
+ void cancelTimeCall(TimeCallee *callee); |
|
48 |
+ |
|
49 |
+ /** |
|
50 |
+ * @brief request callback at certain time |
|
51 |
+ * @param[in] callee whom to call |
|
52 |
+ * @param[in] time when to call |
|
53 |
+ * |
|
54 |
+ * this cancels a previous time call request from callee |
|
55 |
+ */ |
|
56 |
+ void requestTimeCall(TimeCallee *callee, const Time &time); |
|
57 |
+ |
|
58 |
+ /// run call manager |
|
59 |
+ void run(); |
|
60 |
+ |
|
61 |
+protected: |
|
62 |
+ /// what time callees to call at a certain time |
|
63 |
+ TimeMap m_times; |
|
64 |
+ /// when to call time callees |
|
65 |
+ TimeCalleeMap m_timeCallees; |
|
66 |
+}; // class CallMgr |
|
67 |
+ |
|
68 |
+} // namespace Blinker |
|
69 |
+ |
|
70 |
+#endif // #ifndef CALLMGR_H |
|
71 |
+ |
... | ... |
@@ -0,0 +1,207 @@ |
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 <list> |
|
7 |
+#include <string> |
|
8 |
+ |
|
9 |
+#include <BlinkenLib/BlinkenFrame.h> |
|
10 |
+#include <BlinkenLib/BlinkenMovie.h> |
|
11 |
+ |
|
12 |
+#include "CallMgr.h" |
|
13 |
+#include "Directory.h" |
|
14 |
+#include "File.h" |
|
15 |
+#include "Player.h" |
|
16 |
+#include "StreamMgr.h" |
|
17 |
+#include "Time.h" |
|
18 |
+#include "TimeCallee.h" |
|
19 |
+ |
|
20 |
+namespace Blinker { |
|
21 |
+ |
|
22 |
+/** |
|
23 |
+ * @brief constructor |
|
24 |
+ * @param[in] callMgr callback manager |
|
25 |
+ * @param[in] streamMgr stream manager |
|
26 |
+ * @param[in] dirBase base directory |
|
27 |
+ */ |
|
28 |
+Player::Player(CallMgr &callMgr, StreamMgr &streamMgr, |
|
29 |
+ const Directory &dirBase): |
|
30 |
+ m_callMgr(callMgr), |
|
31 |
+ m_streamMgr(streamMgr), |
|
32 |
+ m_dirBase(dirBase), |
|
33 |
+ m_dirPlaylist(dirBase.getSubdir("playlist")), |
|
34 |
+ m_streamName("TEST"), // TODO |
|
35 |
+ m_pStream(NULL), |
|
36 |
+ m_curEntry(m_playlist.begin()), |
|
37 |
+ m_curFrame(0) |
|
38 |
+{ |
|
39 |
+ // get output stream |
|
40 |
+ m_pStream = &m_streamMgr.refStream(m_streamName); |
|
41 |
+ |
|
42 |
+ // load playlist |
|
43 |
+ updatePlaylist(); |
|
44 |
+} |
|
45 |
+ |
|
46 |
+/// virtual destructor |
|
47 |
+Player::~Player() |
|
48 |
+{ |
|
49 |
+ // free all movies |
|
50 |
+ while (!m_playlist.empty()) { |
|
51 |
+ m_playlist.back().freeMovie(); |
|
52 |
+ m_playlist.pop_back(); |
|
53 |
+ } |
|
54 |
+ |
|
55 |
+ // unreference stream |
|
56 |
+ m_pStream = NULL; |
|
57 |
+ m_streamMgr.unrefStream(m_streamName); |
|
58 |
+} |
|
59 |
+ |
|
60 |
+/// callback when requsted time reached |
|
61 |
+void Player::timeCall() |
|
62 |
+{ |
|
63 |
+ // show next frame |
|
64 |
+ showFrame(); |
|
65 |
+} |
|
66 |
+ |
|
67 |
+/// update playlist |
|
68 |
+void Player::updatePlaylist() |
|
69 |
+{ |
|
70 |
+ // get list of files in playlist directory |
|
71 |
+ typedef std::list<std::string> Filelist; |
|
72 |
+ Filelist curFiles; |
|
73 |
+ m_dirPlaylist.getEntries(Directory::TypeFile, curFiles); |
|
74 |
+ |
|
75 |
+ // walk through current playlist and file list simultaneously |
|
76 |
+ bool bWasEmpty = m_playlist.empty(); |
|
77 |
+ Filelist::const_iterator itFile = curFiles.begin(); |
|
78 |
+ Playlist::iterator itEntry = m_playlist.begin(); |
|
79 |
+ bool bCurChg = false; |
|
80 |
+ while (itFile != curFiles.end() || itEntry != m_playlist.end()) { |
|
81 |
+ |
|
82 |
+ // new movie inserted |
|
83 |
+ if (itEntry == m_playlist.end() || *itFile < itEntry->m_name) { |
|
84 |
+ // load movie |
|
85 |
+ Entry entry(*itFile, m_dirPlaylist.getFile(*itFile)); |
|
86 |
+ if (entry.loadMovie()) |
|
87 |
+ // insert playlist entry |
|
88 |
+ m_playlist.insert(itEntry, entry); |
|
89 |
+ // advance to next file |
|
90 |
+ ++itFile; |
|
91 |
+ } |
|
92 |
+ |
|
93 |
+ // movie removed |
|
94 |
+ // movie changed (=> remove and re-insert in next iteration) |
|
95 |
+ else if (itFile == curFiles.end() || *itFile > itEntry->m_name || |
|
96 |
+ itEntry->m_file.checkModified()) { |
|
97 |
+ // check if movie to remov movie is current movie |
|
98 |
+ if (itEntry == m_curEntry) { |
|
99 |
+ // advance current movie to next movie |
|
100 |
+ ++m_curEntry; |
|
101 |
+ bCurChg = true; |
|
102 |
+ } |
|
103 |
+ // remove entry |
|
104 |
+ itEntry->freeMovie(); |
|
105 |
+ itEntry = m_playlist.erase(itEntry); |
|
106 |
+ // do not advance to next file |
|
107 |
+ } |
|
108 |
+ |
|
109 |
+ // movie stayed in playlist and did not change |
|
110 |
+ else { |
|
111 |
+ // advance to next file and next entry |
|
112 |
+ ++itFile; |
|
113 |
+ ++itEntry; |
|
114 |
+ } |
|
115 |
+ |
|
116 |
+ } // while itFile itPlaylist |
|
117 |
+ |
|
118 |
+ // current movie entry changed - or - playlist was empty and is not now |
|
119 |
+ if (bCurChg || (bWasEmpty && !m_playlist.empty())) { |
|
120 |
+ // go to begin of movie and start playing now |
|
121 |
+ m_curFrame = 0; |
|
122 |
+ m_showTime = Time::now(); |
|
123 |
+ showFrame(); |
|
124 |
+ } |
|
125 |
+} |
|
126 |
+ |
|
127 |
+/// show current frame |
|
128 |
+void Player::showFrame() |
|
129 |
+{ |
|
130 |
+ // leave if time is not yet ready to show frame |
|
131 |
+ if (Time::now() < m_showTime) { |
|
132 |
+ m_callMgr.requestTimeCall(this, m_showTime); // request call at show time |
|
133 |
+ return; |
|
134 |
+ } |
|
135 |
+ |
|
136 |
+ // movie finished -> next movie |
|
137 |
+ // use while loops to handle empty movies / empty playlist |
|
138 |
+ bool wrapped = false; |
|
139 |
+ while (true) { |
|
140 |
+ // playlist finished -> re-start from beginning |
|
141 |
+ while (m_curEntry == m_playlist.end()) { |
|
142 |
+ m_curEntry = m_playlist.begin(); |
|
143 |
+ m_curFrame = 0; |
|
144 |
+ // detect empty playlist or playlist with only empty movies |
|
145 |
+ if (wrapped) { |
|
146 |
+ // empty playlist or playlist with only empty movies -> no frame |
|
147 |
+ if (m_pStream) |
|
148 |
+ m_pStream->setNoFrame(); |
|
149 |
+ return; |
|
150 |
+ } |
|
151 |
+ wrapped = true; |
|
152 |
+ } |
|
153 |
+ // movie not yet finished -> done |
|
154 |
+ if (m_curFrame < BlinkenMovieGetFrameCnt(m_curEntry->m_pMovie)) |
|
155 |
+ break; |
|
156 |
+ // movie finished -> next movie |
|
157 |
+ ++m_curEntry; |
|
158 |
+ m_curFrame = 0; |
|
159 |
+ } |
|
160 |
+ |
|
161 |
+ // show frame |
|
162 |
+ stBlinkenFrame *pFrame = |
|
163 |
+ BlinkenMovieGetFrame(m_curEntry->m_pMovie, m_curFrame); |
|
164 |
+ if (m_pStream) |
|
165 |
+ m_pStream->setFrame(pFrame); |
|
166 |
+ |
|
167 |
+ // calculate show time for next frame |
|
168 |
+ Time duration; |
|
169 |
+ duration.fromMs(BlinkenFrameGetDuration(pFrame)); |
|
170 |
+ m_showTime += duration; |
|
171 |
+ m_callMgr.requestTimeCall(this, m_showTime); // request call at show time |
|
172 |
+ |
|
173 |
+ // go to next frame |
|
174 |
+ ++m_curFrame; |
|
175 |
+} |
|
176 |
+ |
|
177 |
+/* ################# |
|
178 |
+ # Player::Entry # |
|
179 |
+ ################# */ |
|
180 |
+ |
|
181 |
+/// constructor |
|
182 |
+Player::Entry::Entry(const std::string &name, const File &file): |
|
183 |
+ m_name(name), |
|
184 |
+ m_file(file), |
|
185 |
+ m_pMovie(NULL) |
|
186 |
+{ |
|
187 |
+} |
|
188 |
+ |
|
189 |
+/// load movie from current file |
|
190 |
+bool Player::Entry::loadMovie() |
|
191 |
+{ |
|
192 |
+ freeMovie(); |
|
193 |
+ m_pMovie = BlinkenMovieLoad(m_file.getPath().c_str()); |
|
194 |
+ return m_pMovie; |
|
195 |
+} |
|
196 |
+ |
|
197 |
+/// free current movie |
|
198 |
+void Player::Entry::freeMovie() |
|
199 |
+{ |
|
200 |
+ if (m_pMovie) { |
|
201 |
+ BlinkenMovieFree(m_pMovie); |
|
202 |
+ m_pMovie = NULL; |
|
203 |
+ } |
|
204 |
+} |
|
205 |
+ |
|
206 |
+} // namespace Blinker |
|
207 |
+ |
... | ... |
@@ -0,0 +1,86 @@ |
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 PLAYER_H |
|
7 |
+#define PLAYER_H |
|
8 |
+ |
|
9 |
+#include <list> |
|
10 |
+#include <string> |
|
11 |
+ |
|
12 |
+#include <BlinkenLib/BlinkenMovie.h> |
|
13 |
+ |
|
14 |
+#include "CallMgr.h" |
|
15 |
+#include "Directory.h" |
|
16 |
+#include "File.h" |
|
17 |
+#include "StreamMgr.h" |
|
18 |
+#include "Time.h" |
|
19 |
+#include "TimeCallee.h" |
|
20 |
+ |
|
21 |
+namespace Blinker { |
|
22 |
+ |
|
23 |
+/// a movie player |
|
24 |
+class Player: public TimeCallee |
|
25 |
+{ |
|
26 |
+protected: |
|
27 |
+ /// playlist entry |
|
28 |
+ struct Entry { |
|
29 |
+ std::string m_name; ///< name of playlist entry |
|
30 |
+ File m_file; ///< file object (to check for updates) |
|
31 |
+ stBlinkenMovie *m_pMovie; ///< movie object |
|
32 |
+ Entry(const std::string &name, const File &file); ///< constructor |
|
33 |
+ bool loadMovie(); ///< load movie from current file |
|
34 |
+ void freeMovie(); ///< free current movie |
|
35 |
+ }; |
|
36 |
+ |
|
37 |
+ /// playlist |
|
38 |
+ typedef std::list<Entry> Playlist; |
|
39 |
+ |
|
40 |
+public: |
|
41 |
+ /** |
|
42 |
+ * @brief constructor |
|
43 |
+ * @param[in] callMgr callback manager |
|
44 |
+ * @param[in] streamMgr stream manager |
|
45 |
+ * @param[in] dirBase base directory |
|
46 |
+ */ |
|
47 |
+ Player(CallMgr &callMgr, StreamMgr &streamMgr, const Directory &dirBase); |
|
48 |
+ |
|
49 |
+ /// virtual destructor |
|
50 |
+ virtual ~Player(); |
|
51 |
+ |
|
52 |
+private: |
|
53 |
+ /// copy constructor disabled |
|
54 |
+ Player(const Player & that); |
|
55 |
+ |
|
56 |
+ /// assignment operator disabled |
|
57 |
+ const Player& operator=(const Player &that); |
|
58 |
+ |
|
59 |
+public: |
|
60 |
+ /// callback when requsted time reached |
|
61 |
+ virtual void timeCall(); |
|
62 |
+ |
|
63 |
+protected: |
|
64 |
+ /// update playlist |
|
65 |
+ void updatePlaylist(); |
|
66 |
+ |
|
67 |
+ /// show current frame |
|
68 |
+ void showFrame(); |
|
69 |
+ |
|
70 |
+protected: |
|
71 |
+ CallMgr &m_callMgr; ///< callback manager |
|
72 |
+ StreamMgr &m_streamMgr; ///< stream manager |
|
73 |
+ Directory m_dirBase; ///< base directory |
|
74 |
+ Directory m_dirPlaylist; ///< playlist directory |
|
75 |
+ std::string m_streamName; ///< name of output stream |
|
76 |
+ Stream *m_pStream; ///< output stream |
|
77 |
+ Playlist m_playlist; ///< current playlist |
|
78 |
+ Playlist::const_iterator m_curEntry; ///< current playlist entry |
|
79 |
+ int m_curFrame; ///< current frame in movie |
|
80 |
+ Time m_showTime; ///< when to show frame |
|
81 |
+}; // class Player |
|
82 |
+ |
|
83 |
+} // namespace Blinker |
|
84 |
+ |
|
85 |
+#endif // #ifndef PLAYER_H |
|
86 |
+ |
... | ... |
@@ -0,0 +1,75 @@ |
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 <iostream> // DEBUG |
|
7 |
+#include <set> |
|
8 |
+#include <stdlib.h> // DEBUG |
|
9 |
+ |
|
10 |
+#include <BlinkenLib/BlinkenFrame.h> |
|
11 |
+ |
|
12 |
+#include "Stream.h" |
|
13 |
+#include "StreamRecv.h" |
|
14 |
+ |
|
15 |
+namespace Blinker { |
|
16 |
+ |
|
17 |
+/// constructor |
|
18 |
+Stream::Stream() |
|
19 |
+{ |
|
20 |
+} |
|
21 |
+ |
|
22 |
+/// virtual destructor |
|
23 |
+Stream::~Stream() |
|
24 |
+{ |
|
25 |
+} |
|
26 |
+ |
|
27 |
+/** |
|
28 |
+ * @brief attach a stream receiver |
|
29 |
+ * @param[in] recv stream receiver to attach |
|
30 |
+ */ |
|
31 |
+void Stream::attach(StreamRecv *recv) |
|
32 |
+{ |
|
33 |
+ m_recvs.insert(recv); |
|
34 |
+} |
|
35 |
+ |
|
36 |
+/** |
|
37 |
+ * @brief detach a stream receiver |
|
38 |
+ * @param[in] recv stream receiver to detach |
|
39 |
+ */ |
|
40 |
+void Stream::detach(StreamRecv *recv) |
|
41 |
+{ |
|
42 |
+ m_recvs.erase(recv); |
|
43 |
+} |
|
44 |
+ |
|
45 |
+/** |
|
46 |
+ * @brief set current frame |
|
47 |
+ * @param[in] pFrame current frame |
|
48 |
+ */ |
|
49 |
+void Stream::setFrame(stBlinkenFrame *pFrame) |
|
50 |
+{ |
|
51 |
+ // DEBUG |
|
52 |
+ char *str = BlinkenFrameToString(pFrame); |
|
53 |
+ std::cout << str; |
|
54 |
+ free(str); |
|
55 |
+ |
|
56 |
+ // pass frame to all receivers |
|
57 |
+ Recvs::iterator it; |
|
58 |
+ for (it = m_recvs.begin(); it != m_recvs.end(); ++it) |
|
59 |
+ (*it)->setFrame(pFrame); |
|
60 |
+} |
|
61 |
+ |
|
62 |
+/// set current frame to none |
|
63 |
+void Stream::setNoFrame() |
|
64 |
+{ |
|
65 |
+ // DEBUG |
|
66 |
+ std::cout << "no frame" << std::endl; |
|
67 |
+ |
|
68 |
+ // pass "no frame" to all receivers |
|
69 |
+ Recvs::iterator it; |
|
70 |
+ for (it = m_recvs.begin(); it != m_recvs.end(); ++it) |
|
71 |
+ (*it)->setNoFrame(); |
|
72 |
+} |
|
73 |
+ |
|
74 |
+} // namespace Blinker |
|
75 |
+ |
... | ... |
@@ -0,0 +1,61 @@ |
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 STREAM_H |
|
7 |
+#define STREAM_H |
|
8 |
+ |
|
9 |
+#include <set> |
|
10 |
+ |
|
11 |
+#include <BlinkenLib/BlinkenFrame.h> |
|
12 |
+ |
|
13 |
+#include "StreamRecv.h" |
|
14 |
+ |
|
15 |
+namespace Blinker { |
|
16 |
+ |
|
17 |
+/// a video stream |
|
18 |
+class Stream: public StreamRecv |
|
19 |
+{ |
|
20 |
+protected: |
|
21 |
+ /// set of receivers of this stream |
|
22 |
+ typedef std::set<StreamRecv *> Recvs; |
|
23 |
+ |
|
24 |
+public: |
|
25 |
+ /// constructor |
|
26 |
+ Stream(); |
|
27 |
+ |
|
28 |
+ /// virtual destructor |
|
29 |
+ virtual ~Stream(); |
|
30 |
+ |
|
31 |
+public: |
|
32 |
+ /** |
|
33 |
+ * @brief attach a stream receiver |
|
34 |
+ * @param[in] recv stream receiver to attach |
|
35 |
+ */ |
|
36 |
+ void attach(StreamRecv *recv); |
|
37 |
+ |
|
38 |
+ /** |
|
39 |
+ * @brief detach a stream receiver |
|
40 |
+ * @param[in] recv stream receiver to detach |
|
41 |
+ */ |
|
42 |
+ void detach(StreamRecv *recv); |
|
43 |
+ |
|
44 |
+ /** |
|
45 |
+ * @brief set current frame |
|
46 |
+ * @param[in] pFrame current frame |
|
47 |
+ */ |
|
48 |
+ virtual void setFrame(stBlinkenFrame *pFrame); |
|
49 |
+ |
|
50 |
+ /// set current frame to none |
|
51 |
+ virtual void setNoFrame(); |
|
52 |
+ |
|
53 |
+protected: |
|
54 |
+ /// receivers of this stream |
|
55 |
+ Recvs m_recvs; |
|
56 |
+}; // class Stream |
|
57 |
+ |
|
58 |
+} // namespace Blinker |
|
59 |
+ |
|
60 |
+#endif // #ifndef STREAM_H |
|
61 |
+ |
... | ... |
@@ -0,0 +1,67 @@ |
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 <map> |
|
7 |
+#include <set> |
|
8 |
+#include <string> |
|
9 |
+ |
|
10 |
+#include "Stream.h" |
|
11 |
+#include "StreamMgr.h" |
|
12 |
+ |
|
13 |
+namespace Blinker { |
|
14 |
+ |
|
15 |
+/// constructor |
|
16 |
+StreamMgr::StreamMgr() |
|
17 |
+{ |
|
18 |
+} |
|
19 |
+ |
|
20 |
+/// destructor |
|
21 |
+StreamMgr::~StreamMgr() |
|
22 |
+{ |
|
23 |
+} |
|
24 |
+ |
|
25 |
+/** |
|
26 |
+ * @brief reference stream |
|
27 |
+ * @param[in] name stream name |
|
28 |
+ * @return stream |
|
29 |
+ * |
|
30 |
+ * if the stream does not exists, it is created |
|
31 |
+ */ |
|
32 |
+Stream & StreamMgr::refStream(const std::string &name) |
|
33 |
+{ |
|
34 |
+ Entry &entry = m_streams[name]; |
|
35 |
+ entry.m_refCnt++; |
|
36 |
+ return entry.m_stream; |
|
37 |
+} |
|
38 |
+ |
|
39 |
+/** |
|
40 |
+ * @brief unreference stream |
|
41 |
+ * @param[in] name stream name |
|
42 |
+ * |
|
43 |
+ * if the last reference is removed, the stream is deleted |
|
44 |
+ */ |
|
45 |
+void StreamMgr::unrefStream(const std::string &name) |
|
46 |
+{ |
|
47 |
+ StreamMap::iterator itStream = m_streams.find(name); |
|
48 |
+ if (itStream != m_streams.end()) { |
|
49 |
+ if (itStream->second.m_refCnt > 0) |
|
50 |
+ itStream->second.m_refCnt--; |
|
51 |
+ if (itStream->second.m_refCnt == 0) |
|
52 |
+ m_streams.erase(itStream); |
|
53 |
+ } |
|
54 |
+} |
|
55 |
+ |
|
56 |
+/* #################### |
|
57 |
+ # StreamMgr::Entry # |
|
58 |
+ #################### */ |
|
59 |
+ |
|
60 |
+/// constructor |
|
61 |
+StreamMgr::Entry::Entry(): |
|
62 |
+ m_refCnt(0) |
|
63 |
+{ |
|
64 |
+} |
|
65 |
+ |
|
66 |
+} // namespace Blinker |
|
67 |
+ |
... | ... |
@@ -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 STREAMMGR_H |
|
7 |
+#define STREAMMGR_H |
|
8 |
+ |
|
9 |
+#include <map> |
|
10 |
+#include <set> |
|
11 |
+#include <string> |
|
12 |
+ |
|
13 |
+#include "Stream.h" |
|
14 |
+ |
|
15 |
+namespace Blinker { |
|
16 |
+ |
|
17 |
+/// stream manager |
|
18 |
+class StreamMgr |
|
19 |
+{ |
|
20 |
+protected: |
|
21 |
+ /// stream map entry |
|
22 |
+ struct Entry { |
|
23 |
+ Stream m_stream; ///< the stream |
|
24 |
+ unsigned int m_refCnt; ///< reference count |
|
25 |
+ Entry(); ///< constructor |
|
26 |
+ }; |
|
27 |
+ |
|
28 |
+ /// map of streams |
|
29 |
+ typedef std::map<std::string, Entry> StreamMap; |
|
30 |
+ |
|
31 |
+public: |
|
32 |
+ /// constructor |
|
33 |
+ StreamMgr(); |
|
34 |
+ |
|
35 |
+ /// destructor |
|
36 |
+ ~StreamMgr(); |
|
37 |
+ |
|
38 |
+private: |
|
39 |
+ /// copy constructor disabled |
|
40 |
+ StreamMgr(const StreamMgr & that); |
|
41 |
+ |
|
42 |
+ /// assignment operator disabled |
|
43 |
+ const StreamMgr& operator=(const StreamMgr &that); |
|
44 |
+ |
|
45 |
+public: |
|
46 |
+ /** |
|
47 |
+ * @brief reference stream |
|
48 |
+ * @param[in] name stream name |
|
49 |
+ * @return stream |
|
50 |
+ * |
|
51 |
+ * if the stream does not exists, it is created |
|
52 |
+ */ |
|
53 |
+ Stream & refStream(const std::string &name); |
|
54 |
+ |
|
55 |
+ /** |
|
56 |
+ * @brief unreference stream |
|
57 |
+ * @param[in] name stream name |
|
58 |
+ * |
|
59 |
+ * if the last reference is removed, the stream is deleted |
|
60 |
+ */ |
|
61 |
+ void unrefStream(const std::string &name); |
|
62 |
+ |
|
63 |
+protected: |
|
64 |
+ /// map of streams |
|
65 |
+ StreamMap m_streams; |
|
66 |
+}; // class StreamMgr |
|
67 |
+ |
|
68 |
+} // namespace Blinker |
|
69 |
+ |
|
70 |
+#endif // #ifndef STREAMMGR_H |
|
71 |
+ |
... | ... |
@@ -0,0 +1,23 @@ |
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 <BlinkenLib/BlinkenFrame.h> |
|
7 |
+ |
|
8 |
+#include "StreamRecv.h" |
|
9 |
+ |
|
10 |
+namespace Blinker { |
|
11 |
+ |
|
12 |
+/// constructor |
|
13 |
+StreamRecv::StreamRecv() |
|
14 |
+{ |
|
15 |
+} |
|
16 |
+ |
|
17 |
+/// virtual destructor |
|
18 |
+StreamRecv::~StreamRecv() |
|
19 |
+{ |
|
20 |
+} |
|
21 |
+ |
|
22 |
+} // namespace Blinker |
|
23 |
+ |
... | ... |
@@ -0,0 +1,37 @@ |
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 STREAMRECV_H |
|
7 |
+#define STREAMRECV_H |
|
8 |
+ |
|
9 |
+#include <BlinkenLib/BlinkenFrame.h> |
|
10 |
+ |
|
11 |
+namespace Blinker { |
|
12 |
+ |
|
13 |
+/// video stream receiver interface |
|
14 |
+class StreamRecv |
|
15 |
+{ |
|
16 |
+public: |
|
17 |
+ /// constructor |
|
18 |
+ StreamRecv(); |
|
19 |
+ |
|
20 |
+ /// virtual destructor |
|
21 |
+ virtual ~StreamRecv(); |
|
22 |
+ |
|
23 |
+public: |
|
24 |
+ /** |
|
25 |
+ * @brief set current frame |
|
26 |
+ * @param[in] pFrame current frame |
|
27 |
+ */ |
|
28 |
+ virtual void setFrame(stBlinkenFrame *pFrame) = 0; |
|
29 |
+ |
|
30 |
+ /// set current frame to none |
|
31 |
+ virtual void setNoFrame() = 0; |
|
32 |
+}; // class StreamRecv |
|
33 |
+ |
|
34 |
+} // namespace Blinker |
|
35 |
+ |
|
36 |
+#endif // #ifndef STREAMRECV_H |
|
37 |
+ |
... | ... |
@@ -0,0 +1,20 @@ |
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 "TimeCallee.h" |
|
7 |
+ |
|
8 |
+namespace Blinker { |
|
9 |
+ |
|
10 |
+/// constructor |
|
11 |
+TimeCallee::TimeCallee() |
|
12 |
+{ |
|
13 |
+} |
|
14 |
+ |
|
15 |
+/// destructor |
|
16 |
+TimeCallee::~TimeCallee(){ |
|
17 |
+} |
|
18 |
+ |
|
19 |
+} // namespace Blinker |
|
20 |
+ |
... | ... |
@@ -0,0 +1,29 @@ |
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 TIMECALLEE_H |
|
7 |
+#define TIMECALLEE_H |
|
8 |
+ |
|
9 |
+namespace Blinker { |
|
10 |
+ |
|
11 |
+/// time callee interface (i.e. called at a certain time) |
|
12 |
+class TimeCallee |
|
13 |
+{ |
|
14 |
+public: |
|
15 |
+ /// constructor |
|
16 |
+ TimeCallee(); |
|
17 |
+ |
|
18 |
+ /// destructor |
|
19 |
+ virtual ~TimeCallee(); |
|
20 |
+ |
|
21 |
+public: |
|
22 |
+ /// callback when requsted time reached |
|
23 |
+ virtual void timeCall() = 0; |
|
24 |
+}; // class TimeCallee |
|
25 |
+ |
|
26 |
+} // namespace Blinker |
|
27 |
+ |
|
28 |
+#endif // #ifndef TIMECALLEE_H |
|
29 |
+ |
... | ... |
@@ -0,0 +1,19 @@ |
1 |
+#include "CallMgr.h" |
|
2 |
+#include "Directory.h" |
|
3 |
+#include "Player.h" |
|
4 |
+#include "StreamMgr.h" |
|
5 |
+ |
|
6 |
+using namespace Blinker; |
|
7 |
+ |
|
8 |
+int main() |
|
9 |
+{ |
|
10 |
+ CallMgr callMgr; |
|
11 |
+ StreamMgr streamMgr; |
|
12 |
+ |
|
13 |
+ Player player(callMgr, streamMgr, Directory("../example.cfg/players/hdl")); |
|
14 |
+ |
|
15 |
+ callMgr.run(); |
|
16 |
+ |
|
17 |
+ return 0; |
|
18 |
+} |
|
19 |
+ |
|
0 | 20 |