Monday, August 29, 2005

E-Modules tutorial on edevelop.org

 
I've cleaned it up a bit more, removed the funky disclaimer (which i actually miss O.o :) ). Generally, I think that version is cleaner, but i've maintained a link to the original.
 
In future, I will also keep posting the raw versions here, while I will clean-up and post another version to edevelop.org
 
 

Friday, August 26, 2005

Very Cool Thoughts On Coding

I just stumbled across these links, and I must say, I love Kevin Barnes' way of putting things.
 

Exploring E17 Modules - Part I

DISCLAIMER: This is not your traditional tutorial where someone that knows somthing tells you about it. No. In this case, this is someone learning about something and writing down thoughts. That it happens to feel somewhat like a tutorial is a side effect. That said. Njoi :-)

After much procrastination, yesternite, i was plain restless, I looked at the numerous projects I have at different stages of completion on my box, and decided to instead look at something different: E17 Modules.

After my fair success with pysystray(http://datavibe.net/~essiene/pysystray), I've been thinking of doing something similar in E17. The only problem is having the time to sit down to understand what is really going on. So yesterday, I took the first plunge.

Its amazing what barriers knowledge can pose, and consequently, what barriers you can surmount, when you have the knowledge. My main problem earlier had been setting up a build environment for a module. I hadn't really understood the working of Autotools (from the angle of the developer), so a few weeks back, I did a Google for AutoTools tutorials and came up with a free book :). After reading upto chapter 12, I really was *enlightened* :-), and finally, looking around the e_modules source tree, I suddenly understood how to insert my own module into the whole e_modules build process. (I'll expantiate on this latter, just incase you are like me, and didn't quite grab it at first).

Anyways, my approach is a very bare bones approach. I took the in-tree weather module, stripped it to its barest components. And created a module i called 'hello' :). And from there, I'll start building up as I keep striving to understand the whole architecture.

My first findings (which are not really news anyways):

1. There are some functions that MUST be supplied by the module (this is akin to implementing an Interface if you're thinking OOP). e_modapi_init(), e_modapi_shutdown, e_modapi_save(), e_modapi_info(), e_modapi_about().

2. Each of these functions takes a single argument. A pointer to an E_Module.

3. The E_Module structure, contains all the information you need to know/tweak for your module.

4. The order goes like this:
a. When you load your module, nothing in your code is called (same when you unload your module). The work starts when you Enable your module or when you Start/Restart E while your module is marked as Enabled
b. When your module gets started some funky stuff happens to load the module into memory, and the first function from your module to be called in e_modapi_info(). In e_modapi_info(), you're supposed to set distinctive characteristics of your module. Like the icon file, the edje file, and some other things like that. In my bare module. I didn't do anything there... just to get stuff running.

c. Next, E's config system queues your e_modapi_save() to be called at a latter time when the system is idle. (Thnx to raster for this explanation, I had it wrong before). e_modapi_save() is actually supposed to be used to persist data used by your module. (more on this latter). In this bare module. I left this blank as well.

d. Finally, you e_modapi_init() is called. Remember this function takes an E_Module *, but returns a void*. Some important things need to happen here. Firstly, You _SHOULD_ return a valid pointer to a data structure that will be used by your module. If you return a NULL the init will fail. You can be sure that if you return anything that points to memory you can't account for you'll have funky results ;) (Be my guest... try this, and lemme know how long it took for you CPU to melt :-) ).
The strategy here, is to create a simple struct that will contain all the info that you need to do you stuff, and return a pointer to that struct. What E does, is take your return value and store it in the E_Module->data attribute, where it will always be available from that point onwards.
Imagine you have this.

typedef struct _hello {
char* message;
} hello;

typedef hello* Hello;

Let that struct be your module Hello struct. for e_modapi_init(), we'll have this:

void*
e_modapi_init(E_Module *m)
{
Hello h = NULL;

/*normally you check for api version here and bail out if version is wrong. lets just ignore that for now*/

h = (Hello) malloc(sizeof(hello)); /*you should usually ecapsulate this in a function like hello_new() that does this and some other stuff for you.*/

if(!h) {
e_error_dialog_show("Hello Module", "Initialize Failed!"); /* I'm adding this so we can see what's going on.*/
return NULL;
}

e_error_dialog_show("Hello Module", "Initialized Successfully!");
e_error_dialog_show("Hello Module", "Hello World!"); /* Finally our own e_module hello world... now the world is at peace ;) */
return h;
}

