RPC in AS3 mit AMFPHP und einer unbekannten Anzahl von Parametern

Wenn man in einem System arbeitet, das an einer zentralen Stelle die RPC anfragen an AMFPHP stellt, steht man vor dem Problem, dass man nicht genau weiß, wie viele Parameter durch das System angefordert werden. Beispielsweise gibt es einer PureMVC-Umgebung einen RPCProxy, der alle AMF-Anfragen verwaltet und nacheinander abarbeitet. Nur leider ist die call-Funktion der NetConnection-Klasse wie folgt definiert:

public function call(command:String, responder:Responder arguments):void

Es besteht die Möglichkeit eine beliebige Anzahl an Parametern an das PHP-Skript zu übergeben. Und genau darin besteht auch das Problem. Wenn man genau weiß, welche Parameter man versenden möchte funktioniert das Ganze wunderbar. In einer PureMVC-Anwendung kann aber von überall eine Notification versendet werden. Man könnte nun das VO im Body der Notification als Argument versenden.

1
2
// Call mit den Parametern als Array
_connection.call("TestService.functionName", _responder,_vo.parameters);

Das hat den Nachteil, dass auf der PHP-Seite nur ein Parameter als Objekt oder Array ankommt.

Folgender Workaround hilft eine unbestimmte Anzahl von Parametern an eine Funktion mit einer beliebigen Anzahl von Parametern zu übergeben:

1
2
3
4
5
6
7
8
9
10
// Speichern der Funktionsreferenz von call
var callFunc:Function = _connection.call;
// Anlegen der ersten beiden Pflichtparameter der Funktion call
var callPara:Array = ["TestService.functionName", _responder];
// Erweitern des Parameterarrays um die unbestimmte Anzahl der Parameter
for each(var obj:Object in _vo.parameters) {
    callPara.push(obj);
}
// Aufrufen der Call-Referenz
callFunc.apply(this, callPara);

Viel Spass mit dem Ding.
Tjomas

dmexco 2009 – Messestand mit Adobe Air und Papervision

Für einen Messestand auf der dmexco 2009 habe ich im Auftrag von margo® drei Flash-Animationen für Strör Interactive sowie BusinessAd programmiert. Besonderheit war die Entwicklung einer zwei Screen Animation im Vollbildmodus, sowie eine Starfield-Animation mit Papervision.

Zwei Screen Animation mit Air

Zwangsläufig wird man Probleme beim Implementieren der Flash-Animation bekommen, wenn der Flash-Player genutzt werden soll. Auf einem erweiterten Desktop können zwei Flash-Filme nicht gleichzeitig im Fullscreen laufen. Wechselt der Film auf Screen zwei in den FS-Modus, schaltet sich der Film auf dem ersten Screen wieder in Normal-Modus.
Gut, wenn man im Hinterkopf hat, dass Adobe Air mehrere native Fenster unterstütz. Schaut man in die Fensteroptionen stellt man fest, dass die Fenster auch ohne Fensterrahmen angezeigt werden können.

1
2
3
4
5
6
7
8
9
10
const options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.systemChrome = NativeWindowSystemChrome.NONE;
const win1:NativeWindow = new NativeWindow(options);
win1.stage.scaleMode = StageScaleMode.NO_SCALE;
win1.stage.align = StageAlign.TOP_LEFT;
win1.stage.stageWidth = 2732;
win1.stage.stageHeight = 768;
win1.x = 0;
win1.y = 0;
win1.activate();

Diese Option ermöglich in unserem Fall die Realisierung eines 2732 x 768 Pixel großen Fenster, welches sich über die gesamten zwei Screens, mit jeweils 1366 x 768 Pixel Auflösung, des erweiterten Desktops erstreckt. Dank dieser Tatsache ist es nicht mehr nötig überhaupt in den Fullscreen-Modus zu wechseln.

Da die Messebauer die Monitore 90° CW rotiert moniert haben, muss die Air-Applikation diesen Missstand wieder korrigieren. Alle Enthaltenen Elemente müssen 90° CCW gedreht werden. Das ergibt beim Testen am heimischen PC einen steifen Nacken. ;)

Auf den Screens kamen bei Strör Interactive, sowie  bei BusinessAd, jeweils eine Papervision Animation zum Einsatz.

Starfield-Animation

