Multiple Inheritance in Objective-C / Core Data vs C++

Multiple inheritance is hard. In fact it is so hard, that only very few programming languages support it. Objective-C is one for instance, where support for multiple inheritance is limited to the conformance to @protocols. Behavior can only be inherited from one single base class.

If you need multiple inheritance in Objective-C you have several options to choose from. Most of the time when you are looking for answers to the question of how to do multiple inheritance in Objective-C the right way, you will be pointed into one of two directions: #1 don’t use it because it implies a flawed design. #2 do it using composition (via delegates).

Option #1 I do not like at all. There are cases where MI is very well suited and only because Objective-C doesn’t support it doesn’t mean it is bad. It just means that the language designers considered it way too complicated to implement for the benefit of a few cases where it makes sense.

For instance, my current use case with strong need for multiple inheritance support is the UML specification. UML makes heavy use of multiple inheritance and if you study the UML model you will find that the abstractions found in there make very well sense because they eliminate redundancy and the need to explain what’s going on. All those abstractions are basically orthogonal classifications which can be combined in a subclass to express things very precise and in a type-safe manner.

So, if you are forced to deal with multiple inheritance in your program you can do so with option #2 in Objective-C. However, in my opinion, this has limitations. I will give you an example: Imagine a model like this:

Let’s say we map this to the following physical implementation in Objective-C. Here, the greenish elements are Objective-C @protocol and the yellowish elements are Objective-C @class:

It follows the often heard recommendation to map inheritance using composition. Here, the Class part of an AssociationClass is mapped to a delegate called “theClassImpl”, whereas the Association base class is mapped to plain Objective-C inheritance.

Suppose now we want to map this structure to CoreData. We need to model NSManagedEntity with NSManagedProperty. CoreData does not work on top of @protocols but on actual @classes. Therefore, we have one physical implementation of the association between Class and Property (owningClass-properties).

But here comes the big BUT: This can only work if we have full control over the OR mapping! CoreData on the other hand, does not rely on interfaces but on the actual implementations. That means, we must publish the otherwise internal composition mapping of theClassImpl to CoreData. If we then have a client of Class (for instance: Property::owningClass) then it will not be possible to downcast such a Class obtained from the persistence layer into an AssociationClass. Instead, it would be necessary to navigate backwards from the Class to the actual AssociationClass. But this kind of “alternative” cast can not be implemented transparently using Objective-C language constructs. An [aClass isKindOfClass:[AssociationClassImpl class]] would yield a technical “NO” and it’s not possible to extend the language to make it yield “YES”.

Such an MI -> SI mapping scenario can only work if every consumer solely relies on the Interfaces only and makes no assumption about internal structures. This would imply that the ORM uses factories instead of instantiating from its meta information. In CoreData, this is not the case.

This is why you can pretty much ignore the advice how to map multiple inheritance at the language level if you don’t also consider the APIs you’re dealing with because those APIs will render the easy sounding solution in the context of reality useless pretty quickly. In my case, I was forced to implement the model part of the system in C++ because C++ has awesomely good support for multiple inheritance. All problems related to the mapping of multiple inheritance to the microprocessor architecture had been solved by Bjarne Stroustrup in C++ since day 1. Read here why and how: http://drdobbs.com/184402074

Here’s how the dreaded diamond from the example above would be implemented in C++:

class Element {
};

class Association: public virtual Element {
};

class Class: public virtual Element {
public:
    std::vector<class Property*> properties;
};

class Property: public Element {
public:
    Class *owningClass;
};

class AssociationClass: public Association, public Class {
};

A straight 1:1 mapping of the concept to the language. Here, class “AssociationClass” would fully inherit the behavior of Class::properties without the need to implement something special. It just works. But, in comparison to Objective-C the C++ implementation lacks support for Core Data. But: so does multiple inheritance in Objective-C with CoreData! So no real difference here.

Conclusion

Multiple inheritance with CoreData is close to impossible except for very simple cases. With C++, besides all its ugliness and controversy, at least you get multiple inheritance in the language and usually in an implementation quality without the need to waste your time thinking around the whole concept.

Why I completely dropped Qt and QtWebKit from my Hybrid App

In my recent articles I described certain aspects related to the use of QtWebKit in a hybrid C++ application. In the meantime, it turned out that Qt and QtWebKit are not such a good bet as I thought they would be at the beginning. Here’s why:

