2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-14 02:27:40 -04:00

CWE Directory Reorganization

Rearrange directory structure of CWE to be loosely equivalent to
the H'uru Plasma repository.

Part 1: Movement of directories and files.
This commit is contained in:
rarified
2021-05-15 12:49:46 -06:00
parent c3f4a640a3
commit 96903e8dca
4002 changed files with 159 additions and 644 deletions

View File

@ -0,0 +1,399 @@
/*==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 "plAutoProfile.h"
#include "plgDispatch.h"
#include "../plNetClient/plNetClientMgr.h"
#include "../plNetClient/plNetLinkingMgr.h"
#include "hsStream.h"
#include "hsTimer.h"
#include "../plMessage/plAgeLoadedMsg.h"
#include "../pnTimer/plTimerCallbackManager.h"
#include "../plMessage/plTimerCallbackMsg.h"
#include "../plAvatar/plAvatarMgr.h"
#include "../plAvatar/plArmatureMod.h"
#include "../plModifier/plSpawnModifier.h"
#include "../plMessage/plConsoleMsg.h"
#include "../pnMessage/plClientMsg.h"
#include "../plAgeLoader/plAgeLoader.h"
#include "plProfileManagerFull.h"
#include "../plFile/plFileUtils.h"
#include "../plPipeline/plDebugText.h"
#include "../pnMessage/plTimeMsg.h"
#include "../plStatusLog/plStatusLog.h"
#include "../plVault/plVault.h"
#include "../plContainer/plConfigInfo.h" // for plStringList
// For taking screenshots
#include "../plGImage/plMipmap.h"
#include "../Apps/plClient/plClient.h"
#include "../plJPEG/plJPEG.h"
#include "plPipeline.h"
#include <algorithm>
class plAutoProfileImp : public plAutoProfile
{
protected:
plStringList fAges;
int fNextAge;
int fNextSpawnPoint;
const char* fLastSpawnPointName;
// For profiling a single age
std::string fAgeName;
bool fLinkedToSingleAge;
bool fJustLinkToAges;
UInt64 fLinkTime;
std::string fStatusMessage;
void INextProfile();
bool INextAge();
bool INextSpawnPoint();
void IInit();
void IShutdown();
public:
plAutoProfileImp();
virtual void StartProfile(const char* ageName);
virtual void LinkToAllAges();
virtual hsBool MsgReceive(plMessage* msg);
};
plAutoProfile* plAutoProfile::Instance()
{
static plAutoProfileImp theInstance;
return &theInstance;
}
////////////////////////////////////////////////////////////////////////////////
plAutoProfileImp::plAutoProfileImp() : fNextAge(0), fNextSpawnPoint(0), fLastSpawnPointName(nil), fLinkedToSingleAge(false), fJustLinkToAges(false)
{
}
void plAutoProfileImp::StartProfile(const char* ageName)
{
if (ageName)
fAgeName = ageName;
else
fAgeName = "";
IInit();
plProfileManagerFull::Instance().ActivateAllStats();
}
void plAutoProfileImp::LinkToAllAges()
{
fJustLinkToAges = true;
IInit();
}
void plAutoProfileImp::IInit()
{
// TODO: Find a better way to grab a list of age names, since the old data server
// no longer exists
/*plIDataServer* dataServer = plNetClientMgr::GetInstance()->GetDataServer();
if (!dataServer)
return;
dataServer->GetDatasetAges(fAges);*/
// The first age we link into is AvatarCustomization, since we have a new avatar.
// Coincidentally, the first age in our list is AvatarCustomization. However,
// sometimes linking from ACA to ACA causes a crash. To get around that, we just
// reverse the list, so it's last.
std::reverse(fAges.begin(), fAges.end());
fNextAge = 0;
RegisterAs(kAutoProfile_KEY);
plgDispatch::Dispatch()->RegisterForExactType(plAgeBeginLoadingMsg::Index(), GetKey());
plgDispatch::Dispatch()->RegisterForExactType(plAgeLoadedMsg::Index(), GetKey());
plgDispatch::Dispatch()->RegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());
plConsoleMsg* consoleMsg = TRACKED_NEW plConsoleMsg(plConsoleMsg::kExecuteLine, "Camera.AlwaysCut true");
consoleMsg->Send();
}
#ifdef HS_BUILD_FOR_WIN32
#include "hsWindows.h"
#include <shellapi.h>
#endif
void plAutoProfileImp::IShutdown()
{
// KLUDGE - Copy the load timing log, in case we used it
#define kTimingLog L"readtimings.0.log"
#define kAgeTimingLog L"agetimings.0.log"
wchar destPath[MAX_PATH];
wchar sourcePath[MAX_PATH];
PathAddFilename(destPath, plProfileManagerFull::Instance().GetProfilePath(), kTimingLog, arrsize(destPath));
PathGetLogDirectory(sourcePath, arrsize(sourcePath));
PathAddFilename(sourcePath, sourcePath, kTimingLog, arrsize(sourcePath));
plFileUtils::FileCopy(sourcePath, destPath);
PathAddFilename(destPath, plProfileManagerFull::Instance().GetProfilePath(), kAgeTimingLog, arrsize(destPath));
PathGetLogDirectory(sourcePath, arrsize(sourcePath));
PathAddFilename(sourcePath, sourcePath, kAgeTimingLog, arrsize(sourcePath));
plFileUtils::FileCopy(sourcePath, destPath);
#ifdef HS_BUILD_FOR_WIN32
ShellExecute(nil, nil, "PostRun.bat", nil, nil, SW_SHOWNORMAL);
#endif
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
plgDispatch::Dispatch()->UnRegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
plgDispatch::Dispatch()->UnRegisterForExactType(plAgeLoadedMsg::Index(), GetKey());
UnRegisterAs(kAutoProfile_KEY);
// Pump the queue so we get fully unregistered
plgDispatch::Dispatch()->MsgQueueProcess();
plClientMsg* clientMsg = TRACKED_NEW plClientMsg(plClientMsg::kQuit);
clientMsg->Send(hsgResMgr::ResMgr()->FindKey(kClient_KEY));
}
void plAutoProfileImp::INextProfile()
{
// Haven't linked to our first age yet, do that before we start profiling
if (fNextAge == 0)
{
if (!INextAge())
IShutdown();
}
else
{
// Log the stats for this spawn point
if (fLastSpawnPointName)
{
const char * ageName = NetCommGetAge()->ageDatasetName;
plProfileManagerFull::Instance().LogStats(ageName, fLastSpawnPointName);
plMipmap mipmap;
if (plClient::GetInstance()->GetPipeline()->CaptureScreen(&mipmap))
{
char fileName[256];
sprintf(fileName, "%s%s_%s.jpg",
plProfileManagerFull::Instance().GetProfilePath(),
ageName, fLastSpawnPointName);
plJPEG::Instance().SetWriteQuality(100);
plJPEG::Instance().WriteToFile(fileName, &mipmap);
}
fLastSpawnPointName = nil;
}
// Try to go to the next spawn point
if (!INextSpawnPoint())
{
// Link to the next age
if (!INextAge())
{
// We've done all the ages, shut down
IShutdown();
}
}
}
}
bool plAutoProfileImp::INextAge()
{
const char* ageName = nil;
if (fAgeName.length() > 0)
{
if (fLinkedToSingleAge)
return false;
fLinkedToSingleAge = true;
ageName = fAgeName.c_str();
}
else
{
if (fNextAge >= fAges.size())
return false;
ageName = fAges[fNextAge].c_str();
}
fNextAge++;
fNextSpawnPoint = 0;
plAgeLinkStruct link;
link.GetAgeInfo()->SetAgeFilename(ageName);
link.SetLinkingRules(plNetCommon::LinkingRules::kBasicLink);
plNetLinkingMgr::GetInstance()->LinkToAge(&link);
fStatusMessage = "Linking to age ";
fStatusMessage += ageName;
return true;
}
bool plAutoProfileImp::INextSpawnPoint()
{
if (fJustLinkToAges)
return false;
const char* kPerfSpawnPrefix = "cPerf-";
int kPerfSpawnLen = strlen(kPerfSpawnPrefix);
// Find the next perf spawn point
bool foundGood = false;
while (fNextSpawnPoint < plAvatarMgr::GetInstance()->NumSpawnPoints())
{
const plSpawnModifier* spawnMod = plAvatarMgr::GetInstance()->GetSpawnPoint(fNextSpawnPoint);
fLastSpawnPointName = spawnMod->GetKeyName();
if (strncmp(fLastSpawnPointName, kPerfSpawnPrefix, kPerfSpawnLen) == 0)
{
fStatusMessage = "Profiling spawn point ";
fStatusMessage += fLastSpawnPointName;
foundGood = true;
break;
}
else
fNextSpawnPoint++;
}
if (!foundGood)
{
fLastSpawnPointName = nil;
fStatusMessage = "No profile spawn point found";
return false;
}
plArmatureMod *avatar = plAvatarMgr::GetInstance()->GetLocalAvatar();
if (avatar)
{
double fakeTime = 0.0f;
avatar->SpawnAt(fNextSpawnPoint, fakeTime);
}
fNextSpawnPoint++;
plTimerCallbackMsg* timerMsg = TRACKED_NEW plTimerCallbackMsg(GetKey());
plgTimerCallbackMgr::NewTimer(30, timerMsg);
return true;
}
hsBool plAutoProfileImp::MsgReceive(plMessage* msg)
{
plEvalMsg* evalMsg = plEvalMsg::ConvertNoRef(msg);
if (evalMsg)
{
if (fStatusMessage.length() > 0)
plDebugText::Instance().DrawString(10, 10, fStatusMessage.c_str());
}
plAgeLoadedMsg* ageLoaded = plAgeLoadedMsg::ConvertNoRef(msg);
if (ageLoaded)
{
if (!ageLoaded->fLoaded)
{
fLinkTime = hsTimer::GetFullTickCount();
hsStatusMessage("Age unloaded");
}
return true;
}
plInitialAgeStateLoadedMsg* ageStateLoaded = plInitialAgeStateLoadedMsg::ConvertNoRef(msg);
if (ageStateLoaded)
{
if (fNextAge > 0)
{
fLinkTime = hsTimer::GetFullTickCount() - fLinkTime;
float ms = hsTimer::FullTicksToMs(fLinkTime);
hsStatusMessageF("Age %s finished load, took %.1f ms",
fAges[fNextAge-1].c_str(),
ms);
plStatusLog::AddLineS("agetimings.log", "Age %s took %.1f ms",
fAges[fNextAge-1].c_str(),
ms);
}
fStatusMessage = "Age loaded. Preparing to profile.";
// Age is loaded, start profiling in 5 seconds (to make sure the avatar is linked in all the way)
plTimerCallbackMsg* timerMsg = TRACKED_NEW plTimerCallbackMsg(GetKey());
plgTimerCallbackMgr::NewTimer(5, timerMsg);
return true;
}
plTimerCallbackMsg* timerMsg = plTimerCallbackMsg::ConvertNoRef(msg);
if (timerMsg)
{
INextProfile();
return true;
}
// When the first age starts to load, register the stupid avatar customization variable
// so the calibration screen won't pop up and ruin everything. I'm sure I could try
// and do this earlier, but I'm not sure when that player folder is set so screw it, it works here.
plAgeBeginLoadingMsg* ageBeginLoadingMsg = plAgeBeginLoadingMsg::ConvertNoRef(msg);
if (ageBeginLoadingMsg)
{
plgDispatch::Dispatch()->UnRegisterForExactType(plAgeBeginLoadingMsg::Index(), GetKey());
VaultAddChronicleEntryAndWait(L"InitialAvCursomizationsDone", 0, L"1");
return true;
}
return false;
}

