Austin Kottke's Code Site

Thoughts about Architecture – Java, C/C++, JS, Objective-C, Swift, Groovy, Grails, (RIP Flash)

For the last few years I’ve been developing in flex. One of the very nice features is RSLs to save on file space, but no matter how much optimization work you end up with a huge SWF right? Which is why developers end up using flash for web development.

How many times have you wanted to use the RPC components but ended up scrapping them because they bloat your SWFs? I’ve had to resort to custom AS3 soap libraries, or even have had to hack an existing AS3 web service implementation because it wasn’t compatible with ALL SOAP specs, as in each server has little nuances which can potentially break an AS3 implementation. The joys =)

Ive been doing a lot of flash dev recently, and one option which I think a lot of flash developers miss over is the fact that they compile assets within assets that are shared across multiple SWF files. E.g. you have the Pure MVC framework or cairngorm classes compiled into 5 swfs, when really, all you need to load in a single shell SWF and all future SWF files can reference the classes normally WITHOUT compiling in the entire framework.

So how do you do this? How do you make your other SWFs not compile the entire framework such as ui components and buttons and flash?

Well, instead of doing all the runtime instantiation and non strong typing – you know like var myClass:* – which is prone to errors, use mxmlc -load-externs.

So the steps are as follows:

  1. Create main loader SWF that uses the majority of the framework, ui components etc.
  2. Generate link-report XML using ant:  <mxmlc … link-report=”shell-link-report.xml”
  3. In your ant build file, when compiling all sub-module swfs, compile all module swfs using load-externs=shell-link-report.xml.

By doing these very simple steps you can reduce legacy swf projects by half sometimes simply because when using the Flash IDE it does not natively create this for you.

I found an awesome video that came out last month from one of the Spring Source engineers on building an entire application in Grails.

I think if anything this video shows the true simplicity of grails. It outlines security, ajax, authentication, jdbc, validation and how fast it is to develop with grails. You see how robust and quick to develop a data-base driven twitter clone.

I come from a myriad of development backgrounds, actually started doing C/8086 assembly back in the day. Went into playstation development, and then moved onto flash, qt c++, win 32, java, and ajax.

I developed heavily in java for the last few years and stumbled upon rails – couldn’t stand the syntax although I loved the power and the scaffolding. I then discovered grails and man this is like a new world. The power of ruby on rails but in a java-like syntax.

The key problems I see in web development are:

1. Properly planning the development project
2. Allocating enough time to do the project without shortcutting it
3. Implementing the project in the time allotted
4. Getting management to work with the clients to properly allocate enough time/money to spend on the lifecycle without shortcutting the features

I think projects that are heavily ajax/html or flex projects can be GREATLY simplified by using grails as it writes a lot of the code for you and can really make some of the back-end development which we never want to do a breeze and very integrated.

The problem with writing entity beans in java is that the annotations and amount of code written pales in comparison to a grails entity bean and how simple it is to add validation, etc.

I plan to do some more examples as I get more and more familiar with the grails code base.

Check it out: http://www.grails.org/

Well, Ive used this logger a million times and thought it would be useful to let others take a look. The main thing this class supports is FILTERING, which is something that a lot of log classes do not have which I find problematic when dealing with a very large project or want to debug on a live server.

Check it out:

package com.adk.util {
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.utils.*;

/**=======================================================================
*
* Generic logger that provides filtering so you can specify exactly
* classes that should be traced out. You do this by adding in a filter
* for a specific class using the logger xml file.
*
* NOTE:
*
* Load in the logger xml file by listening for the LOADED event
* before dispatching and using logging statements.
*
* @example
*
*         var logger:FlashLogger = FlashLogger.getLogger( this, “path.to/logger.xml” );
*             logger.addEventListener( FlashLogger.LOADED, onLoggerLoad );
*
*        public function onLoggerLoad( event:Event ):void
*        {
*            var logger:FlashLogger = FlashLogger.getLogger( this );
*            logger.debug(“Test”, “param2”);
*        }
*
*
* Specify log filters in logger.xml:
*
* <?xml version=”1.0″ ?>
* <Logger logLevel=”DEBUG”>
* <filters>com.adobe, com.adk.util</filters>
* </Logger>
*
* You can add as many filters you want and specify the log level.
*
* @author Austin Kottke
*=======================================================================*/

public class FlashLogger extends EventDispatcher {

/*============================================================================
* Events and log types.
*============================================================================*/
public static var NONE : uint = 0;
public static var INFO : uint = 1;
public static var DEBUG : uint = 2;
public static var WARN : uint = 3;
public static var ERROR : uint = 4;
public static var FATAL : uint = 5;

/*============================================================================
* Variables
*============================================================================*/

public static var LOG_TYPES : Array;
private static var logLevel : int;
private static var filters : Array = new Array();
private static var filtersLoaded : Boolean = false;
private static var created : Boolean = false;
public var className : String ;

/*============================================================================
* EVENTS
*============================================================================*/
public static var LOADED : String = “xmlLoaded”;

/**********************************************************************************
* Adds in a new filter
*
* @param aString Adds in a new filter for the logger.
**********************************************************************************/

public function addFilter( aString : String ) {
FlashLogger.filters.push(aString);
trace(“FlashLogger.addFilter(” + aString + “)”);
}

/**********************************************************************************
* Checks if the class is in the filter.
*
* @return true or false if the class is in the filter or if there are no filters.
**********************************************************************************/

private function isClassInFilter( aClassName : String ) : Boolean {
for ( var i : Number = 0;i < filters.length;i++ )
if ( aClassName.indexOf(filters[i]) >= 0 ) return true;

if ( filters.length == 0 ) return true;

return false;
}

/**********************************************************************************
*  Constructor
**********************************************************************************/

public function FlashLogger( aClassName : String, loggerXMLPath : String ) {
className = aClassName;
if ( !created ) {
FlashLogger.LOG_TYPES = new Array(“NONE”, “INFO”, “DEBUG”, “WARN”, “ERROR”, “FATAL”);
setLogLevel(DEBUG);
created = true;
loadLogXml(loggerXMLPath);
}
}

/**********************************************************************************
*  Sets the log level
*
* @param aLogLevel the log level for debugging purposes
**********************************************************************************/

public function setLogLevel( aLogLevel : uint ) {
logLevel = aLogLevel;
trace(“FlashLogger.setLogLevel(” + FlashLogger.LOG_TYPES[aLogLevel] + “)”);
}

public function getLogLevelByName( aLogLevelName : String ) : Number {
for ( var i : Number = 0;i < FlashLogger.LOG_TYPES.length;i++ ) {
var curLevel : String = FlashLogger.LOG_TYPES[i].toLowerCase();
if ( curLevel.indexOf(aLogLevelName.toLowerCase()) >= 0 )
return i;
}
return 1;
}

/**********************************************************************************
*  Retrieves the logger
*
* @param className The class name for the logger to be debugged correctly.
**********************************************************************************/

public static function getLogger( obj : Object, loggerXMLPath : String = “logger.xml”) : FlashLogger {
var className : String = getQualifiedClassName(obj).split(“::”).join(“.”);
var logger : FlashLogger = new FlashLogger(className, loggerXMLPath);
return logger;
}

/**********************************************************************************
* Load in the xml configuration for the flash logger. By default this
* is logger.xml
**********************************************************************************/

private function loadLogXml( aPath : String = “” ) : void {
var url : URLLoader = new URLLoader();
url.addEventListener(Event.COMPLETE, loadLogFilters);
url.load(new URLRequest(aPath));
}

/**********************************************************************************
* Sets the filters based on the xml file.
**********************************************************************************/

private function loadLogFilters( event : Event = null ) : void {
try {
var loggerConfig : XML = new XML(event.target.data) ;
var filters : Array = loggerConfig.filters.split(” “).join(“”).split(“,”);
var logLevel : String = loggerConfig.@logLevel;
setLogLevel(getLogLevelByName(logLevel));

for ( var i : Number = 0;i < filters.length;i++ ) {
addFilter(filters[i]);
}
filtersLoaded = true;
this.dispatchEvent(new Event(LOADED));
}
catch (e : Error ) {
trace(“FlashLogger [ERROR] error loading filters: ” + e.message);
}
}

/**********************************************************************************
*  Ouputs a debug message.
*
* @param message The message to output
**********************************************************************************/

public function debug(…paramaters) : void {
if ( logLevel == NONE ) return;

if ( isClassInFilter(className) ) outputLogging(DEBUG, paramaters.join(“, “));
}

/**********************************************************************************
*  Ouputs an info message.
*
* @param message The message to output
**********************************************************************************/

public function info(…paramaters) : void {
if ( logLevel == NONE ) return;

if ( isClassInFilter(className) ) outputLogging(INFO, paramaters.join(“, “));
}

/**********************************************************************************
*  Ouputs an error message.
*
* @param message The message to output
**********************************************************************************/

public function error(…paramaters) : void {
if ( logLevel == NONE ) return;

if ( isClassInFilter(className) ) outputLogging(ERROR, paramaters.join(“, “));
}

/**********************************************************************************
*  Core trace output
*
* @param logLevel The log level to output
* @param message The message to display
**********************************************************************************/

private function outputLogging( logLevel : int, message : String ) {
if ( !filtersLoaded ) {
trace(“FlashLogger [ERROR] – please load in logger.xml before using this logger.”);
return;
}
var my_date : Date = new Date();
var hours:String = my_date.hours.toString();
var minutes:String = my_date.minutes.toString();
var seconds:String = my_date.seconds.toString();

if( my_date.hours < 10 ) hours = “0” + hours;
if( my_date.minutes < 10 ) minutes = “0” + minutes;
if( my_date.seconds < 10 ) seconds = “0” + seconds;

var time : String = hours + “:” + minutes + “:” + seconds;
trace(“[” + time + “] [” + FlashLogger.LOG_TYPES[logLevel] + “] (” + className + “) ” + message);
}
}
}

