14. August 2011

Zweitgeist Kündigung aufgehoben


Das Hamburger Landgericht hat die Kündigung bei Zweitgeist aufgehoben.

Tja, die Mühlen der Justiz mahlen langsam. Es hat 2 Jahre gedauert. Aber jetzt ist offiziell klargestellt: die Kündigung war unwirksam.

Was für eine Kündigung? Februar 2009 wurde ich als Geschäftsführer bei der von Christine und mir gegründeten Firma Zweitgeist fristlos gekündigt. Die Kündigung war Teil des Versuchs einiger Investoren, Zweitgeist an den Rand des Konkurses zu führen, um die Firma dann zu übernehmen.

Was heißt hier Firma übernehmen? Einige Investoren haben ein lächerlich niedriges Angebot gemacht, um den Gründern ihre Anteile abzukaufen. Damit man auf dem Papier die Firma so niedrig bewerten konnte, musste sie sehr schlecht aussehen. Das ist nicht leicht bei 3 Millionen Usern und 400.000 neuen Usern pro Monat und wenn man anfängt wirklich Geld zu verdienen. Deshalb mussten alle Mitarbeiter entlassen werden. Eine Firma ohne Mitarbeiter sieht nämlich wirklich schlecht aus.

Jedenfalls sind bei diesem "Spielchen" 25 Arbeitsplätze verloren gegangen. Eure Arbeitsplätze, sozusagen Kollateralschaden, weil jemand eine stark wachsende Internetfirma übernehmen wollte. Aber das kümmert Investoren nicht wirklich. Da zählt nur der mögliche Gewinn beim Verkauf. Und da gab es eben einen Investor, der sich ausgerechnet hat, dass er seinen Anteil vervierfachen kann. Später mehr dazu.

Jedenfalls hat das Gericht klargestellt, dass der erste Akt, die Kündigung, ungültig war.

happy_pokering()

PS: Dass mir jetzt keiner mit Winner-Stories/Loser-Stories kommt. Natürlich haben alle nur verloren. Die anderen hoffen aber, dass nicht bekannt wird, was für einen Mist sie gebaut haben. Aber es ist das wahre Leben, mein Leben und euer Leben, eure Arbeitsplätze. Es ist wahr, deshalb gehört es geschrieben und nicht verheimlicht. Heimlich ist jetzt aus.

4. August 2011

Adwords Test gesponsort von Google

Google hat mir vor einiger Zeit einen 100 € Adwords Gutschein geschickt. Anscheinend gräbt Google inzwischen auch Registergerichte durch nach neuen Firmen. Mir solls recht sein. Besser als noch ein Büromaterial-Katalog.

Das - dachte ich mir - ist doch eine gute Gelegenheit, mal kostenlos mit Adwords zu experimentieren. Die Kampagne von Google wendet sich an alle möglichen IT-Firmen. Also - dachte ich mir - muss man nicht unbedingt SEO/Adwords Experte sein, um das Angebot zu nutzen. Adwords - dachte ich mir - wird schon so einfach sein, dass ich es auch verstehe. Schliesslich - dachte ich mir - wollen sie ja, dass die kostenlose Adwords Kampagne so gut gefällt, dass man noch etwas mehr investiert. Falsch gedacht.

Adwords ist nicht für Dummies und nicht für Handbuch-Ignorierer, wie mich. Die Kampage ist zwar einfach aufgesetzt, funktioniert aber leider nicht. Ich bekomme keine Klicks. Die Ads werden gar nicht angezeigt, weil angeblich die Keyword-Relevanz zu schlecht ist.

Am Inhalt kann es nicht liegen. Der Inhalt besteht aus Massen an selbstgeschriebenen Text zu einem bestimmten Thema. Die Seiten sind reichhaltig, fokussiert, originär: www.galactic-developments.de. Daran kann es nicht liegen. Die Keywords stammen aus dem Text und jedes Keyword linkt auf die Seite aus der es stammt. Trotzdem werden die Keywords nicht angezeigt. Selbst wenn ich wollte, könnte ich nichts investieren, um die Website zu pushen, denn Google will mein Geld nicht.

