Nachdem mir die zuletzt gepostete bat-Version zur automatischen Erstellung einer Build-Version in FlashDevelop nicht wirklich zugesagt hat, habe ich mich erneut damit auseinander gesetzt. Die letzte Lösung war ja nur ein Workaround mit einer pseudo-Build-Nummer, die aus dem Datum konstruiert wird. Die neue Version ist jetzt mit JavaScript geschrieben und läuft als hta-Anwendung. Das macht vieles in diesem Script imho erheblich leichter und die Build-Nummer wird jetzt ‘richtig’ inkrementiert. Das Script kann hier heruntergeladen werden. Eine readme-Datei ist auch dabei
.
Archive for the ‘Flex’ Category
Build Version Increment Script mit HTA
Eigene Build-Version für ActionScript unter FlashDevelop
Nach einer gefühlten Ewigkeit der Suche habe ich nun endlich eine *.bat-Datei schreiben können, die mir bei jedem Compilierungsvorgang in FlashDevelop eine neue Versionsnummer in eine ActionScript-Datei schreibt. Diese kann dann problemlos im restlichen ActionScript-Projekt wie gewohnt verwendet werden, so dass ich nun in jedem compilierten SWF automatisch eine neue Versionsnummer habe.
Der Code der updateVersion.bat ist folgender:
REM Writes the date and time as current version into src/org/buehling/Version.as
@echo off
FOR /F "tokens=1,2,3,4,5 delims=/. " %%a in ('date/T') do set CDATE=%%c_%%b_%%a
REM @echo %cdate%
FOR /F "tokens=1,2,3,4,5 delims=/: " %%a in ('time/T') do set CTIME=%%b_%%a
REM @echo %ctime%
SET VERSIONFILE=src\org\buehling\Version.as
SET VERSION=%CDATE%_%CTIME%
del "%VERSIONFILE%"
echo package org.buehling >> %VERSIONFILE%
echo { >> %VERSIONFILE%
echo //CAUTION: >> %VERSIONFILE%
echo //THIS FILE IS CREATED AUTOMATICALLY BY updateVersion.bat AT EACH COMPILATION! >> %VERSIONFILE%
echo //Any changes will be overridden and lost! >> %VERSIONFILE%
echo public class Version { >> %VERSIONFILE%
echo public static const VERSION:String = "%VERSION%"; >> %VERSIONFILE%
echo } >> %VERSIONFILE%
echo } >> %VERSIONFILE%
Die Datei liegt im Wurzelordner des FlashDevelop-Projekts und wurde mit der Zeile $(ProjectDir)\updateVersion.bat in die “Pre-Build Command Line” Tools der Projekteigenschaften aufgenommen. Vor jedem Compilieren ruft FD die Datei auf, die wiederum die Datei src/org/buehling/Version.as neu anlegt und darin das aktuelle Datum der Form YYYY_MM_DD_hh_mm in eine String-Variable schreibt.
Listing der Version.as:
package org.buehling
{
//CAUTION:
//THIS FILE IS CREATED AUTOMATICALLY BY updateVersion.bat AT EACH COMPILATION!
//Any changes will be overridden and lost!
public class Version {
public static const VERSION:String = "2009_12_30_25_23";
}
}
In anderen Projektteilen, binde ich den Wert dann ganz normal ein, z.B. in ein Flex-Label: <mx:Label text="{Version.VERSION}" />
Update: In diesem Post schreibe ich über die Erzeugung einer Build-Version-Nummer auf Basis eines echten Zählers mittels hta.
Rest-Syntax delegieren
Die in ActionScript 3 eingeführte Rest-Syntax, die eine beliebige Anzahl von restlichen Argumenten in einer Funktionsdeklaration erlaubt, kann ganz praktisch sein, wenn man nicht weiß, was kommt. Ein Einsatzbeispiel ist NetConnection.call(), das neben einem String und einem Responder-Objekt eine beliebige Anzahl an Folgeparametern erlaubt. Was aber, wenn man diese Argumente delegieren möchte?
In meinem Fall hatte ich eine Wrapper-Klasse geschrieben, die mir die Verbindungsdetails zu einer externen Datenquelle kapselt. Auch das Responder-Objekt wurde komplett privat verwaltet. Den eigentlichen Aufruf wollte ich aber flexibel halten, so dass der NetConnection-Call nach außen hin in einer eigenen Funktion public gemacht wurde. Das bedeutet, dass meine call-Funktion als call(cmd:String, ... args) deklariert werden sollte. cmd und args sind die einzigen Parameter, die von außen zugesteuert werden können und völlig unabhängig sind. Der Responder ist für die Außenwelt uninteressant, da er ja in meiner Klasse verwaltet wird und daher direkt an die NetConnection gegeben werden kann.
Das Problem: Innerhalb function myCall(cmd:String, ... args):void kann man nicht einfach nc.call(cmd,res,args); aufrufen, weil die restlichen Argumente innerhalb der Funktion in einem Array vorliegen. Das bedeutet, dass nc.call(cmd,res,args) ein einziges Objekt, nämlich ein Array, als Argument erhält und nicht wie gewünscht alle Einzelargumente. Natürlich hätte ich auch einfach das NetConnection-Objekt public machen können, aber das wäre nicht gerade im Sinn der Kapselung und würde zudem auch die Veröffentlichung des Responders erfordern, der ja an den eigentlichen call übergeben werden muss.
Die Lösung: man darf die gewünschte Funktion, in diesem Fall NetConnection.call, nicht direkt aufrufen, sondern muss sie als Funktionsobjekt behandeln und die Methode apply auf ihm aufrufen. apply akzeptiert bzw. verlangt alle Funktionsparameter in Form eines Arrays, was für die restlichen Argumente ja schon zutrifft. Die beiden anderen fest deklarierten Parameter muss man allerdings auch in dieses Array einfügen, da hier eben alles in einem Array liegen muss.
class MyConnector
{
private nc:NetConnection;
private res:Responder;
...
function call(cmd:String,... args)
{
nc.call.apply(nc,new Array(cmd, res).concat(args));
}
...
}
So… und wenn diesen Beitrag noch jemand versteht: Hut ab! ![]()
Flex CSS-Skin mit nicht verwendeten Style-Definitionen compilieren
Beim Versuch einen anderen CSS-Skin zu laden, erhielt ich die Warnung “Warning: The CSS type selector ‘AccordionHeader’ was not processed, because the type was not used in the application.”. Das wäre soweit nicht tragisch, würden Warnungen nicht nerviger Weise den Build-Prozess verhindern. Mit folgendem Compiler-Paramater lassen sich derartige CSS-Warnungen ausschalten:
-show-unused-type-selector-warnings=false
(Einzustellen in FlashDevelop via Menü Project – Properties – Compiler Options – Additional Compiler Options)
SWC-Archive mit FlashDevelop
SWC-Komponenten für ActionScript kann man auch in FlashDevelop relativ einfach erzeugen, in dem man das ExportSWC-Plugin installiert.
Wenn es Probleme mit den neuen Features des FlashPlayer 10 wie z.B. Vectoren gibt, kann evtl. helfen das Flex 4 SDK verwenden. Dieses Problem hatte ich z.B. als ich versucht habe die Away3D-Klassen in ein SWC-Archiv zusammenzufassen, um sie so von ASDoc auszuschließen und die Projekt-Sourcen übersichtlich zu halten.
FlashDevelop unterstützt übrigens auch automatische Importe, in dem man die unbekannte Klasse mit dem Vervollständigungstool Strg+1 importiert.
Air-Projekt in FlashDevelop anlegen
Ein Air-Projekt in FlashDevelop anzulegen ist zumindest in der derzeitigen Kombination FD 3.0.0/Air SDK 1.5/FP 10 nicht auf Anhieb fehlerfrei möglich. Es muss aber eigentlich in erster Linie nur die Air SDK-Version in der application.xml angepasst werden.
AIR-Projekt in FlashDevelop anlegen:
- Project > New Project > AIR Flex 3 Projector
- Wenn beim Starten nix passiert, manuell testen: Zertifikat erstellen mit der automatisch angelegten
CreateCertificate.bat, dannPackageApplication.batausführen. Dort sieht man dann ggf. Compilerfehler die das Starten verhindern. Wenn alles fehlerfrei ist, sollte die AIR-App mit dem Start-Button einfach zu starten sein. - Wenn Error 305 “Initial window content SWF version exceeds namespace version” auftritt, die Version des Air-SDK in
application.xmlerhöhen: <application xmlns=”http://ns.adobe.com/air/application/1.5“> - Evtl. das nützliche Toolkit
everythingflexairlib.swceinbinden:everythingflexairlib.swcnach/libdes Projekts kopieren- per Kontextmenü der Library hinzufügen
Syntaxhighlight und Autocomplete usw. Funktionieren übrigens innerhalb von MXMLs nur, wenn der Script-Tag das CData-Markup enthält.
Flex: Transition-Effekt manuell zuweisen
Möchte man einen Ein- oder Ausblendeffekt für Flex-Komponenten verwenden, so kann man einen solchen, per MXML-Attribut hinzufügen (siehe z.B. Quickstart). Doch wie kann ein solcher Effekt auf Komponenten angewendet werden, die nicht via MXML sondern beispielsweise dynamisch zur Laufzeit per ActionScript-Code erstellt werden? Die Lösung liegt im StyleSheet-Konzept, das meines Erachtens hier ein wenig hinkt, da hier eine Form von Verhalten statt nur grafischer Erscheinung definiert wird.
Um einen Zoom-Effekt programmatisch einer UI-Komponenten zuzuweisen:
public class SuperPanelPlus extends Panel
{
...
protected static var hideEffect:Effect = new Zoom();
...
public function SuperPanelPlus()
{
...
setStyle("hideEffect", hideEffect);
}
...
}
Air-Application-Icons mit FlashDevelop
Bei der Entwicklung von Desktop-Anwendungen mit Adobe Air ist es schön, wenn man seiner eigenen Anwendung auch ein eigenes Symbol zuweisen kann, das in Startmenü, auf dem Desktop und als Fenstericon verwendet wird. Dies kann durch den Icon-Tag in der application.xml erreicht werden, der die Angabe mehrerer PNG-Dateien für unterschiedliche Auflösungen des Symbols ermöglicht. Die Dateipfade müssen dabei relativ zum Standort der application.xml angegeben werden, wie nebenstehende Grafik zeigt.
Versucht man jetzt das Anwendungspaket zu erstellen, erhält man eine Fehlermeldung, dass die Icons nicht im Paket enthalten seien. Um dies zu korrigieren und die Symbole explizit in das Paket zu integrieren, muss (beim Arbeiten mit FlashDevelop) die Kommandozeile in der PackageApplication.bat angepasst werden. Es genügt erfreulicher Weise den Aufruf des Air Developer Tools (adt, Referenz) zu erweitern, in dem man die Variable FILE_OR_DIR um den Symbolpfad ergänzt, siehe Abbildung.