Apple

First and foremost, the most interesting question in a hybrid app written in C++ is: where do you want it to run? In my case, it is on Mac OS X in the first place, then on Windows and very likely also on Apple’s iPhone or iPad. However, this puts me in a situation where I have to decide which subset of these platforms I support primarily and which ones secondarily as there is no such thing as a common layer to access all of them from a single code base. It is either a combination of Mac OS X and Windows via the Qt port or a combination of Mac OS X and iPad/iPhone that can go as the primary target.

For a certain time, I concentrated on the first combination as shown above while hoping that time works for me and somebody ports Qt to the iPhone, and there already is a project for that at http://www.qt-iphone.com/Introduction.html. But, in the meantime, Apple introduced iPhone OS 4.0 and *bam* there will never be such a thing, because http://daringfireball.net/2010/04/iphone_agreement_bans_flash_compiler “and only code written in C, C++, and Objective-C may compile and directly link against the Documented APIs (e.g., Applications that link to Documented APIs through an intermediary translation or compatibility layer or tool are prohibited)”, a rule introduced by Apple which is actually targeted against Adobe and its Flash technology but will also affect Qt, especially because that comes from Nokia, another one of Apple’s (future arch) rivals. This means that Qt can never be the common layer on all of my targeted platforms. Given that, and the fact I target Mac OS X first, Windows second, and that I also tend to shift Windows one step further down and promote the iPad version instead which completely changes the porting picture:

This looks much cleaner now as it provides unified, access to all Apple platforms. For Windows and Android Google Chromium is a good choice.

But what about Qt in general?

Qt / Nokia

The first part was the rational part, here comes the emotional one:

In the recent weeks I had enough time to dive into the details of Qt in all aspects. Its visual quality, its API quality, its implementation quality and the quality and structure of their development process. My conclusion from that is that it is the wrong way of doing things as evaluated from a broader perspective.

What is very important in a visual app is visual quality. Qt does a good job in replicating functionality of controls on each addressed platform. But, it can never, by its nature, take care about the special controls certain platforms offer because then it wouldn’t be cross-platform any more. Qt certainly has to focus on the lowest common denominator across all supported platforms. By driving the GUI via Qt controls, an application loses the capability to provide the eye-candy to the platform user like he is used to. The most prominent example of this is Google Maps which is based on Qt and which totally lacks platform L&F on the Mac up to a degree where it certainly loses style. In Google Maps this is not so important as interaction with the Earth requires a special user interface anyway and the rest of the app is unimportant, but it shows how difficult it is even for Google to provide attractive visual quality on the platform. Gaining access to the platform specialities is difficult as everything is hidden by Qt in private implementations. You have no chance to do “that special thing”.

Qt has a comprehensive “fat” API that consumes everything from all platforms and which has to take care about the specialities on all platforms, which is of course its nature but which is also very difficult to maintain and to improve over years. Development of Qt is distributed across Europe with Nokia focussing on minimizing cost not maximizing quality. Their development centers are mostly in cheaper parts of Europe and they try to cooperate with educational institutions to bring the costs down. This might be a legacy from Trolltech but is still in place and shows that quality is not their first concern.

So far I have touched Qt releases 4.5, 4.6 and 4.7 and came across older API documentations. From there I can tell that many things they have done are not very well and strategically thought out. They introduced too many APIs doing similar things and deprecating previous ones (QML, QtQuick, Scripting with QtScript and in QtWebKit, Qt3 vs. Qt4, QGraphicsScene, QItemView, QtDesigner, QtCreator). To me this is too much feature driven and dictated by the progress of other market players. Then I saw these super new technologies contrasted by very basic demo videos in YouTube showing excitement over very basic features which is not very professional – you can check out their channel on http://www.youtube.com/user/QtStudios to get an idea. What I want as a consumer of platform technology building a commercial grade application is that the selected platform is very stable and well thought out. But there is just too much noise coming from Qt and to make matters worse, none of the new features really feels final, it feels more like work in progress and you can never know how long something survives. Last not least, one day down the road Nokia might become a rival again to Apple just as relevant as Google now is. Economically speaking, Nokia already is, but Apple sees Google as its main competitor, not Microsoft and not Nokia. They are just not in the same technology league any more. Apple and Google have the brains now.

