Flash Player feature request

March 14th, 2009

We are working on an OSGI framework implement in AsctionScript 3 FP9+ that can be used for both Flex and Flash combined  if needed.

As you may know one of the key features of an OSGI framework is the way it defines bundles interoperability using services and service consumers.
Some bundles may export services that other bundles will consume. The framework offers means of subscribing and unsubscribing from services, the service consumers than cast the framework provided object to the needed ServiceInterface. This way strong typing and code hinting is available during bundle design and the dependency to any particular ServiceImpl is removed.

There are 2 ways that I found that this could be implemented, but both ways have major drawbacks.

Solution 1: The first thought would be to load every bundle in it’s own ApplicationDomain this would make sure no name space collusions will occur and no other bundle will be able to access it’s content directly (not impossible but rather difficult).
Scenario:
BundleA export a service using the IService interfae and BundleB consumes this service, both Bundles are compiled  with the Interfaces build in.
Drawback: when BundleB code will cast the Framework.getService(IService) as IService … it will obviously get null, since the IService interface in BundleA and BundleB are of 2 different versions. Even though their code is identical VM considers them 2 distinct definitions since they are in 2 distinct ApplicationDomains. If the BundleB will not cast it to IService it will be able to call methods and access public properties, but no compile time checking and  generally error-prone.
Also Only objects available into the parent application domain will be accessible using their names everything else is just generic Object.

Solution 2: Another way to implement this would be to load everything into the main ApplicatonDomain, which will solve the above drawback but will add others.
Scenario: BundleA uses a class called HashMap version 1, Bundle B uses the same class HashMap but version 2, Version 2 is backwards compatible with Version 1, but not the other way around.
Drawback: if the first to load will be BundleA then it will register the HashMap v1, and when BundleB loads it’s v2 of HashMap will be ignored so BundleB will most probably misbehave, throw exceptions etc. and this errors are quite difficult do debug.

A way around Solution 1’s Drawback would be to export the interfaces to a separate SWF file and load it into the main ApplicationDomain, Interface collisions are less likely to occur in a flash application (relatively low complexity compared to potential server-side complexity). But this requires lots of configuration to be done during compile time, as the interfaces need to be explicitly excluded from 1 SWF and Included in another, and it still not solves all of the potential problems.

One of the reasons we cannot find a way around them is the ApplicationDomain beeing final. Although we understand the security reasons for it being final, we still think it’s a bit too restrictive. There should be a mechanism for one ApplicationDomain to import definitions from another ApplicationDomain if the SWF loaded into that ApplicationDomain exports those definitions.

Also it would be very good if one could define a ClassLoader for an ApplicationDomain so if a var bundleAvar = new BundleBClass() is called and BundleBClass is missing in BundleA … the BundleA.applicationDomain.

var someService:IWeatherService = Framework.getService(’IWeatherService’) as IWeatherService;
in this case if the IWeatherService is not defined in the Bundle (and it should not be defined) .. it can be loaded from the bundle that provides the service and has marked the Interface as exported.

To sum it up, what I suggest is to add 3 methods(getter/setter) to the ApplicationDomain:
- get/set definitionResolver():IDefinitionResolver, can only be set from within the ApplicationDomain, most secure way would probably be to set it at compile time and deny override at runtime.
- exportPackage or exportDefinition(definition:Class) … callable only from within the current ApplicationDomain;
- importPackage or importDefinition(QualifiedClassName:String, provider:ApplicationDomain) … callable for the current applicationDomain

the IDefinitionResolver should have:
- resolve(QualifiedClassName):* or throws the Definition Not found exception

If that made any sense what so ever to you, please vote for this feature here: http://bugs.adobe.com/jira/browse/FP-1733
Any other ideas are welcomed as well.
You can read more on the subject here: http://forums.puremvc.org/index.php?topic=222.0

Radu Cocieru Thoughts , ,

Adobe Max day 1 wrap up

December 2nd, 2008

It’s been a very interesting day.

The keynote was quite interesting even through I’ve seen the topics before on  different blogs still seeing this live is really inspiring and opens up your mind.

The introducing to Flash Catalyst(aka Thermo) and C++ libraries for Flash (Alchemy) where my favorites from the day 1 at Max.

I was happy to see that the luck of certain features we’ve been complaining about have made it to the Flex 4 Builder (Spark), things like move re factoring, package explorer, Asdoc, and help tool tips really made my day, great productivity boosters if you ask me.

The Alchemy demos are really something, already have a couple of ideas of where I could use this especially on some AIR apps where size of the swf is not that important.