That's a very basic e_modapi_init() to get you going. When you being thinking of saving and restoring data, a bit more will need to be done here, and when you throw in menus, GUI, config stuff... that baby can begin to do realy much more... for now tho.. this is all you need.

e. After init returns. You module should be fully running. There are two more important hooks that you need to take care of. e_modapi_save(), and e_modapi_shutdown(). Like I mentioned earlier, e_modapi_save() is used to persist data. And we don't really want to do any persisting now, so we ignore it. On the other hand e_modapi_shutdown(), will be called when we Disable our Module, or when E is going down (for good, or for a restart). What we need to do in shutdown() is to release all memory we claimed in init(). But how do we get that data? The E_Module struct has a number of attributes we should get very friendly with, but right now, what we're iterested in, is the data struct we initialized in init(), That data struct is stored in the 'data' attribute of our E_Module struct. In our case this should suffice.

int
e_modapi_shutdown(E_Module *m)
{
Hello h = NULL;

h = m->data; /* this is how we get back our Hello struct from the module subsystem. There are other attributes that hold other things, face, menu, etc. ignore for now */

free(h);

e_error_dialog_show("Hello Module", "Shutdown Completed");

return 1;
}

In our case, that simple function will do our shutdown for us.

f. Lets quickly run over the info, save, and about. Remember, e_modapi_info() is the first function that is called in your module. Its supposed to help setup information on your module, like label, icon_file (which shows up in the menu), etc. about is called when the about menu item is clicked. Typically should just give info on your module and exit, but hey.... you can write a webserver inside there if you're so inclined :), just return 1 when you're done. For save/info, we'll do nothing. Here we go:

int
e_modapi_info(E_Module *m)
{
return 1;
}

int
e_modapi_save(E_Module *m)
{
return 1;
}

int
e_modapi_about(E_Module *m)
{
e_error_dialog_show("Hello Module",
"A hello wold module for E17. To appease the gods of tutorials.\n"
"If we don't have this, we may be banished to debugging the great "
"Aiii Eee for the rest of our days! \n\n"
" Visit: http://essiene.blogspot.com/2005/07/travellers-log-1.html "
"for more information :)"
);

return 1;
}


5. Finally comes the part that kept me from doing this for a very long time. I didn't understand the compilation process. Well, now I understand it a bit more, thanks to reading up autotools (btw, FREE BOOKS ROXS :-) )

The _easiest_ way *THAT I* found to compile my module was to add it to the e_module tree from CVS. If you already have that proceed. Else, check http://www.get-e.org for instructions on how to grab E from CVS. You only need the e_module tree really. So this could be a quick start here. The password for anonymous is blank. Remember that.

$ cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment login
$ cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment co e17/apps/e_modules

These two commands will check out e_modules for you:

The e_modules directory will contain this directory src/modules, where all the other modules exist.
a. Create a new directory called hello in the src/modules directory.
b. Type your source files in here. Traditionally, the files are named e_mod_main.c and e_mod_main.h (for any custom headers you want to define and function prototypes). Remember to include the correct header files, e.h for all the e stuff, and any other functions you use. (stdlib.h for malloc and free)
c. You'll need a file Makefile.am, that is used by autotools to generate Makefile.in which is used by configure to generate Makefile. (pretty twisted huh? Yup... if you don't understand it that is :) )
d. For that, you can copy the Makefile.am from the flame module directory, into your directory, and rename all instances of 'flame' to 'hello'
e. Some files are mentioned in that Makefile.am that you don't have currently, so i suggest that you copy module_icon.png from the flame module over as well. Don't wory, it won't break anything.
f. Now move into the parent directory (modules), and edit the Makefile.am there. add 'hello' to the end of the line that says SUBDIRS = . (this enables your module folder to be processed)
g. Step upto the e_modules root folder and edit configure.in. At the bottom of the file, there will be a set of lines that look like: src/modules/flame/Makefile. Add your line after the rest, but before the square brackets. Something like this should suffice: src/modules/hello/Makefile
h. Save and exit configure.in
i. If you fetched from CVS, this is the time to type ./autogen.sh in the e_modules root (if you downloaded a tarball, then just go ahead and type ./configure, specifying the neccessary options to configure/autogen.sh)
j. go ahead and make with make install
k. load the module like you would load other modules
l. enable it. You should see your message boxen now :)