View File

@ -0,0 +1,62 @@
/*==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==*/
#ifndef plAutoProfile_h_inc
#define plAutoProfile_h_inc
#include "../pnKeyedObject/hsKeyedObject.h"
class plAutoProfile : public hsKeyedObject
{
public:
CLASSNAME_REGISTER(plAutoProfile);
GETINTERFACE_ANY(plAutoProfile, hsKeyedObject);
static plAutoProfile* Instance();
// If ageName is nil, do all ages
virtual void StartProfile(const char* ageName = nil)=0;
// For when we just want to link to each age, for other reasons (profiling load times)
virtual void LinkToAllAges()=0;
};
#endif // plAutoProfile_h_inc

View File

@ -0,0 +1,320 @@
/*==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 "plProfile.h"
#include "plProfileManager.h"
#include "../plNetClient/plNetClientMgr.h"
#include "hsTimer.h"
plProfile_CreateCounter("Age Upload BitsPerSec", "Network", UploadAgeBitsPerSec);
plProfile_CreateMemCounter("Upload Bytes", "Network", UploadBW);
plProfile_CreateMemCounter("Upload Avg Packet Size", "Network", UploadAPS);
plProfile_CreateCounter("Upload Num Packets", "Network", UploadPPS);
plProfile_CreateCounter("Upload Avg Packets Queued", "Network", UploadPQ);
plProfile_CreateCounter("Recvd Multiple Acks", "Network", RMultAcksPQ);
plProfile_CreateCounter("Age Download BitsPerSec", "Network", DownloadAgeBitsPerSec);
plProfile_CreateMemCounter("Download Bytes", "Network", DownloadBW);
plProfile_CreateMemCounter("Download Avg Packet Size", "Network", DownloadAPS);
plProfile_CreateCounter("Download Num Packets", "Network", DownloadPPS);
plProfile_CreateCounter("Download Avg Packets Queued", "Network", DownloadPQ);
plProfile_CreateCounter("Download Dropped Pkts", "Network", DownloadDP);
plProfile_CreateCounter("Remote Players", "Network", RemotePlayers);
plProfile_CreateCounter("Peers", "Network", Peers);
plProfile_CreateCounter("Player ID", "Network", PlayerID);
plProfile_CreateCounter("Account ID", "Network", AccountID);
plProfile_CreateTimer("Avg Receipt Time", "Network", AvgReceiptTime);
plProfile_CreateTimer("Peak Receipt Time", "Network", PeakReceiptTime);
#ifdef HS_FIND_MEM_LEAKS
plProfile_CreateMemCounter("Allocated", "Memory", MemAllocated);
plProfile_CreateMemCounter("Peak Alloc", "Memory", MemPeakAlloc);
#endif
static plProfileVar gVarRFPS("RFPS", "General", plProfileVar::kDisplayTime | plProfileVar::kDisplayFPS);
plProfile_Extern(DrawTriangles);
plProfile_Extern(MatChange);
plProfile_CreateCounter("Polys Per Material", "General", PolysPerMat);
#ifdef PL_PROFILE_ENABLED
#define plProfile_GetValue(varName) gProfileVar##varName.GetValue()
#else
#define plProfile_GetValue(varName) 0
#endif
void CalculateProfiles()
{
// KLUDGE - do timing that overlaps the beginframe / endframe (where timing is normally reset)
static UInt32 lastTicks = plProfileManager::GetTime();
UInt32 curTicks = plProfileManager::GetTime();
gVarRFPS.Set(curTicks - lastTicks);
lastTicks = curTicks;
// KLUDGE - calulate the polys per material
if (plProfile_GetValue(MatChange) == 0)
plProfile_Set(PolysPerMat, 0);
else
plProfile_Set(PolysPerMat, plProfile_GetValue(DrawTriangles) / plProfile_GetValue(MatChange));
#ifdef HS_FIND_MEM_LEAKS
// plProfile_Set(MemAllocated, MemGetAllocated());
// plProfile_Set(MemPeakAlloc, MemGetPeakAllocated());
#endif
// Network stats
plNetClientMgr* nc = plNetClientMgr::GetInstance();
if (!nc->GetFlagsBit(plNetClientMgr::kDisabled))
{
#if 0
hsAssert(nc->GetNetCore(), "nil net core in stats?");
plNetCoreStats* ns = nc->GetNetCore()->GetStats();
plProfile_Set(UploadAgeBitsPerSec, (UInt32)nc->GetNetClientStats().GetAgeStatsULBitsPerSec());
plProfile_Set(UploadBW, ns->GetULBits()/8);
plProfile_Set(UploadPPS, ns->GetULPackets());
plProfile_Set(UploadAPS, (UInt32)ns->GetULAvgPacketBytes());
plProfile_Set(UploadPQ, (UInt32)ns->GetULAvgNumPacketsQueued());
plProfile_Set(RMultAcksPQ, nc->GetNetClientStats().GetRecvdMultipleAcks());
plProfile_Set(DownloadAgeBitsPerSec, (UInt32)nc->GetNetClientStats().GetAgeStatsDLBitsPerSec());
plProfile_Set(DownloadBW, ns->GetDLBits()/8);
plProfile_Set(DownloadPPS, ns->GetDLPackets());
plProfile_Set(DownloadAPS, (UInt32)ns->GetDLAvgPacketBytes());
plProfile_Set(DownloadPQ, (UInt32)ns->GetDLAvgNumPacketsQueued());
plProfile_Set(DownloadDP, ns->GetDLDroppedPackets());
plProfile_Set(RemotePlayers, nc->RemotePlayerKeys().size());
plProfile_Set(Peers, ns->GetNumPeers());
plProfile_Set(PlayerID, nc->GetPlayerID());
plProfile_Set(AccountID, nc->GetAccountID());
plProfile_Set(AvgReceiptTime, hsTimer::PrecSecsToTicks(ns->GetAvgReceiptTime()));
plProfile_Set(PeakReceiptTime, hsTimer::PrecSecsToTicks(ns->GetPeakReceiptTime()));
#endif
}
}
#include "../plPipeline/plPlates.h"
static plGraphPlate* fFPSPlate = nil;
static plGraphPlate* fNetBWPlate = nil;
static plGraphPlate* fNetPPSPlate = nil;
static plGraphPlate* fNetQueuesPlate = nil;
static plGraphPlate* fNetAvgBWPlate = nil;
static plGraphPlate* fNetAvgPPSPlate = nil;
static plGraphPlate* fNetAvgQueuesPlate = nil;
static int ICreateStdPlate(plGraphPlate** graph)
{
if (plPlateManager::InstanceValid())
{
plPlateManager::Instance().CreateGraphPlate(graph);
(*graph)->SetSize(0.25, 0.25);
(*graph)->SetDataRange(0, 100, 100);
return hsOK;
}
return hsFail;
}
void CreateStandardGraphs(const char* groupName, bool create)
{
if (strcmp(groupName, "General") == 0)
{
if (create)
{
if (ICreateStdPlate(&fFPSPlate) == hsOK)
{
fFPSPlate->SetTitle("mSecs");
fFPSPlate->SetLabelText("Tot", "Draw", "Upd");
}
}
else
{
plPlateManager::Instance().DestroyPlate(fFPSPlate);
fFPSPlate = nil;
}
}
else if (strcmp(groupName, "Network") == 0)
{
if (create)
{
if (ICreateStdPlate(&fNetBWPlate) == hsOK)
{
fNetBWPlate->SetDataLabels(0, 2000);
fNetBWPlate->SetTitle("Bytes");
fNetBWPlate->SetLabelText("UL", "DL");
ICreateStdPlate(&fNetPPSPlate);
fNetPPSPlate->SetDataLabels(0, 20);
fNetPPSPlate->SetTitle("Packets");
fNetPPSPlate->SetLabelText("UL", "DL");
ICreateStdPlate(&fNetQueuesPlate);
fNetQueuesPlate->SetDataLabels(0, 20);
fNetQueuesPlate->SetTitle("Queue Counts");
fNetQueuesPlate->SetLabelText("UL", "DL");
ICreateStdPlate(&fNetQueuesPlate);
fNetQueuesPlate->SetDataLabels(0, 20);
fNetQueuesPlate->SetTitle("Queue Counts");
fNetQueuesPlate->SetLabelText("UL", "DL");
ICreateStdPlate(&fNetQueuesPlate);
fNetQueuesPlate->SetDataLabels(0, 20);
fNetQueuesPlate->SetTitle("Queue Counts");
fNetQueuesPlate->SetLabelText("UL", "DL");
ICreateStdPlate(&fNetAvgBWPlate);
fNetAvgBWPlate->SetDataLabels(0, 5000);
fNetAvgBWPlate->SetTitle("Avg BytesPS");
fNetAvgBWPlate->SetLabelText("UL", "DL");
ICreateStdPlate(&fNetAvgPPSPlate);
fNetAvgPPSPlate->SetDataLabels(0, 40);
fNetAvgPPSPlate->SetTitle("Avg PacketsPS");
fNetAvgPPSPlate->SetLabelText("UL", "DL");
ICreateStdPlate(&fNetAvgQueuesPlate);
fNetAvgQueuesPlate->SetDataLabels(0, 40);
fNetAvgQueuesPlate->SetTitle("Avg Queue CountsPS");
fNetAvgQueuesPlate->SetLabelText("UL", "DL");
}
}
else
{
plPlateManager::Instance().DestroyPlate(fNetBWPlate);
plPlateManager::Instance().DestroyPlate(fNetPPSPlate);
plPlateManager::Instance().DestroyPlate(fNetQueuesPlate);
plPlateManager::Instance().DestroyPlate(fNetAvgBWPlate);
plPlateManager::Instance().DestroyPlate(fNetAvgPPSPlate);
plPlateManager::Instance().DestroyPlate(fNetAvgQueuesPlate);
fNetBWPlate = nil;
fNetPPSPlate = nil;
fNetQueuesPlate = nil;
fNetAvgBWPlate = nil;
fNetAvgPPSPlate = nil;
fNetAvgQueuesPlate = nil;
}
}
}
plProfile_CreateTimer("Draw", "General", DrawTime);
plProfile_CreateTimer("Update", "General", UpdateTime);
void UpdateStandardGraphs(float xPos, float yPos)
{
#define PositionPlate(plate) \
plate->SetPosition(xPos, yPos); \
yPos += 0.25; \
plate->SetVisible(true);
if (fFPSPlate)
{
fFPSPlate->AddData(
gVarRFPS.GetValue(),
plProfile_GetValue(DrawTime),
plProfile_GetValue(UpdateTime));
PositionPlate(fFPSPlate);
}
plNetClientMgr* nc = plNetClientMgr::GetInstance();
#if 0
plNetCoreStats* ns = nc ? nc->GetNetCore()->GetStats() : nil;
if (!nc || !ns)
return;
if (fNetBWPlate)
{
fNetBWPlate->AddData(
(UInt32)(ns->GetULBits()/8.f),
(UInt32)(ns->GetDLBits()/8.f));
PositionPlate(fNetBWPlate);
}
if (fNetPPSPlate)
{
fNetPPSPlate->AddData(
ns->GetULPackets(),
ns->GetDLPackets());
PositionPlate(fNetPPSPlate);
}
if (fNetQueuesPlate)
{
unsigned int ul, dl;
nc->GetNetCore()->GetOutQueueMsgCount(plNetCore::kPeerAll,ul);
nc->GetNetCore()->GetInQueueMsgCount(plNetCore::kPeerAll,dl);
fNetQueuesPlate->AddData(ul,dl);
PositionPlate(fNetQueuesPlate);
}
if (fNetAvgBWPlate)
{
fNetAvgBWPlate->AddData(
(UInt32)(ns->GetULBitsPS()/8.f),
(UInt32)(ns->GetDLBitsPS()/8.f));
PositionPlate(fNetAvgBWPlate);
}
if (fNetAvgPPSPlate)
{
fNetAvgPPSPlate->AddData(
(Int32)ns->GetULNumPacketsPS(),
(Int32)ns->GetDLNumPacketsPS());
PositionPlate(fNetAvgPPSPlate);
}
if (fNetAvgQueuesPlate)
{
fNetAvgQueuesPlate->AddData(
(Int32)ns->GetULAvgNumPacketsQueued(),
(Int32)ns->GetDLAvgNumPacketsQueued());
PositionPlate(fNetAvgQueuesPlate);
}
#endif
}

View File

@ -0,0 +1,45 @@
/*==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==*/
void CalculateProfiles();
void CreateStandardGraphs(const char* groupName, bool create);
void UpdateStandardGraphs(float xPos, float yPos);