Don’t get me wrong, the Qt guys are doing a good job and they surely do it with a lot of enthusiasm, all I want to say is that Qt is just not the best bet in a commercial hybrid application. That is why I gave up on it.

Rationale for HTML in native applications

In my last article (Not So Easy) Hybrid Applications with Qt, WebKit and JavaScriptCore, I explained my thoughts on the limitations of the scripting capabilities built into Qt’s WebKit port. One of the options to build a nice web based UI within a native C++ application would be to use WebKit directly. Before I elaborate on that in an upcoming article, I would like to explain why this would be worth considering at all.

Here’s a picture of how I see current state of the art in UI development:

Over the course of the last 15-20 years software engineers focussed on the provisioning of higher level windowing toolkits on top of the very low level UI libraries like X11 and WINAPI. These higher level toolkits tried to provide some consistent look & feel to the end user, sometimes across platforms. They all lack, however, one essential feature: style. This is a direct result of providing a prepackaged look which can hardly be changed by the application developer. And this lack of style is a result of lack of flexibility.

On the other hand, people love style which is the reason why they prefer the web, i.e., HTML based UIs over native UIs in many cases. Engineers cannot provide style because they mostly love their particular toolset and fight with other engineers whose one’s is best.

The question is: Who can provide style? One possible answer is: Graphical designers can! With HTML, they can not only create good looking user interfaces, but they can also create different UIs for different target audiences, which makes HTML so attractive across all industries. The required flexibility is only achievable with HTML or with special interfaces based on very low level drawing capabilities like OpenGL in computer games and it is hardly imaginable to create each and every user interface from scratch like computer games. This leaves HTML as the most attractive solution.

Given that, my #1 goal is to provide as much as HTML in a native application as possible, because only then I can consume stylish designs created by graphical designers in a quality which only graphical designers are able to produce.

(Not So Easy) Hybrid Applications with Qt, WebKit and JavaScriptCore

Recently I discovered a set of slides from the Nokia’s Head of Technology Development, Pekka Kosonen, here: http://www.slideshare.net/pkosonen/next-generation-hybrid-applications-with-qt-presentation-for-see-2009 In this presentation, Pekka gives an overview about what Nokia’s Qt team calls “Hybrid Applications”. What this basically means is an application which makes use of web technology within traditional programming environments like C++. I am myself working on an application based on such an architecture, though I didn’t have a name for such an approach yet, so my thanks goes to Nokia for providing me with another buzzword for my professional life as a software consultant 😉

In this article I want to focus on my current approach, the current state of the API implementations at Nokia and their limitations.

The picture shows the basic structure of my application architecture, as it was design at the very beginning. At its core, there is the model object layer. This layer carries all business objects as well as business functionalities and will be implemented as QObjects while making use of some essential features of Qt like its datatypes and some of the hardware abstraction APIs. One particular aspect important to mention is the QtScript API, which shall be used by the final application after deployment to provide functional customizability to the customer of the application.

QtScript is a scripting environment that is as of Qt 4.5 based on the JavaScriptCore framework provided by WebKit, i.e., a highly optimized scripting engine, it even comes with a JIT. Using the QtScript APIs it is possible to integrate the complete model objects layer into the JavaScript engine.

The presentation layer in my application consists of 2 parts: the presentation of structured text, tables, forms etc. and the presentation of 2-dimensional drawings. In the hybrid application, the display of structured text will be accomplished using QWebViews, which delegate internally to a WebKit engine (the same WebKit as found in Apple’s Safari or Google’s Chrome web browsers). The complexity of the WebKit engine is completely encapsulated by QWebView wrapper classes like QWebElement and QWebFrame. For the 2D drawing part of the application Qt’s QGraphicsScene will be used. Alternatively, HTML 5.0 JavaScript Canvas could be used if performance is good enough.

Now back to the presentation I mentioned above: In the API of a QWebFrame there are 2 interesting methods:

void addToJavaScriptWindowObject ( const QString & name, QObject * object )
void addToJavaScriptWindowObject ( const QString & name, QObject * object, QScriptEngine::ValueOwnership own )

which can be used to provide the UI scripting environment with direct access to the model object layer and vice versa. However, these two functions are the only access point towards the browser internal scripting engine, which makes it impossible to add serious scripting support into the UI scripting part. Having access from the WebKit JavaScript to the C++ model object would offer the possibility to implement very lean presentation in JavaScript, for instance to react on a signal in JavaScript like something has been added to some model element could then lead to a new <TR> being added to a <TABLE>, which coulld all be handled via JavaScript!

