Index: webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc |
diff --git a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc b/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc |
deleted file mode 100644 |
index e81813653bbc4f80c1fbf4cf323acd2ae66748f0..0000000000000000000000000000000000000000 |
--- a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc |
+++ /dev/null |
@@ -1,1058 +0,0 @@ |
-/* |
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
- * |
- * Use of this source code is governed by a BSD-style license |
- * that can be found in the LICENSE file in the root of the source |
- * tree. An additional intellectual property rights grant can be found |
- * in the file PATENTS. All contributing project authors may |
- * be found in the AUTHORS file in the root of the source tree. |
- */ |
- |
-#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h" |
- |
-#include <math.h> |
-#include <stdio.h> |
- |
-#include <algorithm> |
-#include <sstream> |
- |
-#ifdef MATLAB |
-#include "engine.h" // NOLINT(build/include) |
-#endif |
- |
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
-#include "webrtc/system_wrappers/include/event_wrapper.h" |
-#include "webrtc/system_wrappers/include/tick_util.h" |
- |
-using webrtc::CriticalSectionScoped; |
-using webrtc::CriticalSectionWrapper; |
-using webrtc::EventWrapper; |
-using webrtc::TickTime; |
- |
-#ifdef MATLAB |
-MatlabEngine eng; |
- |
-MatlabLine::MatlabLine(int maxLen /*= -1*/, const char *plotAttrib /*= NULL*/, const char *name /*= NULL*/) |
-: |
-_xArray(NULL), |
-_yArray(NULL), |
-_maxLen(maxLen), |
-_plotAttribute(), |
-_name() |
-{ |
- if (_maxLen > 0) |
- { |
- _xArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL); |
- _yArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL); |
- } |
- |
- if (plotAttrib) |
- { |
- _plotAttribute = plotAttrib; |
- } |
- |
- if (name) |
- { |
- _name = name; |
- } |
-} |
- |
-MatlabLine::~MatlabLine() |
-{ |
- if (_xArray != NULL) |
- { |
- mxDestroyArray(_xArray); |
- } |
- if (_yArray != NULL) |
- { |
- mxDestroyArray(_yArray); |
- } |
-} |
- |
-void MatlabLine::Append(double x, double y) |
-{ |
- if (_maxLen > 0 && _xData.size() > static_cast<uint32_t>(_maxLen)) |
- { |
- _xData.resize(_maxLen); |
- _yData.resize(_maxLen); |
- } |
- |
- _xData.push_front(x); |
- _yData.push_front(y); |
-} |
- |
- |
-// append y-data with running integer index as x-data |
-void MatlabLine::Append(double y) |
-{ |
- if (_xData.empty()) |
- { |
- // first element is index 0 |
- Append(0, y); |
- } |
- else |
- { |
- // take last x-value and increment |
- double temp = _xData.back(); // last x-value |
- Append(temp + 1, y); |
- } |
-} |
- |
- |
-void MatlabLine::SetMaxLen(int maxLen) |
-{ |
- if (maxLen <= 0) |
- { |
- // means no maxLen |
- _maxLen = -1; |
- } |
- else |
- { |
- _maxLen = maxLen; |
- |
- if (_xArray != NULL) |
- { |
- mxDestroyArray(_xArray); |
- mxDestroyArray(_yArray); |
- } |
- _xArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL); |
- _yArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL); |
- |
- maxLen = ((unsigned int)maxLen <= _xData.size()) ? maxLen : (int)_xData.size(); |
- _xData.resize(maxLen); |
- _yData.resize(maxLen); |
- |
- //// reserve the right amount of memory |
- //_xData.reserve(_maxLen); |
- //_yData.reserve(_maxLen); |
- } |
-} |
- |
-void MatlabLine::SetAttribute(char *plotAttrib) |
-{ |
- _plotAttribute = plotAttrib; |
-} |
- |
-void MatlabLine::SetName(char *name) |
-{ |
- _name = name; |
-} |
- |
-void MatlabLine::GetPlotData(mxArray** xData, mxArray** yData) |
-{ |
- // Make sure we have enough Matlab allocated memory. |
- // Assuming both arrays (x and y) are of the same size. |
- if (_xData.empty()) |
- { |
- return; // No data |
- } |
- unsigned int size = 0; |
- if (_xArray != NULL) |
- { |
- size = (unsigned int)mxGetNumberOfElements(_xArray); |
- } |
- if (size < _xData.size()) |
- { |
- if (_xArray != NULL) |
- { |
- mxDestroyArray(_xArray); |
- mxDestroyArray(_yArray); |
- } |
- _xArray = mxCreateDoubleMatrix(1, _xData.size(), mxREAL); |
- _yArray = mxCreateDoubleMatrix(1, _yData.size(), mxREAL); |
- } |
- |
- if (!_xData.empty()) |
- { |
- double* x = mxGetPr(_xArray); |
- |
- std::list<double>::iterator it = _xData.begin(); |
- |
- for (int i = 0; it != _xData.end(); it++, i++) |
- { |
- x[i] = *it; |
- } |
- } |
- |
- if (!_yData.empty()) |
- { |
- double* y = mxGetPr(_yArray); |
- |
- std::list<double>::iterator it = _yData.begin(); |
- |
- for (int i = 0; it != _yData.end(); it++, i++) |
- { |
- y[i] = *it; |
- } |
- } |
- *xData = _xArray; |
- *yData = _yArray; |
-} |
- |
-std::string MatlabLine::GetXName() |
-{ |
- std::ostringstream xString; |
- xString << "x_" << _name; |
- return xString.str(); |
-} |
- |
-std::string MatlabLine::GetYName() |
-{ |
- std::ostringstream yString; |
- yString << "y_" << _name; |
- return yString.str(); |
-} |
- |
-std::string MatlabLine::GetPlotString() |
-{ |
- |
- std::ostringstream s; |
- |
- if (_xData.size() == 0) |
- { |
- s << "[0 1], [0 1]"; // To get an empty plot |
- } |
- else |
- { |
- s << GetXName() << "(1:" << _xData.size() << "),"; |
- s << GetYName() << "(1:" << _yData.size() << ")"; |
- } |
- |
- s << ", '"; |
- s << _plotAttribute; |
- s << "'"; |
- |
- return s.str(); |
-} |
- |
-std::string MatlabLine::GetRefreshString() |
-{ |
- std::ostringstream s; |
- |
- if (_xData.size() > 0) |
- { |
- s << "set(h,'xdata',"<< GetXName() <<"(1:" << _xData.size() << "),'ydata',"<< GetYName() << "(1:" << _yData.size() << "));"; |
- } |
- else |
- { |
- s << "set(h,'xdata',[NaN],'ydata',[NaN]);"; |
- } |
- return s.str(); |
-} |
- |
-std::string MatlabLine::GetLegendString() |
-{ |
- return ("'" + _name + "'"); |
-} |
- |
-bool MatlabLine::hasLegend() |
-{ |
- return (!_name.empty()); |
-} |
- |
- |
-// remove data points, but keep attributes |
-void MatlabLine::Reset() |
-{ |
- _xData.clear(); |
- _yData.clear(); |
-} |
- |
- |
-void MatlabLine::UpdateTrendLine(MatlabLine * sourceData, double slope, double offset) |
-{ |
- Reset(); // reset data, not attributes and name |
- |
- double thexMin = sourceData->xMin(); |
- double thexMax = sourceData->xMax(); |
- Append(thexMin, thexMin * slope + offset); |
- Append(thexMax, thexMax * slope + offset); |
-} |
- |
-double MatlabLine::xMin() |
-{ |
- if (!_xData.empty()) |
- { |
- std::list<double>::iterator theStart = _xData.begin(); |
- std::list<double>::iterator theEnd = _xData.end(); |
- return(*min_element(theStart, theEnd)); |
- } |
- return (0.0); |
-} |
- |
-double MatlabLine::xMax() |
-{ |
- if (!_xData.empty()) |
- { |
- std::list<double>::iterator theStart = _xData.begin(); |
- std::list<double>::iterator theEnd = _xData.end(); |
- return(*max_element(theStart, theEnd)); |
- } |
- return (0.0); |
-} |
- |
-double MatlabLine::yMin() |
-{ |
- if (!_yData.empty()) |
- { |
- std::list<double>::iterator theStart = _yData.begin(); |
- std::list<double>::iterator theEnd = _yData.end(); |
- return(*min_element(theStart, theEnd)); |
- } |
- return (0.0); |
-} |
- |
-double MatlabLine::yMax() |
-{ |
- if (!_yData.empty()) |
- { |
- std::list<double>::iterator theStart = _yData.begin(); |
- std::list<double>::iterator theEnd = _yData.end(); |
- return(*max_element(theStart, theEnd)); |
- } |
- return (0.0); |
-} |
- |
- |
- |
-MatlabTimeLine::MatlabTimeLine(int horizonSeconds /*= -1*/, const char *plotAttrib /*= NULL*/, |
- const char *name /*= NULL*/, |
- int64_t refTimeMs /* = -1*/) |
- : |
-_timeHorizon(horizonSeconds), |
-MatlabLine(-1, plotAttrib, name) // infinite number of elements |
-{ |
- if (refTimeMs < 0) |
- _refTimeMs = TickTime::MillisecondTimestamp(); |
- else |
- _refTimeMs = refTimeMs; |
-} |
- |
-void MatlabTimeLine::Append(double y) |
-{ |
- MatlabLine::Append(static_cast<double>(TickTime::MillisecondTimestamp() - _refTimeMs) / 1000.0, y); |
- |
- PurgeOldData(); |
-} |
- |
- |
-void MatlabTimeLine::PurgeOldData() |
-{ |
- if (_timeHorizon > 0) |
- { |
- // remove old data |
- double historyLimit = static_cast<double>(TickTime::MillisecondTimestamp() - _refTimeMs) / 1000.0 |
- - _timeHorizon; // remove data points older than this |
- |
- std::list<double>::reverse_iterator ritx = _xData.rbegin(); |
- uint32_t removeCount = 0; |
- while (ritx != _xData.rend()) |
- { |
- if (*ritx >= historyLimit) |
- { |
- break; |
- } |
- ritx++; |
- removeCount++; |
- } |
- if (removeCount == 0) |
- { |
- return; |
- } |
- |
- // remove the range [begin, it). |
- //if (removeCount > 10) |
- //{ |
- // printf("Removing %lu elements\n", removeCount); |
- //} |
- _xData.resize(_xData.size() - removeCount); |
- _yData.resize(_yData.size() - removeCount); |
- } |
-} |
- |
- |
-int64_t MatlabTimeLine::GetRefTime() |
-{ |
- return(_refTimeMs); |
-} |
- |
- |
- |
- |
-MatlabPlot::MatlabPlot() |
-: |
-_figHandle(-1), |
-_smartAxis(false), |
-_critSect(CriticalSectionWrapper::CreateCriticalSection()), |
-_timeToPlot(false), |
-_plotting(false), |
-_enabled(true), |
-_firstPlot(true), |
-_legendEnabled(true), |
-_donePlottingEvent(EventWrapper::Create()) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- _xlim[0] = 0; |
- _xlim[1] = 0; |
- _ylim[0] = 0; |
- _ylim[1] = 0; |
- |
-#ifdef PLOT_TESTING |
- _plotStartTime = -1; |
- _plotDelay = 0; |
-#endif |
- |
-} |
- |
- |
-MatlabPlot::~MatlabPlot() |
-{ |
- _critSect->Enter(); |
- |
- // delete all line objects |
- while (!_line.empty()) |
- { |
- delete *(_line.end() - 1); |
- _line.pop_back(); |
- } |
- |
- delete _critSect; |
- delete _donePlottingEvent; |
-} |
- |
- |
-int MatlabPlot::AddLine(int maxLen /*= -1*/, const char *plotAttrib /*= NULL*/, const char *name /*= NULL*/) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- if (!_enabled) |
- { |
- return -1; |
- } |
- |
- MatlabLine *newLine = new MatlabLine(maxLen, plotAttrib, name); |
- _line.push_back(newLine); |
- |
- return (static_cast<int>(_line.size() - 1)); // index of newly inserted line |
-} |
- |
- |
-int MatlabPlot::AddTimeLine(int maxLen /*= -1*/, const char *plotAttrib /*= NULL*/, const char *name /*= NULL*/, |
- int64_t refTimeMs /*= -1*/) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- if (!_enabled) |
- { |
- return -1; |
- } |
- |
- MatlabTimeLine *newLine = new MatlabTimeLine(maxLen, plotAttrib, name, refTimeMs); |
- _line.push_back(newLine); |
- |
- return (static_cast<int>(_line.size() - 1)); // index of newly inserted line |
-} |
- |
- |
-int MatlabPlot::GetLineIx(const char *name) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- if (!_enabled) |
- { |
- return -1; |
- } |
- |
- // search the list for a matching line name |
- std::vector<MatlabLine*>::iterator it = _line.begin(); |
- bool matchFound = false; |
- int lineIx = 0; |
- |
- for (; it != _line.end(); it++, lineIx++) |
- { |
- if ((*it)->_name == name) |
- { |
- matchFound = true; |
- break; |
- } |
- } |
- |
- if (matchFound) |
- { |
- return (lineIx); |
- } |
- else |
- { |
- return (-1); |
- } |
-} |
- |
- |
-void MatlabPlot::Append(int lineIndex, double x, double y) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- if (!_enabled) |
- { |
- return; |
- } |
- |
- // sanity for index |
- if (lineIndex < 0 || lineIndex >= static_cast<int>(_line.size())) |
- { |
- throw "Line index out of range"; |
- exit(1); |
- } |
- |
- return (_line[lineIndex]->Append(x, y)); |
-} |
- |
- |
-void MatlabPlot::Append(int lineIndex, double y) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- if (!_enabled) |
- { |
- return; |
- } |
- |
- // sanity for index |
- if (lineIndex < 0 || lineIndex >= static_cast<int>(_line.size())) |
- { |
- throw "Line index out of range"; |
- exit(1); |
- } |
- |
- return (_line[lineIndex]->Append(y)); |
-} |
- |
- |
-int MatlabPlot::Append(const char *name, double x, double y) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- if (!_enabled) |
- { |
- return -1; |
- } |
- |
- // search the list for a matching line name |
- int lineIx = GetLineIx(name); |
- |
- if (lineIx < 0) //(!matchFound) |
- { |
- // no match; append new line |
- lineIx = AddLine(-1, NULL, name); |
- } |
- |
- // append data to line |
- Append(lineIx, x, y); |
- return (lineIx); |
-} |
- |
-int MatlabPlot::Append(const char *name, double y) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- if (!_enabled) |
- { |
- return -1; |
- } |
- |
- // search the list for a matching line name |
- int lineIx = GetLineIx(name); |
- |
- if (lineIx < 0) //(!matchFound) |
- { |
- // no match; append new line |
- lineIx = AddLine(-1, NULL, name); |
- } |
- |
- // append data to line |
- Append(lineIx, y); |
- return (lineIx); |
-} |
- |
-int MatlabPlot::Length(char *name) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- if (!_enabled) |
- { |
- return -1; |
- } |
- |
- int ix = GetLineIx(name); |
- if (ix >= 0) |
- { |
- return (static_cast<int>(_line[ix]->_xData.size())); |
- } |
- else |
- { |
- return (-1); |
- } |
-} |
- |
- |
-void MatlabPlot::SetPlotAttribute(char *name, char *plotAttrib) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- if (!_enabled) |
- { |
- return; |
- } |
- |
- int lineIx = GetLineIx(name); |
- |
- if (lineIx >= 0) |
- { |
- _line[lineIx]->SetAttribute(plotAttrib); |
- } |
-} |
- |
-// Must be called under critical section _critSect |
-void MatlabPlot::UpdateData(Engine* ep) |
-{ |
- if (!_enabled) |
- { |
- return; |
- } |
- |
- for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++) |
- { |
- mxArray* xData = NULL; |
- mxArray* yData = NULL; |
- (*it)->GetPlotData(&xData, &yData); |
- if (xData != NULL) |
- { |
- std::string xName = (*it)->GetXName(); |
- std::string yName = (*it)->GetYName(); |
- _critSect->Leave(); |
-#ifdef MATLAB6 |
- mxSetName(xData, xName.c_str()); |
- mxSetName(yData, yName.c_str()); |
- engPutArray(ep, xData); |
- engPutArray(ep, yData); |
-#else |
- int ret = engPutVariable(ep, xName.c_str(), xData); |
- assert(ret == 0); |
- ret = engPutVariable(ep, yName.c_str(), yData); |
- assert(ret == 0); |
-#endif |
- _critSect->Enter(); |
- } |
- } |
-} |
- |
-bool MatlabPlot::GetPlotCmd(std::ostringstream & cmd, Engine* ep) |
-{ |
- _critSect->Enter(); |
- |
- if (!DataAvailable()) |
- { |
- return false; |
- } |
- |
- if (_firstPlot) |
- { |
- GetPlotCmd(cmd); |
- _firstPlot = false; |
- } |
- else |
- { |
- GetRefreshCmd(cmd); |
- } |
- |
- UpdateData(ep); |
- |
- _critSect->Leave(); |
- |
- return true; |
-} |
- |
-// Call inside critsect |
-void MatlabPlot::GetPlotCmd(std::ostringstream & cmd) |
-{ |
- // we have something to plot |
- // empty the stream |
- cmd.str(""); // (this seems to be the only way) |
- |
- cmd << "figure; h" << _figHandle << "= plot("; |
- |
- // first line |
- std::vector<MatlabLine*>::iterator it = _line.begin(); |
- cmd << (*it)->GetPlotString(); |
- |
- it++; |
- |
- // remaining lines |
- for (; it != _line.end(); it++) |
- { |
- cmd << ", "; |
- cmd << (*it)->GetPlotString(); |
- } |
- |
- cmd << "); "; |
- |
- if (_legendEnabled) |
- { |
- GetLegendCmd(cmd); |
- } |
- |
- if (_smartAxis) |
- { |
- double xMin = _xlim[0]; |
- double xMax = _xlim[1]; |
- double yMax = _ylim[1]; |
- for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++) |
- { |
- xMax = std::max(xMax, (*it)->xMax()); |
- xMin = std::min(xMin, (*it)->xMin()); |
- |
- yMax = std::max(yMax, (*it)->yMax()); |
- yMax = std::max(yMax, fabs((*it)->yMin())); |
- } |
- _xlim[0] = xMin; |
- _xlim[1] = xMax; |
- _ylim[0] = -yMax; |
- _ylim[1] = yMax; |
- |
- cmd << "axis([" << _xlim[0] << ", " << _xlim[1] << ", " << _ylim[0] << ", " << _ylim[1] << "]);"; |
- } |
- |
- int i=1; |
- for (it = _line.begin(); it != _line.end(); i++, it++) |
- { |
- cmd << "set(h" << _figHandle << "(" << i << "), 'Tag', " << (*it)->GetLegendString() << ");"; |
- } |
-} |
- |
-// Call inside critsect |
-void MatlabPlot::GetRefreshCmd(std::ostringstream & cmd) |
-{ |
- cmd.str(""); // (this seems to be the only way) |
- std::vector<MatlabLine*>::iterator it = _line.begin(); |
- for (it = _line.begin(); it != _line.end(); it++) |
- { |
- cmd << "h = findobj(0, 'Tag', " << (*it)->GetLegendString() << ");"; |
- cmd << (*it)->GetRefreshString(); |
- } |
- //if (_legendEnabled) |
- //{ |
- // GetLegendCmd(cmd); |
- //} |
-} |
- |
-void MatlabPlot::GetLegendCmd(std::ostringstream & cmd) |
-{ |
- std::vector<MatlabLine*>::iterator it = _line.begin(); |
- bool anyLegend = false; |
- for (; it != _line.end(); it++) |
- { |
- anyLegend = anyLegend || (*it)->hasLegend(); |
- } |
- if (anyLegend) |
- { |
- // create the legend |
- |
- cmd << "legend(h" << _figHandle << ",{"; |
- |
- |
- // iterate lines |
- int i = 0; |
- for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++) |
- { |
- if (i > 0) |
- { |
- cmd << ", "; |
- } |
- cmd << (*it)->GetLegendString(); |
- i++; |
- } |
- |
- cmd << "}, 2); "; // place legend in upper-left corner |
- } |
-} |
- |
-// Call inside critsect |
-bool MatlabPlot::DataAvailable() |
-{ |
- if (!_enabled) |
- { |
- return false; |
- } |
- |
- for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++) |
- { |
- (*it)->PurgeOldData(); |
- } |
- |
- return true; |
-} |
- |
-void MatlabPlot::Plot() |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- _timeToPlot = true; |
- |
-#ifdef PLOT_TESTING |
- _plotStartTime = TickTime::MillisecondTimestamp(); |
-#endif |
-} |
- |
- |
-void MatlabPlot::Reset() |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- _enabled = true; |
- |
- for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++) |
- { |
- (*it)->Reset(); |
- } |
- |
-} |
- |
-void MatlabPlot::SetFigHandle(int handle) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- if (handle > 0) |
- _figHandle = handle; |
-} |
- |
-bool |
-MatlabPlot::TimeToPlot() |
-{ |
- CriticalSectionScoped cs(_critSect); |
- return _enabled && _timeToPlot; |
-} |
- |
-void |
-MatlabPlot::Plotting() |
-{ |
- CriticalSectionScoped cs(_critSect); |
- _plotting = true; |
-} |
- |
-void |
-MatlabPlot::DonePlotting() |
-{ |
- CriticalSectionScoped cs(_critSect); |
- _timeToPlot = false; |
- _plotting = false; |
- _donePlottingEvent->Set(); |
-} |
- |
-void |
-MatlabPlot::DisablePlot() |
-{ |
- _critSect->Enter(); |
- while (_plotting) |
- { |
- _critSect->Leave(); |
- _donePlottingEvent->Wait(WEBRTC_EVENT_INFINITE); |
- _critSect->Enter(); |
- } |
- _enabled = false; |
-} |
- |
-int MatlabPlot::MakeTrend(const char *sourceName, const char *trendName, double slope, double offset, const char *plotAttrib) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- int sourceIx; |
- int trendIx; |
- |
- sourceIx = GetLineIx(sourceName); |
- if (sourceIx < 0) |
- { |
- // could not find source |
- return (-1); |
- } |
- |
- trendIx = GetLineIx(trendName); |
- if (trendIx < 0) |
- { |
- // no trend found; add new line |
- trendIx = AddLine(2 /*maxLen*/, plotAttrib, trendName); |
- } |
- |
- _line[trendIx]->UpdateTrendLine(_line[sourceIx], slope, offset); |
- |
- return (trendIx); |
- |
-} |
- |
- |
-MatlabEngine::MatlabEngine() |
-: |
-_critSect(CriticalSectionWrapper::CreateCriticalSection()), |
-_eventPtr(NULL), |
-_running(false), |
-_numPlots(0) |
-{ |
- _eventPtr = EventWrapper::Create(); |
- |
- _plotThread(MatlabEngine::PlotThread, this, |
- kLowPriority, "MatlabPlot"); |
- _running = true; |
- _plotThread->Start(); |
-} |
- |
-MatlabEngine::~MatlabEngine() |
-{ |
- _critSect->Enter(); |
- |
- if (_plotThread) |
- { |
- _running = false; |
- _eventPtr->Set(); |
- |
- _plotThread->Stop(); |
- } |
- |
- _plots.clear(); |
- |
- delete _eventPtr; |
- _eventPtr = NULL; |
- |
- _critSect->Leave(); |
- delete _critSect; |
- |
-} |
- |
-MatlabPlot * MatlabEngine::NewPlot(MatlabPlot *newPlot) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- //MatlabPlot *newPlot = new MatlabPlot(); |
- |
- if (newPlot) |
- { |
- newPlot->SetFigHandle(++_numPlots); // first plot is number 1 |
- _plots.push_back(newPlot); |
- } |
- |
- return (newPlot); |
- |
-} |
- |
- |
-void MatlabEngine::DeletePlot(MatlabPlot *plot) |
-{ |
- CriticalSectionScoped cs(_critSect); |
- |
- if (plot == NULL) |
- { |
- return; |
- } |
- |
- std::vector<MatlabPlot *>::iterator it; |
- for (it = _plots.begin(); it < _plots.end(); it++) |
- { |
- if (plot == *it) |
- { |
- break; |
- } |
- } |
- |
- assert (plot == *it); |
- |
- (*it)->DisablePlot(); |
- |
- _plots.erase(it); |
- --_numPlots; |
- |
- delete plot; |
-} |
- |
- |
-bool MatlabEngine::PlotThread(void *obj) |
-{ |
- if (!obj) |
- { |
- return (false); |
- } |
- |
- MatlabEngine *eng = (MatlabEngine *) obj; |
- |
- Engine *ep = engOpen(NULL); |
- if (!ep) |
- { |
- throw "Cannot open Matlab engine"; |
- return (false); |
- } |
- |
- engSetVisible(ep, true); |
- engEvalString(ep, "close all;"); |
- |
- while (eng->_running) |
- { |
- eng->_critSect->Enter(); |
- |
- // iterate through all plots |
- for (unsigned int ix = 0; ix < eng->_plots.size(); ix++) |
- { |
- MatlabPlot *plot = eng->_plots[ix]; |
- if (plot->TimeToPlot()) |
- { |
- plot->Plotting(); |
- eng->_critSect->Leave(); |
- std::ostringstream cmd; |
- |
- if (engEvalString(ep, cmd.str().c_str())) |
- { |
- // engine dead |
- return (false); |
- } |
- |
- // empty the stream |
- cmd.str(""); // (this seems to be the only way) |
- if (plot->GetPlotCmd(cmd, ep)) |
- { |
- // things to plot, we have already accessed what we need in the plot |
- plot->DonePlotting(); |
- |
- int64_t start = TickTime::MillisecondTimestamp(); |
- // plot it |
- int ret = engEvalString(ep, cmd.str().c_str()); |
- printf("time=%I64i\n", TickTime::MillisecondTimestamp() - start); |
- if (ret) |
- { |
- // engine dead |
- return (false); |
- } |
- |
-#ifdef PLOT_TESTING |
- if(plot->_plotStartTime >= 0) |
- { |
- plot->_plotDelay = TickTime::MillisecondTimestamp() - plot->_plotStartTime; |
- plot->_plotStartTime = -1; |
- } |
-#endif |
- } |
- eng->_critSect->Enter(); |
- } |
- } |
- |
- eng->_critSect->Leave(); |
- // wait a while |
- eng->_eventPtr->Wait(66); // 33 ms |
- } |
- |
- if (ep) |
- { |
- engClose(ep); |
- ep = NULL; |
- } |
- |
- return (true); |
- |
-} |
- |
-#endif // MATLAB |