Auf dem Messestand zeigten zusätzlich zwei Beamer Logos in einer Starfield-Animation. Diese wurde mit Papervision umgesetzt. Uns lagen die Logos als Vektorgrafiken vor, wurden aber beim Mappen der Textur des MovieMaterials in Bitmaps umgerechnet. Das macht Papervision automatisch und ist auch logisch, da die MovieMaterial- die BitmapMaterial-Klasse erweitert.

Nun stand ich vor dem Problem, dass die Logos stark verpixeln, wenn sie frontal auf die Kamera zufliegen, oder diese sogar durchfliegen. Die Rasterung der Grafiken steigert sich mit jedem virtuellen Pixel im 3D-Raum, wenn die Logos der Kamera näher kommen. Um diesem Effekt entgegen zu wirken griff ich in die Trickkiste. Nachdem die Planes, dank der “useOwnContainer”-Flag, im Viewport ihren eigenen Container erhalten, kann man die Position und Größe der 3D Objekte in 2D auslesen. Kurz bevor die Kamera durchflogen wird, werden die 3D-Planes auf Alpha=0 gestellt und auf der Bühne die original Vektorgrafik über den Viewport gelegt. Der Wechsel zwischen 3D und 2D ist bei einem Frontalanflug kaum zu unterscheiden. In den folgenden Frames werden die Größe und Position des 3D Objekts auf das 2D Logo übersetzt. Eine Alternative ist das Verwenden größerer Bitmaps, was aber die Performance deutlich verschlechtert. Der Austausch-Vorgang ist hingegen sehr schnell und einfach, dafür aber nur in Spezialfällen geeignet.

1
2
3
4
5
6
7
8
if(z < 500){
_disObj.width = container.width;
_disObj.height = container.height;
_disObj.y = container.getRect(_stage).y;
_disObj.x = container.getRect(_stage).x;
_disObj.visible = true;
alpha = 0;
}

Die Überprüfungen laufen im Plane selbst ab. Im Beispiel wird die Annäherung an die Kamera durch die Z-Entfernung angegeben. Das “_disObj” ist die 2D-Vektorgrafik. Die Übertragung der Werte findet nach jeder Bewegung des Planes statt.

Messeaufbau und Testphase

Hier ein paar Eindrücke der Testphase in den kölner Messehallen bis 2 Uhr Nachts.

Gruß Tjomas

FSA 2009 – Polizei wird handgreiflich

Unglaublich wenn man sieht, wie die Polizei auf der Freiheit statt Angst Demo gegen Passanten vorgeht. Muss man sich jetzt wirklich schon vor der Polizei in acht nehmen, wenn man für seine Grundrechte eintreten will. Bin noch gespannt, wo das ganze hinführen wird.

YouTube-Kommentar:
Dieses Video von der FSA09 ist dem CCC zugesteckt worden. Hintergrund ist, dass der Fahrradfahrer im blauen Hemd Anzeige gegen einen anderen Polizisten erstatten wollte, weil der einen Freund von ihm unter unfreundlichen Umständen (”aggro-zecke trifft aggro-polizist”) festgesetzt wurde. In dem Video sieht man, wie die Polizisten gegen ihn und diverse unschuldige Passanten handgreiflich werden.


Gruß Tjomas

Meine erste Android-App

Hi,
habe gerade meine erste App für Googles Android OS namens ProviderInfo fertig gestellt. Da ich o2-Kunde bin und eine Festnetz und o2-Flat habe, wollte ich eine App, das mir beim Telefonieren anzeigt, ob ich kostenfrei telefoniere oder nicht. Zusätzlich wertet das Programm die ausgehenden Anrufe aus und ermittelt das Verhältnis von kostenfreien und kostenpflichtigen Anrufen. Für Menschen, mit anderen Flatrates, kann man die Provider in den Flatrate-Settings festlegen.

Das Programm achtet bei Festnetz-Flats auch auf die Ländervorwahl. Momentan ist Deutschland fest voreingestellt. Es ist nicht im Market verfügbar. Das Programm kann man hier kostenfrei (und auf eigenen Gefahr) heruntergeladen werden.

Gruß Tjomas

Bauer Agency Cup 2009

Ich möchte zu diesem Thema nicht viele Worte verlieren, sondern die Bilder für sich sprechen lassen.
Nicht vergessen auch den Blog von ilovedorado anzuschauen.