View 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);
}
}
}

View File

@ -0,0 +1,131 @@
/*==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==*/
#ifndef plProfileManagerFull_h_inc
#define plProfileManagerFull_h_inc
#include "plProfileManager.h"
#include "hsStlUtils.h"
#include "hsStlSortUtils.h"
class plProfileManager;
class plGraphPlate;
class plStatusLog;
class hsStream;
class plProfileVar;
class plProfileManagerFull
{
public:
typedef std::set<const char*, stringISorter> GroupSet;
protected:
plProfileManager::VarVec& fVars;
bool fLogStats; // If true, log the stats at the end of the frame
std::wstring fLogAgeName;
std::string fLogSpawnName;
std::vector<plGraphPlate*> fGraphs;
plGraphPlate* fDetailGraph;
struct detailVar
{
plProfileVar* var;
Int32 min;
Int32 max;
};
std::vector<detailVar> fDetailVars; // the vars we want to show on the detail graph
GroupSet fShowGroups;
plProfileVar* fShowLaps;
UInt32 fMinLap; // For Display
void IPrintGroup(hsStream* s, const char* groupName, bool printTitle=false);
void ILogStats();
plProfileVar* IFindTimer(const char* name);
void ISetActive(const char* groupName, bool active);
plProfileManagerFull();
public:
static plProfileManagerFull& Instance();
void EndFrame(); // Call end frame on our special timers
void Update();
void GetGroups(GroupSet& groups);
void ShowGroup(const char* groupName);
void ShowNextGroup();
struct LapPair { const char* group; const char* varName; };
typedef std::vector<LapPair> LapNames;
void GetLaps(LapNames& lapNames);
void ShowLaps(const char* groupName, const char* varName);
void SetMinLap(int m) { fMinLap = m; };
void PageDownLaps() { fMinLap += 40; }
void PageUpLaps() { fMinLap = (fMinLap < 40) ? 0 : fMinLap - 40;}
void CreateGraph(const char* varName, UInt32 min, UInt32 max);
void ResetDefaultDetailVars();
void ShowDetailGraph();
void HideDetailGraph();
void AddDetailVar(const char* varName, UInt32 min, UInt32 max);
void RemoveDetailVar(const char* varName);
void UpdateDetailLabels();
void ResetMax();
void LogStats(const char* ageName, const char* spawnName);
const wchar* GetProfilePath();
// If you're going to call LogStats, make sure to call this first so all stats will be evaluated before logging
void ActivateAllStats();
};
#endif // plProfileManagerFull_h_inc

View File

@ -0,0 +1,50 @@
/*==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==*/
#ifndef plStatGatherCreatable_h_inc
#define plStatGatherCreatable_h_inc
#include "../pnFactory/plCreator.h"
#include "plAutoProfile.h"
REGISTER_NONCREATABLE(plAutoProfile);
#endif // plStatGatherCreatable_h_inc