Well, that's how far I got last night. Before I started delving into the E sources trying to understand more stuff, also asking questions on IRC. In the next log, i'll attempt to tackle persisting information, and maybe adding menus and or faces. I hope this helps someone out there :)

Wednesday, August 24, 2005

Its Official GTalk Rox

:)

Threaded handlers in Pysystray

One of the important TODO's I have for pysystray is making the menu item callbacks/handlers threaded. To acheive this, I thought of the simlplest most unobstrusive way to add it, and I decided to go with Decorators.
 
Uptill yesternite, I didn't really get Decorators, but back at home, Stan (my flat mate) and I took a look at the PEP, and suddently It was all clear.
 
I then wrote this simple decorator:
 
>>> import thread
>>>
>>> def run_threaded(func):
>>>    def wrapper(*args):
>>>        thread.start_new_thread(func, tuple(args))
>>>    return wrapper
 
 
To run any function in a seperate thread of execution you'd do this:
 
>>> import time #just for a sleeping example :)
 
>>> @run_threaded
>>> def looper(x):
>>>     for i in xrange(0, x): #gotta love generators :)
>>>         print i
>>>        time.sleep(2)
 
now running:
 
>>> looper(10)
 
will run it in a seperate thread of execution.
 
With me finally understanding Decorators, I now have just metaclasses left to understand before I can say I'm trully upto step on python 2.4's features. But man... you just gotta love this language... Its sooooo malleable.
 
I've added the run_threaded decorator to pysystray, but i've not released this version yet... I'm going to refactor the files a bit more, and try to attack one or two more todo's before i release 0.5.0.
 
Btw, If you're wondering why this is an important addition... Currently, if a MenuItem callback/handler takes too long to complete, it hangs the UI, and the pop-up menu no more shows up. This will also be helpfull for the on_load event handler so it also doesn't lock up the UI.
 
Oh.. btw, I'm thinking of using the Google API message notifier for pysystray's notifier... If its possible. I'll start groking the SDK next :)

Google Rulez!!!!

OMG!!!!
 
Yesterday, I installed Google Desktop 2, allowed it to index Bolivia (my laptop), and was just tripping all over it, and was just about to post praises, but guess what happened?
 
Google Talk was released this morning, and DAMN!!! I've fallen all over myself on this dual move.
 
Everyone at my office already crying 'Death to Yahoo Chat' just by using Google Talk Beta!!! Its amazing, and the Voice Talk feature just plain blew us all away. Yahoo Chat is toooooo darn heavy... sheesh!!!
 
The things that Google does are now bodering on Magic ;), I mean, with Google Desktop, who needs that Start Menu anymore? Just type the beginnings of your program name, and its finds it, you press enter and 'launcho!!!'
 
Google Desktop also has notifiers for my Outlook mails, Gmail, everything, and even an Outlook search plugin... which totally rox!!! Ofcourse, i've disabled my Outlook notifier and i'm using Google's Notifier now.
 
My homepage is now set to Google Desktop's Homepage, which is totally what I love.
 
What's next? Oh well.... there's the SDK with Python bindings :D, so I guess you can already percieve what's next... oh yeah... baby... we're gonna hack the hell outta that SDK :D
 
Oh.. and Google Talk is keeping with Open standards, supporting XMPP/Jabber... cool...  Man, these guys are seriously throwing open the field... now a major IM provider is behind Jabber, I wonder how Yahoo and MSN respond to that... not that I care anyways :D
 
Yahoo made a good move with konfabulator, as i'm still going to keep my Konfabulator weather widget on my desktop, but hey... that's about all i'm going to be using from them :D
 
The world is getting more intersting... i'm just wondering what next... Googlix? A Google Linux Distro? O.o... they have the world by the balls already... and the world doesn't seem to mind ;)
 
Oh... boy.. exciting times :)
 
 

Tuesday, August 23, 2005

pysystray progress

Yesterday, on request by some users, I changed the licensing to BSD style. There is now a 0.4.2 release, which just contains that change.
 
This seems to be the least problematic license out there, and I really don't have to wrangle my head around the specifics. I just want to write code that others can use, period.
 
 
There is now a couple of things to do, cheif among them is to make the menu items actions threaded, so that it doesn't lock up the UI while long actions are being performed. That and Adding an on_load, event that can be set to start a process once the App starts. Those are my highest priority features before i start considering a version 1.0.
 