Gruß Tjomas

Alternative zu Switch-Case in AS3

Wie angekündigt, stelle ich jetzt eine Möglichkeit vor, um die Komplexität seiner Funktionen zu reduzieren, indem man alternative Ansätze anstelle von Switch benutzt.

Eine Switch-Anweisung gegen einen riesen Block Bedingungen zu tauschen hat wenig Sinn. :)

Bevor ich meine Alternative vorstelle, möchte ich nur festhalten, dass es durchaus bessere Wege als den meinen geben könnte und ihr mich gerne belehren dürft.

HashMaps
Meine Variante sieht vor in HashMaps einen Key (der ursprüngliche Case) mit einer Referenz auf eine Funktion zu verbinden.

1
2
3
4
5
6
7
8
9
10
11
12
13
protected var cases:HashMap;

private function initCases():void
{
    //Die Cases werden nur einmal erstellt
    if (cases == null)
    {
        cases = new HashMap();
        cases.insert("case1", pkw);
        cases.insert("case2", rad);
        cases.insert("case3", bus);
    }
}

Im oberen Beispiel habe ich case1-3 mit den Funktionen pkw,rad und bus verbunden.
Für dieses Beispiel habe ich die HasMap von as3ds gewählt.
Nun kann man die HashMap nach dem Key fragen und bekommt als Antwort die Funktion geliefert.
Das ähnelt in gewisser Weise dem Sprung der Switch-Anweisung in den jeweiligen Case.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//ALT
//ALT
private function anotherSwitch(value:String):void{
    switch(value){
        case "case1": trace("Auto"); break;
        case "case2": trace("Fahrrad"); break;
        case "case3": trace("Bus"); break;
    }
}

//NEU
//NEU
//Die Funktion suchen und ausführen
private function anotherSwitch(value:String):void{
    cases.find(value)();
}
private function pkw():void{trace("Auto");}
private function rad():void{trace("Fahrrad");}
private function bus():void{trace("Bus");}

Wenn man den Aufwand der beiden Versionen vergleicht, fällt auf, dass der Code nicht wesentlich länger ist. Es spricht also nichts dagegen. Gerade bei einer großen Anzahl von Fällen, wird die Übersichtlichkeit deutlich erhöht. Auf diese Art und Weise entsteht das gleiche Verhalten nur ohne Sprünge und mit sauber getrennten Funktionen.

Das lauffähige Beispiel kann man hier saugen.

Gruß Tjomas

AS3V als ANT Plugin für sauberen AS3-Code

Bin die Tage auf Joa Ebert’s AS3V ANT Plugin gestoßen, das eine echte Unterstützung bei der täglichen AS3-Programmierung darstellt. Im großen und ganzen wird der eigene Code analysiert und evtl. nützliche Verbesserungen vorgeschlagen.

Das Tool bietet einfach zu viele Optimierungen, sodass ich nur meine häufigsten Fehler umschreibe.

Häufigste Fehler

Found a power of two. You can use a binary operator here.
Immer dann wenn Operationen mit 2er Potenzen durchgeführt werden, bietet es sich an, dafür eine entsprechende Bit-Operationen zu nutzen.

1
2
3
4
5
6
7
8
// SCHLECHT
var w:int = this.stage.stageWidth / 2;
var h:int = this.stage.stageHeight / 4;
var i:int = frameCounter % 4;
// BESSER
var w:int = this.stage.stageWidth >> 1;
var h:int = this.stage.stageHeight >> 2;
var i:int = frameCounter & 3;

Avoid “x as Class” and use “Class(x)” instead.
Ein Cast nach dem Schema Class(x) löst im unzulässigen Fall einen Fehler aus. Der Cast mittels x as Class gibt null zurück.

Private variable “_xyz” is never read.
Es wird auf ungenutzte Variablen hingewiesen, die keinen Nutzen haben. In Eclipse für Java-Entwickler Standard, aber für AS3 eine echte Bereicherung. Ich habe mich schon oft gefragt, wofür Variablen da sind, wenn ich lange nicht in den Quellcode geschaut habe.

Variable is not modified and could be constant.
Mir ist vorher nie aufgefallen wie viele unnötige Variablen ich nutze, die durchaus Konstanten sein könnten. Eigentlich habe ich nun mehr const’s als var’s ;) . Lediglich in Schleifen und Ähnlichem sind die var’s geblieben.

