WMPerfMonComponents.Mod 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442
  1. MODULE WMPerfMonComponents; (** AUTHOR "staubesv"; PURPOSE "Components used by the Performance Monitor application"; *)
  2. IMPORT
  3. Plugins := WMPerfMonPlugins,
  4. Streams, Modules, Strings, KernelLog,
  5. WMRestorable, WMMessages, WMProperties,
  6. WMWindowManager, XML, WMComponents, WMStandardComponents, WMDiagramComponents,
  7. WMGrids, WMStringGrids, WMEditors, WMRectangles, WMGraphics, WMEvents;
  8. CONST
  9. (** View types *)
  10. UnknownView* = 0;
  11. GraphView* = 1;
  12. GridView* = 2;
  13. ChartView* = 3;
  14. (* Default width and height of plugin windows *)
  15. DefaultPwWidth = 600; DefaultPwHeight = 200;
  16. (* If smaller than this size, the plugin windows will be scaled *)
  17. MinPwWidth = 200; MinPwHeight = 100;
  18. Tab = 9X;
  19. BgFillColor* = 0444444FFH;
  20. TextColor* = WMGraphics.White;
  21. LineHeight* = 20;
  22. ButtonWidth* = 80;
  23. PerfViewFillColor = 0444444FFH;
  24. PerfViewColor = LONGINT(0FF0000FFH);
  25. UseSkinColors* = FALSE;
  26. TYPE
  27. PluginContainer* = OBJECT(WMComponents.VisualComponent)
  28. VAR
  29. pluginViews : PluginView;
  30. nbrOfPlugins : LONGINT;
  31. PROCEDURE SetPluginHeights;
  32. VAR p : PluginView; height, h : LONGINT; rect : WMRectangles.Rectangle;
  33. BEGIN
  34. IF pluginViews # NIL THEN
  35. rect := bounds.Get(); h := rect.b - rect.t;
  36. height := h DIV nbrOfPlugins ;
  37. p := pluginViews; WHILE p # NIL DO p.bounds.SetHeight(height); p := p.next; END;
  38. pluginViews.bounds.SetHeight(height + (h MOD nbrOfPlugins));
  39. END;
  40. END SetPluginHeights;
  41. PROCEDURE Resized*;
  42. BEGIN
  43. SetPluginHeights;
  44. Resized^;
  45. END Resized;
  46. PROCEDURE AlignSubComponents*;
  47. BEGIN
  48. SetPluginHeights;
  49. AlignSubComponents^;
  50. END AlignSubComponents;
  51. (* Only used in LocatePlugins! *)
  52. PROCEDURE AddPlugin*(plugin : Plugins.Plugin; viewType : LONGINT);
  53. VAR pv : PluginView; graphView : PluginGraphView; gridView : PluginGridView;
  54. BEGIN
  55. ASSERT(plugin # NIL);
  56. ASSERT((viewType = GraphView) OR (viewType = GridView));
  57. IF viewType = GraphView THEN
  58. NEW(graphView, plugin); pv := graphView;
  59. ELSE
  60. NEW(gridView, plugin); pv := gridView;
  61. END;
  62. pv.alignment.Set(WMComponents.AlignTop);
  63. pv.next := pluginViews; pluginViews := pv;
  64. INC(nbrOfPlugins);
  65. AddContent(pv);
  66. END AddPlugin;
  67. (** Returns FALSE if no plugins found *)
  68. PROCEDURE LocatePlugins*() : BOOLEAN;
  69. BEGIN
  70. HALT(301); RETURN FALSE; (* abstract *)
  71. END LocatePlugins;
  72. PROCEDURE &Init*;
  73. VAR l : WMStandardComponents.Label;
  74. BEGIN
  75. Init^;
  76. IF ~LocatePlugins() THEN
  77. l := NewLabel("No plugins found.", WMComponents.AlignClient, 0, 0);
  78. l.alignH.Set(WMGraphics.AlignCenter); l.alignV.Set(WMGraphics.AlignCenter);
  79. AddContent(l);
  80. END;
  81. SetNameAsString(StrPluginContainer);
  82. END Init;
  83. END PluginContainer;
  84. TYPE
  85. UpdateInfo = RECORD
  86. events : SET;
  87. perf : REAL;
  88. sampleInterval, sampleBufferSize, screenInterval : LONGINT;
  89. END;
  90. (* Displays a list of all plugins registered at Updater. The user may select a plugin and open a window for it *)
  91. SelectionComponent* = OBJECT (WMComponents.VisualComponent)
  92. VAR
  93. openGraphBtn, openGridBtn, openChartBtn, refreshBtn : WMStandardComponents.Button;
  94. grid : WMStringGrids.StringGrid;
  95. spacings : WMGrids.Spacings;
  96. applyBtn, clearBtn : WMStandardComponents.Button;
  97. sampleIntervalEditor, sampleBufferSizeEditor, screenIntervalEditor : WMEditors.TextField;
  98. cpuTimeLabel : Indicator;
  99. updateInfo, synchronizedUpdateInfo : UpdateInfo;
  100. w : Streams.StringWriter;
  101. alive, dead, update : BOOLEAN;
  102. PROCEDURE Resized*;
  103. VAR sum, w, i : LONGINT; rect : WMRectangles.Rectangle;
  104. BEGIN
  105. rect := bounds.Get(); w := rect.r - rect.l;
  106. FOR i := 0 TO LEN(spacings)-1 DO sum := sum + spacings[i]; END;
  107. IF w > sum THEN
  108. grid.Acquire;
  109. grid.model.Acquire;
  110. spacings[1] := spacings[1] + (w - sum) DIV 2;
  111. spacings[2] := spacings[2] + (w - sum) DIV 2 + (w - sum) MOD 2;
  112. grid.model.Release;
  113. grid.Release;
  114. END;
  115. Resized^;
  116. END Resized;
  117. PROCEDURE CreatePluginWindows(viewType : LONGINT);
  118. VAR
  119. graphWindow : PluginGraphWindow; gridWindow : PluginGridWindow; chartWindow : PluginChartWindow;
  120. p : Plugins.Plugin; changed : BOOLEAN;
  121. scol, srow, ecol, erow, row : LONGINT;
  122. ptr : ANY;
  123. BEGIN
  124. ASSERT((viewType = GraphView) OR (viewType = GridView) OR (viewType = ChartView));
  125. grid.GetSelection(scol, srow, ecol, erow);
  126. IF (srow >= 1) & (erow >= 1) THEN
  127. FOR row := srow TO erow DO
  128. grid.Acquire;
  129. grid.model.Acquire;
  130. ptr := grid.model.GetCellData(0, row);
  131. grid.model.Release;
  132. grid.Release;
  133. IF (ptr # NIL) & (ptr IS Plugins.Plugin) THEN
  134. p := ptr (Plugins.Plugin);
  135. IF (viewType = GraphView) THEN
  136. NEW(graphWindow, p, NIL);
  137. changed := TRUE;
  138. ELSIF (viewType = GridView) THEN
  139. NEW(gridWindow, p, NIL);
  140. changed := TRUE;
  141. ELSIF (viewType = ChartView) THEN
  142. NEW(chartWindow, p, NIL);
  143. changed := TRUE;
  144. ELSE
  145. (* TODO: do something *)
  146. END;
  147. END;
  148. END;
  149. IF changed THEN UpdateGrid; END;
  150. END;
  151. END CreatePluginWindows;
  152. PROCEDURE ButtonHandler(sender, data : ANY);
  153. VAR b : WMStandardComponents.Button; ui, si, bs : LONGINT;
  154. BEGIN
  155. IF (sender # NIL) & (sender IS WMStandardComponents.Button) THEN
  156. b := sender (WMStandardComponents.Button);
  157. IF b = openGraphBtn THEN
  158. CreatePluginWindows(GraphView);
  159. ELSIF b = openGridBtn THEN
  160. CreatePluginWindows(GridView);
  161. ELSIF b = openChartBtn THEN
  162. CreatePluginWindows(ChartView);
  163. ELSIF b = refreshBtn THEN
  164. UpdateGrid;
  165. ELSIF b = applyBtn THEN
  166. GetSampleParameters(ui, bs, si);
  167. Plugins.updater.SetIntervals(ui, bs, si); (* VAR parameters*)
  168. SetSampleParameters(ui, bs, si);
  169. ELSIF b = clearBtn THEN
  170. Plugins.updater.ClearAll;
  171. END;
  172. END;
  173. END ButtonHandler;
  174. PROCEDURE GetSampleParameters(VAR ui, bs, si : LONGINT);
  175. VAR string : ARRAY 16 OF CHAR;
  176. BEGIN
  177. sampleIntervalEditor.GetAsString(string); Strings.StrToInt(string, ui);
  178. screenIntervalEditor .GetAsString(string); Strings.StrToInt(string, si);
  179. sampleBufferSizeEditor.GetAsString(string); Strings.StrToInt(string, bs);
  180. END GetSampleParameters;
  181. PROCEDURE SetSampleParameters(ui, bs, si : LONGINT);
  182. VAR string : ARRAY 16 OF CHAR;
  183. BEGIN
  184. Strings.IntToStr(ui, string); sampleIntervalEditor.SetAsString(string);
  185. Strings.IntToStr(bs, string); sampleBufferSizeEditor.SetAsString(string);
  186. Strings.IntToStr(si, string); screenIntervalEditor .SetAsString(string);
  187. END SetSampleParameters;
  188. PROCEDURE UpdateGrid;
  189. VAR ca : Plugins.PluginArray; row : LONGINT;
  190. BEGIN
  191. ca := Plugins.updater.GetPlugins();
  192. IF ca # NIL THEN
  193. grid.Acquire;
  194. grid.model.Acquire;
  195. grid.model.SetNofRows(LEN(ca)+1);
  196. FOR row := 0 TO LEN(ca)-1 DO
  197. grid.model.SetCellTextAOC(0, row+1, 0, ca[row].p.name);
  198. grid.model.SetCellTextAOC(1, row+1, 0, ca[row].p.description);
  199. grid.model.SetCellTextAOC(2, row+1, 0, ca[row].p.devicename);
  200. grid.model.SetTextAlign(3, row+1, WMGraphics.AlignCenter);
  201. IF ca[row].IsActive() THEN
  202. grid.model.SetCellText(3, row+1, StrYes);
  203. ELSE
  204. grid.model.SetCellText(3, row+1, StrNo);
  205. END;
  206. grid.model.SetCellData(0, row+1, ca[row]);
  207. END;
  208. grid.model.Release;
  209. grid.Release;
  210. ELSE
  211. grid.Acquire;
  212. grid.model.Acquire;
  213. grid.model.SetNofRows(2);
  214. grid.model.SetCellText(0, 1, StrNotAvailable);
  215. grid.model.SetCellText(1, 1, StrNotAvailable);
  216. grid.model.SetCellText(2, 1, StrNotAvailable);
  217. grid.model.SetCellText(2, 1, StrNotAvailable);
  218. grid.model.Release;
  219. grid.Release;
  220. END;
  221. END UpdateGrid;
  222. PROCEDURE CreateSelectionPanel() : WMStandardComponents.GroupPanel;
  223. VAR panel : WMStandardComponents.GroupPanel; line : WMStandardComponents.Panel;
  224. BEGIN
  225. panel := NewGroupPanel("Plugins", WMComponents.AlignClient, 0);
  226. line := NewPanel(WMComponents.AlignBottom, 0, LineHeight); panel.AddContent(line);
  227. openGraphBtn := NewButton("Graph", ButtonHandler); line.AddContent(openGraphBtn);
  228. openGridBtn := NewButton("Grid", ButtonHandler); line.AddContent(openGridBtn);
  229. openChartBtn := NewButton("Chart", ButtonHandler); line.AddContent(openChartBtn);
  230. line.AddContent(NewLabel(" Select a plugin and press Graph, Grid or Both", WMComponents.AlignClient, 0, 0));
  231. refreshBtn := NewButton("Refresh", ButtonHandler); refreshBtn.alignment.Set(WMComponents.AlignRight);
  232. line.AddContent(refreshBtn);
  233. NEW(grid);
  234. grid.fixedCols.Set(1); grid.fixedRows.Set(1);
  235. grid.bounds.SetExtents(500, 200); grid.alignment.Set(WMComponents.AlignClient);
  236. grid.SetSelectionMode(WMGrids.GridSelectRows);
  237. grid.alwaysShowScrollX.Set(FALSE); grid.showScrollX.Set(TRUE);
  238. grid.alwaysShowScrollY.Set(FALSE); grid.showScrollY.Set(TRUE);
  239. grid.allowColResize.Set(TRUE); grid.allowRowResize.Set(FALSE);
  240. NEW(spacings, 4); spacings[0] := 130; spacings[1] := 250; spacings[2] := 250; spacings[3] := 70;
  241. grid.Acquire;
  242. grid.model.Acquire;
  243. grid.model.SetNofCols(4); grid.SetColSpacings(spacings);
  244. grid.model.SetNofRows(2);
  245. grid.model.SetCellText(0, 0, Strings.NewString("Plugin"));
  246. grid.model.SetCellText(1, 0, Strings.NewString("Description"));
  247. grid.model.SetCellText(2, 0, Strings.NewString("Device"));
  248. grid.model.SetCellText(3, 0, Strings.NewString("Status"));
  249. grid.model.Release;
  250. grid.Release;
  251. panel.AddContent(grid);
  252. RETURN panel;
  253. END CreateSelectionPanel;
  254. PROCEDURE CreateBottomPanel() : WMStandardComponents.GroupPanel;
  255. VAR panel : WMStandardComponents.GroupPanel;
  256. BEGIN
  257. panel := NewGroupPanel("Global sampling options", WMComponents.AlignBottom, 45);
  258. panel.AddContent(NewLabel(" Sample Interval [ms]: ", WMComponents.AlignLeft, 120, 0));
  259. sampleIntervalEditor := NewTextField(40); panel.AddContent(sampleIntervalEditor);
  260. panel.AddContent(NewLabel(" Screen Interval [ms]: ", WMComponents.AlignLeft, 120, 0));
  261. screenIntervalEditor := NewTextField(40); panel.AddContent(screenIntervalEditor );
  262. panel.AddContent(NewLabel(" Averaging [samples]: ", WMComponents.AlignLeft, 120, 0));
  263. sampleBufferSizeEditor := NewTextField(40); panel.AddContent(sampleBufferSizeEditor);
  264. SetSampleParameters(Plugins.updater.sampleInterval, Plugins.updater.sampleBufferSize, Plugins.updater.screenInterval);
  265. cpuTimeLabel := NewIndicator(" 0.0%", WMComponents.AlignLeft, 120, 0); panel.AddContent(cpuTimeLabel);
  266. clearBtn := NewButton("Clear", ButtonHandler); clearBtn.alignment.Set(WMComponents.AlignRight);
  267. panel.AddContent(clearBtn);
  268. applyBtn := NewButton("Apply", ButtonHandler); applyBtn.alignment.Set(WMComponents.AlignRight);
  269. panel.AddContent(applyBtn);
  270. RETURN panel;
  271. END CreateBottomPanel;
  272. PROCEDURE &Init*;
  273. BEGIN
  274. Init^;
  275. SetNameAsString(StrSelectionComponent);
  276. alive := TRUE; dead := FALSE; update := FALSE; NEW(w, 64);
  277. AddContent(CreateBottomPanel());
  278. AddContent(CreateSelectionPanel());
  279. UpdateGrid;
  280. Plugins.updater.AddListener({Plugins.EventPerfUpdate} + {Plugins.EventParametersChanged} + {Plugins.EventPluginsChanged}, EventHandler);
  281. END Init;
  282. PROCEDURE EventHandler(events : SET; perf : REAL);
  283. BEGIN {EXCLUSIVE}
  284. updateInfo.events := events;
  285. updateInfo.perf := perf;
  286. updateInfo.sampleInterval := Plugins.updater.sampleInterval;
  287. updateInfo.sampleBufferSize := Plugins.updater.sampleBufferSize;
  288. updateInfo.screenInterval := Plugins.updater.screenInterval;
  289. update := TRUE;
  290. END EventHandler;
  291. PROCEDURE Finalize*;
  292. BEGIN
  293. Plugins.updater.RemoveListener(EventHandler);
  294. BEGIN {EXCLUSIVE} alive := FALSE; END;
  295. (* Release obj lock to force condition evaluation *)
  296. BEGIN {EXCLUSIVE} AWAIT(dead); END;
  297. Finalize^;
  298. END Finalize;
  299. PROCEDURE Update;
  300. VAR string : ARRAY 64 OF CHAR;
  301. BEGIN
  302. IF (Plugins.EventPerfUpdate IN synchronizedUpdateInfo.events) THEN
  303. w.String(" CPU:"); w.FloatFix(synchronizedUpdateInfo.perf, 5, 1, 0); w.Char("%"); w.Update;
  304. w.Get(string); SELF.cpuTimeLabel.SetCaption(string);
  305. END;
  306. IF (Plugins.EventParametersChanged IN synchronizedUpdateInfo.events) THEN
  307. SetSampleParameters(synchronizedUpdateInfo.sampleInterval, synchronizedUpdateInfo.sampleBufferSize, synchronizedUpdateInfo.screenInterval);
  308. END;
  309. IF (Plugins.EventPluginsChanged IN synchronizedUpdateInfo.events) THEN
  310. UpdateGrid;
  311. END;
  312. END Update;
  313. BEGIN {ACTIVE}
  314. WHILE alive DO
  315. BEGIN {EXCLUSIVE} AWAIT(update OR ~alive);
  316. synchronizedUpdateInfo := updateInfo;
  317. update := FALSE;
  318. END;
  319. IF alive THEN Update; END;
  320. END;
  321. BEGIN {EXCLUSIVE} dead := TRUE; END;
  322. END SelectionComponent;
  323. TYPE
  324. Indicator* = OBJECT(WMStandardComponents.Panel)
  325. VAR
  326. value : ARRAY 128 OF CHAR;
  327. textColor : LONGINT;
  328. PROCEDURE &Init*;
  329. BEGIN
  330. Init^;
  331. SetNameAsString(StrIndicator);
  332. value := "";
  333. textColor := 0;
  334. END Init;
  335. PROCEDURE SetCaption*(CONST x : ARRAY OF CHAR);
  336. BEGIN
  337. Acquire; COPY(x, value); Release;
  338. Invalidate;
  339. END SetCaption;
  340. PROCEDURE DrawBackground*(canvas : WMGraphics.Canvas);
  341. BEGIN
  342. DrawBackground^(canvas);
  343. canvas.SetColor(textColor);
  344. Acquire;
  345. WMGraphics.DrawStringInRect(canvas, GetClientRect(), FALSE, WMComponents.AlignNone, WMGraphics.AlignCenter, value);
  346. Release;
  347. END DrawBackground;
  348. END Indicator;
  349. TYPE
  350. (** Base class for plugin views *)
  351. PluginView* = OBJECT(WMStandardComponents.GroupPanel)
  352. VAR
  353. plugin : Plugins.Plugin;
  354. statistics : WMDiagramComponents.Statistics;
  355. next : PluginView;
  356. PROCEDURE &New*(plugin : Plugins.Plugin);
  357. VAR caption : ARRAY 128 OF CHAR;
  358. BEGIN
  359. Init;
  360. ASSERT(plugin # NIL);
  361. SELF.plugin := plugin;
  362. IF ~UseSkinColors THEN fillColor.Set(0); textColor.Set(TextColor); END;
  363. caption := " "; Strings.Append(caption, plugin.p.name);
  364. IF plugin.p.devicename # "" THEN
  365. Strings.Append(caption, " ("); Strings.Append(caption, plugin.p.devicename); Strings.Append(caption, ")");
  366. END;
  367. SELF.caption.SetAOC(caption);
  368. InitStats(plugin.datamodel.GetNofDimensions());
  369. InitView;
  370. plugin.IncNbrOfClients;
  371. SetNameAsString(StrPluginView);
  372. END New;
  373. PROCEDURE InitView*;
  374. BEGIN
  375. HALT(301); (* abstract *)
  376. END InitView;
  377. (** Update statistics field. Returns TRUE if succeeded, FALSE if values not up to date *)
  378. PROCEDURE UpdateStats*() : BOOLEAN;
  379. BEGIN
  380. plugin.datamodel.Acquire; plugin.datamodel.GetStatistics(statistics); plugin.datamodel.Release;
  381. IF statistics.valid THEN
  382. IF plugin.p.scale # 1.0 THEN
  383. ScaleDataset(plugin.p.scale, statistics.cur);
  384. ScaleDataset(plugin.p.scale, statistics.min);
  385. ScaleDataset(plugin.p.scale, statistics.max);
  386. ScaleDataset(plugin.p.scale, statistics.avg);
  387. ScaleDataset(plugin.p.scale, statistics.sum);
  388. END;
  389. END;
  390. RETURN statistics.valid;
  391. END UpdateStats;
  392. PROCEDURE Finalize*;
  393. BEGIN
  394. Finalize^;
  395. plugin.DecNbrOfClients;
  396. END Finalize;
  397. PROCEDURE ScaleDataset(scale : REAL; VAR dataset : WMDiagramComponents.Dataset);
  398. VAR i : LONGINT;
  399. BEGIN
  400. FOR i := 0 TO LEN(dataset)-1 DO
  401. dataset[i] := dataset[i] * scale;
  402. END;
  403. END ScaleDataset;
  404. PROCEDURE InitStats(dimensions : LONGINT);
  405. BEGIN
  406. NEW(statistics.cur, dimensions);
  407. NEW(statistics.min, dimensions); NEW(statistics.max, dimensions);
  408. NEW(statistics.sum, dimensions); NEW(statistics.avg, dimensions);
  409. END InitStats;
  410. END PluginView;
  411. (* The panel of a PluginView consists of three elements:
  412. * - a Label describing the plugin (title)
  413. * - a PerfViewPanel graphically visualizing the measurements
  414. * - a Label showing the measurements as numbers
  415. *)
  416. PluginGraphView* = OBJECT(PluginView)
  417. VAR
  418. stats : Streams.StringWriter;
  419. pview : WMDiagramComponents.MultiPointView;
  420. info : Indicator;
  421. PROCEDURE Update;
  422. BEGIN
  423. ShowStats;
  424. Invalidate;
  425. END Update;
  426. PROCEDURE Resized*;
  427. BEGIN
  428. IF bounds.GetHeight() < 100 THEN
  429. info.visible.Set(FALSE);
  430. ELSE
  431. info.visible.Set(TRUE);
  432. END;
  433. Resized^;
  434. END Resized;
  435. PROCEDURE InitView*;
  436. VAR temp : ARRAY 16 OF CHAR;
  437. BEGIN
  438. NEW(pview);
  439. pview.alignment.Set(WMComponents.AlignClient);
  440. IF ~UseSkinColors THEN pview.fillColor.Set(PerfViewFillColor); pview.color.Set(PerfViewColor); END;
  441. pview.showValues.Set(TRUE); pview.autoMin.Set(FALSE);
  442. pview.SetExtModel(plugin.datamodel);
  443. pview.SetExtUpdate(Update);
  444. NEW(info); info.bounds.SetHeight(LineHeight); info.alignment.Set(WMComponents.AlignBottom);
  445. IF ~UseSkinColors THEN info.fillColor.Set(LONGINT(0CCCCCCFFH)); info.textColor := WMGraphics.Black; END;
  446. info.SetFont(WMGraphics.GetFont("Courier", 10, {}));
  447. pview.min.Set(plugin.p.min); IF plugin.p.max # 0 THEN pview.max.Set(plugin.p.max); END;
  448. pview.autoMin.Set(plugin.p.autoMin); pview.autoMax.Set(plugin.p.autoMax);
  449. COPY(plugin.p.unit, temp);
  450. IF plugin.p.perSecond THEN Strings.Append(temp, "/s"); END;
  451. pview.unit.SetAOC(temp);
  452. AddInternalComponent(info);
  453. AddInternalComponent(pview);
  454. NEW(stats, 256);
  455. SetNameAsString(StrPluginGraphView);
  456. END InitView;
  457. PROCEDURE ShowStats;
  458. VAR string : ARRAY 256 OF CHAR; statsMax0 : REAL;
  459. PROCEDURE ShowUnit;
  460. BEGIN
  461. IF plugin.p.statsUnit # "" THEN
  462. stats.String(plugin.p.statsUnit);
  463. IF plugin.p.perSecond THEN stats.String("/s"); END;
  464. END;
  465. END ShowUnit;
  466. PROCEDURE ShowPercent(value : REAL);
  467. BEGIN
  468. IF plugin.p.showPercent & (plugin.p.max > 0) THEN
  469. stats.String(" ("); stats.FloatFix(100.0 * value / statsMax0, 5, 1, 0); stats.String("%)")
  470. END;
  471. END ShowPercent;
  472. PROCEDURE ShowValue(CONST name : ARRAY OF CHAR; value : REAL);
  473. BEGIN
  474. stats.String(name); stats.FloatFix(value, plugin.p.minDigits, plugin.p.fraction, 0); ShowUnit; ShowPercent(value);
  475. END ShowValue;
  476. BEGIN
  477. IF UpdateStats() THEN
  478. stats.Reset; statsMax0 := plugin.p.max * plugin.p.scale;
  479. ShowValue(" Cur: ", statistics.cur[0]); stats.Char(Tab);
  480. ShowValue("Min: ", statistics.min[0]); stats.Char(Tab);
  481. ShowValue("Max: ", statistics.max[0]); stats.Char(Tab);
  482. ShowValue("Avg: ", statistics.avg[0]);
  483. IF ~plugin.p.perSecond & plugin.p.showSum THEN
  484. stats.Char(Tab); stats.String("Tot: "); stats.FloatFix(statistics.sum[0], plugin.p.minDigits, plugin.p.fraction, 0); ShowUnit;
  485. END;
  486. stats.Update; stats.Get(string); info.SetCaption(string);
  487. END;
  488. END ShowStats;
  489. END PluginGraphView;
  490. TYPE
  491. PluginGridView = OBJECT(PluginView)
  492. VAR
  493. grid : WMStringGrids.StringGrid;
  494. ds : Plugins.DatasetDescriptor;
  495. spacings : WMGrids.Spacings;
  496. nofRows : LONGINT;
  497. PROCEDURE NbrToStr(nbr :LONGREAL; VAR string : ARRAY OF CHAR);
  498. BEGIN
  499. IF nbr < MAX(LONGINT) THEN
  500. Strings.IntToStr(ENTIER(nbr), string);
  501. ELSE
  502. Strings.FloatToStr(nbr, 0, 0, 3, string);
  503. END;
  504. END NbrToStr;
  505. PROCEDURE UpdateGrid(sender, data : ANY);
  506. CONST MaxLength = 32;
  507. VAR row : LONGINT; string : ARRAY MaxLength OF CHAR;
  508. BEGIN
  509. IF UpdateStats() THEN
  510. grid.Acquire;
  511. grid.model.Acquire;
  512. FOR row := 1 TO nofRows-1 DO
  513. NbrToStr(statistics.cur[row-1], string); grid.model.SetCellTextAOC(2, row, MaxLength, string);
  514. NbrToStr(statistics.min[row-1], string); grid.model.SetCellTextAOC(3, row, MaxLength, string);
  515. NbrToStr(statistics.max[row-1], string); grid.model.SetCellTextAOC(4, row, MaxLength, string);
  516. NbrToStr(statistics.avg[row-1], string); grid.model.SetCellTextAOC(5, row, MaxLength, string);
  517. NbrToStr(statistics.sum[row-1], string); grid.model.SetCellTextAOC(6, row, MaxLength, string);
  518. IF ds # NIL THEN
  519. string := "";
  520. IF (WMDiagramComponents.Hidden IN ds[row-1].flags) THEN
  521. grid.model.SetCellText(7, row, StrHidden);
  522. ELSIF (WMDiagramComponents.Sum IN ds[row-1].flags) THEN
  523. grid.model.SetCellText(7, row, StrSum);
  524. ELSIF (WMDiagramComponents.Maximum IN ds[row-1].flags) THEN
  525. grid.model.SetCellText(7, row, StrMax);
  526. ELSE
  527. grid.model.SetCellText(7, row, StrNormal);
  528. END;
  529. ELSE
  530. grid.model.SetCellText(7, row, StrNormal);
  531. END;
  532. END;
  533. grid.model.Release;
  534. grid.Release;
  535. END;
  536. END UpdateGrid;
  537. PROCEDURE InitGrid;
  538. VAR col, row : LONGINT;
  539. BEGIN
  540. NEW(grid);
  541. grid.fixedRows.Set(1);
  542. grid.bounds.SetExtents(500, 200); grid.alignment.Set(WMComponents.AlignClient);
  543. grid.SetSelectionMode(WMGrids.GridSelectRows);
  544. grid.alwaysShowScrollX.Set(FALSE); grid.showScrollX.Set(TRUE);
  545. grid.alwaysShowScrollY.Set(FALSE); grid.showScrollY.Set(TRUE);
  546. grid.allowColResize.Set(TRUE); grid.allowRowResize.Set(FALSE);
  547. NEW(spacings, 8);
  548. spacings[0] := 30; spacings[1] := 120; spacings[2] := 80; spacings[3] := 80;
  549. spacings[4] := 80; spacings[5] := 80; spacings[6] := 80; spacings[7] := 40;
  550. grid.Acquire;
  551. grid.model.Acquire;
  552. grid.model.SetNofCols(8); grid.SetColSpacings(spacings);
  553. grid.model.SetNofRows(nofRows);
  554. (* column titles *)
  555. grid.model.SetCellText(0, 0, StrColor);
  556. grid.model.SetCellText(1, 0, StrName);
  557. grid.model.SetCellText(2, 0, StrCurrent);
  558. grid.model.SetCellText(3, 0, StrMin);
  559. grid.model.SetCellText(4, 0, StrMax);
  560. grid.model.SetCellText(5, 0, StrAvg);
  561. grid.model.SetCellText(6, 0, StrSum);
  562. grid.model.SetCellText(7, 0, StrMode);
  563. (* static grid content *)
  564. FOR row := 1 TO nofRows-1 DO
  565. FOR col := 2 TO 6 DO
  566. grid.model.SetTextAlign(col, row, WMGraphics.AlignRight);
  567. END;
  568. grid.model.SetTextAlign(7, row, WMGraphics.AlignCenter);
  569. grid.model.SetCellColors(0, row, ds[row-1].color, grid.clTextDefault.Get());
  570. grid.model.SetCellText(1, row, Strings.NewString(ds[row-1].name));
  571. END;
  572. grid.model.Release;
  573. grid.Release;
  574. END InitGrid;
  575. PROCEDURE InitView*;
  576. BEGIN
  577. ds := plugin.p.datasetDescriptor;
  578. IF ds # NIL THEN
  579. nofRows := LEN(ds) + 1;
  580. ELSE
  581. nofRows := 2;
  582. END;
  583. InitGrid;
  584. AddInternalComponent(grid);
  585. UpdateGrid(NIL, NIL);
  586. plugin.datamodel.onChanged.Add(UpdateGrid);
  587. SetNameAsString(StrPluginGridView);
  588. END InitView;
  589. PROCEDURE Resized*;
  590. VAR sum, w, i : LONGINT; rect : WMRectangles.Rectangle;
  591. BEGIN
  592. rect := bounds.Get(); w := rect.r - rect.l - 20 (*scrollbar width*);
  593. FOR i := 0 TO LEN(spacings)-1 DO
  594. sum := sum + spacings[i];
  595. END;
  596. IF w = sum THEN
  597. (* do nothing *)
  598. ELSIF w > sum THEN (* enlarge grid *)
  599. grid.Acquire;
  600. grid.model.Acquire;
  601. FOR i := 0 TO LEN(spacings)-1 DO
  602. spacings[i] := spacings[i] + (w - sum) DIV 8;
  603. END;
  604. spacings[LEN(spacings)-1] := spacings[LEN(spacings)-1] + (w - sum) MOD 8;
  605. grid.model.Release;
  606. grid.Release;
  607. ELSE (* make spacings smaller *)
  608. grid.Acquire;
  609. grid.model.Acquire;
  610. FOR i := 0 TO LEN(spacings)-1 DO
  611. spacings[i] := w DIV 8;
  612. END;
  613. spacings[LEN(spacings)-1] := spacings[LEN(spacings)-1] + (w MOD 8);
  614. grid.model.Release;
  615. grid.Release;
  616. END;
  617. Resized^;
  618. END Resized;
  619. PROCEDURE Finalize*;
  620. BEGIN
  621. Finalize^;
  622. plugin.datamodel.onChanged.Remove(UpdateGrid);
  623. END Finalize;
  624. END PluginGridView;
  625. TYPE
  626. PluginChartView = OBJECT(PluginView)
  627. VAR
  628. barChart : WMDiagramComponents.BarChart;
  629. ds : Plugins.DatasetDescriptor;
  630. heights : POINTER TO ARRAY OF LONGREAL;
  631. PROCEDURE InitView*;
  632. VAR
  633. labels : POINTER TO ARRAY OF Strings.String;
  634. colors : POINTER TO ARRAY OF WMGraphics.Color;
  635. i : LONGINT;
  636. BEGIN
  637. ds := plugin.p.datasetDescriptor;
  638. NEW(heights, LEN(ds));
  639. NEW(labels, LEN(ds));
  640. NEW(colors, LEN(ds));
  641. FOR i := 0 TO LEN(ds)-1 DO
  642. heights[i] := 0.0;
  643. labels[i] := Strings.NewString(ds[i].name);
  644. colors[i] := ds[i].color;
  645. END;
  646. NEW(barChart); barChart.alignment.Set(WMComponents.AlignClient);
  647. barChart.backgroundColor.Set(WMGraphics.White);
  648. barChart.textColor.Set(WMGraphics.Black);
  649. barChart.SetData(heights^, LEN(heights));
  650. barChart.SetLabels(labels^);
  651. barChart.SetColors(colors^);
  652. AddInternalComponent(barChart);
  653. UpdateChart(NIL, NIL);
  654. plugin.datamodel.onChanged.Add(UpdateChart);
  655. SetNameAsString(StrPluginGridView);
  656. END InitView;
  657. PROCEDURE UpdateChart(sender, data : ANY);
  658. VAR max : REAL; i : LONGINT;
  659. PROCEDURE FindMax() : REAL;
  660. VAR i : LONGINT; max : REAL;
  661. BEGIN
  662. max := 0.0;
  663. FOR i := 0 TO LEN(statistics.cur)-1 DO
  664. IF (statistics.cur[i] > max) THEN max := statistics.cur[i]; END;
  665. END;
  666. RETURN max;
  667. END FindMax;
  668. BEGIN
  669. IF UpdateStats() THEN
  670. max := FindMax();
  671. IF (max > 0.0) THEN
  672. FOR i := 0 TO LEN(heights)-1 DO
  673. heights[i] := statistics.cur[i] / max;
  674. END;
  675. ELSE
  676. FOR i := 0 TO LEN(heights)-1 DO
  677. heights[i] := 0.0;
  678. END;
  679. END;
  680. barChart.SetData(heights^, LEN(heights));
  681. END;
  682. END UpdateChart;
  683. PROCEDURE Finalize*;
  684. BEGIN
  685. Finalize^;
  686. plugin.datamodel.onChanged.Remove(UpdateChart);
  687. END Finalize;
  688. END PluginChartView;
  689. TYPE
  690. (** Simple multipointview component that is XML capabale *)
  691. PerfMonSimpleGraph* = OBJECT(WMComponents.VisualComponent)
  692. VAR
  693. plugin- : WMProperties.StringProperty;
  694. showValues- : WMProperties.BooleanProperty;
  695. label : WMStandardComponents.Label;
  696. pview : WMDiagramComponents.MultiPointView;
  697. pluginInstance : Plugins.Plugin;
  698. PROCEDURE & Init*;
  699. BEGIN
  700. Init^;
  701. NEW(plugin, PrototypePlugin, NIL, NIL); properties.Add(plugin);
  702. NEW(showValues, PrototypeShowValues, NIL, NIL); properties.Add(showValues);
  703. label := NewLabel("No plugin specified", WMComponents.AlignClient, 0, 0);
  704. label.alignV.Set(WMGraphics.AlignCenter);
  705. label.alignH.Set(WMGraphics.AlignCenter);
  706. AddContent(label);
  707. NEW(pview);
  708. pview.alignment.Set(WMComponents.AlignClient);
  709. pview.visible.Set(FALSE);
  710. IF ~UseSkinColors THEN pview.fillColor.Set(PerfViewFillColor); pview.color.Set(PerfViewColor); END;
  711. pview.showValues.Set(TRUE); pview.autoMin.Set(FALSE);
  712. AddContent(pview);
  713. InstallPlugin;
  714. SetNameAsString(StrPerfMonSimpleGraph);
  715. SetGenerator("WMPerfMonComponents.GenPerfMonSimpleGraph");
  716. END Init;
  717. PROCEDURE InitDiagram(pluginInstance : Plugins.Plugin; index : LONGINT);
  718. VAR temp : ARRAY 16 OF CHAR;
  719. BEGIN
  720. ASSERT(plugin # NIL);
  721. pluginInstance.IncNbrOfClients();
  722. pview.SetExtModel(pluginInstance.datamodel);
  723. pview.min.Set(pluginInstance.p.min); IF pluginInstance.p.max # 0 THEN pview.max.Set(pluginInstance.p.max); END;
  724. pview.autoMin.Set(pluginInstance.p.autoMin); pview.autoMax.Set(pluginInstance.p.autoMax);
  725. COPY(pluginInstance.p.unit, temp);
  726. IF pluginInstance.p.perSecond THEN Strings.Append(temp, "/s"); END;
  727. pview.unit.SetAOC(temp);
  728. END InitDiagram;
  729. PROCEDURE InstallPlugin;
  730. VAR string : Strings.String; msg : ARRAY 32 OF CHAR; index : LONGINT;
  731. BEGIN
  732. label.visible.Set(TRUE); pview.visible.Set(FALSE);
  733. IF pluginInstance # NIL THEN
  734. pluginInstance.DecNbrOfClients();
  735. pluginInstance := NIL;
  736. END;
  737. string := plugin.Get();
  738. IF string # NIL THEN
  739. pluginInstance := Plugins.updater.GetByFullname(string^, index, msg);
  740. IF pluginInstance # NIL THEN
  741. InitDiagram(pluginInstance, index);
  742. label.visible.Set(FALSE); pview.visible.Set(TRUE);
  743. ELSE
  744. label.caption.SetAOC(msg);
  745. END;
  746. ELSE
  747. label.caption.SetAOC("No plugin specified");
  748. END;
  749. END InstallPlugin;
  750. PROCEDURE RecacheProperties*;
  751. BEGIN
  752. RecacheProperties^;
  753. pview.showValues.Set(showValues.Get());
  754. InstallPlugin;
  755. END RecacheProperties;
  756. PROCEDURE PropertyChanged*(sender, property : ANY);
  757. BEGIN
  758. IF (property = plugin) THEN
  759. RecacheProperties;
  760. Invalidate;
  761. ELSIF (property = showValues) THEN
  762. pview.showValues.Set(showValues.Get());
  763. Invalidate;
  764. ELSE
  765. PropertyChanged^(sender, property);
  766. END;
  767. END PropertyChanged;
  768. PROCEDURE Finalize*;
  769. BEGIN
  770. IF pluginInstance # NIL THEN
  771. pluginInstance.DecNbrOfClients();
  772. pluginInstance := NIL;
  773. END;
  774. Finalize^;
  775. END Finalize;
  776. END PerfMonSimpleGraph;
  777. TYPE
  778. KillerMsg = OBJECT
  779. END KillerMsg;
  780. PluginWindow* = OBJECT (WMComponents.FormWindow)
  781. VAR
  782. plugin : Plugins.Plugin;
  783. width, height : LONGINT;
  784. PROCEDURE CreateForm*() : WMComponents.VisualComponent;
  785. BEGIN
  786. HALT(301); RETURN NIL; (* abstract *)
  787. END CreateForm;
  788. PROCEDURE Resized*(width, height : LONGINT);
  789. BEGIN
  790. IF (width >= MinPwWidth) & (height >= MinPwHeight) THEN
  791. scaling := FALSE;
  792. SELF.width := width; SELF.height := height;
  793. ELSE
  794. scaling := TRUE;
  795. END;
  796. Resized^(width, height);
  797. END Resized;
  798. PROCEDURE SetActive*(active : BOOLEAN);
  799. BEGIN
  800. plugin.SetActive(active);
  801. END SetActive;
  802. PROCEDURE &New*(plugin : Plugins.Plugin; c : WMRestorable.Context);
  803. VAR
  804. size, configuration : XML.Element;
  805. vc : WMComponents.VisualComponent;
  806. scale : BOOLEAN;
  807. BEGIN
  808. ASSERT(plugin # NIL);
  809. SELF.plugin := plugin;
  810. scaling := FALSE; scale := FALSE;
  811. vc := CreateForm();
  812. IF c # NIL THEN
  813. width := c.r - c.l; height := c.b - c.t;
  814. size := WMRestorable.GetElement(c, "Data\Size");
  815. IF size # NIL THEN
  816. WMRestorable.LoadLongint(size, "Width", width);
  817. WMRestorable.LoadLongint(size, "Height", height);
  818. IF (width < MinPwWidth) OR (height < MinPwHeight) THEN
  819. scale := TRUE;
  820. END;
  821. END;
  822. ELSE
  823. width := DefaultPwWidth; height := DefaultPwHeight;
  824. END;
  825. Init(width, height, FALSE);
  826. SetContent(vc);
  827. IF (plugin.p.devicename # "") THEN
  828. SetTitle(Strings.NewString(plugin.p.devicename));
  829. ELSE
  830. SetTitle(Strings.NewString(plugin.p.name));
  831. END;
  832. IF c # NIL THEN
  833. WMRestorable.AddByContext(SELF, c);
  834. configuration := WMRestorable.GetElement(c, "Data\Configuration");
  835. LoadFromXml(configuration);
  836. IF scale THEN Resized(c.r - c.l, c.b - c.t); END;
  837. ELSE
  838. WMWindowManager.DefaultAddWindow(SELF);
  839. END;
  840. IncCount;
  841. END New;
  842. (** Load plugin state from XML element *)
  843. PROCEDURE LoadFromXml*(configuration : XML.Element);
  844. VAR active : BOOLEAN;
  845. BEGIN
  846. IF configuration # NIL THEN
  847. WMRestorable.LoadBoolean(configuration, "Active", active); plugin.SetActive(active);
  848. WMRestorable.LoadBoolean(configuration, "PerSecond", plugin.p.perSecond);
  849. END;
  850. END LoadFromXml;
  851. (** Store plugin state into XML element. Can be overwritten to be extended *)
  852. PROCEDURE StoreToXml() : XML.Element;
  853. VAR elem, data : XML.Element;
  854. BEGIN
  855. NEW(data); data.SetName("Data");
  856. NEW(elem); elem.SetName("View"); data.AddContent(elem);
  857. IF (SELF IS PluginGraphWindow) THEN
  858. WMRestorable.StoreLongint(elem, "Type", GraphView);
  859. ELSIF (SELF IS PluginGridWindow) THEN
  860. WMRestorable.StoreLongint(elem, "Type", GridView);
  861. ELSE
  862. WMRestorable.StoreLongint(elem, "Type", UnknownView);
  863. END;
  864. NEW(elem); elem.SetName("Identification"); data.AddContent(elem);
  865. WMRestorable.StoreString(elem, "Name", plugin.p.name);
  866. WMRestorable.StoreString(elem, "Device", plugin.p.devicename);
  867. NEW(elem); elem.SetName("Configuration"); data.AddContent(elem);
  868. WMRestorable.StoreBoolean(elem, "Active", plugin.IsActive());
  869. WMRestorable.StoreBoolean(elem, "PerSecond", plugin.p.perSecond);
  870. NEW(elem); elem.SetName("Size"); data.AddContent(elem);
  871. WMRestorable.StoreLongint(elem, "Width", width);
  872. WMRestorable.StoreLongint(elem, "Height", height);
  873. RETURN data;
  874. END StoreToXml;
  875. PROCEDURE Handle*(VAR x: WMMessages.Message);
  876. VAR data : XML.Element;
  877. BEGIN
  878. IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) THEN
  879. IF (x.ext IS KillerMsg) THEN Close
  880. ELSIF (x.ext IS WMRestorable.Storage) THEN
  881. data := StoreToXml();
  882. x.ext(WMRestorable.Storage).Add("WMPerfMonPluginsPlugin", "WMPerfMonComponents.RestorePlugin", SELF, data);
  883. ELSE Handle^(x)
  884. END
  885. ELSE Handle^(x)
  886. END
  887. END Handle;
  888. PROCEDURE Close*;
  889. BEGIN
  890. Close^; DecCount;
  891. END Close;
  892. END PluginWindow;
  893. TYPE
  894. PluginGraphWindow* = OBJECT (PluginWindow)
  895. VAR
  896. graphView : PluginGraphView;
  897. stop, clear, automin, automax, perSecond, legend : WMStandardComponents.Button;
  898. PROCEDURE ButtonHandler(sender, data : ANY);
  899. VAR
  900. b : WMStandardComponents.Button; string : ARRAY 32 OF CHAR;
  901. gridWindow : PluginGridWindow;
  902. BEGIN
  903. b := sender (WMStandardComponents.Button);
  904. IF b = stop THEN
  905. SetActive(~plugin.IsActive());
  906. ELSIF b = clear THEN
  907. plugin.Reset;
  908. ELSIF b = automin THEN
  909. graphView.pview.autoMin.Set(~graphView.pview.autoMin.Get());
  910. IF graphView.pview.autoMin.Get() THEN automin.caption.SetAOC("AutoMin:On"); ELSE automin.caption.SetAOC("AutoMin:Off"); END;
  911. ELSIF b = automax THEN
  912. graphView.pview.autoMax.Set(~graphView.pview.autoMax.Get());
  913. IF graphView.pview.autoMax.Get() THEN automax.caption.SetAOC("AutoMax:On"); ELSE automax.caption.SetAOC("AutoMax:Off"); END;
  914. ELSIF b = perSecond THEN
  915. plugin.p.perSecond := ~plugin.p.perSecond;
  916. IF plugin.p.perSecond THEN
  917. string := ""; Strings.Append(string, plugin.p.unit); Strings.Append(string, "/s");
  918. graphView.pview.unit.SetAOC(string);
  919. perSecond.caption.SetAOC("PerSecond:On");
  920. ELSE
  921. graphView.pview.unit.SetAOC(plugin.p.unit);
  922. perSecond.caption.SetAOC("PerSecond:Off");
  923. END;
  924. ELSIF b = legend THEN
  925. NEW(gridWindow, plugin, NIL);
  926. END;
  927. END ButtonHandler;
  928. PROCEDURE CreateForm*(): WMComponents.VisualComponent;
  929. VAR panel, toolbar : WMStandardComponents.Panel;
  930. BEGIN
  931. panel := NewPanel(WMComponents.AlignClient, 0, 0); panel.bearing.Set(WMRectangles.MakeRect(2,5,2,2));
  932. toolbar := NewPanel(WMComponents.AlignBottom, 0, 20);
  933. panel.AddContent(toolbar);
  934. NEW(graphView, plugin); graphView.alignment.Set(WMComponents.AlignClient);
  935. panel.AddContent(graphView);
  936. NEW(stop); stop.bounds.SetWidth(100); stop.alignment.Set(WMComponents.AlignLeft);
  937. stop.onClick.Add(ButtonHandler);
  938. toolbar.AddContent(stop);
  939. NEW(clear); clear.bounds.SetWidth(100); clear.alignment.Set(WMComponents.AlignLeft);
  940. clear.onClick.Add(ButtonHandler); clear.caption.SetAOC("Clear");
  941. toolbar.AddContent(clear);
  942. NEW(automin); automin.bounds.SetWidth(100); automin.alignment.Set(WMComponents.AlignLeft);
  943. automin.onClick.Add(ButtonHandler);
  944. toolbar.AddContent(automin);
  945. NEW(automax); automax.bounds.SetWidth(100); automax.alignment.Set(WMComponents.AlignLeft);
  946. automax.onClick.Add(ButtonHandler);
  947. toolbar.AddContent(automax);
  948. NEW(perSecond); perSecond.bounds.SetWidth(100); perSecond.alignment.Set(WMComponents.AlignLeft);
  949. perSecond.onClick.Add(ButtonHandler);
  950. toolbar.AddContent(perSecond);
  951. IF LEN(plugin.p.datasetDescriptor) > 1 THEN
  952. NEW(legend); legend.bounds.SetWidth(100); legend.alignment.Set(WMComponents.AlignLeft);
  953. legend.onClick.Add(ButtonHandler); legend.caption.SetAOC("Legend");
  954. toolbar.AddContent(legend);
  955. END;
  956. IF plugin.p.autoMin THEN automin.caption.SetAOC("AutoMin:On"); graphView.pview.autoMin.Set(TRUE);
  957. ELSE automin.caption.SetAOC("AutoMin:Off"); graphView.pview.autoMin.Set(FALSE);
  958. END;
  959. IF plugin.p.autoMax THEN automax.caption.SetAOC("AutoMax:On"); graphView.pview.autoMax.Set(TRUE);
  960. ELSE automax.caption.SetAOC("AutoMax:Off"); graphView.pview.autoMax.Set(FALSE);
  961. END;
  962. IF plugin.IsActive() THEN stop.caption.SetAOC("Counter:On"); ELSE stop.caption.SetAOC("Counter:Off"); END;
  963. IF plugin.p.perSecond THEN perSecond.caption.SetAOC("PerSecond:On"); ELSE perSecond.caption.SetAOC("PerSecond:Off"); END;
  964. RETURN panel;
  965. END CreateForm;
  966. PROCEDURE LoadFromXml*(configuration : XML.Element);
  967. BEGIN
  968. LoadFromXml^(configuration);
  969. IF configuration # NIL THEN
  970. WMRestorable.LoadBoolean(configuration, "AutoMin", plugin.p.autoMin);
  971. WMRestorable.LoadBoolean(configuration, "AutoMax", plugin.p.autoMax);
  972. END;
  973. END LoadFromXml;
  974. PROCEDURE StoreToXml() : XML.Element;
  975. VAR elem, data : XML.Element;
  976. BEGIN
  977. data := StoreToXml^();
  978. NEW(elem); elem.SetName("GraphView"); data.AddContent(elem);
  979. WMRestorable.StoreBoolean(elem, "AutoMin", graphView.pview.autoMin.Get());
  980. WMRestorable.StoreBoolean(elem, "AutoMax", graphView.pview.autoMax.Get());
  981. RETURN data;
  982. END StoreToXml;
  983. END PluginGraphWindow;
  984. TYPE
  985. PluginGridWindow* = OBJECT(PluginWindow)
  986. VAR
  987. gridView : PluginGridView;
  988. allBtn, noneBtn, toggleBtn, graphBtn : WMStandardComponents.Button;
  989. PROCEDURE SetHide(hide : BOOLEAN);
  990. VAR i : LONGINT; ds : Plugins.DatasetDescriptor;
  991. BEGIN
  992. ds := gridView.plugin.p.datasetDescriptor;
  993. FOR i := 0 TO LEN(ds)-1 DO
  994. IF hide THEN
  995. INCL(ds[i].flags, WMDiagramComponents.Hidden);
  996. ELSE
  997. EXCL(ds[i].flags, WMDiagramComponents.Hidden);
  998. END;
  999. END;
  1000. END SetHide;
  1001. PROCEDURE ButtonHandler(sender, data : ANY);
  1002. VAR
  1003. ds : Plugins.DatasetDescriptor; scol, srow, ecol, erow, row : LONGINT;
  1004. graphWindow : PluginGraphWindow;
  1005. nofHidden : LONGINT;
  1006. hide : BOOLEAN;
  1007. BEGIN
  1008. IF sender = allBtn THEN
  1009. SetHide(FALSE);
  1010. ELSIF sender = noneBtn THEN
  1011. SetHide(TRUE);
  1012. ELSIF sender = toggleBtn THEN
  1013. gridView.grid.GetSelection(scol, srow, ecol, erow);
  1014. ds := gridView.plugin.p.datasetDescriptor;
  1015. IF (srow >= 1) & (erow >= 1) THEN
  1016. IF (srow = erow) THEN
  1017. (* toggle between Normal, Sum, Maximum, Hidden *)
  1018. IF (WMDiagramComponents.Hidden IN ds[srow-1].flags) THEN
  1019. (* Hidden -> Normal *)
  1020. ds[srow-1].flags := ds[srow-1].flags - {WMDiagramComponents.Hidden, WMDiagramComponents.Sum, WMDiagramComponents.Maximum};
  1021. ELSIF ({WMDiagramComponents.Hidden, WMDiagramComponents.Sum, WMDiagramComponents.Maximum} * ds[srow-1].flags = {}) THEN
  1022. (* Normal -> Sum *)
  1023. WMDiagramComponents.ClearFlag(WMDiagramComponents.Sum, ds);
  1024. WMDiagramComponents.ClearFlag(WMDiagramComponents.Maximum, ds);
  1025. INCL(ds[srow-1].flags, WMDiagramComponents.Sum);
  1026. ELSIF (WMDiagramComponents.Sum IN ds[srow-1].flags) THEN
  1027. (* Sum -> Maximum *)
  1028. WMDiagramComponents.ClearFlag(WMDiagramComponents.Sum, ds);
  1029. WMDiagramComponents.ClearFlag(WMDiagramComponents.Maximum, ds);
  1030. INCL(ds[srow-1].flags, WMDiagramComponents.Maximum);
  1031. ELSE
  1032. (* Maximum -> Hidden *)
  1033. WMDiagramComponents.ClearFlag(WMDiagramComponents.Sum, ds);
  1034. WMDiagramComponents.ClearFlag(WMDiagramComponents.Maximum, ds);
  1035. INCL(ds[srow-1].flags, WMDiagramComponents.Hidden);
  1036. END;
  1037. ELSE
  1038. nofHidden := WMDiagramComponents.GetNumberOf(WMDiagramComponents.Hidden, row-1, erow-1, ds);
  1039. hide := nofHidden < (erow - srow + 1);
  1040. FOR row := srow TO erow DO
  1041. IF hide THEN
  1042. INCL(ds[row-1].flags, WMDiagramComponents.Hidden);
  1043. ELSE
  1044. EXCL(ds[row-1].flags, WMDiagramComponents.Hidden);
  1045. END;
  1046. END;
  1047. END;
  1048. END;
  1049. ELSIF sender = graphBtn THEN
  1050. NEW(graphWindow, plugin, NIL);
  1051. ELSE
  1052. END;
  1053. END ButtonHandler;
  1054. PROCEDURE CreateForm*(): WMComponents.VisualComponent;
  1055. VAR panel, toolbar : WMStandardComponents.Panel; label : WMStandardComponents.Label;
  1056. BEGIN
  1057. panel := NewPanel(WMComponents.AlignClient, 0, 0); panel.bearing.Set(WMRectangles.MakeRect(2,5,2,2));
  1058. toolbar := NewPanel(WMComponents.AlignBottom, 0, 20);
  1059. panel.AddContent(toolbar);
  1060. label := NewLabel(" Display in graph: ", WMComponents.AlignLeft, 120, 0); toolbar.AddContent(label);
  1061. allBtn := NewButton("All", ButtonHandler); toolbar.AddContent(allBtn);
  1062. noneBtn := NewButton("None", ButtonHandler); toolbar.AddContent(noneBtn);
  1063. toggleBtn := NewButton("Toggle Selected", ButtonHandler); toolbar.AddContent(toggleBtn);
  1064. graphBtn := NewButton("Graph", ButtonHandler); graphBtn.alignment.Set(WMComponents.AlignRight);
  1065. toolbar.AddContent(graphBtn);
  1066. NEW(gridView, plugin); gridView.alignment.Set(WMComponents.AlignClient);
  1067. panel.AddContent(gridView);
  1068. RETURN panel;
  1069. END CreateForm;
  1070. END PluginGridWindow;
  1071. TYPE
  1072. PluginChartWindow* = OBJECT(PluginWindow)
  1073. VAR
  1074. chartView : PluginChartView;
  1075. verticalBtn : WMStandardComponents.Button;
  1076. vertical : BOOLEAN;
  1077. PROCEDURE ButtonHandler(sender, data : ANY);
  1078. BEGIN
  1079. IF (sender = verticalBtn) THEN
  1080. vertical := ~vertical;
  1081. chartView.barChart.SetVertical(vertical);
  1082. END;
  1083. END ButtonHandler;
  1084. PROCEDURE CreateForm*(): WMComponents.VisualComponent;
  1085. VAR panel, toolbar : WMStandardComponents.Panel;
  1086. BEGIN
  1087. panel := NewPanel(WMComponents.AlignClient, 0, 0); panel.bearing.Set(WMRectangles.MakeRect(2,5,2,2));
  1088. toolbar := NewPanel(WMComponents.AlignBottom, 0, 20);
  1089. panel.AddContent(toolbar);
  1090. verticalBtn := NewButton("Vertical", ButtonHandler); toolbar.AddContent(verticalBtn);
  1091. verticalBtn.isToggle.Set(TRUE);
  1092. vertical := FALSE;
  1093. NEW(chartView, plugin); chartView.alignment.Set(WMComponents.AlignClient);
  1094. chartView.barChart.SetVertical(FALSE);
  1095. panel.AddContent(chartView);
  1096. RETURN panel;
  1097. END CreateForm;
  1098. END PluginChartWindow;
  1099. VAR
  1100. PrototypePlugin : WMProperties.StringProperty;
  1101. PrototypeShowValues : WMProperties.BooleanProperty;
  1102. StrPluginContainer, StrSelectionComponent,
  1103. StrPluginView, StrPluginGraphView, StrPluginGridView,
  1104. StrPerfMonSimpleGraph, StrYes, StrNo, StrNotAvailable, StrIndicator,
  1105. StrColor, StrName, StrCurrent, StrMin, StrMax, StrAvg, StrSum, StrMode, StrHidden, StrNormal : Strings.String;
  1106. nofWindows : LONGINT;
  1107. PROCEDURE GenPerfMonSimpleGraph*() : XML.Element;
  1108. VAR sg : PerfMonSimpleGraph;
  1109. BEGIN
  1110. NEW(sg); RETURN sg;
  1111. END GenPerfMonSimpleGraph;
  1112. PROCEDURE InitStrings;
  1113. BEGIN
  1114. StrPluginContainer := Strings.NewString("PluginContainer");
  1115. StrSelectionComponent := Strings.NewString("SelectionComponent");
  1116. StrPluginView := Strings.NewString("PluginView");
  1117. StrPluginGraphView := Strings.NewString("PluginGraphView");
  1118. StrPluginGridView := Strings.NewString("PluginGridView");
  1119. StrPerfMonSimpleGraph := Strings.NewString("PerfMonSimpleGraph");
  1120. StrYes := Strings.NewString("Yes");
  1121. StrNo := Strings.NewString("No");
  1122. StrNotAvailable := Strings.NewString("n/a");
  1123. StrIndicator := Strings.NewString("Indicator");
  1124. StrColor := Strings.NewString("Color");
  1125. StrName := Strings.NewString("Name");
  1126. StrCurrent := Strings.NewString("Current");
  1127. StrMin := Strings.NewString("Min");
  1128. StrMax := Strings.NewString("Max");
  1129. StrAvg := Strings.NewString("Avg");
  1130. StrSum := Strings.NewString("Sum");
  1131. StrMode := Strings.NewString("Mode");
  1132. StrHidden := Strings.NewString("Hidden");
  1133. StrNormal := Strings.NewString("Normal");
  1134. END InitStrings;
  1135. PROCEDURE InitPrototypes;
  1136. VAR plPerfMonSimpleGraph : WMProperties.PropertyList;
  1137. BEGIN
  1138. NEW(plPerfMonSimpleGraph); WMComponents.propertyListList.Add("PerfMonSimpleGraph", plPerfMonSimpleGraph);
  1139. NEW(PrototypePlugin, NIL, Strings.NewString("Plugin"), Strings.NewString("Fullname of PerfMon plugin to be displayed"));
  1140. plPerfMonSimpleGraph.Add(PrototypePlugin);
  1141. NEW(PrototypeShowValues, NIL, Strings.NewString("ShowValues"), Strings.NewString("Show minimum and maximum values in diagram"));
  1142. PrototypeShowValues.Set(FALSE);
  1143. END InitPrototypes;
  1144. PROCEDURE NewButton*(CONST caption : ARRAY OF CHAR; handler : WMEvents.EventListener) : WMStandardComponents.Button;
  1145. VAR button : WMStandardComponents.Button;
  1146. BEGIN
  1147. NEW(button); button.alignment.Set(WMComponents.AlignLeft); button.bounds.SetWidth(ButtonWidth);
  1148. button.caption.SetAOC(caption); button.onClick.Add(handler);
  1149. RETURN button;
  1150. END NewButton;
  1151. PROCEDURE NewGroupPanel*(CONST caption : ARRAY OF CHAR; alignment, height : LONGINT) : WMStandardComponents.GroupPanel;
  1152. VAR panel : WMStandardComponents.GroupPanel;
  1153. BEGIN
  1154. NEW(panel); panel.alignment.Set(alignment); panel.bounds.SetHeight(height);
  1155. panel.bearing.Set(WMRectangles.MakeRect(2,5,2,2));
  1156. panel.caption.SetAOC(caption);
  1157. IF ~UseSkinColors THEN
  1158. panel.fillColor.Set(BgFillColor); panel.textColor.Set(WMGraphics.White);
  1159. END;
  1160. RETURN panel;
  1161. END NewGroupPanel;
  1162. PROCEDURE NewIndicator*(CONST caption : ARRAY OF CHAR; alignment, width, height : LONGINT) : Indicator;
  1163. VAR i : Indicator;
  1164. BEGIN
  1165. NEW(i); i.alignment.Set(alignment); i.bounds.SetExtents(width, height);
  1166. i.SetCaption(caption);
  1167. IF ~UseSkinColors THEN
  1168. i.fillColor.Set(BgFillColor); i.textColor := TextColor;
  1169. END;
  1170. RETURN i;
  1171. END NewIndicator;
  1172. PROCEDURE NewLabel*(CONST caption : ARRAY OF CHAR; alignment, width, height : LONGINT) : WMStandardComponents.Label;
  1173. VAR label : WMStandardComponents.Label;
  1174. BEGIN
  1175. NEW(label); label.alignment.Set(alignment); label.bounds.SetExtents(width, height);
  1176. label.caption.SetAOC(caption);
  1177. IF ~UseSkinColors THEN
  1178. label.fillColor.Set(BgFillColor); label.textColor.Set(TextColor);
  1179. END;
  1180. RETURN label;
  1181. END NewLabel;
  1182. PROCEDURE NewTextField*(width : LONGINT) : WMEditors.TextField;
  1183. VAR textfield : WMEditors.TextField;
  1184. BEGIN
  1185. NEW(textfield); textfield.bounds.SetWidth(width); textfield.alignment.Set(WMComponents.AlignLeft);
  1186. IF ~UseSkinColors THEN textfield.fillColor.Set(WMGraphics.White); END;
  1187. RETURN textfield;
  1188. END NewTextField;
  1189. PROCEDURE NewPanel*(alignment, width, height : LONGINT) : WMStandardComponents.Panel;
  1190. VAR panel : WMStandardComponents.Panel;
  1191. BEGIN
  1192. NEW(panel); panel.alignment.Set(alignment); panel.bounds.SetExtents(width, height);
  1193. IF ~UseSkinColors THEN
  1194. panel.fillColor.Set(BgFillColor);
  1195. END;
  1196. RETURN panel;
  1197. END NewPanel;
  1198. PROCEDURE RestorePlugin*(c : WMRestorable.Context);
  1199. VAR
  1200. identification, view : XML.Element;
  1201. name : Plugins.Name; devicename : Plugins.DeviceName; plugin : Plugins.Plugin;
  1202. graphWindow : PluginGraphWindow; gridWindow : PluginGridWindow;
  1203. viewType : LONGINT;
  1204. BEGIN
  1205. ASSERT(c # NIL);
  1206. name := ""; devicename := "";
  1207. identification := WMRestorable.GetElement(c, "Data\Identification");
  1208. IF identification # NIL THEN
  1209. WMRestorable.LoadString(identification, "Name", name);
  1210. WMRestorable.LoadString(identification, "Device", devicename);
  1211. IF name # "" THEN
  1212. plugin := Plugins.updater.GetByName(name, devicename);
  1213. IF plugin # NIL THEN
  1214. view := WMRestorable.GetElement(c, "Data\View");
  1215. IF view # NIL THEN
  1216. WMRestorable.LoadLongint(view, "Type", viewType);
  1217. IF viewType = GraphView THEN
  1218. NEW(graphWindow, plugin, c);
  1219. ELSIF viewType = GridView THEN
  1220. NEW(gridWindow, plugin, c);
  1221. ELSE
  1222. KernelLog.String("WMPerfMon: Error: Unknown view type."); KernelLog.Ln;
  1223. END;
  1224. ELSE
  1225. KernelLog.String("WMPerfMon: Error: Could not determine view type of plugin to be restored."); KernelLog.Ln;
  1226. END;
  1227. ELSE
  1228. KernelLog.String("WMPerfMon: Plugin "); KernelLog.String(name); KernelLog.String(" on device ");
  1229. KernelLog.String(devicename); KernelLog.String(" not available."); KernelLog.Ln;
  1230. END;
  1231. END;
  1232. END;
  1233. END RestorePlugin;
  1234. PROCEDURE IncCount;
  1235. BEGIN {EXCLUSIVE}
  1236. INC(nofWindows);
  1237. END IncCount;
  1238. PROCEDURE DecCount;
  1239. BEGIN {EXCLUSIVE}
  1240. DEC(nofWindows);
  1241. END DecCount;
  1242. PROCEDURE Cleanup;
  1243. VAR die : KillerMsg; msg : WMMessages.Message; m : WMWindowManager.WindowManager;
  1244. BEGIN {EXCLUSIVE}
  1245. NEW(die); msg.ext := die; msg.msgType := WMMessages.MsgExt;
  1246. m := WMWindowManager.GetDefaultManager();
  1247. m.Broadcast(msg);
  1248. AWAIT(nofWindows = 0);
  1249. END Cleanup;
  1250. BEGIN
  1251. InitStrings;
  1252. InitPrototypes;
  1253. Modules.InstallTermHandler(Cleanup);
  1254. END WMPerfMonComponents.