This however, will not be possible as long as the API to access the WebKit’s JavaScriptCore is solely based on these two methods only and as there is no way to enrich the WebKit engine with the necessary configuration to tell it about the object model features like all its associations or constructors.

All of this is possible, however, in the standalone QtScript engine, which is essentially based on the same JavaScriptCore but which unfortunately is completely separate from the browser’s JavaScriptCore even though they both do the same. Both JavaScriptCore even have different source code copies in the Qt source code. I can only assume that Nokia separated both because they target different execution environments and therefore they must be adapted differently, but even if, I would like to ask why?

My conclusion so far is that I either have to wait for Qt to integrate both engines in a homogenous style (or do it myself) or think elsewhere, perhaps by integrating the WebKit directly and dropping QWebView completely.

Apple’s iPad 1

Mir stellt sich die Frage nach der Zielgruppe, die Apple hier im Visier hat. Den vieltippenden Businessman sicher nicht. Und eine Business-Präsentation dürfte auf dem Teil ziemlich lächerlich wirken. Den surfenden Couch-Potato, der einfach nur das Internet konsumiert vielleicht. Das kann man weiterdenken in den surfenden Couch-CEO, der mal eben während des Abendessens seinen Geschäftbericht grafisch dargestellt haben möchte. Das könnte ich mir durchaus vorstellen, abgesehen von der wenig angetanen Ehefrau.

Apple will auf jeden Fall die volle Kontrolle über den Softwarebestand, daher wurden alle Datenträgerzugänge weggelassen. Software gibt’s nur im AppStore, gute Software dort nur gegen Geld. Dies finde ich eine sehr positive Entwicklung, weg von zu viel minderwertiger, nur verschenkbarer Open-Source hin zu Qualitätssoftware gegen Geld. Sehr gut für professionelle Softwarehäuser.

Anwendungen sehe ich vor allem in Bereichen, in den es auf persönliche Mobilität in Zusammenhang mit dem Abruf oder Präsentation von Informationen ankommt. Z.B. im Gastronomiebereich: das elekronische, per Wifi aktualisierte Menü, als Erfassungsgerät für das Servicepersonal. Für Mediziner ist es geradezu ideal, schnell in der Anzeige der Daten des Patienten sowie schnelle Datenerfassung durch simplen Touch, getippt wird hier eher wenig. Im Marketing, im Umfragebereich. Es wird natürlich auch jede Menge Spassapplikationen geben, den elektronischen Bieruntersetzer z.B. Sehr interessant dürfte das Gerät auch im Bereich der Kindererziehung werden, als Spielzeug mit Lernfunktion.

QWebView QWebElement Experiment

1. Teil

In diesem Experiment mit dem QWebView und dessen DOM-Elementen, den QWebElement’s (aus der Qt beta 4.6) untersuche ich die Performance im Falle hochfrequenter Updates auf dem DOM. Ziel ist es herauszufinden, ob sich herkömmliche GUI-Entwicklungen (z.B. mit QtGui) durch eingebettete browserbasierte Ansätze effizient ersetzen lassen, um dadurch in den Genuss der fortgeschrittenen Layoutingfähigkeiten moderner Webbrowser zu gelangen.

Video in Originalauflösung: http://www.pareis.com/images/stories/video/QtWebView-Experiment.mov

Die Testapplikation verwalten im Bereich des C++ Modells Referenzen auf die angeschlossenen View-Elemente im DOM des eingebetteten Browserwidgets. Bei Änderungen an den Modelldaten werden die formatierten Zahleninformationen in die DOM-Elemente geschrieben und anschliessend je nach Änderungstyp die CSS class der Zelle (table cell, td) gesetzt.

