Wer möchte schon gerne, dass sein Name im Web mit einem Programmierfehler in Verbindung gebracht wird? Doch genau das passiert ganz schnell, wenn man ein Projekt in seinem Benutzerverzeichnis anlegt und dieses mit Debug-Informationen veröffentlicht – da dies die Standardeinstellung ist, passiert das im Eifer des Gefechtes schnell auch mal versehentlich. Denn dann ist der komplette Pfad zu den zugehörigen Klassen im Flash Debug Player sichtbar (der normale Flash Player zeigt dies nicht an). Das ist nicht nur bei Programmierfehlern peinlich sondern kann auch richtig Probleme machen, wenn der Auftraggeber nicht möchte, dass der Name des Programmierers mit einem Projekt in Verbindung gebracht wird.
Mit dem folgenden einfachen Flex-Inhalt erzwinge ich einen Fehler, um das Verhalten eines veröffentlichten Projektes im Fehlerfall zu testen:
1
2
3
4
5
6
7
8
9
10
11
12
13
| <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="creationCopmplete_handler(event);">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
private function creationCopmplete_handler(event:FlexEvent):void {
throw new Error("Forced Error");
}
]]>
</mx:Script>
</mx:Application> |
Bei der normalen Kompilierung erscheint dann eine Meldung inkl. aller Pfade:

Durch die Compiler-Einstellung -debug=false kann dies aber verhindert werden und die Fehlermeldung ist dann in der Folge anonymisiert. Das selbe Ergebnis erzielen Sie übrigens auch über das Menü PROJECT | EXPORT RELEASE BUILD…!

Leider fehlen nun jedoch auch wichtige Informationen für das Debugging. Sprich: Es sollte so oder so ein Projektverzeichnis zum Kompilieren gewählt werden, das keine Rückschlüsse auf den Urheber zulässt – dann muss man sich auch nicht bei einer Debug-Version für Fehler schämen.
ActionScript ist mit Flash CS4 Professional trotz der in den Medien kursierenden Diskussionen rund um die ActionScript-Basis ECMAScript 4 weiter gewachsen (http://www.flashforum.de/forum/showthread.php?t=257795 und http://blogs.adobe.com/open/2008/08/blog_entry_dated_81408_715_pm.html). Die spektakulärste Neuerung aus Sicht von Programmierern könnte dabei der neue Datentype Vector sein. Dieser erlaubt erstmals typisierte und damit typsichere Listen. Die Verwendung geschieht analog zur Klasse Array. Einzig die Typisierung und das Erstellen bedürfen einer neuen Schreibweise mit Angabe des Typs in spitzen Klammern getrennt durch einen Punkt:
1
2
| var v:Vector.<String>;
v = new Vector.<String>(); |
Zu den Neuerungen gehören außerdem die Klassen rund um Text, Pixel Bender (Codename Hydra), 3D und inverse Kinematik. Außerdem kann man nun Sounds zur Laufzeit erzeugen, primitive Formen leichter mit der Graphics-Klasse zeichnen und Dateien auch aus dem Browser heraus per FileReferenc lokal laden und speichern. Und in der Bibliothek ist endlich sichtbar, ob es sich um einen MovieClip, ein Sprite oder ein mit dem Flex Integration Kit für Flash aufbereitetes Symbol handelt. Bei der Zusammenarbeit mit Flex hilft es außerdem sehr, dass Flash nun endlich auch Metadaten wie AccessibilityClass, ResourceBundle, Style, Embed und SWF versteht – nicht nur in Klassen sogar in Bildskripts. Gerade Embed ist auch in reinen Flash Projekten durchaus nützlich, um Inhalte allein durch die Programmierung und ohne den Umweg über die Bibliothek zu nutzen.
Die Einstellungsmöglichkeiten von ActionScript umfassen nicht mehr nur eine Sammlung von Klassenpfaden sondern sind ähnlich wie bei Flex in Quellcode-Pfade, externe Bibliotheken zur Laufzeit (Runtime Shared Libraries) und Bibliohtekspfade zur Kompilierzeit unterteilt. Hinter den ActionScript-Einstellungen im Register Flash der Einstellungen für das Veröffentlichen im Menü Datei verbergen sich nicht nur die Klassenpfade. Dort können auch Konstanten angelegt werden, die wie normale Variablen in ActionScript zu nutzen sind. Außerdem erlauben diese auch eine bedingte Kompilierung, wenn der relevante Code hinter der Konstante in geschweiften Klammern steht:
1
2
3
4
| CONFIG::FLASH_AUTHORING {
trace("Foo");
}
trace(CONFIG::FLASH_AUTHORING); |
Im ersten Teil des Flash Checkers habe ich eine einfache Flash-Erweiterung verfasst, die die Dokumenteinstellungen einer FLA-Datei prüft. Dem einen oder anderen mag es übel aufstoßen, dass diese Erweiterung für die Flash Entwicklungsumgebung in JavaScript verfasst wurde. Mal abgesehen davon, dass – wer unbedingt will – auch DLLs programmieren und als Erweiterung einbinden kann, ist JavaScript jedoch besser als sein Ruf: Beispielsweise die objektorientiere Programmierung ist durchaus möglich. Wenn auch nur Prototypen basiert. Das heißt, dass man bei JavaScript die Vererbung per Hand über sogenannte Prototypen erreicht. Denn jedes Objekt in der JavaScript-Welt verfügt über eine Prototyp-Eigenschaft, die auf ein anderes Objekt verweist. Und sollte eine Methode oder Eigenschaft nicht in einem Objekt verfügbar sein, dann wird halt im Prototyp nachgeschaut. Und sollte in diesem Objekt die Methode oder Eigenschaft ebenfalls nicht verfügbar sein, dann wird halt in dessen Prototyp nachgeschaut. Und so weiter und so fort…
Das Pendant zu einer Klasse erstellen Sie in JavaScript mit einer Funktion.
1
2
3
| function FlashChecker () {
this.property = "foo";
} |
Eine Instanz dieser „Klasse“ erzeugt das Schlüsselwort new, in dem erst ein neues Objekt angelegt und die Funktion ähnlich einem Konstruktor im Kontext dieses neuen Objektes ausgeführt wird (das Schlüsselwort this bezieht sich in diesem Fall auf das gerade neu erzeugte Instanzobjekt).
1
| var checker = new FlashChecker(); |
Es ist gängige Praxis, die Methoden einer „Klasse“ in das Prototyp-Objekt zu schreiben, damit die Methoden nur einmal deklariert und nur einmal im Speicher abgelegt werden.
1
2
3
4
5
6
7
8
9
10
11
12
| FlashChecker.prototype.checkDocumentSettings = function (currentDocument) {
var playerVersion = currentDocument.getPlayerVersion();
var asVersion = currentDocument.asVersion;
var fps = currentDocument.frameRate;
var height = currentDocument.height;;
var width = currentDocument.width;
if (playerVersion != "9") fl.trace("Warning: Wrong player version!");
if (asVersion != 3) fl.trace("Warning: Wrong ActionScript version!");
if (fps != 24) fl.trace("Warning: Wrong framerate!");
if (height != 800) fl.trace("Warning: Wrong height!");
if (width != 800) fl.trace("Warning: Wrong width!");
} |
Die Instanzen haben dann über den Prototyp implizit (also ohne dass man es extra hinschreiben muss) per __proto__-Eigenschaft Zugriff darauf, so dass der Verwendung durch die Instanzen nichts im Wege steht.
1
2
3
| var checker = new FlashChecker();
var currentDocument = fl.getDocumentDOM();
checker.checkDocumentSettings(currentDocument); |