Monday, August 22, 2005

pysystray on sourceforge

I've been quiet for a while. Deliberately too.
 
In that time, quite a lot of things have happened, all not too good, but some very exciting.
 
I'm currently hosting pysystray on sourceforge. The homepage is at http://datavibe.net/~essiene/pysystray
 
I tried everything in my power to get the sourceforge supplied webspace to host the homepage for the project, but nada.... it didn't work. So i gave up and went along with my webspace.
 
So far, i've had some good feedback, and a major project seems to want to use it, I just got mail from someone on their dev team this morning, just clarifying the licensing :)
 
Cool huh? Yeah... makes me feel good that pysystray is usefull for someone afterall.
 
I'll update with what happens to that :)

Friday, August 05, 2005

more EET progress, update on D Xlib

Got some more lines of code in yesternite. Moving a bit slowly... i have this project at work that is tasking me out.

Anyways, i've added support for image data to the EET File. In the course of this, i had to create two struct ImageHeader, and Image, to make it all cleaner to use. Image may become a class with its own methods in a future incarnation/refactoring cycle. I can smell it already, but i'll delay the decision untill its obvious. Next come the DataDescriptor stuff i've been avoiding :D. Once i'm able to do those, i'll give myself an ECCTD certification. What's ECCTD? Duhhh!!! Essien Certified C To D Porter... DOH!!! :)

On the D Xlib front. Dejan (http://dejan.lekic.org), has finally gotten around to trying out what i've done so far, and declared we're good to go for the next step. Incidentally, we've decided to put a chill pill on Directly making Xlib D, OOP. What i think is that it will happen when we start the next phase... uhh.. yeah... This was just a precursor to another project. Porting DFL to Linux (http://www.dprogramming.com/dfl.php).

Just incase you haven't yet figured it out... that's how the XLib to D port came up :). Vathix, who is the author of DFL would want to have DFL on Linux, so Dejan and I are helping out, and in the process, hopefully filling a great need.

Anyways, we're ready to start moving on DFL, and we're going to be modelling it after dotGNU's Xsharp (A from scratch implementation of the .NET System.Windows.Forms functionality for the dotGNU project).

Dejan should setup subversion for Xlib D, and we'll be on our way... lets see how much work we can punch in this weekend.

exml : first feelings...

First of all Libxml2 is a great library. I truly respect it.

Ok… that said, the C API … it has too many gotcha’s… sheesh!!!

Lets say I have a file ‘root.xml’ that looks like this

<root>
<node1>
<node2>
foo
</node2>

<node2>
bar
</node2>
</node1>
</root>


Using libxml2 directly, I can get a structure representing the whole document with

xmlDocPtr doc = xmlParseFile(“root.xml”);

To get the root node:

xmlNodePtr node = xmlDocGetRootElement(doc);

currently, node will contain information about the <root> level.

If I try to printf() node->name, it correctly reports ‘root’. Nil Problemo.

My problem arises when I start trying to walk the tree. xmlNodePtr has a member called children,
And its supposed to return the children node. Anyways… if I do:

node = node->children;

I expect it to now be pointing at <node1> right? Well, its not… instead when I try to printf() node->name at this point,
It gives me ‘text’.

Ok… before some libxml2 guru crucifies me, I’m sure there’s something I’ve not read the documentation for, but hey… that’s the behaviour I expect… or am I missing something?
Don’t answer… but I guess I am. I kept trying to play with this for a couple of hrs, trying to recursively walk thru any document… and this behaviour kept tripping me.

Anyways, I just thought.. hmm… what is in exml? Afterall what do I have to loose? I have the entire enlightenment cvs tree on my system anyways…. So away I went.

Using exml, I was pleasantly surprised at how it matched up with my thinking and my expectations (I belive my expectations of API’s are usually very high).

Anyways…. To get the entire document with exml I do:


EXML* doc = exml_new();
exml_file_read(doc, “root.xml”);

Almost same as libxml2, and a bit more verbose I admit. I would have preferred it being structured after a constructor paradigm.

Now, I can query the current point that the document is at. Via functions… so if I do:

printf(“tag = %s\nvalue = %s\n”, exml_tag_get(doc), exml_value_get(doc));

nice and easy… ofcourse… you can still an object that refers to the current node, by:

