Monday, January 25, 2010

Today's development environments relatively suck...

I wanted to not break the "rant -> nice post -> rant  -> nice post -> etc" pattern i had on this blog until my last post, but since months passed without a new post it seems i have much more rants to say than useful posts to write. And from some POV, a rant is a useful thing, especially my rants because i write them with passion and love while listening to awesome chiptune music. So here goes my latest so far rant, this time its about how much the -mainstream- development tools of our era (that's 2010) suck, in a relative way, when compared to some -mainstream- development tools of the older times.

I'm amazed how much sometimes programmers ignore the work of others, especially in the domain of their own tools. So many nice ideas, practices and even standards (in usability) are simply ignored because they were made by the other guys. This can be seen clearly in open source/free software world which prefers to ignore good stuff simply because they were made by some entity they dislike (usually the suspect here is Microsoft), even if there is absolutely no reason to do so. But this isn't something only FLOSS people do. Freeware, shareware, commercial, etc developers are guilty of this too. But i'm going to focus on the FLOSS side of things only because that's what i can't fix.

The story begins about the moment when i decided to press the almighty Ctrl+F1 key in my FreePascal IDE. You know, the IDE that looks like the old Turbo Vision-based Borland IDE for Turbo/Borland Pascal 7 and some Turbo/Borland C/C++ IDE of that period. I wanted to see the docs about some function or something. Well, i was greeted with a nice screen telling me that i need to download the docs because they decided to not include it for some reason having to do with including a 5mb package in a 60mb package would be wasteful or something like that (ok, i'm exaggerating, the help package is 11mb and the compiler package is 35mb). Apparently everyone who uses FreePascal knows the docs inside out and they never need to read them. Ok, actually they don't know them, they do read them. That's because they're included in the compiler actually, but they're in PDF format. Unfortunately the IDE cannot read PDF files so you need to read them outside of the IDE using a program like, say, Adobe Reader or some sort of half baked PDF reader that can read most of the PDF files their developers feed it but always fail when you want to read a specific PDF. Ok the PDFs that come with FreePascal can be read by all PDF readers i've tried (which include Adobe Reader, whatever comes with GNOME and nothing else). But correct me if i'm wrong, i don't find it easy to search through a bunch of PDF files for the definition of a single function, not to mention that if this function is a widely used one (like writeln), i'll need to skip a bunch of examples. So the next part is to download the HTML files from the site and feed them to the IDE (which, btw, cannot find them automatically - no, you have to inform it where the files are). This will make the IDE read all these files and after processing for a few minutes (in my quadcore computer, YMMV) to generate some sort of index (which sometimes it fails to save to disk and crash). After this process is done, we can finally use the help files from within the IDE. Pressing Ctrl+F1 will now almost do the job of showing the help you request. I say almost because usually the help system isn't sure what you want to do and displays either some random page or an index which takes ages to load and contains a few billion words to choose from.

Now you might be thinking (as a knee-jerk reaction, i'm sure) that the FreePascal situation is the fault of the project's programmers and it doesn't represent the situation in all tools. Actually i agree with both: it is the fault of the project's programmers and it doesn't represent the situation in all tools. This is because FreePascal has actually some of the best documentation system and unlike most tools out there there is actually human (as opposed to drone) readable documentation. And the fact that i can press a single key and get some sort of context-sensitive docs (even if usually aren't what i'm looking for, but at least they're trying) is good. Another project that has the half part done right is OpenWatcom, which includes documentation for almost everything. Unfortunately OpenWatcom's IDE is an abomination even for 1993 standards when the Watcom part was popular.

But the problem exists in other tools as well. Eclipse, for example, simply fails to provide any sort of similar functionality. While there are some nice touches, like the ability to display JavaDocs while editing Java files and maybe comments in C/C++ files (or the whole source if its around, which in the case of small functions is helpful), it is simply impossible in the stock installation to get something like the FreePascal system above: pressing a key and getting info for whatever is under the cursor. There is some plugin which under some situations -which i never managed to encounter- can display the docs from glibc, but i think the docs are displayed as a popup.

A better case is NetBeans which simply has a better JavaDoc browser - the default OS web browser. But that's all you can get. Try to ask for information about what class means and the IDE will hang for a while (probably it tries to figure out why someone might want to know a language construct) and then will simply beep. Beep. As if saying fuck you to the developer, fuck you for wanting documentation about something not part of the API.

I'm not going to mention vim and emacs. The former is a generic text editor which tries to become a development environment and the latter is an operating system which tries to become a text editor. From the two, i prefer emacs but only because i hate the modal nature of vim and it works via ssh. Unfortunately, like Eclipse, emacs' idea of context-sensitive documentation is launching some sort of hypertext system (info) to display glibc documentation.

Now let's take a look on some old environment we hopefully all know and used to be one of the best, if not the best, at its time: Turbo Pascal 5.5. I chose this specific version because its available for free from Embarcadero's site (which currently holds the copyright). Running the IDE greets us with a nice warm screen (as warm as can be done in DOS colors without bleeding your eyes anyway - oh sorry, Linux console has the same colors too... but i'm going to leave that part for another rant some other day).

Here is what we see after we type TURBO.

So, we start typing some code here. Nothing special, just some program that asks us our name and displays a greeting back. This is something a lot of people who are learning programming will write as one of their first steps...


Now, excuse me, but isn't this a much better looking screen than what we would get if we wrote this in Emacs?


But i'm comparing apples with oranges here. Or blues with blacks. Or whatever. So, at this point lets assume we want to learn what the hell writeln is here. So we move our cursor to the begin word and press Ctrl+F1. This is what we see...

Well, it isn't the best description, but there is a pointer to the Write procedure and an example:

Check the text at the bottom right part of the screen: you can put this example in your code. Not only the documentation explains what the function is all about, but you can test the function right there. Doing the same in FreePascal shows the documentation for the WriteLn function in its own help system:


That contains a lot of more information and while there doesn't seem to be a method to automatically put the example in the editor, the text can be copy/pasted to the editor using normal editing keys. I'm going to argue though that i don't care about the source position part and that the syntax in Turbo Pascal 5.5's help made more sense. Also i think the text would be formatted better but anyway. On the positive part, there is information on what can go wrong, portability notes and more suggestions for similar functions.

Unfortunately, the nice part stops when i'm trying to see documentation about a language feature. For example, lets see what begin is all about. In Turbo Pascal 5.5 pressing Ctrl+F1 over the begin word i get this screen:


Actually this is one of the best descriptions for the begin/end construct i've read. Simple and to the point. Probably the memory limitations of the time helped to be a bit creative, because in FreePascal's documentation the description makes less sense:
Compound statements are a group of statements, separated by semicolons, that are surrounded by the keywords Begin and End. The last statement - before the End keyword - doesn’t need to be followed by a semicolon, although it is allowed. A compound statement is a way of grouping statements together, executing the statements sequentially. They are treated as one statement in cases where Pascal syntax expects 1 statement, such as in if...then...else statements.
I'm not sure the part about the semicolon needs to be mentioned there too, but anyway. Trying to do the same (press Ctrl+F1 over the begin word) in FreePascal i get this screen:


Oops.

Obviously the help system couldn't find any topic about begin, so it displayed the closest it could find. Unfortunately this isn't what i'm looking for. Pressing Shift+F1 to view the index, it seems that there isn't a topic about the begin keyword. And there isn't a topic about any keyword.

FreePascal's context-sensitive documentation doesn't care about the language itself.

And this isn't a problem with FreePascal only as i figured out. In Eclipse i simply can't find information about the case structure in C, C++ or Java. I simply can't find documentation about C++ templates anywhere in the otherwise huge /usr/share/doc directory in my Ubuntu account. Nothing related to these languages can be found in these places.

The documentation case sucks. As i said at the beginning though, FreePascal and OpenWatcom do include documentation for the languages (a huge thumbs up for these people doing something like that). Having documentation for the language is a good thing, even if GCC simply ignores that for decades now. All i'm asking for is for this documentation to be accessible in a context sensitive way from within the IDEs of my choice, just like it used to be in popular environments 21 years ago.

Two decades ago the development experience was much better than it is today.

I've become a bit bored writing stuff right now, so i'm going to close with two things: first, Microsoft does the right thing by including documentation for everything. If you press F1 over any word, be it API or language keyword, you'll get the docs for it. I don't like the fact that this is done over the Internet, which makes it very slow and the new help browser they have sucks big time (what was wrong with the old CHM or even better, the lightning fast HLP?). But at least they have it.

Second, the rant isn't over. Getting help is one thing, but its not the only issue we have today and was solved at the past. Creating projects and making GUI applications are two other issues. I'll post about them at some point later. Especially on the GUI part is amazing how much people don't get how it should be done.

Wednesday, October 21, 2009

Why does Wine still lacks behind Windows XP?

According to the Wikipedia, Windows XP was released at 2001 - about eight years ago. Wine started development at 1993, 16 years ago. By the time Windows XP was released, Wine had already eight years of development and in fact it started almost at the same time as the initial release of Windows NT.

So, with all the force and power of open source software and the practically frozen API of Windows XP (with its few differences - at least in the core - since Windows 2000 and previous versions), how comes that today, eight years after XP's release and sixteen years after the initial version, Wine still lacks behind Windows XP to the extent that almost everything needs an application-specific patch to run?

How comes that there are so many "does not run" posts in the Ubuntu Forums? How comes that it is simply not possible to download an .exe setup file, run it and have the whole thing integrated seamlessly in the system? Windows is much more of a stable environment than Linux - it doesn't change as frequently. The target doesn't move that much.

With all those thousands of developers in Wine's about box, how comes i still can't download, install and run a program or a game much like i would do under Windows XP?

What is wrong?

PAK files, simple formats and a new mouse

I'm interested in learning low-poly 3D modelling using Blender and i thought it would be a good idea to study the mesh of some low-poly models used in games. A game i like and has some nice models is Quake 2, which is one of the few FPS games i have available in Linux. After checking with Blender 2.5, which is what i use (although it is still pre-alpha and crashes a lot, i prefer the new UI to the old one), i figured out that i should use Blender 2.49 for viewing the meshes because 2.5 lacks an MD2 importer.

So i decided to open Quake 2's MD2 models to Blender and see how the mesh is constructed, how the textures are arranged, unwrapped, etc. But there i hit one small issue: Quake 2's data files are packed in a special file format, PAK, that is used by Quake 1 and Quake 2. I tried to find some program to extract these files, but after looking around for a while, it seemed that i had to use Wine and a Windows-based program in order to extract the files.

However, i remember from the older days when i was messing with Quake 1's source code that the PAK file format was a very simple uncompressed format. So i looked around for an explanation of the format so i could write a simple extractor. I found some information about reading files using Visual Basic and using that, i decided to write an extractor.

It turns out, the file format is extremely simple. It is just a single directory (basically, an array of entries) stored on disk pointing to several places inside the archive for the file data. All you need to read a file is to look it up in the directory, find its position, move the file reading header to this position and start reading. If the file formats you use do not depend on end-of-file situations (read stuff until you reach the file's end), you can even use plain old FILE* and fread for reading the data and use only a special "fopen" that places the file's read position to the correct place. In fact, this is what i remember Quake 1 doing.

And scanning the file is also very straightforward: do you want to scan all the files in the maps directory? Just search for the entries starting with "maps/". Do you want to see if maps has a subdirectory? Check if there is a '/' character after the entries in it.

Such simple formats makes the development of an engine simpler and faster. Personally i try to use custom simple format everywhere i can - keeping the dirty stuff outside of the engine and using only pure formats for the engine's code. So for textures, for example, i prefer to use a custom format that simply contains the OpenGL data i will upload. No PNG, JPG, TGA or whatever else loaders. Just the data. Similarly for model formats. No Collada, 3DS, OBJ or whatever: just the indices, vertices, matrices and whatever else is needed but no more.

So, anyway. I wrote the PAK file extration utility and also i wrote another utility that creates PAK files (and can also create "patch" PAK files using an existing file for time reference). They are written in plain ANSI C (with UNIX header files, but it also compiles with MinGW under Windows). You can find them in the Git repository. The repository also contains a programming language agnostic description of the PAK file format because i didn't like the Visual Basic one i found.

As for the mouse. Well, i saw that Apple released a new mouse they call "magic mouse". It is a multitouch mouse (the world's first - although Microsoft also experimented with those but they used a camera to track the fingers and to me Apple's mouse seems -and looks- better). They also released new iMacs and MacBooks and i think i'll get one of the new MacBooks with the 7hrs battery life. Of course i'll pay the "Europe tax" - which in this case is about 333 euros because for some people 1 euro = 1 dollar and i can't order stuff from US.

Monday, October 19, 2009

Compositing in X sucks. Who had this brilliant idea?

I was wondering why my compositing desktop is so slow when resizing, maximizing/restoring and opening windows. And i've found a reply from some nVidia guy in a forum (here is the post) who said that each time you resize a window in a compositing manager, the manager:
  • creates a new pixmap with the new size in system memory
  • copies the old pixmap's contents from the video memory to the new pixmap
  • draws the window's contents inside that new pixmap
  • creates a new GL drawable (texture) in video memory
  • copies the pixmap's contents to video memory
So in short, for each resize the manager does a read from video memory to system memory, an allocation of new video resources, and a write to video memory from system memory. And most of these operations are done in CPU, including filling the window's contents (aren't we past the mid-90s when filling rectangles and drawing lines was done entirely in CPU?).

This video memory read part makes most people notice the slowness (because its a very slow operation - and not needed in most cases, but is done to avoid some flickering), although it should be already very obvious that the above process is slow by itself. I mean, creating a new texture each time a window is resized? Copying contents from video memory to system memory and again to video memory? Does the hardware released the past decade lack the feature to draw stuff in video memory? There is no reason to touch the system memory if the underlying hardware is able to draw using only the hardware. And i'm sure my 8600M is totally able to do so.

The irony is that older, crappier notebook cards have better performance with this because they share their memory with system memory so copies are faster. I think that this is the reason most people do not have this problem with Intel cards, for example.

I'm hearing people at the background shouting "then get the source and fix it!". Well, first of all, STFU. Secondly, fixing this means modifying many parts of how the Xorg draws windows and i doubt the Xorg developers would accept such a radical patch from someone who they never heard before and -clearly- doesn't know the Xorg codebase (which means that there will be mistakes in the code). And i don't want to spend my -little- time doing something that will be probably rejected.

Besides i'm sure other people already tried and their patches never reached the main tree.

But i don't know why this is still there. Aren't Xorg developers worried about the performance? Compositing is barely usable if you're not using an Intel card and as long as the current method is there, nothing will be improved.

The best option would be for everything to be hardware accelerated using OpenGL. With everything, i mean everything: filling rectangles, drawing rectangles, lines, curves, shapes, text, images, etc. Pixmaps should always be in video memory. Make "X shared memory" obsolete. Make an extension which gives access to the GL drawable for programs to write stuff directly (for video playback, etc). Bring this window system to 2010 where even a $200 laptop has decent programmable hardware acceleration.

Sunday, October 18, 2009

A Java trick for SWT goodness

If you have ever used Eclipse's Visual Designer for SWT, you'll realized two things:
  • being able to automatically "understand" how the GUI is made and "parse" the code so it can create the GUI directly from your own code without the need of helper XML, FRM, TXT or in-code comments (although it uses some of them) is awesome.
  • doing all the above makes it crawl. Its terribly slow.
And of course you'll also realized that Visual Designer is the only free option out there. And unfortunately, when compared to other GUI designers for other toolkits, it is low on features and usability. Matisse from NetBeans and -especially- the form designer of the Lazarus IDE, are two very good GUI designers. Of course Matisse is for Swing (and it has a tendency to screw up the layout), which i find terribly slow by itself, and Lazarus is tied to FreePascal and FCL (although i think it is possible to write some plugin for it to export the layout for use by other toolkits - but its not a true replacement).

So, if you want to use SWT (because its fast and uses native controls so it doesn't feel out of place like Swing) and you don't have a penny to spare, you're stuck with Visual Designer. I can see that Visual Designer has the potential to be the best designer out there (and not because its based on Eclipse :->), but at this point its performance makes it a very hard tool to use.

So i'm trying to avoid using it wherever possible. While in other tools, i try to use them as much as possible to save time, in Visual Designer i only use it for the layout. No event assignment, no name fixes (its faster to use the source code editor to rename some field than the visual editor...), etc.

When i'm making a new window, i use two classes for it: a "visual" class, which is made using the Visual Editor, and a "code" (normal) class which has 99.5% of the logic and extends the visual class. So for a "MainShell" class (which is the name i usually use for the main windows), i have two classes:
  • MainShellVisual - this is edited using Visual Editor
  • MainShell - this extends MainShellVisual
to combine these two, MainShellVisual in its constructor calls the createShell function that Visual Designer generates. If needed, the MainShell overrides this function to create some extra objects (such as a AWT canvas using SWT_AWT). The MainShell class also provides a getShell function which returns the Shell object created in it.

By default, Visual Designer creates all new class fields as private but since i don't want to access them from the "Visual" class, i replace "private" with "protected". This way i can access the controls from the code class. To fire events from the visual class, i use a special class i call ActionInvoker.

This "action invoker" class is simply a class that calls a function of a specified object, using reflection, that has the same name as the action it is asked to invoke. The constructor takes a single object (which will contain the function) as shown:
/**
 * Utility class to invoke actions in objects.
 * 
 * Actions are simply functions which take no argument and return nothing.
 * 
 * @author Bad Sector
 */
public class ActionInvoker
{
    private Object obj;
    private Class cls;
    
    /**
     * Constructs the invoker for the given object.
     * 
     * @param obj the object where actions are
     */
    public ActionInvoker(Object obj)
    {
        this.obj = obj;
        cls = obj.getClass();
    }

    ...
}
the class provides an invoke function which does the actual invoking part. If the given object doesn't contain a method like the one the action requests, it shows an SWT message box (so i can know which actions are not implemented yet). The invoke's code is:
/**
 * Invoke the action.
 * 
 * @param action the action's name
 */
public void invoke(String action)
{
    try {
        Method m = cls.getMethod(action, (Class[]) null);
        m.invoke(obj, (Object[]) null);
        return;
    } catch (Throwable t) {
    }
    
    MessageBox mbox = new MessageBox(Display.getCurrent().getActiveShell(),
        SWT.ICON_WARNING | SWT.OK);
    mbox.setMessage("Action '" + action + "' was not handled.");
    mbox.open();
}

So to use the ActionInvoker class, i simply create an instance of it in the visual class' constructor before even calling createShell (because controls can fire events while they're created) and i pass this as the object that provides the action functions. Then using the Visual Designer or the source code editor, i add event handlers which simply call invoker.invoke("someAction"). This will try to call the "someAction" function of the object (which will be the MainShell object, not the MainShellVisual, since this is the object that i use to create the shell). If the function exists, it will be called, otherwise a message box will be shown.

Now, as i said above, i try to use the Visual Editor as less as possible. Assigning event handlers for menus is a PITA, so i decided to automate it a bit. I wrote a function inside ActionInvoker which scans a Menu object for its menu items and automatically assigns listeners (handlers) which invoke actions depending on the menu item's text. Of course, the text is transformated so that it is a proper Java identifier. Here is the code of that function (with its helper functions):
private void addItemSelectionListener(MenuItem item, final String name)
{
    item.addSelectionListener(new SelectionAdapter() {
        public void widgetSelected(SelectionEvent e)
        {
            invoke(name);
        }
    });
}

private void registerMenuItemActions(String base, Menu menu)
{
    MenuItem[] items = menu.getItems();
    for (MenuItem item : items) {
        String tname = base + item.getText();
        
        if (item.getMenu() != null) registerMenuItemActions(tname, item
            .getMenu());
        
        StringBuilder name = new StringBuilder();
        boolean nextUpper = false;
        for (int i = 0; i < tname.length(); i++) {
            if (!nextUpper) nextUpper = i == base.length()
                && base.length() > 0;
            char ch = nextUpper ? Character.toUpperCase(tname.charAt(i))
                : Character.toLowerCase(tname.charAt(i));
            if (ch == ' ') nextUpper = true;
            else {
                if (Character.isLetterOrDigit(ch)) {
                    name.append(ch);
                    nextUpper = false;
                }
            }
        }
        addItemSelectionListener(item, name.toString());
    }
}

/**
 * Registers actions to be invoked for each menu item inside this menu (and
 * all possible submenu items of submenus). The action names are based on
 * the menu item's text using Java-like capitalization. For example a
 * "save as" option under a "file" menu will call the "fileSaveAs" action.
 * 
 * @param menu the root menu
 */
public void registerMenuItemActions(Menu menu)
{
    registerMenuItemActions("", menu);
}
So, at the end of the createShell function, i just do a call to invoker.registerMenuItemAction(menuBar) and i have event listeners registered for all items. This is very handy because all i have to do to add a handler for an "open" menu item under a "file" menu is to write a function in the code class named "fileOpen". And if i'm not sure about the function's name, i just select the menu item while the program is running and the invoke function will inform me about the missing function's name :-).

I think this solution is even better (or at least, easier) than using some visual tool to assign events. And these actions can be used from other parts of the GUI too - although using an automated approach might not be that possible (on the other hand, most controls have a custom user "data" field, so that might be usable for this).

Of course this is a bit hacky, but as long as it works, its fine for me :-). A situation where this will fail to work, though, is when localizing the program - since the items' text wil change, the program will use other action names. However with some extra code this can be fixed if the program registers the event handlers while in "English" mode. Personally i rarely localize my programs, so this isn't a concern for me.

Thursday, October 15, 2009

Git über alles

Up to this point i was using Subversion for my programs. Subversion is good and nice, but at some point i reached a problem: if you want to do proper versioning, you have to have access to the server. This is obvious - it is a centralized versioning system after all.

However, this was a problem with my case. I moved from Samos to Athens recently and i wouldn't have net access all the time. Moreover, when i got net access, it was painfully slow - sometimes slower than a modem. So i would limit my commits. To avoid that, and be able to code from wherever i am in my laptop without losing versioning, i decided to take a look at those decentralized versioning systems.

At the past i took a look at Bazaar, which was created by the makers of Ubuntu, Canonical. I remember liking it, but not enough to switch from Subversion. Also i remember having some issues with it - mostly about the interface. So when i decided to take another look in these decentralized systems, i decided to check out some other programs first.

The other "contestants" were Git and Mercurial. I'm sure there are more around, but these two (and Bazaar) are what i hear most of the time about. I decided to give git a try. The first negative part i hit was that there is no (proper) GUI version and especially the Windows support is inferior to any other program. However, its not like i'm afraid of the command line - i just prefer to click on buttons instead of typing on the keyboard; i do a lot of typing when writing the code and i want a change now and then :-P - so although i would prefer a GUI client, i decided to check it out anyway. Besides it was made for the management of the Linux Kernel, by Linus Torvalds himself and if any project is all about decentralized source control, this is the kernel. And it also helped that i read at some pages people saying that Git might be a better contribution to the world than Linux by Linus.

So, i started messing with it. The initial learning curve was a bit steep, but with the help of the great Pro Git Book i managed to understand Git quickly (and in fact, quicker than Bazaar). After a while, i was blown away by what i could do with it and when later i had to work with some Subversion repositories of my own, it felt like i was kept behind - dragged to use something inferior. At this point i thought that Git might be the solution to what i was looking for.

Of course there was also the option for Mercurial. If Git was better than Subversion, but up to this point i was using Subversion because i didn't knew about Git, then it could be possible that Mercurial was better than Git and i didn't knew about it. So i decided to search a bit about it. After a while, i learned that Mercurial wasn't much different than Git, although it had better Windows support (which is why Sun decided to use Mercurial instead of Git for OpenJDK). However it seemed to me that Git had more features than Mercurial and, at least according to other people who tested this, it is a bit faster.

However the deal that closed the case was when i tried to convert my Subversion repositories to Git. Converting Subversion repositories to Mercurial doesn't seem a very hard job, but Git goes a bit further by providing a git-svn tool that makes it possible to use Git with Subversion, as if a Subversion repository was just a remote Git repository.

Also being able to have local branches (branches which remain locally and don't move with a pull to remote repositories) is another big plus for Git. This way i can create a branch for a feature i'm working on, but also work on the main branch and when i commit it, only the main branch is commited. That is very good for working while disconnected or for new features which i'm not very sure about.

So yes, i basically chose Git over Mercurial based on what i've read about. It isn't the best method to make choices - i should test drive Mercurial myself - but its the best available one if you don't want to spend much time in the process. Besides, it seems that switching to other versioning systems is a possible task. At least switching from Subversion to Git was a command away :-).

As for Bazaar. Well, i decided to not look into it because people reported that it is very slow. Add to this that it isn't as popular as Mercurial and Git, i think it isn't worth - at the moment, at least - to spend more time on this. But if it ever becomes a better choice than Git, i'll reconsider it.

Of course i don't want to spend much time on such stuff. I use Git for more than a month with several projects converted from Subversion to Git and so far it looks good.

Initially i used GitHub for my stuff, but the performance of the site was very poor, so i decided to host my repositories myself in a dedicated subdomain in my server. It doesn't look as sleek as GitHub, but on the other hand i can create Trac pages for the projects if needed. And Trac so far provides much more features than GitHub - like a proper ticket system and -with the aid of a plugin- a Discussion forum. At some point i'll move my GitHub projects to the page above, but for the moment i just keep them there.

Monday, October 12, 2009

I think this is the fourth one...

This is the first time i use an external blogging service instead of hosting the blog myself. The reason? I just wanted to try blogger.com and see if it provides a better service than what i could do in my own server. Also there is a whole network with "blogger.com" accounts.

So far it seems ok. Dunno. I'll see if i will continue using it.