Found a cyclomatic complexity of 16. Consider refactoring.
Wenn eine Funktion zu komplex wird, sodass diese nicht mehr gut lesbar ist, sollte man dringend über ein Refactoring nachdenken. Einfachste Methode ist das Unterteilen in mehrere kleine Funktionen. Was macht man allerdings bei größeren Switch-Anweisungen? ( Dazu schreibe ich nochmal extra einen Eintrag ).

Too many statements in constructor. Consider refactoring.
Haltet euren Konstruktor einfach möglichst schmal. Das Hilft auch für die Übersichtlichkeit.

You are using this string 16 times in this method. Consider using a variable for it.
Das Tool geht sogar soweit, dass es prüft, ob ein String in einer Version mehr als 3 mal vorkommt und die Nutzung einer Variablen vorschlägt. Erstaunlich auf was man alles achten kann.

Plugin einrichten

Nachdem man die Jar File in ein Verzeichnis seiner Wahl in seinem Workspace untergebracht hat, kann man diese einfach per ANT ausführen und auf seinen Code hetzen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<property name="asc.jar" location="${flex.sdk}/lib/asc.jar"/>
<property name="as3v.jar" location="${basedir}/jar/as3v.jar"/>
   
<taskdef name="as3v" classname="com.joa_ebert.as3v.embedding.ant.AS3VTask" classpath="${as3v.jar}"/>
   
<path id="as3v.classpath">
    <pathelement path="${java.class.path}"/>
    <pathelement location="${asc.jar}"/>
    <pathelement location="${as3v.jar}"/>
</path>

<target name="test.violation">
    <as3v>
        <classpath refid="as3v.classpath"/>
        <sourcePath directory="${basedir}/src/"/>
    </as3v>
</target>

Damit ist schon so gut wie alles getan. Nun müsst Ihr nur noch die unglaublich vielen Fehler beseitigen.

Danke Herr Ebert ;)
Gruß Tjomas

CDATA Fehler mit SOS MAX – Socket Output Server

Wer bereits versucht hat XML mittels SOS Max zu tracen, hat es vielleicht auch schon erlebt, dass XML-Traces zu Fehlern in der Verarbeitung führen, sobald ein CDATA Element enthalten ist. Die einfachste Möglichkeit den unliebsamen Fehler los zu werden, ist vor dem Trace alle CDATA Tags zu löschen. Wer mit einer XML Socket Connection auf SOS zugreift, kann das all umschließende CDATA nachträglich wieder anfügen.

1
2
3
message = message.replace(/<!\[CDATA\[|\]\]>/g, "");
//
_socket.send("!SOS<showMessage key='Trace'><![CDATA[" + message + "]]></showMessage>\n");

Ich hoffe, dass ich euch einige Minuten Arbeit gespart habe.
Gruß Tjomas

FontSize Buttons in FlexBuilder3

Endlich kann man in FlexBuilder die Schriftgröße des Editors mit 1 Klick einstellen. Möglich wird das durch das Eclipse Plugin Fontsize-Buttons. Aufmerksam wurde ich durch Duane Nickull, der diesen kleinen Helfer bei der Präsentation bei IBM nutzte.

FlexBuilder3 Fontsize-Buttons Plugin

FlexBuilder3 Fontsize-Buttons Plugin

Flexughh mit Adobe Evangelisten Duane Nickull

Am gestrigen Abend hat die Flex User Group Hamburg zum Treffen mit Adobes Evangelisten Duane Nickull geladen. Man traf sich in überschaubarer Runde in den Räumen von IBM.

Im Vorfeld würde das Thema des Abends per Voting bestimmt. Gewählt wurde “Building service clients (talking to J2EE over multiple protocols – AMF, SOAP, HTTP + XML)“.
Im groben und Ganzen war es allerdings eine Einführung die neuen Wizards des Flash-Builders-4.  Gezeigt wurde immer die gleiche Vorgehensweise, um die verschiedenen Services anzusprechen und den nötigen MXML und AS3 Code generieren zu lassen. Hätte lieber im Detail erfahren, worin die Unterschiede in der Herangehensweise für die Protokolle liegen.

Konnte leider nicht ganz so viel Neues aus dem Meeting ziehen, aber es war trotzdem ein schöner Abend.

Gruß Tjomas