EXML_Node* node = exml_get(doc);

And the previous can be done with:

printf(“tag = %s\nvalue = %s\n”, node->tag, node->value);

So far, nothing really different.

The tripping part is if I want to get the <node1> part of the document. EXML has very handy functions for clearly moving around the document unambiguously. (I don’t know if libxml2 has these as well, but I didn’t wait to find out once I discovered exml’s ease of use)

exml_down(), exml_up(), exml_next(), exml_next_nomove(), exml_goto(), exml_goto_top();

each of these move you in a specific direction without suprising results, and return the value of the next node tag as a char*, or NULL if there is no next node.

Still trying to drill down to ‘foo’ and ‘bar’ from our xml document, I would do this:

//I’m not checking for errors or freeing memory as I’m going, in real code, I’d do these.

EXML* doc = exml_new();
exml_file_read(doc, “root.xml”); //right now we have the whole document, and we’re at <root>
exml_down(doc); //we’re now at <node1>
exml_down(doc); //we’re now at <node2> so we can read and get ‘foo’

printf(“Expecting ‘foo’, got : ‘%s’\n”, exml_value_get(doc));

exml_next(doc); //we’re now at the second <node2> so we can read and get ‘bar’

printf(“Expecting ‘bar’, got : ‘%s’\n”, exml_value_get(doc));


well…that’s it basically… that’s just it.

All in all EXML.h is just 81 lines of defs, white space included. Also, I didn’t need any primer to figure out how to use this library. I just looked at the header file and it was clear (Rule Of Least Surprise).

To my lazy mind… this is currently THE xml C library for me now. The only thing for some other folks may be that it depends on Ecore, another part of the EFL, which actually depends on Evas and EET as well, for me tho… I already depend on the EFL, so I don’t mind one bit.

Did I remember to mention that its built ontop of libxml? Yup… it’s a very nice piece of work… building on the solid layer that is libxml2, but not having all the gotcha’s etc.

Ofcourse, there’s no inherent support (YET) for XPATH, XSLT, etc, and all the goodies that libxml2 already has, still, it works so far, and in less than 15 minutes after looking at the header file for the first time, I already had the weather.com parsing library upto the point where I can inteprete simple search queries…

Nice? You bet!!!

Essien, out.

Ajax Paper

http://www.adaptivepath.com/publications/essays/archives/000385.php

 

This seems to be one of the earliest and authoritative on the AJAX phenomenon. Good read.

Thursday, August 04, 2005

C Xml Processing

Started trying to grok XML Processing in C, and so far, I’m learning libxml2. Seems interesting, though really painfull initially ( I mean, coming from ElementTree and the links of Amara that are available in Python, libxml2 C Api can be very primitive). But now, its not looking that bad at all, infact, I can say I’m enjoying myself… currently I’m turning my attention to using it to grab information from the weather.com webservice (I expect to have a libweathercom from that experiment). Then ofcourse, there is the conversion to D (if it hasn’t already been done)… who says life is boring? :)

 

Essien.. out!!!

EET progress

I’ve moved over the hoop that was causing me grief in my EET File class. Its done now, and unittested. I’ve also discovered that apparently a file can’t be opened for Appending… that’s somewhat odd, there are some File Mode flags for READ, WRITE, READ_WRITE.I’ve not been able to use READ_WRITE to successfully open a file. Tired asking around #edevelop. No one answered authoritatively, but ‘Codewarrior’ suggested I may be right.

 

Anyways, that won’t stop me from moving ahead.

 

There are some tricky contstructs still infront, so, my path for the rest of the week is cut out for me I guess. Interesting? YOU  BET!!! :)

Wednesday, August 03, 2005

Xlib Classes for D

Yesternite, I got around to start encapsulating Xlib C functionality into D Classes.

 