Mögliche Schwachstellen meiner Kampagne:

  • Die Website hat keine META-Keywords.
  • Die Landing Pages haben nicht das Keyword im Title.
  • Die Kampagne hat nur ein Ad. Man könnte für jeses Keyword ein Ad machen.
  • Die Keywords kommen nicht im Ad-Text vor.
  • Die Website ist nicht SEO-optimiert.
  • Ich habe nichts zu verkaufen. Adwords ist für Shops gemacht, die immer direkt auf ein Produkt linken.
_happy_advertising()

14. Juni 2011

An HTML based Chat Window with WebKit, jQuery, and tricks

Over the weekend I was working on the OVW chat window. The chat window is very similar to the avatar display and also very different. The similarities are:

  • both are display modules
  • both use WebKit
Because they are both display modules, I could take the avatar display module code and strip away the avatar part to keep only nicknames. The chat window needs only nicknames. Later there will be images and more features. But for the start we need only text. The chat module has the same structure as the avatar module. It subscribes to a small number of virtual presence model events and then turns around and paints the display in HTML.


See the ui-layout-* CSS-classes? They are used by jQuery UI Layout. There is a bit of configuration necessary, but only a bit: http://code.google.com/p/ovw/source/browse/trunk/Apollo/bin/Win32/Debug/modules/Chat/Chat.html?r=255#153

As always, styling is very simple. Need bold nicknames? Here they are:
#ChatOut .cNickname { font-weight:bold; }
On the other hand, chat window and avatar display are very different:
  • chat is a dialog where the Chat.html code is in an IFRAME
  • avatar display paints directly, has no dialog frame
Calling the avatar display I can simply call a JavaScript function in WebKit. But in case of a Dialog with IFRAME, things are a bit more complicated. The IFRAME is a HTML window inside the HTML window. The WebView module has only a handle to the outer HTML/JavaScript. There is no direct access to the JavaScript of the inner HTML. I can call a JavaScript function in WebKit, but the function is executed in the context of the dialog wrapper. This is OK, if I want to control the dialog functions. But talking to the inner HTML is more difficult.

I am sure there are way to get to an embedded IFRAME from C++. But I did not want to get too deep into enumerating WebKit objects from C++. I needed a way to call JavaScript in the embedded IFRAME from the parent frame. Luckily we are in the same security domain, so calling JavaScript across frames is no problem. My solution is to call a function in the Dialog, which calls a function in the IFRAME, which evals the code I want to execute in the IFRAME.
function ContentEval(sCode)

{
return document.getElementById('Content').contentWindow.EvalJS(sCode);
}
Not very nice. A bit dirty, but it works. Also not very fast. Anyway, there are not many messages which take this route. Just adding participants and chat lines. I am confident, that we find a better way to do this later.

_happy_wrapping()

UPDATE: a week later, I have direct access to embedded frames. I am searching the frame by it's DOM-ID, then call the function inside the frame. I do GetFrameByPath to find the frame, because the frame may be inside another frame. Frames inside frames will be identified by a "/" separated list of DOM-IDs. That's my so called frame-path: http://code.google.com/p/ovw/source/browse/trunk/Apollo/bin/Win32/Debug/modules/Chat/Chat.html?r=414#200

The GetFrameByPath function is a mess of COM auto-pointers and QueryInterface. The ugly face of C++. Thank FSM someone invented better ways.

7. Juni 2011

More OVW Progress

Another week of evenings and weekend worth of progress on the next weblin generation (OVW). I am now working on browser tracking, support for multiple tabs and the multiple views for the same scene.


1. Firefox Add-on

Unfortunately, the rather simple weblin way of tracking browsers is not sufficient anymore. We want tabs (more about tabs and windows at the OVW blog).

