2007-01-20 03:53:23 +08:00
|
|
|
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2007 Robert Osfield
|
|
|
|
*
|
|
|
|
* This library is open source and may be redistributed and/or modified under
|
|
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* OpenSceneGraph Public License for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <osg/Stats>
|
|
|
|
#include <osg/Notify>
|
|
|
|
|
|
|
|
using namespace osg;
|
|
|
|
|
2007-01-30 22:47:13 +08:00
|
|
|
Stats::Stats(const std::string& name):
|
|
|
|
_name(name)
|
|
|
|
{
|
|
|
|
allocate(25);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-20 03:53:23 +08:00
|
|
|
Stats::Stats(const std::string& name, unsigned int numberOfFrames):
|
|
|
|
_name(name)
|
|
|
|
{
|
|
|
|
allocate(numberOfFrames);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Stats::allocate(unsigned int numberOfFrames)
|
|
|
|
{
|
2007-02-15 00:24:49 +08:00
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
|
|
|
|
2007-01-20 03:53:23 +08:00
|
|
|
_baseFrameNumber = 0;
|
|
|
|
_latestFrameNumber = 0;
|
|
|
|
_attributeMapList.clear();
|
|
|
|
_attributeMapList.resize(numberOfFrames);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Stats::setAttribute(int frameNumber, const std::string& attributeName, double value)
|
|
|
|
{
|
|
|
|
if (frameNumber<getEarliestFrameNumber()) return false;
|
2007-02-15 00:24:49 +08:00
|
|
|
|
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
|
|
|
|
2007-01-20 03:53:23 +08:00
|
|
|
if (frameNumber>_latestFrameNumber)
|
|
|
|
{
|
|
|
|
// need to advance
|
|
|
|
|
|
|
|
// first clear the entries up to and including the new frameNumber
|
|
|
|
for(int i = _latestFrameNumber+1; i<= frameNumber; ++i)
|
|
|
|
{
|
|
|
|
int index = (i - _baseFrameNumber) % _attributeMapList.size();
|
|
|
|
_attributeMapList[index].clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (frameNumber-_baseFrameNumber) >= static_cast<int>(_attributeMapList.size()))
|
|
|
|
{
|
|
|
|
_baseFrameNumber = (frameNumber/_attributeMapList.size())*_attributeMapList.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
_latestFrameNumber = frameNumber;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int index = getIndex(frameNumber);
|
|
|
|
if (index<0)
|
|
|
|
{
|
|
|
|
osg::notify(osg::NOTICE)<<"Failed to assing valid index for Stats::setAttribute("<<frameNumber<<","<<attributeName<<","<<value<<")"<<std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
AttributeMap& attributeMap = _attributeMapList[index];
|
|
|
|
attributeMap[attributeName] = value;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-02-15 00:24:49 +08:00
|
|
|
bool Stats::getAttributeNoMutex(int frameNumber, const std::string& attributeName, double& value) const
|
2007-01-20 03:53:23 +08:00
|
|
|
{
|
|
|
|
int index = getIndex(frameNumber);
|
|
|
|
if (index<0) return false;
|
|
|
|
|
|
|
|
const AttributeMap& attributeMap = _attributeMapList[index];
|
|
|
|
AttributeMap::const_iterator itr = attributeMap.find(attributeName);
|
2007-01-22 02:24:54 +08:00
|
|
|
if (itr == attributeMap.end()) return false;
|
2007-01-20 03:53:23 +08:00
|
|
|
|
|
|
|
value = itr->second;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-01-30 21:48:04 +08:00
|
|
|
bool Stats::getAveragedAttribute(const std::string& attributeName, double& value, bool averageInInverseSpace) const
|
2007-01-30 19:40:23 +08:00
|
|
|
{
|
2007-01-30 21:48:04 +08:00
|
|
|
return getAveragedAttribute(getEarliestFrameNumber(), getLatestFrameNumber(), attributeName, value, averageInInverseSpace);
|
2007-01-30 19:40:23 +08:00
|
|
|
}
|
|
|
|
|
2007-01-30 21:48:04 +08:00
|
|
|
bool Stats::getAveragedAttribute(int startFrameNumber, int endFrameNumber, const std::string& attributeName, double& value, bool averageInInverseSpace) const
|
2007-01-30 19:40:23 +08:00
|
|
|
{
|
|
|
|
if (endFrameNumber<startFrameNumber)
|
|
|
|
{
|
|
|
|
std::swap(endFrameNumber, startFrameNumber);
|
|
|
|
}
|
2007-02-15 00:24:49 +08:00
|
|
|
|
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
2007-01-30 19:40:23 +08:00
|
|
|
|
|
|
|
double total = 0.0;
|
|
|
|
double numValidSamples = 0.0;
|
|
|
|
for(int i = startFrameNumber; i<=endFrameNumber; ++i)
|
|
|
|
{
|
|
|
|
double v = 0.0;
|
2007-02-15 00:24:49 +08:00
|
|
|
if (getAttributeNoMutex(i,attributeName,v))
|
2007-01-30 19:40:23 +08:00
|
|
|
{
|
2007-01-30 21:48:04 +08:00
|
|
|
if (averageInInverseSpace) total += 1.0/v;
|
|
|
|
else total += v;
|
2007-01-30 19:40:23 +08:00
|
|
|
numValidSamples += 1.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (numValidSamples>0.0)
|
|
|
|
{
|
2007-01-30 21:48:04 +08:00
|
|
|
if (averageInInverseSpace) value = numValidSamples/total;
|
|
|
|
else value = total/numValidSamples;
|
2007-01-30 19:40:23 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else return false;
|
|
|
|
}
|
|
|
|
|
2007-02-15 00:24:49 +08:00
|
|
|
Stats::AttributeMap& Stats::getAttributeMapNoMutex(int frameNumber)
|
2007-01-20 03:53:23 +08:00
|
|
|
{
|
|
|
|
int index = getIndex(frameNumber);
|
|
|
|
if (index<0) return _invalidAttributeMap;
|
|
|
|
|
|
|
|
return _attributeMapList[index];
|
|
|
|
}
|
|
|
|
|
2007-02-15 00:24:49 +08:00
|
|
|
const Stats::AttributeMap& Stats::getAttributeMapNoMutex(int frameNumber) const
|
2007-01-20 03:53:23 +08:00
|
|
|
{
|
|
|
|
int index = getIndex(frameNumber);
|
|
|
|
if (index<0) return _invalidAttributeMap;
|
|
|
|
|
|
|
|
return _attributeMapList[index];
|
|
|
|
}
|
|
|
|
|
2007-01-22 19:22:37 +08:00
|
|
|
void Stats::report(std::ostream& out, const char* indent) const
|
2007-01-20 03:53:23 +08:00
|
|
|
{
|
2007-02-15 00:24:49 +08:00
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
|
|
|
|
2007-01-22 19:22:37 +08:00
|
|
|
if (indent) out<<indent;
|
2007-01-20 03:53:23 +08:00
|
|
|
out<<"Stats "<<_name<<std::endl;
|
|
|
|
for(int i = getEarliestFrameNumber(); i<= getLatestFrameNumber(); ++i)
|
|
|
|
{
|
|
|
|
out<<" FrameNumber "<<i<<std::endl;
|
2007-02-15 00:24:49 +08:00
|
|
|
const osg::Stats::AttributeMap& attributes = getAttributeMapNoMutex(i);
|
2007-01-22 19:22:37 +08:00
|
|
|
for(osg::Stats::AttributeMap::const_iterator itr = attributes.begin();
|
2007-01-20 03:53:23 +08:00
|
|
|
itr != attributes.end();
|
|
|
|
++itr)
|
|
|
|
{
|
2007-01-22 19:22:37 +08:00
|
|
|
if (indent) out<<indent;
|
2007-01-20 03:53:23 +08:00
|
|
|
out<<" "<<itr->first<<"\t"<<itr->second<<std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2007-01-22 19:22:37 +08:00
|
|
|
|
|
|
|
void Stats::report(std::ostream& out, unsigned int frameNumber, const char* indent) const
|
|
|
|
{
|
2007-02-15 00:24:49 +08:00
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
|
|
|
|
2007-01-22 19:22:37 +08:00
|
|
|
if (indent) out<<indent;
|
|
|
|
out<<"Stats "<<_name<<" FrameNumber "<<frameNumber<<std::endl;
|
2007-02-15 00:24:49 +08:00
|
|
|
const osg::Stats::AttributeMap& attributes = getAttributeMapNoMutex(frameNumber);
|
2007-01-22 19:22:37 +08:00
|
|
|
for(osg::Stats::AttributeMap::const_iterator itr = attributes.begin();
|
|
|
|
itr != attributes.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
if (indent) out<<indent;
|
|
|
|
out<<" "<<itr->first<<"\t"<<itr->second<<std::endl;
|
|
|
|
}
|
|
|
|
}
|