Main index > About new desklets > cpu monitor

By ZeroDivide (Desklet Author), on Tue Mar 8 20:32:00 2005: cpu monitor.

I posted a screenshot of a few system monitors I made a while ago here.
They were really slow and had the theme hard coded, so I decided to do a rewrite.

After some simple profiling I found that recording the main display routine as a macro and playing it back was about 3 times faster than what I had been doing.
I also moved all alpha blending to the background updates, although i'm not sure how much this really effects performance.

Now the desklet is faster and fully themeable (well.. almost), but the code is starting to get out of hand.

I would really like to fix this code up and use it as a base for other desklets.
This is the first time iv'e used python and object oriented programming so any help with the structure, syntax, style etc.. of my code would be great :)

the cpu load is about 1% (athlon 1.4ghz) with 6 desklets updating every second in this shot
http://img.photobucket.com/albums/v285/zerodivide/thcpumon.jpg

link to the code

By exilejedi (Core Developer & Desklet Author), on Tue Mar 8 21:36:59 2005.

Ooo, pretty! :-)

I would be glad to take a look at the code, though I am unlikely to be able to give it much of a reading until Thursday or the weekend.

I am curious to see how you implemented the different themes, as I have sort of abstract ideas about how I would do it in my own code, but I haven't had time to put any of them in practice.

Cheers,

Mike

By syfou (Core Developer & Desklet Author), on Wed Mar 9 00:47:07 2005.

This looks very promising - I can't wait to see the final desklet sitting on my desk. As Michael would say: keep up the good work! :-)

I am a bit in a rush this week, so I cannot look at your code as much as I would like too, but be sure I will make a thorough reading next weekend at the latest. I will leave Pyhon-related analysis to Mike, since he is an experienced Python coder while I am not; I will mostly focus on adesklets-related issues. One thing though - could you make a tarball somewhere of all the hardcoded artwork? I am a bit lazy, and I would prefer not to build all the fake images myself...

The only thing that seems problematic from a first peak at your code is the way you handle background versus foreground. Typically, foreground would contain the elements that changes often (text, gauge bar content, etc), while background thoses which are pretty much always statically in place, whatever what happens (frames, background images). If I look at your code right, what you do here is to compose at each step a full image you then put back as the foreground image of a non-transparent window - this is not a problem for desklets with a mostly static face, like weather, but it is when you plan generating a somewhat more complex image every second. Good practice in this case would be to create a transparent window, reasign the backgound to some other image than ID#1 (using window_set_background_image), draw on it if and only if a BackgroundGrab event is generated, composing the borders, the gauge frame, everything that is static once and for all then (you probably want to invole a buffer somewhere also to avoid flickering).

From there, you would not need to bother anymore about all those background elements making your drawing sequence large (only what is really changing - which is far less: some text, the bar lenght mostly)... Another advantage is that the performance will improve, even without using pre-recorded sequences, because far less operations will have to be executed at each drawing step...

If you want a short, easy to follow example on how to use an alternate background, you can look at test/bumpmap.py from adesklets source package. Hope this help!

By ZeroDivide (Desklet Author), on Wed Mar 9 02:48:53 2005.

Thanks for your comments guys

syfou: This is all the drawing that is done on a normal update

Code:


#refresh the section of the buffer that holds the gauge, text and icon

adesklets.context_set_image(self.buffer)
adesklets.blend_image_onto_image(1,0,self.top_canvas.x,self.top_canvas.y,self.top_canvas.w,self.top_canvas.h,
                                     self.top_canvas.x,self.top_canvas.y,self.top_canvas.w,self.top_canvas.h)

#draw gauge on buffer

adesklets.blend_image_onto_image(self.image,0,
                                 0,0,'$' + self.var_name,self.h,
                                 self.x+self.canvas.x,self.y+self.canvas.y,'$' + self.var_name,self.h)

#draw text on buffer

adesklets.context_set_color(0,0,0,255)
adesklets.context_set_font(self.font)
adesklets.text_draw(self.x+self.canvas.x, self.y+self.canvas.y, '$' + self.var_name)

#copy the section of the buffer that holds the gauge, text and icon to the foreground

adesklets.context_set_image(0)
adesklets.blend_image_onto_image(self.buffer,0,
              self.top_canvas.x,self.top_canvas.y,self.top_canvas.w,self.top_canvas.h,
              self.top_canvas.x,self.top_canvas.y,self.top_canvas.w,self.top_canvas.h)


It is a little wasteful to be including the icon in two of those blits, but shouldn't hurt that much.

The background_grab function is a bit big though, mostly due to me trying to cut all alpha blending out of the main drawing routine. Is this even worth it?


I don't have a place to host a tar of the images, but I can email it to whoever wants it.

By syfou (Core Developer & Desklet Author), on Wed Mar 9 03:17:18 2005.

Sorry, I read you wrong there - your refresh routine is more spartant than I though. This said, there are other reasons not to do the foreground/background mixing manually the way you do:
basically, this operation is much more efficiently handled by the interpreter via the window_transparency facility, since some screen update optimization can be performed there that cannot be made consistently available through the 'direct mode interface' - this explains in part the speed-up you observe when using macro-recording here *(the other one being of course the lack of back and forth delays between the driving desklet and the interpreter). Plus, you do get rid of all those alpha-blending considerations.

As I said, I'll have to get back to you later... I need some sleep now. :-(

And yes, please send me your images hierarchy by email (syfou@users.sourceforge.net) - this will be much appreciated. Regards,

