forked from aya/aya
Initial commit
This commit is contained in:
206
client/studio/src/RobloxTaskScheduler.cpp
Normal file
206
client/studio/src/RobloxTaskScheduler.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
|
||||
|
||||
|
||||
#include "RobloxTaskScheduler.hpp"
|
||||
|
||||
// Qt Headers
|
||||
#include <QTimer>
|
||||
#include <QHeaderView>
|
||||
|
||||
// Roblox Headers
|
||||
#include "TaskScheduler.hpp"
|
||||
|
||||
#include "TaskScheduler.Job.hpp"
|
||||
|
||||
|
||||
// Roblox Studio Headers
|
||||
#include "QtUtilities.hpp"
|
||||
|
||||
static const int UpdateInterval = 1000;
|
||||
static const int sMaxColumnCount = 7;
|
||||
|
||||
TSJobItem* ArbiterItem::getOrCreateTSJobItem(boost::shared_ptr<const Aya::TaskScheduler::Job> pJob)
|
||||
{
|
||||
int currentIndex = 0;
|
||||
TSJobItem* pTSItem = NULL;
|
||||
while (currentIndex < childCount())
|
||||
{
|
||||
// static cast since we know all of the inserted child items are of type TSJobItem
|
||||
pTSItem = static_cast<TSJobItem*>(child(currentIndex));
|
||||
if (pTSItem && pTSItem->getJob() == pJob)
|
||||
return pTSItem;
|
||||
++currentIndex;
|
||||
}
|
||||
|
||||
// we couldn't find an item, so create one
|
||||
return new TSJobItem(this, pJob);
|
||||
}
|
||||
|
||||
TSJobItem::TSJobItem(ArbiterItem* pParentItem, boost::shared_ptr<const Aya::TaskScheduler::Job> pJob)
|
||||
: m_pJob(pJob)
|
||||
{
|
||||
pParentItem->addChild(this);
|
||||
setText(0, m_pJob->name.c_str());
|
||||
}
|
||||
|
||||
void TSJobItem::updateValues()
|
||||
{
|
||||
bool isSleeping = m_pJob->getSleepingTime() > Aya::Time::Interval(5);
|
||||
if (!isSleeping)
|
||||
{
|
||||
double error = m_pJob->averageError();
|
||||
setText(1, Aya::format("%.2f", error).c_str());
|
||||
|
||||
double priority = m_pJob->getPriority();
|
||||
setText(2, Aya::format("%.1f", priority).c_str());
|
||||
|
||||
double dutyCycle = m_pJob->averageDutyCycle();
|
||||
setText(3, Aya::format("%.1f%%", 100.0 * dutyCycle).c_str());
|
||||
|
||||
double sps = m_pJob->averageStepsPerSecond();
|
||||
setText(4, Aya::format("%.1f/s", sps).c_str());
|
||||
|
||||
double cv = m_pJob->getStepStats().stepInterval().coefficient_of_variation();
|
||||
setText(5, Aya::format("%.1f%%", 100.0 * cv).c_str());
|
||||
|
||||
double step = m_pJob->averageStepTime() * 1000;
|
||||
setText(6, Aya::format("%.3fms", step).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
// start the count from 1 as the 0 column is job's name and should not be modified
|
||||
for (int ii = 1; ii < sMaxColumnCount; ++ii)
|
||||
setText(ii, "");
|
||||
}
|
||||
|
||||
setIcon(0, QIcon(QtUtilities::getPixmap(":/images/TASKSCHEDULERIMAGES.bmp", (int)m_pJob->getState(), 16, true)));
|
||||
}
|
||||
|
||||
RobloxTaskScheduler::RobloxTaskScheduler()
|
||||
: m_pTimer(new QTimer(this))
|
||||
{
|
||||
setColumnCount(sMaxColumnCount);
|
||||
QStringList headerLabels;
|
||||
headerLabels << "Name" << "Error" << "Priority" << "Activity" << "Rate" << "CV" << "Time";
|
||||
setHeaderLabels(headerLabels);
|
||||
|
||||
setSortingEnabled(true);
|
||||
|
||||
header()->setDefaultSectionSize(50);
|
||||
header()->resizeSection(0, 100);
|
||||
header()->setSortIndicator(0, Qt::AscendingOrder);
|
||||
|
||||
m_pTimer->setInterval(UpdateInterval);
|
||||
connect(m_pTimer, SIGNAL(timeout()), this, SLOT(updateValues()));
|
||||
}
|
||||
|
||||
RobloxTaskScheduler::~RobloxTaskScheduler() {}
|
||||
|
||||
void RobloxTaskScheduler::updateValues()
|
||||
{
|
||||
// if the window is hidden, stop the update timer
|
||||
if (!isVisible())
|
||||
{
|
||||
m_pTimer->stop();
|
||||
return;
|
||||
}
|
||||
|
||||
setUpdatesEnabled(false);
|
||||
|
||||
Jobs jobs;
|
||||
Aya::TaskScheduler::singleton().getJobsInfo(jobs);
|
||||
|
||||
std::set<TSJobItem*> currentTSJobItems;
|
||||
ArbiterItem* pArbiterItem = NULL;
|
||||
TSJobItem* pTSJobItem = NULL;
|
||||
|
||||
for (Jobs::iterator iter = jobs.begin(); iter != jobs.end(); ++iter)
|
||||
{
|
||||
boost::shared_ptr<const Aya::TaskScheduler::Job> pJob = (*iter);
|
||||
if (pJob)
|
||||
{
|
||||
boost::shared_ptr<Aya::TaskScheduler::Arbiter> pArbiter(pJob->getArbiter());
|
||||
if (!pArbiter)
|
||||
continue;
|
||||
|
||||
pArbiterItem = getOrCreateArbiterItem(pArbiter);
|
||||
AYAASSERT(pArbiterItem);
|
||||
|
||||
QString arbiterName = pArbiter->arbiterName().c_str();
|
||||
if (pArbiter->isThrottled())
|
||||
arbiterName += " (throttled)";
|
||||
|
||||
if (arbiterName != pArbiterItem->text(0))
|
||||
pArbiterItem->setText(0, arbiterName);
|
||||
|
||||
pTSJobItem = pArbiterItem->getOrCreateTSJobItem(pJob);
|
||||
AYAASSERT(pTSJobItem);
|
||||
|
||||
pTSJobItem->updateValues();
|
||||
currentTSJobItems.insert(pTSJobItem);
|
||||
}
|
||||
}
|
||||
|
||||
syncTSJobItems(currentTSJobItems);
|
||||
sortItems(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
|
||||
|
||||
setUpdatesEnabled(true);
|
||||
}
|
||||
|
||||
void RobloxTaskScheduler::setVisible(bool visible)
|
||||
{
|
||||
if (visible)
|
||||
{
|
||||
m_pTimer->start();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pTimer->stop();
|
||||
}
|
||||
RobloxReportView::setVisible(visible);
|
||||
}
|
||||
|
||||
ArbiterItem* RobloxTaskScheduler::getOrCreateArbiterItem(boost::shared_ptr<Aya::TaskScheduler::Arbiter> pArbiter)
|
||||
{
|
||||
ArbiterItemsMap::const_iterator iter = m_arbiterMap.find(pArbiter);
|
||||
if (iter != m_arbiterMap.end())
|
||||
return iter->second;
|
||||
|
||||
ArbiterItem* pArbiterItem = new ArbiterItem();
|
||||
addCategoryItem(pArbiterItem);
|
||||
pArbiterItem->setExpanded(true);
|
||||
// add it into map
|
||||
m_arbiterMap[pArbiter] = pArbiterItem;
|
||||
|
||||
return pArbiterItem;
|
||||
}
|
||||
|
||||
void RobloxTaskScheduler::syncTSJobItems(const std::set<TSJobItem*>& currentTSJobItems)
|
||||
{
|
||||
// delete items which are not there in current items collection
|
||||
// -- not removing iterator as we are going to copy current items collection
|
||||
std::set<TSJobItem*>::iterator iter = m_TSJobItems.begin();
|
||||
while (iter != m_TSJobItems.end())
|
||||
{
|
||||
if (currentTSJobItems.find(*iter) == currentTSJobItems.end())
|
||||
delete *iter;
|
||||
++iter;
|
||||
}
|
||||
|
||||
// remove top level items if they do not have any children
|
||||
ArbiterItemsMap::iterator iter1 = m_arbiterMap.begin();
|
||||
while (iter1 != m_arbiterMap.end())
|
||||
{
|
||||
if (iter1->second->childCount() < 1)
|
||||
{
|
||||
delete iter1->second;
|
||||
m_arbiterMap.erase(iter1++);
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter1;
|
||||
}
|
||||
}
|
||||
|
||||
m_TSJobItems = currentTSJobItems;
|
||||
}
|
||||
Reference in New Issue
Block a user