void Browser::updateCells() {
    for(int i=0; i<batch; i++) {
        int r = rand() % rows;
        int c = rand() % columns;
        double orig = values[r][c];
        double &now = values[r][c];
        now = 150.0 * rand()/((double)RAND_MAX + 1) - 20.0;
        QString s = QString("%1").arg(now, 0, 'f', 2);
        cell[r][c].setPlainText(s);
        if(now  orig) {
            cell[r][c].removeClass("down");
            cell[r][c].removeClass("norm");
            cell[r][c].addClass("up");
        } else {
            cell[r][c].removeClass("down");
            cell[r][c].removeClass("up");
            cell[r][c].addClass("norm");
        }
        coord cc = {r,c};
        queue.enqueue(cc);
        if(queue.size()>1000/interval/2*batch) {
            cc = queue.dequeue();
            cell[cc.r][cc.c].removeClass("up");
            cell[cc.r][cc.c].removeClass("down");
            cell[cc.r][cc.c].addClass("norm");
        }
        nupdates++;
    }
    elapsed += t.elapsed();
}

Die Ergebnisse können sich sehen lassen. Das eingebettete Browser-Widget bewältigt mehr als 1000 TD Änderungen pro Sekunde. Den limitierenden Faktor stellt der QTimer dar bzw. dessen Signals. Werden aber viele View-Änderungen innerhalb eines einzelnen Qt-Events durchgeführt, bleibt die CPU-Last im sinnvollen Rahmen. Ein sehr positiver Aspekt ist die problemlose Bedienbarkeit der Oberfläche selbst im Bereich der Sättigung.

2. Teil

In einem 2. Versuch habe ich einen direkten Vergleich der Performance zwischen dem embedded QWebView Browser und einer rein Qt-basierten Anzeige vorgenommen. Ausserdem habe ich die Ereignisproduktion in einen separaten Thread ausgelagert.

In der 2. Applikation arbeiten folgende Codebestandteile:

Das Modell emittiert Changes:

void Changer::run() {
    forever {
        if(stopped) return;
        msleep(1000/interval);
        for(int i=0; i<batch; i++) {
            int r = rand() % rows;
            int c = rand() % columns;
            double orig = values[r][c];
            emit changed(r, c, orig,
                values[r][c] = 150.0 * rand()/((double)RAND_MAX + 1) - 20.0);
        }
    }
}

Im embedded QWebView die gleiche Verarbeitung wie oben, leicht modifiziert:

void Browser::updateCell(int r, int c, double orig, double now) {

    QString s = QString("%1").arg(now, 0, 'f', 2);

    QWebElement &ccc = cell[r][c];
    ccc.setPlainText(s);

    if(color->isChecked()) {
        if(now < orig) {
            ccc.setAttribute("class", "down");
        } else if(now > orig) {
            ccc.setAttribute("class", "up");
        } else {
            ccc.setAttribute("class", "norm");
        }
    }
}

Im Qt Widgets basierten Ansatz sieht es fast identisch aus, ausser dass hier keine class-Attribute gesetzt werden (was in Qt auch ginge, jedoch aus Performancegründen nicht in Betracht gezogen wurde) sondern Farbvorgaben gemacht werden, was selbstredend nicht so sehr flexibel ist wie HTML:

void QtBrowser::updateCell(int r, int c, double orig, double now) {

    QString s = QString("%1").arg(now, 0, 'f', 2);

    QLabel *ccc = cell[r][c];
    ccc->setText(s);

    if(color->isChecked()) {
        if(now < orig) {
            ccc->setPalette(red);
            ccc->setAutoFillBackground(true);
        } else if(now > orig) {
            ccc->setPalette(green);
            ccc->setAutoFillBackground(true);
        } else {
            ccc->setAutoFillBackground(false);
        }
    }
}

Threadanalyse

QWebView-threads

Threaddump eines laufenden QWebView

Im browserbasierten Ansatz werden ca. 61% der Zeit mit Repaints, ca. 3.5% mit dem Eventhandling und interessanterweise ca. 30% mit einem asynchronen (timergesteuerten) Layouting zugebracht.

QtWidgets-threads

Threadanalyse Qt Widgets basierte Anzeige

In Fall der Qt Widgets basierten Implementierung werden ca. 76% der Zeit im Repaint und ca. 15% im Eventhandling verbracht.

Fazit

Ich komme nach diesem Experiment also zu dem Schluss, dass der embedded Browser gegenüber dem Qt-basierten Ansatz zunächst erst einmal keine signifikanten Performancenachteile besitzt und sich daher als Basis für die Implementierung von Rich-Client-Applikationen mit C++ anbietet, bei denen es auf sehr gute Grafikfähigkeiten gepaart mit einem hochperformanten Kern ankommt.