mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-20 04:09:16 +00:00
Hoist MOULOpenSourceClientPlugin/Plasma20/* to top level
to match H'uru layout and make patching/cherry-picking easier.
This commit is contained in:
692
Sources/Plasma/PubUtilLib/plStatGather/plProfileManagerFull.cpp
Normal file
692
Sources/Plasma/PubUtilLib/plStatGather/plProfileManagerFull.cpp
Normal file
@ -0,0 +1,692 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "plProfileManagerFull.h"
|
||||
#include "plProfileManager.h"
|
||||
|
||||
#include "../plPipeline/plDebugText.h"
|
||||
#include "../plPipeline/plPlates.h"
|
||||
|
||||
#include "plCalculatedProfiles.h"
|
||||
|
||||
#include "hsStream.h"
|
||||
#include "../pnUtils/pnUtils.h"
|
||||
#include "../plUnifiedTime/plUnifiedTime.h"
|
||||
#include "../plFile/plFileUtils.h"
|
||||
|
||||
plProfileManagerFull::plProfileManagerFull() :
|
||||
fVars(plProfileManager::Instance().fVars),
|
||||
fLogStats(false),
|
||||
fShowLaps(nil),
|
||||
fMinLap(0),
|
||||
fDetailGraph(nil)
|
||||
{
|
||||
}
|
||||
|
||||
plProfileManagerFull& plProfileManagerFull::Instance()
|
||||
{
|
||||
static plProfileManagerFull theInstance;
|
||||
return theInstance;
|
||||
}
|
||||
|
||||
void plProfileManagerFull::GetGroups(GroupSet& groups)
|
||||
{
|
||||
groups.clear();
|
||||
for (int i = 0; i < fVars.size(); i++)
|
||||
groups.insert(fVars[i]->GetGroup());
|
||||
}
|
||||
|
||||
void plProfileManagerFull::ShowGroup(const char* groupName)
|
||||
{
|
||||
if (!groupName)
|
||||
groupName = "General";
|
||||
|
||||
// If we're already showing this group, stop
|
||||
if (fShowGroups.find(groupName) != fShowGroups.end())
|
||||
{
|
||||
CreateStandardGraphs(groupName, false);
|
||||
fShowGroups.erase(groupName);
|
||||
ISetActive(groupName, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* shareGroupName = nil;
|
||||
for (int i = 0; i < fVars.size(); i++)
|
||||
{
|
||||
if (stricmp(fVars[i]->GetGroup(), groupName) == 0)
|
||||
{
|
||||
shareGroupName = fVars[i]->GetGroup();
|
||||
}
|
||||
}
|
||||
|
||||
// We do have a group with this name, so insert one of the variable's
|
||||
// pointers to the name into our list (we can hang on to those pointers)
|
||||
if (shareGroupName)
|
||||
{
|
||||
ISetActive(shareGroupName, true);
|
||||
CreateStandardGraphs(shareGroupName, true);
|
||||
fShowGroups.insert(shareGroupName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plProfileManagerFull::ShowNextGroup()
|
||||
{
|
||||
const char* curGroup = nil;
|
||||
if (fShowGroups.begin() != fShowGroups.end())
|
||||
curGroup = *(fShowGroups.begin());
|
||||
|
||||
GroupSet groups;
|
||||
GetGroups(groups);
|
||||
|
||||
const char* nextGroup = nil;
|
||||
if (curGroup)
|
||||
{
|
||||
CreateStandardGraphs(curGroup, false);
|
||||
|
||||
GroupSet::iterator it = groups.find(curGroup);
|
||||
it++;
|
||||
if (it != groups.end())
|
||||
{
|
||||
nextGroup = *it;
|
||||
}
|
||||
ISetActive(curGroup,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextGroup = *(groups.begin());
|
||||
}
|
||||
|
||||
fShowGroups.clear();
|
||||
if (nextGroup)
|
||||
{
|
||||
ISetActive(nextGroup, true);
|
||||
CreateStandardGraphs(nextGroup, true);
|
||||
fShowGroups.insert(nextGroup);
|
||||
}
|
||||
}
|
||||
|
||||
plProfileVar* plProfileManagerFull::IFindTimer(const char *name)
|
||||
{
|
||||
for (int i = 0; i < fVars.size(); i++)
|
||||
{
|
||||
if (stricmp(fVars[i]->GetName(), name) == 0)
|
||||
return fVars[i];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
void plProfileManagerFull::GetLaps(LapNames& lapNames)
|
||||
{
|
||||
for (int i = 0; i < fVars.size(); i++)
|
||||
{
|
||||
plProfileVar* var = fVars[i];
|
||||
if (var->GetLaps())
|
||||
{
|
||||
LapPair lapPair;
|
||||
lapPair.group = var->GetGroup();
|
||||
lapPair.varName = var->GetName();
|
||||
lapNames.push_back(lapPair);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
kColName,
|
||||
kColValue,
|
||||
kColAvg,
|
||||
kColMax,
|
||||
kColIndex,
|
||||
};
|
||||
|
||||
typedef std::vector<plProfileBase*> ProfileGroup;
|
||||
|
||||
static void PrintColumn(ProfileGroup& group, const char* groupName, int column, int x, int y, int& width, int& height, int off =0)
|
||||
{
|
||||
plDebugText& txt = plDebugText::Instance();
|
||||
int yInc = txt.GetFontHeight() + 2;
|
||||
|
||||
height = 0;
|
||||
width = 0;
|
||||
|
||||
width = hsMaximum(width, txt.CalcStringWidth(groupName) + 1);
|
||||
txt.DrawString(x, y+height, groupName, 255, 255, 255, 255, plDebugText::kStyleBold);
|
||||
height += yInc;
|
||||
|
||||
UInt32 samplesWidth = txt.CalcStringWidth("[000]");
|
||||
|
||||
for (int i = 0; i < group.size(); i++)
|
||||
{
|
||||
char str[1024];
|
||||
|
||||
switch (column)
|
||||
{
|
||||
case kColName:
|
||||
strcpy(str, group[i]->GetName());
|
||||
|
||||
// Since we don't draw the samples text for stats that only have 1 sample,
|
||||
// if the stat with the longest name is fluctuating between 1 and more than
|
||||
// 1 sample the width of the column will jump around. So we calculate the
|
||||
// width based on the stat name plus the width of the widest sample we should
|
||||
// get
|
||||
width = hsMaximum(width, txt.CalcStringWidth(str) + samplesWidth + 1);
|
||||
|
||||
// Now add on the samples text, if we have any
|
||||
if (group[i]->GetTimerSamples())
|
||||
{
|
||||
char cnt[20];
|
||||
sprintf(cnt, "[%d]", group[i]->GetTimerSamples());
|
||||
strcat(str, cnt);
|
||||
}
|
||||
break;
|
||||
case kColValue:
|
||||
group[i]->PrintValue(str);
|
||||
break;
|
||||
case kColAvg:
|
||||
group[i]->PrintAvg(str);
|
||||
break;
|
||||
case kColMax:
|
||||
group[i]->PrintMax(str);
|
||||
break;
|
||||
case kColIndex:
|
||||
sprintf(str,"[%3d]",i+off);
|
||||
break;
|
||||
}
|
||||
|
||||
txt.DrawString(x, y+height, str);
|
||||
if (column != kColName)
|
||||
width = hsMaximum(width, txt.CalcStringWidth(str) + 1);
|
||||
height += yInc;
|
||||
}
|
||||
|
||||
// So the columns don't jump around as much as values change, pad them out to a certain width
|
||||
width = hsMaximum(width, txt.CalcStringWidth("000.0 ms") + 1);
|
||||
}
|
||||
|
||||
static void PrintGroup(ProfileGroup& group, const char* groupName, int& x, int& y)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
PrintColumn(group, groupName, kColName, x, y, width, height);
|
||||
x += width + 10;
|
||||
|
||||
PrintColumn(group, "Avg", kColAvg, x, y, width, height);
|
||||
x += width + 10;
|
||||
|
||||
PrintColumn(group, "Cur", kColValue, x, y, width, height);
|
||||
x += width + 10;
|
||||
|
||||
PrintColumn(group, "Max", kColMax, x, y, width, height);
|
||||
x += width + 10;
|
||||
|
||||
y += height;
|
||||
}
|
||||
|
||||
|
||||
static void PrintLapGroup(ProfileGroup& group, const char* groupName, int& x, int& y, int min)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
if(min > 0)
|
||||
{
|
||||
PrintColumn(group, "Index", kColIndex, x, y, width, height, min);
|
||||
x += width + 10;
|
||||
}
|
||||
|
||||
PrintColumn(group, "Avg", kColAvg, x, y, width, height);
|
||||
x += width + 10;
|
||||
|
||||
PrintColumn(group, groupName, kColName, x, y, width, height);
|
||||
x += width + 10;
|
||||
|
||||
PrintColumn(group, "Cur", kColValue, x, y, width, height);
|
||||
x += width + 10;
|
||||
|
||||
y += height;
|
||||
}
|
||||
|
||||
void plProfileManagerFull::EndFrame()
|
||||
{
|
||||
CalculateProfiles();
|
||||
}
|
||||
|
||||
void plProfileManagerFull::Update()
|
||||
{
|
||||
if (fLogStats)
|
||||
ILogStats();
|
||||
|
||||
//
|
||||
// Print the groups we're showing
|
||||
//
|
||||
int maxX = 0;
|
||||
|
||||
int y = 10;
|
||||
GroupSet::iterator it;
|
||||
for (it = fShowGroups.begin(); it != fShowGroups.end(); it++)
|
||||
{
|
||||
const char* groupName = *it;
|
||||
|
||||
std::vector<plProfileBase*> group;
|
||||
|
||||
for (int i = 0; i < fVars.size(); i++)
|
||||
if (hsStrEQ(fVars[i]->GetGroup(), groupName))
|
||||
group.push_back(fVars[i]);
|
||||
|
||||
int x = 10;
|
||||
PrintGroup(group, groupName, x, y);
|
||||
|
||||
maxX = hsMaximum(maxX, x);
|
||||
y += 10;
|
||||
}
|
||||
|
||||
//
|
||||
// Print the laps we're showing
|
||||
//
|
||||
if (fShowLaps && fShowLaps->GetLaps())
|
||||
{
|
||||
plProfileLaps* laps = fShowLaps->GetLaps();
|
||||
|
||||
std::vector<plProfileBase*> group;
|
||||
int numLaps = laps->GetNumLaps();
|
||||
|
||||
if(numLaps < fMinLap)
|
||||
fMinLap = 0;
|
||||
for (int i = 0; i < numLaps; i++)
|
||||
{
|
||||
if(i >= fMinLap && i < (fMinLap + 40))
|
||||
group.push_back(laps->GetLap(i));
|
||||
}
|
||||
y = 10;
|
||||
char buf[256];
|
||||
sprintf(buf, "%s - %s", fShowLaps->GetGroup(), fShowLaps->GetName());
|
||||
PrintLapGroup(group, buf, maxX, y, fMinLap);
|
||||
}
|
||||
|
||||
//
|
||||
// Update the graphs
|
||||
//
|
||||
float size = 0.25;
|
||||
float xPos = 1 - size / 2;
|
||||
float yPos = -1 + size / 2;
|
||||
|
||||
for (int i = 0; i < fGraphs.size(); i++)
|
||||
{
|
||||
plGraphPlate* graph = fGraphs[i];
|
||||
plProfileVar* var = IFindTimer(graph->GetTitle());
|
||||
|
||||
if (var)
|
||||
{
|
||||
graph->SetPosition(xPos, yPos);
|
||||
graph->AddData(var->GetValue());
|
||||
graph->SetVisible(true);
|
||||
|
||||
yPos += size;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateStandardGraphs(xPos, yPos);
|
||||
|
||||
float detailSize = 0.9;
|
||||
float detailX = 1 - detailSize / 2;
|
||||
float detailY = 1 - detailSize / 2;
|
||||
if (fDetailGraph)
|
||||
{
|
||||
fDetailGraph->SetPosition(detailX,detailY);
|
||||
double value;
|
||||
double scale;
|
||||
int i;
|
||||
std::vector<Int32> values;
|
||||
for (i=0; i<fDetailVars.size(); i++)
|
||||
{
|
||||
value = (double)fDetailVars[i].var->GetValue();
|
||||
scale = 100.0/((double)(fDetailVars[i].max-fDetailVars[i].min));
|
||||
value = scale*value-fDetailVars[i].min;
|
||||
values.push_back((Int32)value);
|
||||
}
|
||||
fDetailGraph->AddData(values);
|
||||
fDetailGraph->SetVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
void plProfileManagerFull::ActivateAllStats()
|
||||
{
|
||||
for (int i = 0; i < fVars.size(); i++)
|
||||
{
|
||||
fVars[i]->SetActive(true);
|
||||
fVars[i]->Start();
|
||||
}
|
||||
}
|
||||
|
||||
void plProfileManagerFull::IPrintGroup(hsStream* s, const char* groupName, bool printTitle)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
for (int i = 0; i < fVars.size(); i++)
|
||||
{
|
||||
plProfileVar* var = fVars[i];
|
||||
if (hsStrEQ(var->GetGroup(), groupName))
|
||||
{
|
||||
if (printTitle)
|
||||
sprintf(buf, "%s:%s", var->GetGroup(), var->GetName());
|
||||
else
|
||||
var->PrintAvg(buf, false);
|
||||
|
||||
s->Write(strlen(buf), buf);
|
||||
s->WriteByte(',');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plProfileManagerFull::LogStats(const char* ageName, const char* spawnName)
|
||||
{
|
||||
fLogStats = true;
|
||||
wchar* temp = hsStringToWString(ageName);
|
||||
fLogAgeName = temp;
|
||||
delete [] temp;
|
||||
fLogSpawnName = spawnName;
|
||||
}
|
||||
|
||||
const wchar* plProfileManagerFull::GetProfilePath()
|
||||
{
|
||||
static wchar profilePath[MAX_PATH];
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
initialized = true;
|
||||
|
||||
plUnifiedTime curTime = plUnifiedTime::GetCurrentTime(plUnifiedTime::kLocal);
|
||||
|
||||
PathGetUserDirectory(profilePath, arrsize(profilePath));
|
||||
PathAddFilename(profilePath, profilePath, L"Profile", arrsize(profilePath));
|
||||
plFileUtils::CreateDir(profilePath);
|
||||
|
||||
wchar buff[256];
|
||||
swprintf(buff, L"%02d-%02d-%04d_%02d-%02d//",
|
||||
curTime.GetMonth(),
|
||||
curTime.GetDay(),
|
||||
curTime.GetYear(),
|
||||
curTime.GetHour(),
|
||||
curTime.GetMinute());
|
||||
|
||||
PathAddFilename(profilePath, profilePath, buff, arrsize(profilePath));
|
||||
plFileUtils::CreateDir(profilePath);
|
||||
}
|
||||
|
||||
return profilePath;
|
||||
}
|
||||
|
||||
void plProfileManagerFull::ILogStats()
|
||||
{
|
||||
wchar statFilename[256];
|
||||
swprintf(statFilename, L"%s%s.csv", GetProfilePath(), fLogAgeName.c_str());
|
||||
|
||||
bool exists = plFileUtils::FileExists(statFilename);
|
||||
|
||||
hsUNIXStream s;
|
||||
if (s.Open(statFilename, L"ab"))
|
||||
{
|
||||
GroupSet groups;
|
||||
GetGroups(groups);
|
||||
|
||||
GroupSet::iterator it;
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
const char* kSpawn = "Spawn";
|
||||
s.Write(strlen(kSpawn), kSpawn);
|
||||
s.WriteByte(',');
|
||||
|
||||
for (it = groups.begin(); it != groups.end(); it++)
|
||||
{
|
||||
const char* groupName = *it;
|
||||
IPrintGroup(&s, groupName, true);
|
||||
}
|
||||
s.WriteByte('\r');
|
||||
s.WriteByte('\n');
|
||||
}
|
||||
|
||||
s.Write(fLogSpawnName.length(), fLogSpawnName.c_str());
|
||||
s.WriteByte(',');
|
||||
|
||||
for (it = groups.begin(); it != groups.end(); it++)
|
||||
{
|
||||
const char* groupName = *it;
|
||||
IPrintGroup(&s, groupName);
|
||||
}
|
||||
s.WriteByte('\r');
|
||||
s.WriteByte('\n');
|
||||
|
||||
s.Close();
|
||||
}
|
||||
|
||||
fLogStats = false;
|
||||
fLogAgeName = L"";
|
||||
fLogSpawnName = "";
|
||||
}
|
||||
|
||||
|
||||
void plProfileManagerFull::ShowLaps(const char* groupName, const char* varName)
|
||||
{
|
||||
plProfileVar* var = nil;
|
||||
|
||||
|
||||
if(fShowLaps)
|
||||
fShowLaps->SetLapsActive(false);
|
||||
|
||||
for (int i = 0; i < fVars.size(); i++)
|
||||
{
|
||||
int j = 0;
|
||||
while(fVars[i]->GetName()[j++] == ' ') {}
|
||||
if (stricmp(&(fVars[i]->GetName()[j-1]), varName) == 0 &&
|
||||
stricmp(fVars[i]->GetGroup(), groupName) == 0)
|
||||
{
|
||||
var = fVars[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (var)
|
||||
{
|
||||
if (var == fShowLaps)
|
||||
{
|
||||
|
||||
fShowLaps = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
fShowLaps = var;
|
||||
}
|
||||
}
|
||||
if(fShowLaps)
|
||||
fShowLaps->SetLapsActive(true);
|
||||
}
|
||||
|
||||
void plProfileManagerFull::CreateGraph(const char* varName, UInt32 min, UInt32 max)
|
||||
{
|
||||
// If the graph is already created, destroy it
|
||||
for (int i = 0; i < fGraphs.size(); i++)
|
||||
{
|
||||
if (strcmp(fGraphs[i]->GetTitle(), varName) == 0)
|
||||
{
|
||||
plPlateManager::Instance().DestroyPlate(fGraphs[i]);
|
||||
fGraphs.erase(fGraphs.begin()+i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
plProfileVar* var = IFindTimer(varName);
|
||||
if (var)
|
||||
{
|
||||
plGraphPlate* graph = nil;
|
||||
plPlateManager::Instance().CreateGraphPlate(&graph);
|
||||
graph->SetSize(0.25, 0.25);
|
||||
graph->SetDataRange(min, max, 100);
|
||||
graph->SetTitle(var->GetName());
|
||||
|
||||
fGraphs.push_back(graph);
|
||||
}
|
||||
}
|
||||
|
||||
void plProfileManagerFull::ResetDefaultDetailVars()
|
||||
{
|
||||
fDetailVars.clear();
|
||||
AddDetailVar("ApplyAnimation",0,50);
|
||||
AddDetailVar("AnimatingPhysicals",0,50);
|
||||
AddDetailVar("StoppedAnimPhysicals",0,50);
|
||||
AddDetailVar("DrawableTime",0,50);
|
||||
AddDetailVar("Polys",0,150000);
|
||||
AddDetailVar("Step",0,50);
|
||||
AddDetailVar("LineOfSight",0,50);
|
||||
AddDetailVar(" PhysicsUpdates",0,50);
|
||||
AddDetailVar("Stream Shove Time",0,50);
|
||||
AddDetailVar("RenderSetup",0,50);
|
||||
}
|
||||
|
||||
void plProfileManagerFull::ShowDetailGraph()
|
||||
{
|
||||
// if graph is already created, kill it
|
||||
if (fDetailGraph)
|
||||
HideDetailGraph();
|
||||
if (fDetailVars.size() == 0)
|
||||
ResetDefaultDetailVars();
|
||||
|
||||
plPlateManager::Instance().CreateGraphPlate(&fDetailGraph);
|
||||
fDetailGraph->SetSize(0.9,0.9);
|
||||
fDetailGraph->SetDataRange(0,500,500);
|
||||
fDetailGraph->SetDataLabels(0,100); // should be relatively simple to cast everything to a 0-100 range
|
||||
fDetailGraph->SetTitle("Detail");
|
||||
UpdateDetailLabels();
|
||||
}
|
||||
|
||||
void plProfileManagerFull::HideDetailGraph()
|
||||
{
|
||||
if (fDetailGraph)
|
||||
{
|
||||
plPlateManager::Instance().DestroyPlate(fDetailGraph);
|
||||
fDetailGraph = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void plProfileManagerFull::AddDetailVar(const char* varName, UInt32 min, UInt32 max)
|
||||
{
|
||||
int i=0;
|
||||
for (i=0; i<fDetailVars.size(); i++)
|
||||
{
|
||||
if (stricmp(fDetailVars[i].var->GetName(), varName) == 0)
|
||||
return; // don't add it again
|
||||
}
|
||||
|
||||
plProfileVar* var = IFindTimer(varName);
|
||||
if (!var)
|
||||
return;
|
||||
var->SetActive(true);
|
||||
|
||||
if (fDetailVars.size() == 10)
|
||||
fDetailVars.erase(fDetailVars.begin()); // we don't want any more then 10 at this point, so drop the oldest one
|
||||
detailVar temp;
|
||||
temp.var = var;
|
||||
temp.min = min;
|
||||
temp.max = max;
|
||||
fDetailVars.push_back(temp);
|
||||
UpdateDetailLabels();
|
||||
}
|
||||
|
||||
void plProfileManagerFull::RemoveDetailVar(const char* varName)
|
||||
{
|
||||
int i=0;
|
||||
for (i=0; i<fDetailVars.size(); i++)
|
||||
{
|
||||
if (stricmp(fDetailVars[i].var->GetName(), varName) == 0)
|
||||
{
|
||||
fDetailVars.erase(fDetailVars.begin()+i);
|
||||
}
|
||||
}
|
||||
UpdateDetailLabels();
|
||||
}
|
||||
|
||||
void plProfileManagerFull::UpdateDetailLabels()
|
||||
{
|
||||
if (fDetailGraph)
|
||||
{
|
||||
int i;
|
||||
std::vector<std::string> labels;
|
||||
for (i=0; i<fDetailVars.size(); i++)
|
||||
labels.push_back(fDetailVars[i].var->GetName());
|
||||
|
||||
fDetailGraph->SetLabelText(labels);
|
||||
|
||||
// update the colors as well, just in case
|
||||
std::vector<UInt32> colors;
|
||||
colors.push_back(0xff00ff00); // green
|
||||
colors.push_back(0xff0000ff); // blue
|
||||
colors.push_back(0xffffff00); // yellow
|
||||
colors.push_back(0xffff00ff); // pink
|
||||
colors.push_back(0xffffffff); // white
|
||||
colors.push_back(0xff00ffff); // cyan
|
||||
colors.push_back(0xffff8000); // orange
|
||||
colors.push_back(0xff8000ff); // purple
|
||||
colors.push_back(0xffff0080); // fuscha
|
||||
colors.push_back(0xff808080); // grey
|
||||
|
||||
fDetailGraph->SetDataColors(colors);
|
||||
}
|
||||
}
|
||||
|
||||
void plProfileManagerFull::ResetMax()
|
||||
{
|
||||
for (int i = 0; i < fVars.size(); i++)
|
||||
fVars[i]->ResetMax();
|
||||
}
|
||||
|
||||
void plProfileManagerFull::ISetActive(const char* groupName, bool active)
|
||||
{
|
||||
for (int i = 0; i < fVars.size(); i++)
|
||||
{
|
||||
if (stricmp(fVars[i]->GetGroup(), groupName) == 0)
|
||||
{
|
||||
fVars[i]->SetActive(active);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user