05eaa37f2d869264ebe895ffbc3a3e29899d0c80
Stefan Schuermans 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) 
Stefan Schuermans minor typos in comment

Stefan Schuermans authored 12 years ago

158)   } // while itSubdir itIn
Stefan Schuermans first version of canvas mod...

Stefan Schuermans authored 12 years ago

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) {
Stefan Schuermans typos in comments and docum...

Stefan Schuermans authored 12 years ago

211)     // frame available -> send it