xref: /haiku/src/apps/processcontroller/TeamBarMenu.cpp (revision ed7a35012e2c301208b3a6b720cf389876f47ac5)
1*ed7a3501SAxel Dörfler /*
2*ed7a3501SAxel Dörfler 
3*ed7a3501SAxel Dörfler 	TeamBarMenu.cpp
4*ed7a3501SAxel Dörfler 
5*ed7a3501SAxel Dörfler 	ProcessController
6*ed7a3501SAxel Dörfler 	� 2000, Georges-Edouard Berenger, All Rights Reserved.
7*ed7a3501SAxel Dörfler 	Copyright (C) 2004 beunited.org
8*ed7a3501SAxel Dörfler 
9*ed7a3501SAxel Dörfler 	This library is free software; you can redistribute it and/or
10*ed7a3501SAxel Dörfler 	modify it under the terms of the GNU Lesser General Public
11*ed7a3501SAxel Dörfler 	License as published by the Free Software Foundation; either
12*ed7a3501SAxel Dörfler 	version 2.1 of the License, or (at your option) any later version.
13*ed7a3501SAxel Dörfler 
14*ed7a3501SAxel Dörfler 	This library is distributed in the hope that it will be useful,
15*ed7a3501SAxel Dörfler 	but WITHOUT ANY WARRANTY; without even the implied warranty of
16*ed7a3501SAxel Dörfler 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17*ed7a3501SAxel Dörfler 	Lesser General Public License for more details.
18*ed7a3501SAxel Dörfler 
19*ed7a3501SAxel Dörfler 	You should have received a copy of the GNU Lesser General Public
20*ed7a3501SAxel Dörfler 	License along with this library; if not, write to the Free Software
21*ed7a3501SAxel Dörfler 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22*ed7a3501SAxel Dörfler 
23*ed7a3501SAxel Dörfler */
24*ed7a3501SAxel Dörfler 
25*ed7a3501SAxel Dörfler #include <Roster.h>
26*ed7a3501SAxel Dörfler #include <Bitmap.h>
27*ed7a3501SAxel Dörfler #include <stdlib.h>
28*ed7a3501SAxel Dörfler #include "TeamBarMenu.h"
29*ed7a3501SAxel Dörfler #include "ThreadBarMenu.h"
30*ed7a3501SAxel Dörfler #include "TeamBarMenuItem.h"
31*ed7a3501SAxel Dörfler #include "NoiseBarMenuItem.h"
32*ed7a3501SAxel Dörfler #include "PCView.h"
33*ed7a3501SAxel Dörfler #include <Window.h>
34*ed7a3501SAxel Dörfler 
35*ed7a3501SAxel Dörfler #define EXTRA 10
36*ed7a3501SAxel Dörfler 
37*ed7a3501SAxel Dörfler TeamBarMenu::TeamBarMenu (const char *title, infosPack *infos, int32 teamCount)
38*ed7a3501SAxel Dörfler 	:BMenu (title), fTeamCount (teamCount+EXTRA), fFirstShow (true)
39*ed7a3501SAxel Dörfler {
40*ed7a3501SAxel Dörfler 	SetFlags (Flags () | B_PULSE_NEEDED);
41*ed7a3501SAxel Dörfler 	fTeamList = (team_id*) malloc (sizeof (team_id) * fTeamCount);
42*ed7a3501SAxel Dörfler 	int	k;
43*ed7a3501SAxel Dörfler 	for (k = 0; k < teamCount; k++)
44*ed7a3501SAxel Dörfler 		fTeamList[k] = infos[k].tminfo.team;
45*ed7a3501SAxel Dörfler 	while (k < fTeamCount)
46*ed7a3501SAxel Dörfler 		fTeamList[k++] = -1;
47*ed7a3501SAxel Dörfler 	fRecycleCount = EXTRA;
48*ed7a3501SAxel Dörfler 	fRecycleList = (TRecycleItem*) malloc (sizeof (TRecycleItem) * fRecycleCount);
49*ed7a3501SAxel Dörfler 	SetFont (be_plain_font);
50*ed7a3501SAxel Dörfler 	gCurrentThreadBarMenu = NULL;
51*ed7a3501SAxel Dörfler 	fLastTotalTime = system_time ();
52*ed7a3501SAxel Dörfler 	AddItem (new NoiseBarMenuItem ());
53*ed7a3501SAxel Dörfler }
54*ed7a3501SAxel Dörfler 
55*ed7a3501SAxel Dörfler TeamBarMenu::~TeamBarMenu ()
56*ed7a3501SAxel Dörfler {
57*ed7a3501SAxel Dörfler 	gCurrentThreadBarMenu = NULL;
58*ed7a3501SAxel Dörfler 	free (fTeamList);
59*ed7a3501SAxel Dörfler 	free (fRecycleList);
60*ed7a3501SAxel Dörfler }
61*ed7a3501SAxel Dörfler 
62*ed7a3501SAxel Dörfler void TeamBarMenu::Draw (BRect updateRect)
63*ed7a3501SAxel Dörfler {
64*ed7a3501SAxel Dörfler 	BMenu::Draw (updateRect);
65*ed7a3501SAxel Dörfler 	if (fFirstShow)
66*ed7a3501SAxel Dörfler 	{
67*ed7a3501SAxel Dörfler 		Pulse ();
68*ed7a3501SAxel Dörfler 		fFirstShow = false;
69*ed7a3501SAxel Dörfler 	}
70*ed7a3501SAxel Dörfler }
71*ed7a3501SAxel Dörfler 
72*ed7a3501SAxel Dörfler void TeamBarMenu::Pulse ()
73*ed7a3501SAxel Dörfler {
74*ed7a3501SAxel Dörfler //	Window ()->SetPulseRate (50000);
75*ed7a3501SAxel Dörfler 	Window ()->BeginViewTransaction ();
76*ed7a3501SAxel Dörfler 
77*ed7a3501SAxel Dörfler 	// create the list of items to remove, for their team is gone. Update the old teams.
78*ed7a3501SAxel Dörfler 	int lastRecycle = 0;
79*ed7a3501SAxel Dörfler 	int firstRecycle = 0;
80*ed7a3501SAxel Dörfler 	int	k;
81*ed7a3501SAxel Dörfler 	TeamBarMenuItem *item;
82*ed7a3501SAxel Dörfler 	double			total = 0;
83*ed7a3501SAxel Dörfler 	for (k = 1; (item = (TeamBarMenuItem*) ItemAt(k)) != NULL; k++) {
84*ed7a3501SAxel Dörfler 		item->BarUpdate();
85*ed7a3501SAxel Dörfler 		if (item->fKernel < 0) {
86*ed7a3501SAxel Dörfler 			if (lastRecycle == fRecycleCount) {
87*ed7a3501SAxel Dörfler 				fRecycleCount += EXTRA;
88*ed7a3501SAxel Dörfler 				fRecycleList = (TRecycleItem*) realloc(fRecycleList, sizeof(TRecycleItem)*fRecycleCount);
89*ed7a3501SAxel Dörfler 			}
90*ed7a3501SAxel Dörfler 			fRecycleList[lastRecycle].index = k;
91*ed7a3501SAxel Dörfler 			fRecycleList[lastRecycle++].item = item;
92*ed7a3501SAxel Dörfler 		} else {
93*ed7a3501SAxel Dörfler 			if (lastRecycle > 0) {
94*ed7a3501SAxel Dörfler 				RemoveItems(fRecycleList[0].index, lastRecycle, true);
95*ed7a3501SAxel Dörfler 				k -= lastRecycle;
96*ed7a3501SAxel Dörfler 				lastRecycle = 0;
97*ed7a3501SAxel Dörfler 			}
98*ed7a3501SAxel Dörfler 			total += item->fUser+item->fKernel;
99*ed7a3501SAxel Dörfler 		}
100*ed7a3501SAxel Dörfler 	}
101*ed7a3501SAxel Dörfler 
102*ed7a3501SAxel Dörfler 	// Look new teams that have appeared. Create an item for them, or recycle from the list.
103*ed7a3501SAxel Dörfler 	int32		cookie = 0;
104*ed7a3501SAxel Dörfler 	infosPack	infos;
105*ed7a3501SAxel Dörfler 	item = NULL;
106*ed7a3501SAxel Dörfler 	while (get_next_team_info(&cookie, &infos.tminfo) == B_OK) {
107*ed7a3501SAxel Dörfler 		int	j = 0;
108*ed7a3501SAxel Dörfler 		while (j < fTeamCount && infos.tminfo.team != fTeamList[j])
109*ed7a3501SAxel Dörfler 			j++;
110*ed7a3501SAxel Dörfler 		if (infos.tminfo.team != fTeamList[j]) {
111*ed7a3501SAxel Dörfler 			// new team
112*ed7a3501SAxel Dörfler 			team_info	info;
113*ed7a3501SAxel Dörfler 			j = 0;
114*ed7a3501SAxel Dörfler 			while (j < fTeamCount && fTeamList[j] != -1)
115*ed7a3501SAxel Dörfler 				if (get_team_info(fTeamList[j], &info) != B_OK)
116*ed7a3501SAxel Dörfler 					fTeamList[j] = -1;
117*ed7a3501SAxel Dörfler 				else
118*ed7a3501SAxel Dörfler 					j++;
119*ed7a3501SAxel Dörfler 			if (j == fTeamCount) {
120*ed7a3501SAxel Dörfler 				fTeamCount +=  10;
121*ed7a3501SAxel Dörfler 				fTeamList = (team_id*) realloc(fTeamList, sizeof(team_id)*fTeamCount);
122*ed7a3501SAxel Dörfler 			}
123*ed7a3501SAxel Dörfler 			fTeamList[j] = infos.tminfo.team;
124*ed7a3501SAxel Dörfler 			if (!get_team_name_and_icon(infos, true)) {
125*ed7a3501SAxel Dörfler 				// the team is already gone!
126*ed7a3501SAxel Dörfler 				delete infos.tmicon;
127*ed7a3501SAxel Dörfler 				fTeamList[j] = -1;
128*ed7a3501SAxel Dörfler 			} else {
129*ed7a3501SAxel Dörfler 				if (!item && firstRecycle < lastRecycle) {
130*ed7a3501SAxel Dörfler 					item = fRecycleList[firstRecycle++].item;
131*ed7a3501SAxel Dörfler 				}
132*ed7a3501SAxel Dörfler 				if (item) {
133*ed7a3501SAxel Dörfler 					item->Reset(infos.tmname, infos.tminfo.team, infos.tmicon, true);
134*ed7a3501SAxel Dörfler 				} else {
135*ed7a3501SAxel Dörfler 					BMessage* kill_team = new BMessage('KlTm');
136*ed7a3501SAxel Dörfler 					kill_team->AddInt32("team", infos.tminfo.team);
137*ed7a3501SAxel Dörfler 					item = new TeamBarMenuItem(new ThreadBarMenu(infos.tmname, infos.tminfo.team, infos.tminfo.thread_count),
138*ed7a3501SAxel Dörfler 						kill_team, infos.tminfo.team, infos.tmicon, true);
139*ed7a3501SAxel Dörfler 					item->SetTarget(gPCView);
140*ed7a3501SAxel Dörfler 					AddItem(item);
141*ed7a3501SAxel Dörfler 					item->BarUpdate();
142*ed7a3501SAxel Dörfler 				}
143*ed7a3501SAxel Dörfler 				if (item->fKernel >= 0) {
144*ed7a3501SAxel Dörfler 					total += item->fUser+item->fKernel;
145*ed7a3501SAxel Dörfler 					item = NULL;
146*ed7a3501SAxel Dörfler 				} else {
147*ed7a3501SAxel Dörfler 					fTeamList[j] = -1;
148*ed7a3501SAxel Dörfler 				}
149*ed7a3501SAxel Dörfler 			}
150*ed7a3501SAxel Dörfler 		}
151*ed7a3501SAxel Dörfler 	}
152*ed7a3501SAxel Dörfler 	if (item) {
153*ed7a3501SAxel Dörfler 		RemoveItem(item);
154*ed7a3501SAxel Dörfler 		delete item;
155*ed7a3501SAxel Dörfler 	}
156*ed7a3501SAxel Dörfler 
157*ed7a3501SAxel Dörfler 	// Delete the items that haven't been recycled.
158*ed7a3501SAxel Dörfler 	if (firstRecycle < lastRecycle)
159*ed7a3501SAxel Dörfler 		RemoveItems(IndexOf(fRecycleList[firstRecycle].item), lastRecycle-firstRecycle, true);
160*ed7a3501SAxel Dörfler 
161*ed7a3501SAxel Dörfler 	total /= gCPUcount;
162*ed7a3501SAxel Dörfler 	total = 1-total;
163*ed7a3501SAxel Dörfler 
164*ed7a3501SAxel Dörfler 	fLastTotalTime = system_time ();
165*ed7a3501SAxel Dörfler 	NoiseBarMenuItem	*noiseItem;
166*ed7a3501SAxel Dörfler 	if ((noiseItem = (NoiseBarMenuItem*) ItemAt(0)) != NULL) {
167*ed7a3501SAxel Dörfler 		noiseItem->fBusyWaiting = 0;
168*ed7a3501SAxel Dörfler 		noiseItem->fLost = (total >= 0 ? total : 0);
169*ed7a3501SAxel Dörfler 		noiseItem->DrawBar(false);
170*ed7a3501SAxel Dörfler 	}
171*ed7a3501SAxel Dörfler 
172*ed7a3501SAxel Dörfler //	status_t	st;
173*ed7a3501SAxel Dörfler //	if (gCurrentThreadBarMenu && (st = gCurrentThreadBarMenu->LockLooperWithTimeout(50000)) == B_OK) {
174*ed7a3501SAxel Dörfler 	if (gCurrentThreadBarMenu && gCurrentThreadBarMenu->LockLooperWithTimeout(25000) == B_OK) {
175*ed7a3501SAxel Dörfler 		gCurrentThreadBarMenu->Window()->BeginViewTransaction();
176*ed7a3501SAxel Dörfler 		gCurrentThreadBarMenu->Update();
177*ed7a3501SAxel Dörfler 		gCurrentThreadBarMenu->Window()->EndViewTransaction();
178*ed7a3501SAxel Dörfler 		gCurrentThreadBarMenu->Window()->Flush();
179*ed7a3501SAxel Dörfler 		gCurrentThreadBarMenu->UnlockLooper();
180*ed7a3501SAxel Dörfler 	}
181*ed7a3501SAxel Dörfler //	else
182*ed7a3501SAxel Dörfler //		if (st == B_TIMED_OUT)
183*ed7a3501SAxel Dörfler //			beep();
184*ed7a3501SAxel Dörfler 	Window()->EndViewTransaction();
185*ed7a3501SAxel Dörfler 	Window()->Flush();
186*ed7a3501SAxel Dörfler }
187