* Offloaded the data source retrieval into another thread for more accuracy.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26434 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
# include <AbstractLayoutItem.h>
|
# include <AbstractLayoutItem.h>
|
||||||
#endif
|
#endif
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
|
#include <Autolock.h>
|
||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
#include <Dragger.h>
|
#include <Dragger.h>
|
||||||
#include <MenuItem.h>
|
#include <MenuItem.h>
|
||||||
@@ -93,7 +94,6 @@ private:
|
|||||||
|
|
||||||
const bigtime_t kInitialRefreshInterval = 500000LL;
|
const bigtime_t kInitialRefreshInterval = 500000LL;
|
||||||
|
|
||||||
const uint32 kMsgRefresh = 'refr';
|
|
||||||
const uint32 kMsgToggleDataSource = 'tgds';
|
const uint32 kMsgToggleDataSource = 'tgds';
|
||||||
const uint32 kMsgToggleLegend = 'tglg';
|
const uint32 kMsgToggleLegend = 'tglg';
|
||||||
|
|
||||||
@@ -392,7 +392,8 @@ ActivityView::LegendLayoutItem::BaseAlignment()
|
|||||||
ActivityView::ActivityView(BRect frame, const char* name,
|
ActivityView::ActivityView(BRect frame, const char* name,
|
||||||
const BMessage* settings, uint32 resizingMode)
|
const BMessage* settings, uint32 resizingMode)
|
||||||
: BView(frame, name, resizingMode,
|
: BView(frame, name, resizingMode,
|
||||||
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS)
|
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
|
||||||
|
fSourcesLock("data sources")
|
||||||
{
|
{
|
||||||
_Init(settings);
|
_Init(settings);
|
||||||
|
|
||||||
@@ -407,10 +408,12 @@ ActivityView::ActivityView(BRect frame, const char* name,
|
|||||||
|
|
||||||
ActivityView::ActivityView(const char* name, const BMessage* settings)
|
ActivityView::ActivityView(const char* name, const BMessage* settings)
|
||||||
#ifdef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
: BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS)
|
: BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
|
||||||
#else
|
#else
|
||||||
: BView(BRect(0,0,300,200), name, B_FOLLOW_NONE, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS)
|
: BView(BRect(0,0,300,200), name, B_FOLLOW_NONE,
|
||||||
|
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
|
||||||
#endif
|
#endif
|
||||||
|
fSourcesLock("data sources")
|
||||||
{
|
{
|
||||||
SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
|
||||||
@@ -585,6 +588,8 @@ ActivityView::CreateLegendLayoutItem()
|
|||||||
DataSource*
|
DataSource*
|
||||||
ActivityView::FindDataSource(const DataSource* search)
|
ActivityView::FindDataSource(const DataSource* search)
|
||||||
{
|
{
|
||||||
|
BAutolock _(fSourcesLock);
|
||||||
|
|
||||||
for (int32 i = fSources.CountItems(); i-- > 0;) {
|
for (int32 i = fSources.CountItems(); i-- > 0;) {
|
||||||
DataSource* source = fSources.ItemAt(i);
|
DataSource* source = fSources.ItemAt(i);
|
||||||
if (!strcmp(source->Name(), search->Name()))
|
if (!strcmp(source->Name(), search->Name()))
|
||||||
@@ -601,6 +606,8 @@ ActivityView::AddDataSource(const DataSource* source, const BMessage* state)
|
|||||||
if (source == NULL)
|
if (source == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
BAutolock _(fSourcesLock);
|
||||||
|
|
||||||
int32 insert = DataSource::IndexOf(source);
|
int32 insert = DataSource::IndexOf(source);
|
||||||
for (int32 i = 0; i < fSources.CountItems() && i < insert; i++) {
|
for (int32 i = 0; i < fSources.CountItems() && i < insert; i++) {
|
||||||
DataSource* before = fSources.ItemAt(i);
|
DataSource* before = fSources.ItemAt(i);
|
||||||
@@ -667,6 +674,8 @@ ActivityView::RemoveDataSource(const DataSource* remove)
|
|||||||
{
|
{
|
||||||
bool removed = false;
|
bool removed = false;
|
||||||
|
|
||||||
|
BAutolock _(fSourcesLock);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
DataSource* source = FindDataSource(remove);
|
DataSource* source = FindDataSource(remove);
|
||||||
debug_printf("SEARCH %s, found %p\n", remove->Name(), source);
|
debug_printf("SEARCH %s, found %p\n", remove->Name(), source);
|
||||||
@@ -697,6 +706,8 @@ debug_printf("SEARCH %s, found %p\n", remove->Name(), source);
|
|||||||
void
|
void
|
||||||
ActivityView::RemoveAllDataSources()
|
ActivityView::RemoveAllDataSources()
|
||||||
{
|
{
|
||||||
|
BAutolock _(fSourcesLock);
|
||||||
|
|
||||||
fSources.MakeEmpty();
|
fSources.MakeEmpty();
|
||||||
fValues.MakeEmpty();
|
fValues.MakeEmpty();
|
||||||
}
|
}
|
||||||
@@ -708,8 +719,10 @@ ActivityView::AttachedToWindow()
|
|||||||
Looper()->AddHandler(fSystemInfoHandler);
|
Looper()->AddHandler(fSystemInfoHandler);
|
||||||
fSystemInfoHandler->StartWatching();
|
fSystemInfoHandler->StartWatching();
|
||||||
|
|
||||||
BMessage refresh(kMsgRefresh);
|
fRefreshSem = create_sem(0, "refresh sem");
|
||||||
fRunner = new BMessageRunner(this, &refresh, fRefreshInterval);
|
fRefreshThread = spawn_thread(&_RefreshThread, "source refresh",
|
||||||
|
B_NORMAL_PRIORITY, this);
|
||||||
|
resume_thread(fRefreshThread);
|
||||||
|
|
||||||
FrameResized(Bounds().Width(), Bounds().Height());
|
FrameResized(Bounds().Width(), Bounds().Height());
|
||||||
}
|
}
|
||||||
@@ -721,7 +734,8 @@ ActivityView::DetachedFromWindow()
|
|||||||
fSystemInfoHandler->StopWatching();
|
fSystemInfoHandler->StopWatching();
|
||||||
Looper()->RemoveHandler(fSystemInfoHandler);
|
Looper()->RemoveHandler(fSystemInfoHandler);
|
||||||
|
|
||||||
delete fRunner;
|
delete_sem(fRefreshSem);
|
||||||
|
wait_for_thread(fRefreshThread, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -896,6 +910,8 @@ ActivityView::MessageReceived(BMessage* message)
|
|||||||
Invalidate(_HistoryFrame());
|
Invalidate(_HistoryFrame());
|
||||||
} else {
|
} else {
|
||||||
// check each legend color box
|
// check each legend color box
|
||||||
|
BAutolock _(fSourcesLock);
|
||||||
|
|
||||||
BRect legendFrame = _LegendFrame();
|
BRect legendFrame = _LegendFrame();
|
||||||
for (int32 i = 0; i < fSources.CountItems(); i++) {
|
for (int32 i = 0; i < fSources.CountItems(); i++) {
|
||||||
BRect frame = _LegendColorFrameAt(legendFrame, i);
|
BRect frame = _LegendColorFrameAt(legendFrame, i);
|
||||||
@@ -923,10 +939,6 @@ ActivityView::MessageReceived(BMessage* message)
|
|||||||
ActivityMonitor::ShowAbout();
|
ActivityMonitor::ShowAbout();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kMsgRefresh:
|
|
||||||
_Refresh();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kMsgToggleDataSource:
|
case kMsgToggleDataSource:
|
||||||
{
|
{
|
||||||
int32 index;
|
int32 index;
|
||||||
@@ -1022,6 +1034,8 @@ ActivityView::_LegendHeight() const
|
|||||||
font_height fontHeight;
|
font_height fontHeight;
|
||||||
GetFontHeight(&fontHeight);
|
GetFontHeight(&fontHeight);
|
||||||
|
|
||||||
|
BAutolock _(fSourcesLock);
|
||||||
|
|
||||||
int32 rows = (fSources.CountItems() + 1) / 2;
|
int32 rows = (fSources.CountItems() + 1) / 2;
|
||||||
return rows * (4 + ceilf(fontHeight.ascent)
|
return rows * (4 + ceilf(fontHeight.ascent)
|
||||||
+ ceilf(fontHeight.descent) + ceilf(fontHeight.leading));
|
+ ceilf(fontHeight.descent) + ceilf(fontHeight.leading));
|
||||||
@@ -1056,6 +1070,8 @@ ActivityView::_LegendFrameAt(BRect frame, int32 index) const
|
|||||||
else
|
else
|
||||||
frame.left = frame.right - floorf(frame.Width() / 2) + 5;
|
frame.left = frame.right - floorf(frame.Width() / 2) + 5;
|
||||||
|
|
||||||
|
BAutolock _(fSourcesLock);
|
||||||
|
|
||||||
int32 rows = (fSources.CountItems() + 1) / 2;
|
int32 rows = (fSources.CountItems() + 1) / 2;
|
||||||
float height = floorf((frame.Height() - 5) / rows);
|
float height = floorf((frame.Height() - 5) / rows);
|
||||||
|
|
||||||
@@ -1146,6 +1162,7 @@ ActivityView::_DrawHistory()
|
|||||||
// Draw values
|
// Draw values
|
||||||
|
|
||||||
view->SetPenSize(2);
|
view->SetPenSize(2);
|
||||||
|
BAutolock _(fSourcesLock);
|
||||||
|
|
||||||
for (uint32 i = fSources.CountItems(); i-- > 0;) {
|
for (uint32 i = fSources.CountItems(); i-- > 0;) {
|
||||||
DataSource* source = fSources.ItemAt(i);
|
DataSource* source = fSources.ItemAt(i);
|
||||||
@@ -1210,6 +1227,7 @@ ActivityView::Draw(BRect /*updateRect*/)
|
|||||||
|
|
||||||
// draw legend
|
// draw legend
|
||||||
|
|
||||||
|
BAutolock _(fSourcesLock);
|
||||||
BRect legendFrame = _LegendFrame();
|
BRect legendFrame = _LegendFrame();
|
||||||
|
|
||||||
SetLowColor(fLegendBackgroundColor);
|
SetLowColor(fLegendBackgroundColor);
|
||||||
@@ -1252,22 +1270,46 @@ ActivityView::Draw(BRect /*updateRect*/)
|
|||||||
void
|
void
|
||||||
ActivityView::_Refresh()
|
ActivityView::_Refresh()
|
||||||
{
|
{
|
||||||
SystemInfo info(fSystemInfoHandler);
|
bigtime_t lastTimeout = system_time() - fRefreshInterval;
|
||||||
|
|
||||||
// TODO: run refresh in another thread to decouple it from the UI!
|
while (true) {
|
||||||
|
status_t status = acquire_sem_etc(fRefreshSem, 1, B_ABSOLUTE_TIMEOUT,
|
||||||
|
lastTimeout + fRefreshInterval);
|
||||||
|
if (status == B_OK || status == B_BAD_SEM_ID)
|
||||||
|
break;
|
||||||
|
if (status == B_INTERRUPTED)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (uint32 i = fSources.CountItems(); i-- > 0;) {
|
SystemInfo info(fSystemInfoHandler);
|
||||||
DataSource* source = fSources.ItemAt(i);
|
lastTimeout += fRefreshInterval;
|
||||||
DataHistory* values = fValues.ItemAt(i);
|
|
||||||
|
|
||||||
int64 value = source->NextValue(info);
|
fSourcesLock.Lock();
|
||||||
values->AddValue(info.Time(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bigtime_t now = info.Time();
|
for (uint32 i = fSources.CountItems(); i-- > 0;) {
|
||||||
if (fLastRefresh + fDrawInterval <= now) {
|
DataSource* source = fSources.ItemAt(i);
|
||||||
Invalidate();
|
DataHistory* values = fValues.ItemAt(i);
|
||||||
fLastRefresh = now;
|
|
||||||
|
int64 value = source->NextValue(info);
|
||||||
|
values->AddValue(info.Time(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
fSourcesLock.Unlock();
|
||||||
|
|
||||||
|
bigtime_t now = info.Time();
|
||||||
|
if (fLastRefresh + fDrawInterval <= now) {
|
||||||
|
if (LockLooper()) {
|
||||||
|
Invalidate();
|
||||||
|
UnlockLooper();
|
||||||
|
fLastRefresh = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ status_t
|
||||||
|
ActivityView::_RefreshThread(void* self)
|
||||||
|
{
|
||||||
|
((ActivityView*)self)->_Refresh();
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,8 +8,9 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <View.h>
|
#include <Locker.h>
|
||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
#include "CircularBuffer.h"
|
#include "CircularBuffer.h"
|
||||||
#include "DataSource.h"
|
#include "DataSource.h"
|
||||||
@@ -95,6 +96,7 @@ private:
|
|||||||
void _Init(const BMessage* settings);
|
void _Init(const BMessage* settings);
|
||||||
::Scale* _ScaleFor(scale_type type);
|
::Scale* _ScaleFor(scale_type type);
|
||||||
void _Refresh();
|
void _Refresh();
|
||||||
|
static status_t _RefreshThread(void* self);
|
||||||
void _UpdateOffscreenBitmap();
|
void _UpdateOffscreenBitmap();
|
||||||
BView* _OffscreenView();
|
BView* _OffscreenView();
|
||||||
void _UpdateFrame();
|
void _UpdateFrame();
|
||||||
@@ -121,9 +123,11 @@ private:
|
|||||||
BLayoutItem* fHistoryLayoutItem;
|
BLayoutItem* fHistoryLayoutItem;
|
||||||
BLayoutItem* fLegendLayoutItem;
|
BLayoutItem* fLegendLayoutItem;
|
||||||
#endif
|
#endif
|
||||||
|
mutable BLocker fSourcesLock;
|
||||||
BObjectList<DataSource> fSources;
|
BObjectList<DataSource> fSources;
|
||||||
BObjectList<DataHistory> fValues;
|
BObjectList<DataHistory> fValues;
|
||||||
BMessageRunner* fRunner;
|
thread_id fRefreshThread;
|
||||||
|
sem_id fRefreshSem;
|
||||||
bigtime_t fRefreshInterval;
|
bigtime_t fRefreshInterval;
|
||||||
bigtime_t fLastRefresh;
|
bigtime_t fLastRefresh;
|
||||||
bigtime_t fDrawInterval;
|
bigtime_t fDrawInterval;
|
||||||
|
|||||||
Reference in New Issue
Block a user