Still working from the simple line drawing example, I was able to pick out the necessary layers for a basic Xlib application, and have translated these to classes. So far, I had to create there to work:

 

  1. Display
    1. This seems to be the basis of what you end up seeing. I’m still reading up on what it really is, but I think it’s the basic abstraction of what the XServer actually controls.
  2. Screen
    1. For my program to run, I needed to get the current BlackPixel, WhitePixel values from the DefaultScreen of the Display. So my display class allows me access to the Screens (encapsulated as the Screen class)
  3. Window
    1. Now, those little boxen you see on you monitor. The ones with the close buttons, etc, are actually the windows. Actually I got to find out that even buttons, scrollbars, etc, are all windows under Xlib.
    2. To create me a window I need a parent, and the display has a DefaultRootWindow, which I use as the parent for the top level window of my little line drawing app. Display class has a property, DefaultRoowWindow (encapsulated as a Window class)
    3. Also windows are not visible or usable until after successfully Mapped by X.
  4. GC
    1. This one confused me initially, as I first thought it was another surface encapsulation. Reading the Xlib programming manual in the wee hours of this morning, cleared this up for me.
    2. A GC (Graphic Context), is an encapsulated resource that holds information about drawing primitives, for example, line width, line style, foreground color, etc.
    3. To draw a line, I create a simple GC from the Window, and call its DrawLine method.

 

 

Yesternite, I was a bit lazy about encapsulating the Events immidietly, actually I felt that my initial understanding of the Events wasn’t very good, and I may not do a good job encapsulating, so I left them raw as they are. I’ll read more on them tonite, and do some more work. Once I have the Events also encapsulated, I’ll proceed to write the various unittests for the small functionality present in these classes, and I think I’ll do a File refactoring, it seems those classes are gonna get really big, I don’t want them all in the same single file.

 

Once I’m done with the UnitTests tho, I’ll move on to the second example program, and add features to the classes to get it to run.

 

Btw, I didn’t get to touch the EFL to D port last nite… I have some design decisions to make on EET, and I’m thinking I’ll take the very raw and straightforward way forward for now… when I’m more used to the class, I’ll come back and refactor.

 

Essien, out!

 

 

 

Monday, August 01, 2005

Yahoo! Widgets





You know... ever since Google took the world by storm (uuhh... make that by search... or is it by searching for a storm? :) ), they've left A LOT of competitors behind... and not just in the dust... but in the Sand Dunes.

But i think i can say that Yahoo has been a worthy competitor... they keep responding well, (after all Yahoo's and Google's founders are all Stanford products right?).

Anyways, that aside, Yahoo has done something very cool... they acquired Konfabulator and set it free. I used to use Konfabulator pre 2.0 on my old laptop (wendy), and used to utter some PG Expletives anytime the expiration notice showed up on my box. When i got my new laptop (bolivia), i swore they wouldn't see my boxen anymore... no matter how cool they were (and they're ooooooo sooooo cool). Well a couple of weeks ago, i found out that Yahoo has acquired them, and set it free. So i can USE IT WITHOUT paying (call me cheap-arse, cheap-stake... whateva... that's your problem)

What is Konfabulator? Uhh... check out: http://www.konfabulator.com

what can you do with it?

That screenshot is worth a thousand how-to's (but you don't really need a thousand how-tos on generating a screenshot) [that statement doesn't mean anything, so please don't try to make any meaning out of it:) ]

Weekend Hacks

I had an interesting and fun filled weekend... really.
 
First, I completed the first stage of the Xlib D port. And i have the first sample D Xlib program that draws a line to the screen, waits 10 secs and exits.
This is just the first stage.
 
The next stage involves making the library *FEEL* OOP and feel like D instead of C. This will involve a continous process of introducing classes, etc, to encapsulate most of the pointers flying around.
The hard part is done anyways, this part is a matter of  continous integration, and good judgement. I'm starting that this week, and I'll have to be studying core Xlib programming to understand the application layering, so i can do at least a half decent job. No rushes here.
 
I'll make these available on my download area within the week.
 
On the D EFL port, i've been creating the D layer for EET, and ran into some pointer related issues, as i try to wrap up the function calls into D Classes, but along the way, i learnt more about D's invariants, pre and post conditionals (Contract Programming), this stuff is VERY VERY COOL. When used properly, it really reduces bugs, and helps find bugs faster, combine this with D's inbuilt UnitTesting, and i really don't know why i should use any other language for Midlevel Application Development (Low level is owned by C, and High Level is owned by Dynamic Languages like Python). If you really feel the need for speed... don't take a cup of Java, or try to Sharpen your C, no no no no no, just take the next alphabet... D. :)
 
Needless to say, i felt pretty accomplished this weekend, and rewarded my self with a nice move.... SIN CITY... the movie is sorta weird... but its really cool, and my, was Mickey Rourke, Marv? That guy was my main guy in the movie.
 
Ok.... off to work now :)