Reliable information about visible tabs is only available inside the browser. So I need real browser addons. I started with Firefox some time ago. The addon keeps track of all tabs, when they open/close, become visible and when they navigate. It sends all the information over a local TCP connection to the client (using a simple remote procedure call protocol). This sounds complicated and it is, because the socket implementation in Firefox has its quirks. I could tell stories. But the beauty of a TCP connection is, that if the browser crashes or disappears, then the client will notice when the TCP connection goes down. It will then leave all rooms automatically, even if the browser addon does not say goodbye.

2. Tracking Browser Coordinates

Unfortunately, I don't get a real window handle (HWND) inside the browser. I need a native component to get a HWND for the tab. Why HWND? because I want to track the coordinates of the tab: resize and move events. I could add a native DLL to the addon, but then the addon is not cross-platform. Since I have a native part anyway (the client), I rather make the platform dependent processing in the client.

I implemented a BrowserInfo-module which finds the tab's HWND in the window list and does GetWindowRect() to get coordinates. The module also arranges the window stacking order with SetWindowPos() so that the avatar display is always directly on top of it's browser. That's good old Win32 coding. While most of the code is cross-platform, this part must be adapted to other operating systems, i.e. MacOS.

3. Model View Controller

I am very happy with the Model-View-Controller architecture. The "view" is only responsible for showing avatars. It can be closed and opened and re-creates everything from the model. The view uses the WebKit and JavaScript heavily.

The virtual presence module manages entering and leaving chat rooms, participants and chat lines. This is the "model". The view gets events from the model when participants enter/leave/chat. The view can always query the model. The model has only data structures. The view creates visible avatars.

And best of all: there can be multiple views for the same model. This means, that 2 browser windows can show the same scene.

_happy_modeling()

1. Juni 2011

Open Virtual World Progress

The Open Virtual World project makes significant progress. I am now using WebKit for all user interface components. WebKit is the HTML rendering engine that drives Google Chrome, Safari, and many mobile browsers, because it is easy to integrate and has a good open source license. WebKit is a C++ library and it has a brand new transparency feature. WebKit with transparency is perfect to paint avatars over browser windows.


I can use all the cool Web technologies: CSS, jQuery, canvas. I could even make make my user interface with Flash, SVG, 3D CSS Transforms, WebGL/3D. A CSS style on a text element is much faster to implement than with old graphics libraries. And it is portable to other platforms. Development almost feels like rapid prototyping. The way we are used to program Web frontends. It is a Web frontend, but for a native application. A true cross platform GUI.

This is a comparison of OVW avatars (left) and weblin avatars (right). Weblin avatars are painted to the screen by old school InvalidateRect, WM_PAINT, BitBlt techniques. OVW avatars are rendered by HTML and JavaScript.


Javascript means, that I can use jQuery, which makes effects very easy. Say, I move an avatar with the mouse and let it go. The Weblin avatar slowly slides down to the browser border. In weblin this was animated with a WM_TIMER, and painting the avatar at different positions until it reached the bottom. Then stop the timer. Now, with jQuery I just write one line of JavaScript like:
$(this).animate( { bottom: '0px' }, 800 );
Voilà, the avatar slides down.

There is more at the Open Virtual World blog:
I use Webkit also for windows and dialogs. There are no native windows. Everything is a transparent Win32 window without window border, but with a WebKit inside. All you see is programmed in HTML. Need a semi transparent shadow around your window? Just make a
and use a CSS "box-shadow".


WebKit rox.

Code is at code.google.com.

_happy_sliding()

20. Mai 2011

Technologie und idiotische Investoren

Gerade komme ich wieder mal von einem Barcamp/Conference/Unconference zurück. Da gab es wieder allerlei interessante Vorträge über Technologien und Arbeitsmethoden. Dabei haben wir (ehemalige Mitarbeiter von Weblin) festgestellt, dass das was wir vor 3-5 Jahren gemacht haben, jetzt für die Masse der Entwickler interessant ist. Wir haben damals Probleme erkannt und gelöst, die immer noch aktuell sind und inzwischen wenigstens von den meisten anderen Teams auch angegangen werden.


Bei Weblin hatten wir ab 2006:
und vieles mehr. Frag' doch mal heute - zu Zeiten von NoSQL - wer for 4 Jahren schon "Avoid SQL" gesagt hat.