So I’ve been doing a lot of java/ajax development recently, and having to compare frameworks was one of the main things I’ve had to do. I used JSF 1.2 actually due to legacy server issues, not 2.0 (which I hear is a lot better) but comparing it with Stripes/Wicket I must say that:

1. JSF has a LOT of issues integrating into existing browsers, 2.0 is probably a bit better but sometimes the pain of having to have ALL tags written for you is VERY troublesome. I recently had to use a rich faces fileupload component and the integration on some browsers has major issues. While it is good to have a very tightly integrated ajax framework it sometimes is painful when trying to integrate in something like the YUI components.

2. Stripes/Wicket are good because they leave a lot of the ajax development to yourself and provide a VERY awesome hands on approach where you can actually write your own code with minimal development time. I find this actually was easier on some other projects.

So in a nut shell… Id stick with Stripes/Wicket for a java serverside application as opposed to straight JSF as it is sometimes painful when dealing with all the pre-written javascript components.

I guess this brings up a philosophy:

1. A java server side framework should NEVER be so tightly binded to the front-end UI logic WHEN you are depending on browser support. Or provide some alternative to use the latest prototype/ajax libraries.

2. If it is tightly binded, there should be a very easy way to extend it and use it smoothly. JSF 1.2 was a nightmare !!! =)

For some reason, stripes/velocity and wicket still remain my top java web frameworks. Oh and forget to mention, integration with other flash/flex projects is a lot smoother without using JSF due to the freedom it gives you.

My 2c =)

January 31st, 2010

runtime mxml

1 Comment, as2, as3, flex, by austin.

Ok guys, for one I have to give kudos to flash builder 4 – I think it rocks!

But the one thing which I think would just be the cream of the crop is runtime mxml! I actually ported 60% of the functionality of the flex ui component framework to as2 and now im considering doing an as3 version.

I mean, I think that it would so useful to have runtime mxml, maybe no logic, but just the layout code, that’s all.

Does anyone concur?

January 24th, 2010

Crazy 3D C++ Open GL project

No Comments, 3d, C++, OpenGL, QT, by austin.

Hey guys, I’ve been working on a project for a few months to teach myself open gl and 3d mathematics and nvidia’s cg shader language. I think it came out ok, I learned a lot of technology about graphics, etc. It’s no where near the level of PS3 but it’s got some potential. Qt4 was used for the UI technology.