[EDIT]
I just wanted to add: 1% of CPU usage for 6 desklets on an athlon tbird 1.4 GHz is already pretty good... Let's not ask for the impossible here. :-)

By ZeroDivide (Desklet Author), on Thu Mar 10 11:19:05 2005.

This is just a quick update on what I have been doing to the desklet.

No more drawing on the background image ( ID 1 )

Borders can now be turned on and off from the menu.
No need to edit the config and restart anymore.

I started making a graph, but i'm not quite sure how to theme it yet.
Maybe using a blank image to get the dimensions of the top part of the graph, and then drawing it centered over the bottom image would work best.
The only other ways I can think of require plugging dimensions into a config file or having them hard coded.

I should really be cleaning up the code instead of adding to it, but thats no fun :roll:

By syfou (Core Developer & Desklet Author), on Thu Mar 10 12:53:34 2005.

ZeroDivide wrote:


Borders can now be turned on and off from the menu.
No need to edit the config and restart anymore.

I do not see it (nor the other changes) in your code link above... Where is it? I could have an hour or two later tonight to look at it more seriously.

By ZeroDivide (Desklet Author), on Thu Mar 10 13:24:30 2005.

sorry, I didn't post the changes yet because its extra messy.

I'll clean it up a bit and email it to you soon.

By syfou (Core Developer & Desklet Author), on Sun Mar 13 03:45:05 2005, last edited on Sun Mar 13 11:13:15 2005.

I read your code: it's not as bad as you say it is, far from it... You did not choose the simpliest desklet to start with. :-)

ZeroDivide, by email, wrote:


The drawing code isn't really a problem for me, but actually figuring out a
better way to structure everything would be very helpful.
About structure, most of the problems I see are coming from the somewhat heavy use you make of hard-coded (and non-homegenous) calls you to your Graph, Gauge, Text and Canvas class instances. I am not a big fan of object-oriented design myself, but had you any chance to look at the Model-View-Controller pattern?

It would be somewhat tedious to explain here, so I wrote a bit of exemplification code instead, applied to this situation: here is the html synstax-highlighted version, and this the original python code. Basically, what it does is to relieve the developper from having to explicitely remember and call appropriate methods from all its "widgets" by first creating a coherent model, then iterating through it homogenously as needed. I think using a similar idea in your cpu.py could significanly lower your code complexity.

Here it goes for structure, but there are two other random remaks I would like to throw in: I hope this help a bit and give you some ideas. I am running one cpu.py instance on my desktop since two days, and I must say I like it very much so far. I cannot wait to have it included "officially" on adesklets site.

By ZeroDivide (Desklet Author), on Sun Mar 13 06:53:01 2005.

The example code you wrote looks amazing. Its going to take me a while to wrap my head around the Widget class, but im sure ill learn a lot in the process.

syfou wrote:

You use lots and lots of statically created images for borders in your configuration example. They would add more than 300 KB to your desklets package if you decided to distribute your desklet right away with them. I understand their visual interest, but you should at least use the image_flip_* commands from adesklets whenever you can

The reason I dont use image_flip is because it would limit the type of border you could use. For example: If I wanted to make a border that had a drop shadow, all the border images would be different sizes and would look different, so flipping them wouldn't work.

Most of the images im using now are a lot bigger then they have to be, and the side images can be reduced to having a width or height of 1. I would also only include 1 or 2 different borders in the package, so it shouldn't be that heavy.

syfou wrote:

In fact, I think you should even go a step further by dynamically drawing the borders using adesklets

Maybe I can include both pixmap and dynamically drawn borders.

syfou wrote:

I see you give access to the README file from the pointer context menu. This is a good idea, but shouldn't you fire a read-only program such as less instead of an editor?

Good point, I hadn't even noticed that.


Thanks for taking the time to go through my code and creating that model view controller example, i'll be sure to put it to good use :)

By syfou (Core Developer & Desklet Author), on Sun Mar 13 11:47:40 2005.

ZeroDivide wrote:

The example code you wrote looks amazing. Its going to take me a while to wrap my head around the Widget class, but im sure ill learn a lot in the process.

I am glad if it can help. Just let me know if there are obscure points. I tried my best to not make it too cryptic, but Widget still use a recursive generator, a new-style class interface and a explicit class attribute while being a fuly valid container at the same time: it is an awful lot for so few lines.

ZeroDivide wrote:

The reason I dont use image_flip is because it would limit the type of border you could use. For example: If I wanted to make a border that had a drop shadow, all the border images would be different sizes and would look different, so flipping them wouldn't work.

I did not say you should always use image_flip_* commands, I said you should probably use them whenever it is possible - when your borders show some symmetry, in fact..

ZeroDivide wrote:


Maybe I can include both pixmap and dynamically drawn borders.

That would be nice... In fact, a sufficiently generic Border widget could provide the user most of the effects he would ever want to use, making the use of precompiled borders a lot less usual, and also making my previous comment about image flipping mostly useless.

On another topic, I think you should already consider submitting your desklet for official inclusion on adesklets site (see the documentation for details on how to proceed -- it is fairly straigthforward). This way, people could begin to enjoy it, and you would probably receive more useful feedback. Regards,

By ZeroDivide (Desklet Author), on Sun Mar 13 18:13:08 2005.

syfou wrote:

I think you should already consider submitting your desklet for official inclusion on adesklets site

I'll start getting the desklet ready so hopefully I can submit it sometime tonight.


If anyone knows of a cool cpu icon that they think I should use, please post a link to it here and ill take a look at it.


adesklets is proud to be hosted on:

SourceForge.net Logo

Back to adesklets.sf.net.