first version of canvas mod...
Stefan Schuermans authored 12 years ago
|
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)
11) #include "CallMgr.h"
12) #include "Canvas.h"
13) #include "CanvasInput.h"
14) #include "Directory.h"
15) #include "File.h"
16) #include "Format.h"
17) #include "Module.h"
18) #include "SettingFile.h"
19) #include "StreamMgr.h"
20) #include "StreamRecv.h"
21)
22) namespace Blinker {
23)
24) /**
25) * @brief constructor
26) * @param[in] callMgr callback manager
27) * @param[in] streamMgr stream manager
28) * @param[in] dirBase base directory
29) */
30) Canvas::Canvas(CallMgr &callMgr, StreamMgr &streamMgr, const Directory &dirBase):
31) Module(callMgr, streamMgr, dirBase),
32) m_fileFormat(dirBase.getFile("format")),
33) m_dirInputs(dirBase.getSubdir("inputs")),
34) m_fileOutStream(dirBase.getFile("outstream")),
35) m_pCanvas(NULL),
36) m_canvasHasFrame(false),
37) m_pOutStream(NULL)
38) {
39) // set up
40) createCanvas();
41) updateInListFull();
42) getOutStream();
43) }
44)
45) /// virtual destructor
46) Canvas::~Canvas()
47) {
48) // clean up
49) releaseOutStream();
50) while (!m_inList.empty()) {
51) delete m_inList.back().m_pInput;
52) m_inList.pop_back();
53) }
54) destroyCanvas();
55) }
56)
57) /// check for update of configuration
58) void Canvas::updateConfig()
59) {
60) // format file was modified -> re-create canvas
61) if (m_fileFormat.checkModified()) {
62) createCanvas();
63) }
64)
65) // input list update (directory modified -> full, otherwise -> light)
66) if (m_dirInputs.checkModified())
67) updateInListFull();
68) else
69) updateInListLight();
70)
71) // output stream name file was modified -> re-get output stream
72) if (m_fileOutStream.checkModified()) {
73) releaseOutStream();
74) getOutStream();
75) }
76) }
77)
78) /// (re-)create canvas
79) void Canvas::createCanvas()
80) {
81) std::string strFormat;
82)
83) // get rid of old canvas
84) destroyCanvas();
85)
86) // read format from format file
87) if (!m_fileFormat.getStr(strFormat) || !m_format.fromStr(strFormat))
88) return;
89)
90) // create frame
91) m_pCanvas = BlinkenFrameNew(m_format.m_height, m_format.m_width,
92) m_format.m_channels, m_format.m_maxval, 1);
93) m_canvasHasFrame = 0;
94) }
95)
96) /// tear down canvas
97) void Canvas::destroyCanvas()
98) {
99) if (m_pCanvas) {
100) BlinkenFrameFree(m_pCanvas);
101) m_pCanvas = NULL;
102) m_canvasHasFrame = 0;
103) }
104) }
105)
106) /// light update of input list, i.e. check all entries in current input list
107) void Canvas::updateInListLight()
108) {
109) // walk through all inputs in input list and check for modification
110) InList::iterator itIn;
111) for (itIn = m_inList.begin(); itIn != m_inList.end(); ++itIn)
112) itIn->m_pInput->updateConfig();
113) }
114)
115) /// full update of input list, i.e. scan subdirs in input list directory
116) void Canvas::updateInListFull()
117) {
118) // get list of subdirs in input directory
119) typedef std::list<std::string> Subdirlist;
120) Subdirlist curSubdirs;
121) m_dirInputs.getEntries(Directory::TypeSubdir, curSubdirs);
122)
123) // walk through current input list and subdir list simultaneously
124) Subdirlist::const_iterator itSubdir = curSubdirs.begin();
125) InList::iterator itIn = m_inList.begin();
126) while (itSubdir != curSubdirs.end() || itIn != m_inList.end()) {
127)
128) // new input inserted
129) if (itIn == m_inList.end() ||
130) (itSubdir != curSubdirs.end() && *itSubdir < itIn->m_name)) {
131) // create input object
132) InEntry inEntry(*itSubdir);
133) inEntry.m_pInput = new Input(*this, m_dirInputs.getSubdir(*itSubdir));
134) if (inEntry.m_pInput)
135) // insert input list entry
136) m_inList.insert(itIn, inEntry);
137) // advance to next subdir
138) ++itSubdir;
139) }
140)
141) // input removed
142) else if (itSubdir == curSubdirs.end() || *itSubdir > itIn->m_name) {
143) // remove input
144) delete itIn->m_pInput;
145) itIn = m_inList.erase(itIn);
146) // do not advance to next subdir
147) }
148)
149) // input stayed in input list
150) else {
151) // check for update
152) itIn->m_pInput->updateConfig();
153) // advance to next file and next entry
154) ++itSubdir;
155) ++itIn;
156) }
157)
158) } // while itFile itIn
159) }
160)
161) /// get output stream
162) void Canvas::getOutStream()
163) {
164) // get name of output stream
165) m_fileOutStream.getStr(m_nameOutStream);
166)
167) // get output stream
168) m_pOutStream = &m_streamMgr.refStream(m_nameOutStream);
169)
170) // send current frame to stream
171) sendFrame();
172) }
173)
174) /// release output stream
175) void Canvas::releaseOutStream()
176) {
177) // send no frame information
178) if (m_pOutStream)
179) m_pOutStream->setNoFrame();
180)
181) // unreference output stream
182) m_pOutStream = NULL;
183) m_streamMgr.unrefStream(m_nameOutStream);
184) }
185)
186) /// notfication to redraw (called by inputs)
187) void Canvas::redraw()
188) {
189) // do nothing if there is no canvas
190) if (!m_pCanvas)
191) return;
192)
193) // black background
194) BlinkenFrameClear(m_pCanvas);
195) m_canvasHasFrame = false; // no frame on canvas yet
196)
197) // tell all inputs to draw on canvas
198) InList::iterator itIn;
199) for (itIn = m_inList.begin(); itIn != m_inList.end(); ++itIn)
200) if (itIn->m_pInput->draw())
201) m_canvasHasFrame = true; // drawing successful -> there is a frame now
202)
203) // send current frame to stream
204) sendFrame();
205) }
206)
207) /// send current frame to output stream
208) void Canvas::sendFrame()
209) {
210) if (m_pOutStream) {
|