Features:

1. Bump mapping, spherical mapping, multi-texturing
2. Terrain generation
3. Matrix pallette skinning
4. Realtime lighting
5. Explosions, collision detection
6. MD2, POD model loading
7. Shadows

I posted some shots….

As a note, none of the models are mine, they are just used to demonstrate concepts. Two of the models are NVidia’s and Sony’s used in a book I found. I converted the models to a format I needed, POD. And used shaders to animate the models using matrix pallette skinning.

This is purely used for educational purposes and not to be a commercial project at all.

I tell you it’s been a while since I last posted, but one thing that I have been spending a lot of time is looking at web frameworks. I looked at wicket, web macro, jsp, velocity, and I have to say that the most awesome framework I can see is stripes.

I was first reading a book on hibernate – harnessing hibernate and in the end of the chapter it mentions about Stripes. One of the things I can’t stand is the auto-wiring of Java bean objects and a web form. It’s not a big deal with flex because you have amf, but in a web site it’s a pain.

So take stripes, I just take an entity bean and I can specify the bean on the page and stripes will auto-validate, and send errors if a field is not required. It’s pretty nice.

See below:

*/
@ValidateNestedProperties({
@Validate(field=”firstName”, required=true, minlength=3, maxlength=50),
@Validate(field=”lastName”, required=true, minlength=5, maxlength=50),
@Validate(field=”email”, required=true, minlength=5, converter=EmailTypeConverter.class ),
@Validate(field=”userName”, required=true, minlength=5 ),
@Validate(field=”password”, required=true, minlength=8 )
})
@Validate(encrypted=true)
public UserVO getUser() {
return this.beanContext.getUser();
}

Using annotations the validation occurs and its just a simple matter of inserting a field and binding directly:

Doing this will automatically validate the field in java.

Cool huh?

Well that’s one of the major things I like about it. Besides flex, it’s pretty smoothe. I like wicket, but for some reason I just cant get over writing all my UI logic in java…. I feel like im doing swing again!

Anyway, check out stripes – its pretty cool: www.stripesframework.org

As I look more and more at the industry trends, we see more and more handheld devices being developed, that’s a no brainer. More and more devices, such as the android, sidekick, blackberry and iphone have some form of a web browser. Just the other day I was walking outside and I saw atleast 4 young kids with sidekicks, a blackberry and a couple with an iphone.

Now when we look at trends we see that the majority of people browse with their own personal computers, but as the future progresses more and more people will be using their mobile devices to browse the web. Of the 4 different devices I mentioned NONE have the flash player, or are capable of viewing flash in a normal browsing environment.

Now, I’ve been developing flash applications for over 10 years, I started with flash 4. Used flex, and all variations with design patterns, coding standards, but the one thing that is becoming more difficult is convincing executives of the company to use a flash solution when all of the above devices competently show ajax and html just fine.

I know that the flash player is going to come to the android…. but let’s get real, is adobe taking a serious look at this? I mean its awesome to do flashlite for the various nokia devices and devices that can support this. But there needs to be major changes here because as the industry moves more and more mobile, ajax/html solutions are becoming a lot more appealing because these mobile devices render ajax/html without hickups.

Is there any official word on this, supporting these various devices that are mainstream such as the sidekick, blackberry, iphone and android ?

I dont mean to rehash an old subject, but there are a lot of projects in the works and if there is no flash player for these devices then it really limits the potential and thus getting the bosses to agree to a flash solution greatly decreases. After all they have the blackberries and iphones. I love flash, but really it comes down to getting flash everywhere. Flash won because of how ubiquitous it was, now… this is fading as the mobile arena becomes bigger and bigger.

Every kid on the block is getting a cell phone… Is this a major concern for adobe?

If someone were interested in developing for the android or a sidekick, what is the best way to learn. I know the iphone is objective-c, but does anyone have any advice for this? Im trying to get perspectives from different developers as the best way to learn this field, coming from an as2 – as3 – heavy oop background with some java apps built but not proficient in J2ME. Obviously each unit requires different skills, but what is the best recommended learning environment for this? This is a very general question i realize this, but it would be good to know from pro developers any feedback on this.