Das waren schon damals alles bekannte Technologien - die aber nur 3 % der Startups verwendet haben. Heute völlig normal, keine Kunst. Die Kunst ist es das Richtige zu tun, wenn es noch nicht alle machen. Mit der Auflösung von Weblin wurden eine Menge Entwickler rausgeschickt, die die Technologien in ihre neuen Teams getragen haben und jetzt damit viel Geld verdienen.

So gut waren wir.

Technologie zählt. Alle Firmen, die Erfolg haben, haben super Teams im Hintergrund. Werft das Technik-Team weg und ihr habt nichts. Facebook, Zynga, Bigpoint kaufen Firmen nur, um an die Technik-Teams zu kommen. Für alle, die es noch nicht gemerkt haben: die Zeiten ändern sich.

_happy_ranting()

8. März 2011

Simple Dependency Injection

Dependency injection (DI) is very useful for isolated tests. In short:

Assumed you have a user table in the database. Assumed, that the user table is accessed through a class UserDatabase. Your application wants to cache users for quicker access. This means, that there is at least a list of users in memory. Usually you would wrap this list into a class UserManager. The typical code of UserManager will instantiate a UserDatabase, like:

class UserManager {
UserDatabase DB = new UserDatabase();
UserManager() {}
public UserId CreateUser() {
return DB.CreateUser();
}
...
}

If you want to test UserManager.CreateUser(), then the method needs a UserDatabase instance which will access the real database. This is not what you want, because it is not isolated. You want to test UserManager without activating UserDatabase. It rather would be cool if the UserManager would use a dummy database class which just simulates the behaviour of UserDatabase without actually writing to the real database.

So, we want to equip the UserManager for the test with a MockDatabase, but for the real operation it should use the real UserDatabase. We want to decide which database class the UserManager will be using under which circumstances. Means: we make the proper database and hand it to the UserManager. We inject it. Example:
class UserManager {
UserDatabase DB;
UserManager() { // real constructor
DB = new UserDatabase();
}
UserManager(UserDatabase db) { // test constructor
DB = db;
}
public UserId CreateUser() {
return DB.CreateUser();
}
...
}

The test code will create a new MockDatabase() and use UserManager(UserDatabase db) to inject it. The real code will use the default constructor, which makes its own normal UserDatabase. Not pretty, but possible. If there are more dependencies, then things get nasty with large contructors which are only used for tests and have different code from the real constructor. Not pretty.

There are better ways. For example DI frameworks, which provide sophisticated methods for injecting dependencies without bloating constructors. They use extensive configuration, if you like. I used StructureMap. It works, but I do not like, that I have to learn it. I spend a few hours reading, learning, trying, and even a few hours on it's unexpected limitations. Now I can use StructureMap, but I do not recommend it, if you do not already know it.

Dependency injection can be simpler. Here is my take: we want, that UserManager uses either MockDatabase or a UserDatabase. Why not just tell the UserManager to Use() either database:
class UserManager {
UserDatabase DB { get; set; }
UserManager Use(UserDatabase db) { DB = db; return this; }
public UserId CreateUser() {
return DB.CreateUser();
}
...
}

The test code will then look like:
var um = new UserManager().Use(new MockDatabase());

The production code will be very similar:
var um = new UserManager().Use(new UserDatabase());

The return this; part in Use() takes care, that the configuration can be written in a single line. If there are multiple dependencies, then I can do:
var um = new UserManager()
.Use(new MockDatabase())
.Use(new DummyWebService())
.Use(new TestController());

...because all the different Use() Methods have different parameters types and automatically know what to do. That's it. Use() is my DI framework.

And here comes my favorite single line of dependency injected configuration for a unit test. An ItemCore which uses a RezMockConnection and an ItemRepository which itself uses a MemoryItemStorage.Factory:
var rep = new ItemCore().Use(new ItemRepository().Use(MemoryItemStorage.Factory)).Use(new RezMockConnection()).Repository;


_happy_using()