* The beginnings of an activity monitor application. Very bare and feature-less
right now, but it's already working (and shows that we better compute our system_info::cached_pages field directly). * I am not sure if we want to keep this app here, merge it with ProcessController, or have it as a separate (3rdparty) app. Opinions welcome. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24846 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -2,6 +2,7 @@ SubDir HAIKU_TOP src apps ;
|
||||
|
||||
SubInclude HAIKU_TOP src apps 3dmov ;
|
||||
SubInclude HAIKU_TOP src apps aboutsystem ;
|
||||
SubInclude HAIKU_TOP src apps activitymonitor ;
|
||||
SubInclude HAIKU_TOP src apps bsnow ;
|
||||
SubInclude HAIKU_TOP src apps bootman ;
|
||||
SubInclude HAIKU_TOP src apps cdplayer ;
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "ActivityMonitor.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Application.h>
|
||||
#include <TextView.h>
|
||||
|
||||
#include "ActivityWindow.h"
|
||||
|
||||
|
||||
const char* kSignature = "application/x-vnd.Haiku-ActivityMonitor";
|
||||
|
||||
|
||||
ActivityMonitor::ActivityMonitor()
|
||||
: BApplication(kSignature)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ActivityMonitor::~ActivityMonitor()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityMonitor::ReadyToRun()
|
||||
{
|
||||
fWindow = new ActivityWindow();
|
||||
fWindow->Show();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityMonitor::RefsReceived(BMessage* message)
|
||||
{
|
||||
fWindow->PostMessage(message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityMonitor::MessageReceived(BMessage* message)
|
||||
{
|
||||
BApplication::MessageReceived(message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityMonitor::AboutRequested()
|
||||
{
|
||||
ShowAbout();
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void
|
||||
ActivityMonitor::ShowAbout()
|
||||
{
|
||||
BAlert *alert = new BAlert("about", "ActivityMonitor\n"
|
||||
"\twritten by Axel Dörfler\n"
|
||||
"\tCopyright 2008, Haiku Inc.\n", "Ok");
|
||||
BTextView *view = alert->TextView();
|
||||
BFont font;
|
||||
|
||||
view->SetStylable(true);
|
||||
|
||||
view->GetFont(&font);
|
||||
font.SetSize(18);
|
||||
font.SetFace(B_BOLD_FACE);
|
||||
view->SetFontAndColor(0, 15, &font);
|
||||
|
||||
alert->Go();
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
int
|
||||
main(int /*argc*/, char** /*argv*/)
|
||||
{
|
||||
ActivityMonitor app;
|
||||
app.Run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ACTIVITY_MONITOR_H
|
||||
#define ACTIVITY_MONITOR_H
|
||||
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
class BMessage;
|
||||
class ActivityWindow;
|
||||
|
||||
|
||||
class ActivityMonitor : public BApplication {
|
||||
public:
|
||||
ActivityMonitor();
|
||||
virtual ~ActivityMonitor();
|
||||
|
||||
virtual void ReadyToRun();
|
||||
|
||||
virtual void RefsReceived(BMessage* message);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
virtual void AboutRequested();
|
||||
|
||||
static void ShowAbout();
|
||||
|
||||
private:
|
||||
ActivityWindow* fWindow;
|
||||
};
|
||||
|
||||
extern const char* kSignature;
|
||||
|
||||
#endif // ACTIVITY_MONITOR_H
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.Haiku-ActivityMonitor";
|
||||
|
||||
resource app_version {
|
||||
major = 1,
|
||||
middle = 0,
|
||||
minor = 0,
|
||||
|
||||
variety = B_APPV_BETA,
|
||||
internal = 3,
|
||||
|
||||
short_info = "ActivityMonitor",
|
||||
long_info = "ActivityMonitor ©2008 Haiku, Inc."
|
||||
};
|
||||
|
||||
resource app_flags B_MULTIPLE_LAUNCH;
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
|
||||
resource vector_icon {
|
||||
$"6E6369660E03010000020002023980000000000000004000004BE00008908100"
|
||||
$"010000FFFF01000000020016023CC7EE389BC0BA16573E39B04977C842ADC700"
|
||||
$"FFFFD3020006023C529D3753A2B8966F3D9D084B6044496AAF00474747FFA5A0"
|
||||
$"A002001602BC4E76BC411B3C90DABCA00D47587D4ABA850090FFD40200160238"
|
||||
$"313C3B5CF0BFCD963C7AAC4C13943FCAF901ECFFC3054B04017E020006033E2F"
|
||||
$"99387F17BA42DB3FF5B94A0E32482C90001D1E2C3D454658FF01010102000602"
|
||||
$"3879063B8224BE2CC83B10DB4A1F6F49B894FF9A9A9A00242222020006033C69"
|
||||
$"A60000000000003E186148800049800058F3F3F300D4CECEFFD9D9D902000603"
|
||||
$"3C1F1A33E78CB7ACC03FFE4F48BB3EBD7B6C0078D905818CFF05FF7ADD050200"
|
||||
$"1602349C2E37B5FABA1F6036FC624A3E004B320001D3FF910200160235777837"
|
||||
$"0A67B7E8CE363A844A1D684B45D800F3FF2E0D0A04486050605C51544E04033E"
|
||||
$"5349594856475C49604B5C4E604B0A06262A264C485E5252523030240A04262A"
|
||||
$"4838523030240A044838485E525252300A04262A264C485E48380A04453A4553"
|
||||
$"2844282E0A04B6F9C0F42845282EB701B8EC0A044550455328452AC0F30A0445"
|
||||
$"3A45502A43B701B8EC0408AEBAB6BCBCC32FBD4F2E3930BDA8B9ACC0A5BA9EBC"
|
||||
$"03BB1EBFD937BF0DBD4FC072BCC3C019BDDBC0CB46460204BF23C726BF91C70D"
|
||||
$"BEB5C73FBE9FC87EBE7AC7D9BEC5C922BFAAC97BBF3CC994C018C962C02DC823"
|
||||
$"C053C8C8C008C77F0204BFCEC6FBC042C6E0BF5BC715BF48C85ABF1FC7B3BF71"
|
||||
$"C902C063C95ABFF0C974C0D7C93FC0EAC7FAC113C8A2C0C1C7530E0A07010000"
|
||||
$"0A0101011001178300040A0001021001178400040A020103000A080109000A0B"
|
||||
$"010A1001178120040A030104000A04020506000A090107000A0A0108000A0D01"
|
||||
$"0C0815FF0A0C010B0815FF0A0D010C0A3FEAF70000000000003FEAF7C573B4C2"
|
||||
$"770615FF0A0C010B0A3FEAF70000000000003FEAF7C573B4C2770615FF"
|
||||
};
|
||||
|
||||
#endif // HAIKU_TARGET_PLATFORM_HAIKU
|
||||
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "ActivityView.h"
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Application.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Dragger.h>
|
||||
#include <MenuItem.h>
|
||||
#include <MessageRunner.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "ActivityMonitor.h"
|
||||
#include "DataSource.h"
|
||||
#include "SystemInfo.h"
|
||||
|
||||
|
||||
struct data_item {
|
||||
bigtime_t time;
|
||||
int64 value;
|
||||
};
|
||||
|
||||
const bigtime_t kInitialRefreshInterval = 500000LL;
|
||||
|
||||
const uint32 kMsgRefresh = 'refr';
|
||||
const uint32 kMsgToggleDataSource = 'tgds';
|
||||
|
||||
extern const char* kSignature;
|
||||
|
||||
|
||||
DataHistory::DataHistory(bigtime_t memorize, bigtime_t interval)
|
||||
:
|
||||
fBuffer(10000),
|
||||
fMinimumValue(0),
|
||||
fMaximumValue(0),
|
||||
fRefreshInterval(interval),
|
||||
fLastIndex(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataHistory::~DataHistory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DataHistory::AddValue(bigtime_t time, int64 value)
|
||||
{
|
||||
if (fBuffer.IsEmpty() || fMaximumValue < value)
|
||||
fMaximumValue = value;
|
||||
if (fBuffer.IsEmpty() || fMinimumValue > value)
|
||||
fMinimumValue = value;
|
||||
|
||||
data_item item = {time, value};
|
||||
fBuffer.AddItem(item);
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
DataHistory::ValueAt(bigtime_t time)
|
||||
{
|
||||
// TODO: if the refresh rate changes, this computation won't work anymore!
|
||||
int32 index = (time - Start()) / fRefreshInterval;
|
||||
data_item* item = fBuffer.ItemAt(index);
|
||||
if (item != NULL)
|
||||
return item->value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
DataHistory::MaximumValue() const
|
||||
{
|
||||
return fMaximumValue;
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
DataHistory::MinimumValue() const
|
||||
{
|
||||
return fMinimumValue;
|
||||
}
|
||||
|
||||
|
||||
bigtime_t
|
||||
DataHistory::Start() const
|
||||
{
|
||||
if (fBuffer.CountItems() == 0)
|
||||
return 0;
|
||||
|
||||
return fBuffer.ItemAt(0)->time;
|
||||
}
|
||||
|
||||
|
||||
bigtime_t
|
||||
DataHistory::End() const
|
||||
{
|
||||
if (fBuffer.CountItems() == 0)
|
||||
return 0;
|
||||
|
||||
return fBuffer.ItemAt(fBuffer.CountItems() - 1)->time;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DataHistory::SetRefreshInterval(bigtime_t interval)
|
||||
{
|
||||
// TODO: adjust buffer size
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
ActivityView::ActivityView(BRect frame, const char* name,
|
||||
const BMessage& settings, uint32 resizingMode)
|
||||
: BView(frame, name, resizingMode,
|
||||
B_WILL_DRAW | B_SUBPIXEL_PRECISE | B_FULL_UPDATE_ON_RESIZE
|
||||
| B_FRAME_EVENTS)
|
||||
{
|
||||
_Init(&settings);
|
||||
|
||||
BRect rect(Bounds());
|
||||
rect.top = rect.bottom - 7;
|
||||
rect.left = rect.right - 7;
|
||||
BDragger* dragger = new BDragger(rect, this,
|
||||
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
||||
AddChild(dragger);
|
||||
}
|
||||
|
||||
|
||||
ActivityView::ActivityView(BMessage* archive)
|
||||
: BView(archive)
|
||||
{
|
||||
_Init(archive);
|
||||
}
|
||||
|
||||
|
||||
ActivityView::~ActivityView()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityView::_Init(const BMessage* settings)
|
||||
{
|
||||
fBackgroundColor = (rgb_color){255, 255, 240};
|
||||
SetLowColor(fBackgroundColor);
|
||||
|
||||
fRefreshInterval = kInitialRefreshInterval;
|
||||
fDrawInterval = kInitialRefreshInterval * 2;
|
||||
fLastRefresh = 0;
|
||||
fDrawResolution = 1;
|
||||
|
||||
AddDataSource(new UsedMemoryDataSource());
|
||||
AddDataSource(new CachedMemoryDataSource());
|
||||
AddDataSource(new ThreadsDataSource());
|
||||
AddDataSource(new CpuUsageDataSource());
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ActivityView::Archive(BMessage* into, bool deep) const
|
||||
{
|
||||
status_t status;
|
||||
|
||||
status = BView::Archive(into, deep);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
status = into->AddString("add_on", kSignature);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
status = SaveState(*into);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
BArchivable*
|
||||
ActivityView::Instantiate(BMessage* archive)
|
||||
{
|
||||
if (!validate_instantiation(archive, "ActivityView"))
|
||||
return NULL;
|
||||
|
||||
return new ActivityView(archive);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ActivityView::SaveState(BMessage& state) const
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
DataSource*
|
||||
ActivityView::FindDataSource(const char* name)
|
||||
{
|
||||
for (int32 i = fSources.CountItems(); i-- > 0;) {
|
||||
DataSource* source = fSources.ItemAt(i);
|
||||
if (!strcmp(source->Label(), name))
|
||||
return source;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ActivityView::AddDataSource(DataSource* source)
|
||||
{
|
||||
DataHistory* values = new(std::nothrow) DataHistory(10 * 60000000LL,
|
||||
fRefreshInterval);
|
||||
if (values == NULL)
|
||||
return B_NO_MEMORY;
|
||||
if (!fValues.AddItem(values)) {
|
||||
delete values;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (!fSources.AddItem(source)) {
|
||||
fValues.RemoveItem(values);
|
||||
delete values;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ActivityView::RemoveDataSource(DataSource* source)
|
||||
{
|
||||
int32 index = fSources.IndexOf(source);
|
||||
if (index < 0)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
fSources.RemoveItemAt(index);
|
||||
delete source;
|
||||
DataHistory* values = fValues.RemoveItemAt(index);
|
||||
delete values;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityView::RemoveAllDataSources()
|
||||
{
|
||||
fSources.MakeEmpty();
|
||||
fValues.MakeEmpty();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityView::AttachedToWindow()
|
||||
{
|
||||
BMessage refresh(kMsgRefresh);
|
||||
fRunner = new BMessageRunner(this, &refresh, fRefreshInterval);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityView::DetachedFromWindow()
|
||||
{
|
||||
delete fRunner;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityView::FrameResized(float /*width*/, float /*height*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityView::MouseDown(BPoint where)
|
||||
{
|
||||
#if 0
|
||||
int32 buttons = B_PRIMARY_MOUSE_BUTTON;
|
||||
int32 clicks = 1;
|
||||
if (Looper() != NULL && Looper()->CurrentMessage() != NULL) {
|
||||
Looper()->CurrentMessage()->FindInt32("buttons", &buttons);
|
||||
Looper()->CurrentMessage()->FindInt32("clicks", &clicks);
|
||||
}
|
||||
#endif
|
||||
|
||||
BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
|
||||
menu->SetFont(be_plain_font);
|
||||
BMenuItem* item;
|
||||
|
||||
for (int32 i = 0; i < DataSource::CountSources(); i++) {
|
||||
const DataSource* source = DataSource::SourceAt(i);
|
||||
|
||||
BMessage* message = new BMessage(kMsgToggleDataSource);
|
||||
message->AddInt32("index", i);
|
||||
|
||||
item = new BMenuItem(source->Label(), message);
|
||||
if (FindDataSource(source->Label()))
|
||||
item->SetMarked(true);
|
||||
|
||||
menu->AddItem(item);
|
||||
}
|
||||
|
||||
menu->SetTargetForItems(this);
|
||||
|
||||
ConvertToScreen(&where);
|
||||
menu->Go(where, true, false, true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityView::MouseMoved(BPoint where, uint32 transit,
|
||||
const BMessage* dragMessage)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityView::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case B_ABOUT_REQUESTED:
|
||||
ActivityMonitor::ShowAbout();
|
||||
break;
|
||||
|
||||
case kMsgRefresh:
|
||||
_Refresh();
|
||||
break;
|
||||
|
||||
case kMsgToggleDataSource:
|
||||
{
|
||||
int32 index;
|
||||
if (message->FindInt32("index", &index) != B_OK)
|
||||
break;
|
||||
|
||||
const DataSource* baseSource = DataSource::SourceAt(index);
|
||||
if (baseSource == NULL)
|
||||
break;
|
||||
|
||||
DataSource* source = FindDataSource(baseSource->Label());
|
||||
if (source == NULL)
|
||||
AddDataSource(baseSource->Copy());
|
||||
else
|
||||
RemoveDataSource(source);
|
||||
|
||||
Invalidate();
|
||||
break;
|
||||
}
|
||||
|
||||
case B_MOUSE_WHEEL_CHANGED:
|
||||
{
|
||||
float deltaY = 0.0f;
|
||||
if (message->FindFloat("be:wheel_delta_y", &deltaY) != B_OK
|
||||
|| deltaY == 0.0f)
|
||||
break;
|
||||
|
||||
if (deltaY > 0)
|
||||
fDrawResolution *= 2;
|
||||
else
|
||||
fDrawResolution /= 2;
|
||||
|
||||
if (fDrawResolution < 1)
|
||||
fDrawResolution = 1;
|
||||
if (fDrawResolution > 128)
|
||||
fDrawResolution = 128;
|
||||
|
||||
Invalidate();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BView::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
ActivityView::_PositionForValue(DataSource* source, DataHistory* values,
|
||||
int64 value)
|
||||
{
|
||||
int64 min = source->Minimum();
|
||||
int64 max = source->Maximum();
|
||||
if (source->AdaptiveScale()) {
|
||||
int64 adaptiveMax = int64(values->MaximumValue() * 1.2);
|
||||
if (adaptiveMax < max)
|
||||
max = adaptiveMax;
|
||||
}
|
||||
|
||||
if (value > max)
|
||||
value = max;
|
||||
if (value < min)
|
||||
value = min;
|
||||
|
||||
float height = Bounds().Height();
|
||||
return height - (value - min) * height / (max - min);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityView::Draw(BRect /*updateRect*/)
|
||||
{
|
||||
uint32 step = 2;
|
||||
uint32 resolution = fDrawResolution;
|
||||
if (fDrawResolution > 1) {
|
||||
step = 1;
|
||||
resolution--;
|
||||
}
|
||||
|
||||
uint32 width = Bounds().IntegerWidth() - 10;
|
||||
uint32 steps = width / step;
|
||||
bigtime_t timeStep = fRefreshInterval * resolution;
|
||||
bigtime_t now = system_time();
|
||||
|
||||
SetPenSize(2);
|
||||
|
||||
for (uint32 i = fSources.CountItems(); i-- > 0;) {
|
||||
DataSource* source = fSources.ItemAt(i);
|
||||
DataHistory* values = fValues.ItemAt(i);
|
||||
bigtime_t time = now - steps * timeStep;
|
||||
// for now steps pixels per second
|
||||
|
||||
BeginLineArray(steps);
|
||||
SetHighColor(source->Color());
|
||||
|
||||
float lastY = FLT_MIN;
|
||||
uint32 lastX = 0;
|
||||
|
||||
for (uint32 x = 0; x < width; x += step, time += timeStep) {
|
||||
// TODO: compute starting point instead!
|
||||
if (values->Start() > time || values->End() < time)
|
||||
continue;
|
||||
|
||||
int64 value = values->ValueAt(time);
|
||||
if (timeStep > fRefreshInterval) {
|
||||
// TODO: always start with the same index, so that it always
|
||||
// uses the same values for computation (currently it jumps)
|
||||
uint32 count = 1;
|
||||
for (bigtime_t offset = fRefreshInterval; offset < timeStep;
|
||||
offset += fRefreshInterval) {
|
||||
// TODO: handle int64 overflow correctly!
|
||||
value += values->ValueAt(time + offset);
|
||||
count++;
|
||||
}
|
||||
value /= count;
|
||||
}
|
||||
|
||||
float y = _PositionForValue(source, values, value);
|
||||
if (lastY != FLT_MIN)
|
||||
AddLine(BPoint(lastX, lastY), BPoint(x, y), source->Color());
|
||||
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
}
|
||||
|
||||
EndLineArray();
|
||||
}
|
||||
|
||||
// TODO: add marks when an app started or quit
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityView::_Refresh()
|
||||
{
|
||||
SystemInfo info;
|
||||
|
||||
// TODO: run refresh in another thread to decouple it from the UI!
|
||||
|
||||
for (uint32 i = fSources.CountItems(); i-- > 0;) {
|
||||
DataSource* source = fSources.ItemAt(i);
|
||||
DataHistory* values = fValues.ItemAt(i);
|
||||
|
||||
int64 value = source->NextValue(info);
|
||||
values->AddValue(info.Time(), value);
|
||||
}
|
||||
|
||||
bigtime_t now = info.Time();
|
||||
if (fLastRefresh + fDrawInterval <= now) {
|
||||
Invalidate();
|
||||
fLastRefresh = now;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ACTIVITY_VIEW_H
|
||||
#define ACTIVITY_VIEW_H
|
||||
|
||||
|
||||
#include <View.h>
|
||||
#include <ObjectList.h>
|
||||
|
||||
#include "CircularBuffer.h"
|
||||
|
||||
class BMessageRunner;
|
||||
class DataSource;
|
||||
struct data_item;
|
||||
|
||||
|
||||
class DataHistory {
|
||||
public:
|
||||
DataHistory(bigtime_t memorize, bigtime_t interval);
|
||||
~DataHistory();
|
||||
|
||||
void AddValue(bigtime_t time, int64 value);
|
||||
|
||||
int64 ValueAt(bigtime_t time);
|
||||
int64 MaximumValue() const;
|
||||
int64 MinimumValue() const;
|
||||
bigtime_t Start() const;
|
||||
bigtime_t End() const;
|
||||
|
||||
void SetRefreshInterval(bigtime_t interval);
|
||||
|
||||
private:
|
||||
CircularBuffer<data_item> fBuffer;
|
||||
int64 fMinimumValue;
|
||||
int64 fMaximumValue;
|
||||
bigtime_t fRefreshInterval;
|
||||
int32 fLastIndex;
|
||||
};
|
||||
|
||||
|
||||
class ActivityView : public BView {
|
||||
public:
|
||||
ActivityView(BRect frame, const char* name,
|
||||
const BMessage& settings, uint32 resizingMode);
|
||||
ActivityView(BMessage* archive);
|
||||
virtual ~ActivityView();
|
||||
|
||||
virtual status_t Archive(BMessage* into, bool deep = true) const;
|
||||
static BArchivable* Instantiate(BMessage* archive);
|
||||
|
||||
status_t SaveState(BMessage& state) const;
|
||||
|
||||
DataSource* FindDataSource(const char* name);
|
||||
status_t AddDataSource(DataSource* source);
|
||||
status_t RemoveDataSource(DataSource* source);
|
||||
void RemoveAllDataSources();
|
||||
|
||||
protected:
|
||||
virtual void AttachedToWindow();
|
||||
virtual void DetachedFromWindow();
|
||||
|
||||
virtual void FrameResized(float width, float height);
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void MouseMoved(BPoint where, uint32 transit,
|
||||
const BMessage* dragMessage);
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
virtual void Draw(BRect updateRect);
|
||||
|
||||
private:
|
||||
void _Init(const BMessage* settings);
|
||||
void _Refresh();
|
||||
float _PositionForValue(DataSource* source,
|
||||
DataHistory* values, int64 value);
|
||||
|
||||
rgb_color fBackgroundColor;
|
||||
BObjectList<DataSource> fSources;
|
||||
BObjectList<DataHistory> fValues;
|
||||
BMessageRunner* fRunner;
|
||||
bigtime_t fRefreshInterval;
|
||||
bigtime_t fLastRefresh;
|
||||
bigtime_t fDrawInterval;
|
||||
int32 fDrawResolution;
|
||||
};
|
||||
|
||||
#endif // ACTIVITY_VIEW_H
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "ActivityWindow.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
#include <File.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Menu.h>
|
||||
#include <MenuBar.h>
|
||||
#include <MenuItem.h>
|
||||
#include <Path.h>
|
||||
#include <Roster.h>
|
||||
|
||||
#include "ActivityMonitor.h"
|
||||
#include "ActivityView.h"
|
||||
|
||||
|
||||
ActivityWindow::ActivityWindow()
|
||||
: BWindow(BRect(100, 100, 500, 250), "ActivityMonitor", B_TITLED_WINDOW,
|
||||
B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE)
|
||||
{
|
||||
BMessage settings;
|
||||
_LoadSettings(settings);
|
||||
|
||||
BRect frame;
|
||||
if (settings.FindRect("window frame", &frame) == B_OK) {
|
||||
MoveTo(frame.LeftTop());
|
||||
ResizeTo(frame.Width(), frame.Height());
|
||||
frame.OffsetTo(B_ORIGIN);
|
||||
} else
|
||||
frame = Bounds();
|
||||
|
||||
// create GUI
|
||||
|
||||
BMenuBar* menuBar = new BMenuBar(Bounds(), "menu");
|
||||
AddChild(menuBar);
|
||||
|
||||
frame.top = menuBar->Frame().bottom;
|
||||
|
||||
BView* top = new BView(frame, NULL, B_FOLLOW_ALL, B_WILL_DRAW);
|
||||
top->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
AddChild(top);
|
||||
|
||||
fActivityView = new ActivityView(top->Bounds().InsetByCopy(10, 10),
|
||||
"ActivityMonitor", settings, B_FOLLOW_ALL);
|
||||
top->AddChild(fActivityView);
|
||||
|
||||
// add menu
|
||||
|
||||
// "File" menu
|
||||
BMenu* menu = new BMenu("File");
|
||||
BMenuItem* item;
|
||||
|
||||
menu->AddItem(item = new BMenuItem("About ActivityMonitor" B_UTF8_ELLIPSIS,
|
||||
new BMessage(B_ABOUT_REQUESTED)));
|
||||
menu->AddSeparatorItem();
|
||||
|
||||
menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q'));
|
||||
menu->SetTargetForItems(this);
|
||||
item->SetTarget(be_app);
|
||||
menuBar->AddItem(menu);
|
||||
}
|
||||
|
||||
|
||||
ActivityWindow::~ActivityWindow()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ActivityWindow::_OpenSettings(BFile& file, uint32 mode)
|
||||
{
|
||||
BPath path;
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
path.Append("ActivityMonitor settings");
|
||||
|
||||
return file.SetTo(path.Path(), mode);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ActivityWindow::_LoadSettings(BMessage& settings)
|
||||
{
|
||||
BFile file;
|
||||
status_t status = _OpenSettings(file, B_READ_ONLY);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return settings.Unflatten(&file);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ActivityWindow::_SaveSettings()
|
||||
{
|
||||
BFile file;
|
||||
status_t status = _OpenSettings(file, B_WRITE_ONLY | B_CREATE_FILE
|
||||
| B_ERASE_FILE);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
BMessage settings('actm');
|
||||
status = settings.AddRect("window frame", Frame());
|
||||
if (status == B_OK)
|
||||
status = settings.Flatten(&file);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityWindow::_MessageDropped(BMessage* message)
|
||||
{
|
||||
entry_ref ref;
|
||||
if (message->FindRef("refs", &ref) != B_OK) {
|
||||
// TODO: If app, then launch it, and add ActivityView for this one?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivityWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
if (message->WasDropped()) {
|
||||
_MessageDropped(message);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (message->what) {
|
||||
case B_REFS_RECEIVED:
|
||||
case B_SIMPLE_DATA:
|
||||
_MessageDropped(message);
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ActivityWindow::QuitRequested()
|
||||
{
|
||||
_SaveSettings();
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ACTIVITY_WINDOW_H
|
||||
#define ACTIVITY_WINDOW_H
|
||||
|
||||
|
||||
#include <Window.h>
|
||||
|
||||
class BFile;
|
||||
class ActivityView;
|
||||
|
||||
|
||||
class ActivityWindow : public BWindow {
|
||||
public:
|
||||
ActivityWindow();
|
||||
virtual ~ActivityWindow();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual bool QuitRequested();
|
||||
|
||||
private:
|
||||
status_t _OpenSettings(BFile& file, uint32 mode);
|
||||
status_t _LoadSettings(BMessage& settings);
|
||||
status_t _SaveSettings();
|
||||
|
||||
void _MessageDropped(BMessage *message);
|
||||
|
||||
ActivityView* fActivityView;
|
||||
};
|
||||
|
||||
#endif // ACTIVITY_WINDOW_H
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef CIRCULAR_BUFFER_H
|
||||
#define CIRCULAR_BUFFER_H
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
template<typename Type>
|
||||
class CircularBuffer {
|
||||
public:
|
||||
CircularBuffer(size_t size)
|
||||
:
|
||||
fSize(size)
|
||||
{
|
||||
fBuffer = (Type *)malloc(fSize * sizeof(Type));
|
||||
MakeEmpty();
|
||||
}
|
||||
|
||||
~CircularBuffer()
|
||||
{
|
||||
free(fBuffer);
|
||||
}
|
||||
|
||||
status_t InitCheck() const
|
||||
{
|
||||
return fBuffer != NULL ? B_OK : B_NO_MEMORY;
|
||||
}
|
||||
|
||||
void MakeEmpty()
|
||||
{
|
||||
fIn = 0;
|
||||
fFirst = 0;
|
||||
}
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return fIn == 0;
|
||||
}
|
||||
|
||||
int32 CountItems() const
|
||||
{
|
||||
return fIn;
|
||||
}
|
||||
|
||||
Type* ItemAt(int32 index) const
|
||||
{
|
||||
if (index >= (int32)fIn || index < 0)
|
||||
return NULL;
|
||||
|
||||
return &fBuffer[(fFirst + index) % fSize];
|
||||
}
|
||||
|
||||
void AddItem(const Type& item)
|
||||
{
|
||||
uint32 index;
|
||||
if (fIn < fSize)
|
||||
index = fFirst + fIn++;
|
||||
else
|
||||
index = fFirst++;
|
||||
|
||||
fBuffer[index % fSize] = item;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 fFirst;
|
||||
uint32 fIn;
|
||||
uint32 fSize;
|
||||
Type* fBuffer;
|
||||
};
|
||||
|
||||
#endif // CIRCULAR_BUFFER_H
|
||||
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "DataSource.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <OS.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "SystemInfo.h"
|
||||
|
||||
|
||||
const DataSource* kSources[] = {
|
||||
new UsedMemoryDataSource(),
|
||||
new CachedMemoryDataSource(),
|
||||
new ThreadsDataSource(),
|
||||
new CpuUsageDataSource(),
|
||||
};
|
||||
const size_t kSourcesCount = sizeof(kSources) / sizeof(kSources[0]);
|
||||
|
||||
|
||||
DataSource::DataSource(int64 initialMin, int64 initialMax)
|
||||
:
|
||||
fMinimum(initialMin),
|
||||
fMaximum(initialMax),
|
||||
fInterval(1000000LL),
|
||||
fColor((rgb_color){200, 0, 0})
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataSource::DataSource()
|
||||
:
|
||||
fMinimum(0),
|
||||
fMaximum(100),
|
||||
fInterval(1000000LL),
|
||||
fColor((rgb_color){200, 0, 0})
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataSource::DataSource(const DataSource& other)
|
||||
{
|
||||
fMinimum = other.fMinimum;
|
||||
fMaximum = other.fMaximum;
|
||||
fInterval = other.fInterval;
|
||||
fColor = other.fColor;
|
||||
}
|
||||
|
||||
|
||||
DataSource::~DataSource()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataSource*
|
||||
DataSource::Copy() const
|
||||
{
|
||||
return NULL;
|
||||
// this class cannot be copied
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
DataSource::Minimum() const
|
||||
{
|
||||
return fMinimum;
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
DataSource::Maximum() const
|
||||
{
|
||||
return fMaximum;
|
||||
}
|
||||
|
||||
|
||||
bigtime_t
|
||||
DataSource::RefreshInterval() const
|
||||
{
|
||||
return fInterval;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DataSource::SetLimits(int64 min, int64 max)
|
||||
{
|
||||
fMinimum = min;
|
||||
fMaximum = max;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DataSource::SetRefreshInterval(bigtime_t interval)
|
||||
{
|
||||
fInterval = interval;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DataSource::SetColor(rgb_color color)
|
||||
{
|
||||
fColor = color;
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
DataSource::NextValue(SystemInfo& info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DataSource::Print(BString& text, int64 value) const
|
||||
{
|
||||
text = "";
|
||||
text << value;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
DataSource::Label() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
DataSource::Unit() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
rgb_color
|
||||
DataSource::Color() const
|
||||
{
|
||||
return fColor;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DataSource::AdaptiveScale() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ int32
|
||||
DataSource::CountSources()
|
||||
{
|
||||
return kSourcesCount;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ const DataSource*
|
||||
DataSource::SourceAt(int32 index)
|
||||
{
|
||||
if (index >= (int32)kSourcesCount || index < 0)
|
||||
return NULL;
|
||||
|
||||
return kSources[index];
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
MemoryDataSource::MemoryDataSource()
|
||||
{
|
||||
SystemInfo info;
|
||||
|
||||
fMinimum = 0;
|
||||
fMaximum = info.MaxMemory();
|
||||
}
|
||||
|
||||
|
||||
MemoryDataSource::~MemoryDataSource()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryDataSource::Print(BString& text, int64 value) const
|
||||
{
|
||||
char buffer[32];
|
||||
snprintf(buffer, sizeof(buffer), "%.1g MB", value / 1048576.0);
|
||||
|
||||
text = buffer;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
MemoryDataSource::Unit() const
|
||||
{
|
||||
return "MB";
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
UsedMemoryDataSource::UsedMemoryDataSource()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
UsedMemoryDataSource::~UsedMemoryDataSource()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataSource*
|
||||
UsedMemoryDataSource::Copy() const
|
||||
{
|
||||
return new UsedMemoryDataSource(*this);
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
UsedMemoryDataSource::NextValue(SystemInfo& info)
|
||||
{
|
||||
return info.UsedMemory();
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
UsedMemoryDataSource::Label() const
|
||||
{
|
||||
return "Available Memory";
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
CachedMemoryDataSource::CachedMemoryDataSource()
|
||||
{
|
||||
fColor = (rgb_color){0, 200, 0};
|
||||
}
|
||||
|
||||
|
||||
CachedMemoryDataSource::~CachedMemoryDataSource()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataSource*
|
||||
CachedMemoryDataSource::Copy() const
|
||||
{
|
||||
return new CachedMemoryDataSource(*this);
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
CachedMemoryDataSource::NextValue(SystemInfo& info)
|
||||
{
|
||||
return info.CachedMemory();
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
CachedMemoryDataSource::Label() const
|
||||
{
|
||||
return "Cached Memory";
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
ThreadsDataSource::ThreadsDataSource()
|
||||
{
|
||||
SystemInfo info;
|
||||
|
||||
fMinimum = 0;
|
||||
fMaximum = info.MaxThreads();
|
||||
|
||||
fColor = (rgb_color){0, 0, 200};
|
||||
}
|
||||
|
||||
|
||||
ThreadsDataSource::~ThreadsDataSource()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataSource*
|
||||
ThreadsDataSource::Copy() const
|
||||
{
|
||||
return new ThreadsDataSource(*this);
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
ThreadsDataSource::NextValue(SystemInfo& info)
|
||||
{
|
||||
return info.UsedThreads();
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
ThreadsDataSource::Label() const
|
||||
{
|
||||
return "Threads";
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ThreadsDataSource::AdaptiveScale() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
CpuUsageDataSource::CpuUsageDataSource()
|
||||
:
|
||||
fPreviousActive(0),
|
||||
fPreviousTime(0)
|
||||
{
|
||||
fMinimum = 0;
|
||||
fMaximum = 1000;
|
||||
|
||||
fColor = (rgb_color){200, 200, 0};
|
||||
}
|
||||
|
||||
|
||||
CpuUsageDataSource::CpuUsageDataSource(const CpuUsageDataSource& other)
|
||||
{
|
||||
fPreviousActive = other.fPreviousActive;
|
||||
fPreviousTime = other.fPreviousTime;
|
||||
}
|
||||
|
||||
|
||||
CpuUsageDataSource::~CpuUsageDataSource()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataSource*
|
||||
CpuUsageDataSource::Copy() const
|
||||
{
|
||||
return new CpuUsageDataSource(*this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CpuUsageDataSource::Print(BString& text, int64 value) const
|
||||
{
|
||||
char buffer[32];
|
||||
snprintf(buffer, sizeof(buffer), "%.1g%%", value / 10.0);
|
||||
|
||||
text = buffer;
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
CpuUsageDataSource::NextValue(SystemInfo& info)
|
||||
{
|
||||
int32 running = 0;
|
||||
bigtime_t active = 0;
|
||||
|
||||
for (int32 cpu = 0; cpu < info.Info().cpu_count; cpu++) {
|
||||
active += info.Info().cpu_infos[cpu].active_time;
|
||||
running++;
|
||||
// TODO: take disabled CPUs into account
|
||||
}
|
||||
|
||||
int64 percent = int64(1000.0 * (active - fPreviousActive)
|
||||
/ (running * (info.Time() - fPreviousTime)));
|
||||
if (percent < 0)
|
||||
percent = 0;
|
||||
if (percent > 1000)
|
||||
percent = 1000;
|
||||
|
||||
fPreviousActive = active;
|
||||
fPreviousTime = info.Time();
|
||||
|
||||
return percent;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
CpuUsageDataSource::Label() const
|
||||
{
|
||||
return "CPU Usage";
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef DATA_SOURCE_H
|
||||
#define DATA_SOURCE_H
|
||||
|
||||
|
||||
#include <InterfaceDefs.h>
|
||||
|
||||
class BString;
|
||||
class SystemInfo;
|
||||
|
||||
|
||||
class DataSource {
|
||||
public:
|
||||
DataSource(int64 initialMin, int64 initialMax);
|
||||
DataSource();
|
||||
DataSource(const DataSource& other);
|
||||
virtual ~DataSource();
|
||||
|
||||
virtual DataSource* Copy() const;
|
||||
|
||||
int64 Minimum() const;
|
||||
int64 Maximum() const;
|
||||
bigtime_t RefreshInterval() const;
|
||||
|
||||
virtual void SetLimits(int64 min, int64 max);
|
||||
virtual void SetRefreshInterval(bigtime_t interval);
|
||||
virtual void SetColor(rgb_color color);
|
||||
|
||||
virtual int64 NextValue(SystemInfo& info);
|
||||
virtual void Print(BString& text, int64 value) const;
|
||||
|
||||
virtual const char* Label() const;
|
||||
virtual const char* Unit() const;
|
||||
virtual rgb_color Color() const;
|
||||
virtual bool AdaptiveScale() const;
|
||||
|
||||
static int32 CountSources();
|
||||
static const DataSource* SourceAt(int32 index);
|
||||
|
||||
protected:
|
||||
int64 fMinimum;
|
||||
int64 fMaximum;
|
||||
bigtime_t fInterval;
|
||||
rgb_color fColor;
|
||||
};
|
||||
|
||||
|
||||
class MemoryDataSource : public DataSource {
|
||||
public:
|
||||
MemoryDataSource();
|
||||
virtual ~MemoryDataSource();
|
||||
|
||||
virtual void Print(BString& text, int64 value) const;
|
||||
virtual const char* Unit() const;
|
||||
};
|
||||
|
||||
|
||||
class UsedMemoryDataSource : public MemoryDataSource {
|
||||
public:
|
||||
UsedMemoryDataSource();
|
||||
virtual ~UsedMemoryDataSource();
|
||||
|
||||
virtual DataSource* Copy() const;
|
||||
|
||||
virtual int64 NextValue(SystemInfo& info);
|
||||
virtual const char* Label() const;
|
||||
};
|
||||
|
||||
|
||||
class CachedMemoryDataSource : public MemoryDataSource {
|
||||
public:
|
||||
CachedMemoryDataSource();
|
||||
virtual ~CachedMemoryDataSource();
|
||||
|
||||
virtual DataSource* Copy() const;
|
||||
|
||||
virtual int64 NextValue(SystemInfo& info);
|
||||
virtual const char* Label() const;
|
||||
};
|
||||
|
||||
|
||||
class ThreadsDataSource : public DataSource {
|
||||
public:
|
||||
ThreadsDataSource();
|
||||
virtual ~ThreadsDataSource();
|
||||
|
||||
virtual DataSource* Copy() const;
|
||||
|
||||
virtual int64 NextValue(SystemInfo& info);
|
||||
virtual const char* Label() const;
|
||||
virtual bool AdaptiveScale() const;
|
||||
};
|
||||
|
||||
|
||||
class CpuUsageDataSource : public DataSource {
|
||||
public:
|
||||
CpuUsageDataSource();
|
||||
CpuUsageDataSource(const CpuUsageDataSource& other);
|
||||
virtual ~CpuUsageDataSource();
|
||||
|
||||
virtual DataSource* Copy() const;
|
||||
|
||||
virtual void Print(BString& text, int64 value) const;
|
||||
virtual int64 NextValue(SystemInfo& info);
|
||||
virtual const char* Label() const;
|
||||
|
||||
private:
|
||||
bigtime_t fPreviousActive;
|
||||
bigtime_t fPreviousTime;
|
||||
};
|
||||
|
||||
#endif // DATA_SOURCE_H
|
||||
@@ -0,0 +1,16 @@
|
||||
SubDir HAIKU_TOP src apps activitymonitor ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders shared ;
|
||||
|
||||
Application ActivityMonitor :
|
||||
ActivityMonitor.cpp
|
||||
ActivityView.cpp
|
||||
ActivityWindow.cpp
|
||||
DataSource.cpp
|
||||
SystemInfo.cpp
|
||||
|
||||
: be tracker $(TARGET_LIBSTDC++)
|
||||
: ActivityMonitor.rdef
|
||||
;
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "SystemInfo.h"
|
||||
|
||||
|
||||
SystemInfo::SystemInfo()
|
||||
:
|
||||
fTime(system_time())
|
||||
{
|
||||
get_system_info(&fSystemInfo);
|
||||
}
|
||||
|
||||
|
||||
SystemInfo::~SystemInfo()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
uint64
|
||||
SystemInfo::CachedMemory() const
|
||||
{
|
||||
return fSystemInfo.cached_pages * B_PAGE_SIZE;
|
||||
}
|
||||
|
||||
|
||||
uint64
|
||||
SystemInfo::UsedMemory() const
|
||||
{
|
||||
return fSystemInfo.used_pages * B_PAGE_SIZE;
|
||||
}
|
||||
|
||||
|
||||
uint64
|
||||
SystemInfo::MaxMemory() const
|
||||
{
|
||||
return fSystemInfo.max_pages * B_PAGE_SIZE;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
SystemInfo::UsedThreads() const
|
||||
{
|
||||
return fSystemInfo.used_threads;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
SystemInfo::MaxThreads() const
|
||||
{
|
||||
return fSystemInfo.max_threads;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
SystemInfo::UsedTeams() const
|
||||
{
|
||||
return fSystemInfo.used_teams;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
SystemInfo::MaxTeams() const
|
||||
{
|
||||
return fSystemInfo.max_teams;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef SYSTEM_INFO_H
|
||||
#define SYSTEM_INFO_H
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
class SystemInfo {
|
||||
public:
|
||||
SystemInfo();
|
||||
~SystemInfo();
|
||||
|
||||
uint64 CachedMemory() const;
|
||||
uint64 UsedMemory() const;
|
||||
uint64 MaxMemory() const;
|
||||
|
||||
uint32 UsedThreads() const;
|
||||
uint32 MaxThreads() const;
|
||||
|
||||
uint32 UsedTeams() const;
|
||||
uint32 MaxTeams() const;
|
||||
|
||||
bigtime_t Time() const { return fTime; }
|
||||
const system_info& Info() const { return fSystemInfo; }
|
||||
|
||||
private:
|
||||
system_info fSystemInfo;
|
||||
bigtime_t fTime;
|
||||
};
|
||||
|
||||
#endif // SYSTEM_INFO_H
|
||||
Reference in New Issue
Block a user