BlinkenArea - GitList
Repositories
Blog
Wiki
Blinker
Code
Commits
Branches
Tags
Search
Tree:
f0c104c
Branches
Tags
master
Blinker
src
noarch
Canvas.cpp
implemented specialized setting files for different data types, simplified input/output stream handling in modules
Stefan Schuermans
commited
f0c104c
at 2011-12-04 20:10:37
Canvas.cpp
Blame
History
Raw
/* Blinker Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org> Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html a blinkenarea.org project */ #include <list> #include <string> #include <BlinkenLib/BlinkenFrame.h> #include "CallMgr.h" #include "Canvas.h" #include "CanvasInput.h" #include "Directory.h" #include "File.h" #include "Format.h" #include "FormatFile.h" #include "Module.h" #include "OutStreamFile.h" #include "StreamMgr.h" #include "StreamRecv.h" namespace Blinker { /** * @brief constructor * @param[in] callMgr callback manager * @param[in] streamMgr stream manager * @param[in] dirBase base directory */ Canvas::Canvas(CallMgr &callMgr, StreamMgr &streamMgr, const Directory &dirBase): Module(callMgr, streamMgr, dirBase), m_fileFormat(dirBase.getFile("format")), m_dirInputs(dirBase.getSubdir("inputs")), m_fileOutStream(dirBase.getFile("outstream"), streamMgr), m_pCanvas(NULL), m_canvasHasFrame(false) { // set up createCanvas(); updateInListFull(); } /// virtual destructor Canvas::~Canvas() { // clean up while (!m_inList.empty()) { delete m_inList.back().m_pInput; m_inList.pop_back(); } destroyCanvas(); } /// check for update of configuration void Canvas::updateConfig() { // format file was modified -> re-create canvas if (m_fileFormat.checkModified()) { createCanvas(); } // input list update (directory modified -> full, otherwise -> light) if (m_dirInputs.checkModified()) updateInListFull(); else updateInListLight(); // output stream name file was modified -> re-get output stream if (m_fileOutStream.checkModified()) m_fileOutStream.update(); } /// (re-)create canvas void Canvas::createCanvas() { // get rid of old canvas destroyCanvas(); // read format from format file m_fileFormat.update(); if (!m_fileFormat.m_valid) return; // create frame m_pCanvas = BlinkenFrameNew(m_fileFormat.m_obj.m_height, m_fileFormat.m_obj.m_width, m_fileFormat.m_obj.m_channels, m_fileFormat.m_obj.m_maxval, 1); m_canvasHasFrame = false; } /// tear down canvas void Canvas::destroyCanvas() { if (m_pCanvas) { BlinkenFrameFree(m_pCanvas); m_pCanvas = NULL; m_canvasHasFrame = false; } } /// light update of input list, i.e. check all entries in current input list void Canvas::updateInListLight() { // walk through all inputs in input list and check for modification InList::iterator itIn; for (itIn = m_inList.begin(); itIn != m_inList.end(); ++itIn) itIn->m_pInput->updateConfig(); } /// full update of input list, i.e. scan subdirs in input list directory void Canvas::updateInListFull() { // get list of subdirs in input directory typedef std::list<std::string> Subdirlist; Subdirlist curSubdirs; m_dirInputs.getEntries(Directory::TypeSubdir, curSubdirs); // walk through current input list and subdir list simultaneously Subdirlist::const_iterator itSubdir = curSubdirs.begin(); InList::iterator itIn = m_inList.begin(); while (itSubdir != curSubdirs.end() || itIn != m_inList.end()) { // new input inserted if (itIn == m_inList.end() || (itSubdir != curSubdirs.end() && *itSubdir < itIn->m_name)) { // create input object InEntry inEntry(*itSubdir); inEntry.m_pInput = new Input(*this, m_dirInputs.getSubdir(*itSubdir)); if (inEntry.m_pInput) // insert input list entry m_inList.insert(itIn, inEntry); // advance to next subdir ++itSubdir; } // input removed else if (itSubdir == curSubdirs.end() || *itSubdir > itIn->m_name) { // remove input delete itIn->m_pInput; itIn = m_inList.erase(itIn); // do not advance to next subdir } // input stayed in input list else { // check for update itIn->m_pInput->updateConfig(); // advance to next file and next entry ++itSubdir; ++itIn; } } // while itSubdir itIn } /// notfication to redraw (called by inputs) void Canvas::redraw() { // do nothing if there is no canvas if (!m_pCanvas) return; // black background BlinkenFrameClear(m_pCanvas); m_canvasHasFrame = false; // no frame on canvas yet // tell all inputs to draw on canvas InList::iterator itIn; for (itIn = m_inList.begin(); itIn != m_inList.end(); ++itIn) if (itIn->m_pInput->draw()) m_canvasHasFrame = true; // drawing successful -> there is a frame now // send current frame to stream sendFrame(); } /// send current frame to output stream void Canvas::sendFrame() { // frame available -> send it if (m_canvasHasFrame) m_fileOutStream.setFrame(m_pCanvas); // no frame available -> send this information else m_fileOutStream.setFrame(NULL); } /* ################### # Canvas::InEntry # ################### */ /// constructor Canvas::InEntry::InEntry(const std::string &name): m_name(name), m_pInput(NULL) { } } // namespace Blinker