Got a copy of the Flash Catalyst … too bad it’s only works for MACs hope to find a VM or smth to still be able to run it, I know at least 1 person who’s job would be greatly simplified by this tool.

Radu Cocieru Thoughts , , , , ,

Flex SDK easy Background-Position

August 21st, 2008

One feature that current FLEX SDK skin lacks is the CSS background-position (it centers the image no metter what), here is a quick way to fix this.

CSS:

Box{
   border-skin:ClassReference('ro.huddle.skins.hallo.HalloBorderWithImagePositioning');
   background-image:Embed('/assets/browser_footer.jpg');
   background-position:left,bottom;
}

the HalloBorderWithImagePositioning class:

package ro.huddle.skins.hallo
{
	import flash.display.DisplayObject;
	import flash.display.Shape;

	import mx.core.EdgeMetrics;
	import mx.core.IChildList;
	import mx.core.IContainer;
	import mx.core.IRawChildrenContainer;
	import mx.skins.halo.HaloBorder;

	public class HalloBorderWithImagePositioning extends HaloBorder
	{

		 override public function layoutBackgroundImage():void{
		 	super.layoutBackgroundImage();
		 	if(!hasBackgroundImage) return;

		 	var style:Object = getStyle("backgroundPosition");
		 	// the default alignment is center center
		 	if(!(style is Array) || (style[0]=='center' && style[1]=='center')) return;
		 	var posHorizontal:String = style[0];
		 	var posVertical:String = style[1];

		 	var p:DisplayObject = parent;
		 	var bm:EdgeMetrics = p is IContainer ?
                             IContainer(p).viewMetrics :
                             borderMetrics;
			var childrenList:IChildList = parent is IRawChildrenContainer ?
                                         IRawChildrenContainer(parent).rawChildren :
                                         IChildList(parent);		 	

		 	var backgroundImage:DisplayObject = childrenList.getChildAt(1);

            // default position is center center, or middle,middle
			var bgX:int = backgroundImage.x;
			var bgY:int = backgroundImage.y;

			if(posHorizontal == 'left') bgX = bm.left;
			if(posHorizontal == 'right') bgX = p.width-bm.right-backgroundImage.width;

			if(posVertical == 'top') bgY = bm.top;
			if(posVertical == 'bottom') bgY = p.height-bm.bottom-backgroundImage.height;

		 	backgroundImage.x = bgX;
        	backgroundImage.y = bgY;

        	const backgroundMask:Shape = Shape(backgroundImage.mask);
        	backgroundMask.x = bgX;
        	backgroundMask.y = bgY;
		 }  

	}
}

Because of the RectangularBorder having most of it’s properties private instead of protected, some hacks need to be applied, like getting image from the childsList instead of getting it from the parent by name.

Anyway hope this helps somebody else, it did help me a couple of times.

Radu Cocieru Thoughts , , ,

Got involved with the IGENKO project

May 10th, 2008

One of my latest R&D assignment was to find a CMS system that can be easily integrated with a Flex/Flash front end and work as a Data Service prvider. Basically I was looking for an opensource CMS project that would do all the data/content management and offer the stored data as a service to a Flash enabled front end.

I started by having a look at the most popular CMS out there and see how easy/quick are they to be changed to suite my needs. Looked at Joomla, Typo3, Drupal but none of them where really designed with WEB2.0 in mind maybe except the latest Joomla, built on CakePHP (port of Rails) with a somewhat MVC approach. Joomla did offer the basic Data like services, but since this is the first version using CakePHP the community contributes, that usually makes an open source project great, are kind of missing so it will be a while … and since no standard/protocol of communication is enforced I would say that every contributor will come with his own way of sending things to the front end.

Than I even bought a license of FlashBlocks BIG MISTAKE … the software is totally unusable, if I give to an owner that tool to maintain it’s own site … I should be expecting lots of support calls back and a quite unhappy client on the other side of the line.

The conclusion was that we will have to make our own CMS system for a RIA like website, looking for frameworks to build on I came across the IGENKO project, in a very early stage but good enough to have it as a starting point.

So we decided to get involved with the project and start contributing, solved a couple of issues and added Prana Framework to it for future scalability.

Ideas and thoughts are always welcomed so feel free to join the mailing list ask questions and even contribute :) .

You can read more on Igenko here.

Radu Cocieru Thoughts , , , , ,

Prana Framework 0.5 release

April 22nd, 2008

A very nice Inversion of control container that leverages the flexibility and loose coupling for Flash/Flex applications. Use it with confidence.

Will be posting a how to tutorial soon, so keep watching. Meantime you can read more on the subject.

Radu Cocieru Thoughts , ,