Keep updated with crazedCoders news and events

Edmonton Game...

Video Game Designers Have a Game Plan

read full article »

Mobile Explosion

Alberta companies creating bleeding-edge mobile apps

read full article »

Tapped-In Apps

Five must-have iPhone apps

read full article »

Kihaku Design

2 new apps hit the iTunes AppStore today

read full article »

GrowerDirect iApp

Order flowers on the go

read full article »

Coop Team...

Go ahead and get it for your BlackBerry®. Go ahead!

read full article »
View All
crazedCoders adobe solution partner

Vic on Flex


Entries 120 out of 255, 10, or 20 per page

« Previous   1   2   Next »



Thursday - February 12, 2009
BlazeDS Getting Started App Revisited



As some of you may or may not have noticed, I don't get a chance to blog much these days... managing a fair sized team of developers and maintaining our streak of successful projects tends to keep me very busy. But in recent weeks I've started doing some BlazeDS project work again, and I find that to get my head back "in the game" I like to have a project I can pull up and jump right into, so to speak.

If you've been following my blog you'll know that although I'm a huge Flex guy, Java tends to be something I perceive more as a necessity in getting the job done. I've never been a full time hard core Java developer (my brother takes the honors in that category) and so, most of my posts regarding Java or Hibernate are through the eyes of someone who HAS to know enough to be dangerous.

Now I know that anyone could probably do this, but I figured I'd just put it out there, and maybe save someone the trouble... I've put together a little zip file that contains a Tomcat 5.5.x web app, which consists of a Flex project and a Java project, both of which can be opened in Eclipse. Basically the 2 apps work together to demonstrate:

  • using JNDI to declare database and SMTP services
  • launching HSQLDB in memory inside the web app (gets tiring installing mysql just to play around - I borrowed this from the BlazeDS turnkey solution and tweaked it a bit)
  • using a .property file to store configuration values and then retrieving those from Java
  • doing a very simple "is flex talking to blaze" function
  • doing a quick "is blaze talking to the db" function
  • doing a quick "send email from Flex thru Java to me" function
  • uploading files from Flex to Java and from html to Java
  • the minimum number of jar files needed to pull this off (updated to Blaze 3.2.x)
For me personally these are all really nice to have right at my fingertips. There's additional notes in the zip in the index.htm. Enjoy. You can find the zip file here: http://www.crazedcoders.com/demos/blazeMsg.zip

Keep in mind you may need to adjust your paths in your Flex, as chances are your Tomcat install won't be in the same location as I have it on my Mac.

Posted by Vic Rubba at 7:25 AM Comments

Thursday - August 28, 2008
Flexbuilder Debug Mode Dog Slow on Mac using Firefox



Quick find today.

Little while back debugging in FB 3.0.x became a brutal exercise in futility. Finally reached a point where I couldn't debug at all. At the time I was running FF2.x. Initially upgraded to FB3 with no change, well no change, except that suddenly I wasn't entering debug mode (bug: had GreaseMonkey Add-On installed - removing it fixed that). Once I was entering Debug again, it would grind my Mac to a halt. Switched to Safari and it worked perfectly. Figured out that Piclense / CoolIris addon for Firefox was in fact the culprit. I uninstalled that add-on and suddenly Debug mode was working just fine again. Lesson learned: If debugging against Firefox, be wary what add-ons you have installed. Hopefully this little lesson will help others.

Posted by Vic Rubba at 9:45 PM Comments

Wednesday - August 13, 2008
Why no Sandbox Violation running from Bin?



Ever noticed that once you copy your html/swf files from the bin folder in your flex project to another file location, or just move the bin folder itself, your flex application no longer happily makes the remote data calls that only worked a minute ago in Flexbuilder? Well we ran into an interesting issue, when trying to push custom HTTP headers to a server. It worked fine while debugging in flexbuilder, and even double clicking on the html file in the bin folder worked. Yet the minute I moved the bin folder to say "program files\my proggy", the application would give a nasty error like this:

Error #2170: Security sandbox violation: file:///program files/my proggy/APITest.swf cannot send HTTP headers to http://myservice/DIRTNAPPY/.

I did some research, and there's actually tons of information out there that deals with this issue. First and foremost this article http://www.adobetutorialz.com/articles/1785/1/Local-Sandboxes does a very good job of explaining exactly what is happening behind the scenes.

Essentially Flexbuilder tells Flash that it should trust the bin folder... if you do a search on your development machine for the file flexbuilder_plugin.cfg, you should find it in a folder called FlashPlayerTrust in roughly the same area you normally find SharedObject files. If you open this file in a text editor, you should see pretty much every path to every bin folder for every flex project you have ever worked on. And suddenly everything gets so much clearer.

So I created a new file and placed it next to this flexbuilder_plugin.cfg file, and called it MyProggy.cfg. Flash is configured to read in all files in this folder and parse all paths out of it, and any applications run from these paths will be considered "localTrusted" and will act as they would when run from Flexbuilder. Inside this text file I put one line: "c:\program files\my proggy" and saved it. I then had to restart Firefox for the change to take effect. I also had added a text label to my application and bound the text property to {Security.sandboxType}.

Launching the app again from c:\program files\my proggy now showed the app running in localTrusted mode, and sure enough all my data calls worked just fine. Keep in mind, that all this only works when you intend to host your application on users machines, rather than on a webserver. It's simple enough to add the necessary text file when your application is being installed.

I should add that as a back up plan, you might want to consider trapping the Sandbox Error and then communicating to the user that they'll need to right click on the application, select Settings / click Advanced / then click on Global Security Settings Panel and add the appropriate path to the list of "always trust files in these locations". (still easier than making them go and create this text file themselves and saving it to the right location).

Posted by Vic Rubba at 11:04 PM Comments

Saturday - August 09, 2008
mx.controls.Text: preventing scroll on select



A minor annoyance in Flex that I've lived with for many moons now is that even though I will provide enough vertical space to show all the text or htmlText in a Text Control, when a user attempts to select the text, often times, the text will scroll up, hiding the first line. The easiest fix is to set selectable='false', and in most cases this will do the trick. There are times however, when a client will demand that text remain selectable. And that same client will be the first to complain about the apparently unnecessary scrolling of text.

I played around with this, but seriously, the mx.controls.Text class really doesn't give one much to work with. On browsing through the sdk source, I discovered I'd probably have better luck working with the wrapped UITextField. In the end I tapped into the scroll event and the alwaysShowSelection attribute of the UITextField to get me where I needed to go.

It's been a long week so I'm just going to post up a link to the solution here, and the source code here.

Posted by Vic Rubba at 2:01 AM Comments

Thursday - July 10, 2008
Dogtagit Flex 3 Project



I've been working closely with Threecast on a project for some time now, and they've made a demo site available for me to showcase. It's hosted on port 8888, so you're best off to try this at home. The application is built on SqlServer, .Net, Weborb and Flex 3 using Cairngorm. Feel free to have a look around, and play with it. This version has the login disabled and the data is reset on a regular basis - it's primarily just for preview purposes. You can view the site here:

http://demo.dogtagit.com:8888/beta/main.html


And if you want to sign up and try it out for yourself, you can go to their home page www.dogtagit.com here and sign up.

Posted by Vic Rubba at 6:59 PM Comments

Friday - May 30, 2008
Sometimes cornerRadius just isn't enough



Two tips for coders new to Flex... if you want to have rounded corners in mx.containers like VBox, HBox, Canvas, etc, set the borderStyle to solid and the borderThickness to 0, and then set your cornerRadius to whatever you want. If the borderStyle is left at none (default), the cornerRadius attribute seems broken and ineffective.

The second tip, if you want rounded corners at the top and bottom of your Panel, there's a property called roundedBottomCorners which defaults to false. When set to true, you will see rounding both top and bottom.

Here's an example http://www.crazedcoders.com/demos/rounded/

I should point out that this has been blogged previously here.

Posted by Vic Rubba at 7:34 PM Comments

Friday - April 11, 2008
Invalid Embed directive in stylesheet



On a few occasions now, for no really apparent reason, suddenly our Problem Pane will be spammed with tons of messages all sort of looking like this:

Invalid Embed directive in stylesheet - can't resolve source 'Embed(source = "/assets/common.swf", symbol = "AccordionHeader_disabledOverSkin")'.

In the past, sometimes it would only happen on a mac, other times windows machines. I've tried deleting my bin folder, cleaning the project, recompiling the swf's, moving the swf's around, changing the syntax in the css ever so slightly. I've googled this on many occasions and found no clear answer. Today I decided that I needed to know what caused this and if in fact I figured it out, to share it with you.

What ended up being the root cause of our problem is that in several places in the application we were referencing image assets directly in our assets folder, i.e. /assets/delete.png, which is often the case when our designers aren't keeping up with asset creation and developers just throw some image up as a placeholder for the time being. Now it just so happened that ONE of these references was incorrect and its Embed pointed to a file that did not exist. I discovered this when I commented out our style css references in the application, and saw the error only then. It was this broken reference that caused the above error. I fixed the reference to point to the right file, did a Project clean, and all the Invalid Embed Directive errors went away.

I should note that we had over 100 references to symbols in our css, and by default Flexbuilder only shows the first 100 errors. Unluckily the "unable to resolve 'assets/deleted.png' for transcoding in ...." was error number 138 and did not show up in the list. I had to change my preferences to show all 138 errors.

So the lesson learned is that when you get spammed with this error, it could well be that only one Embed tag somewhere in your app is actually broken, and that your css and swf is probably just fine.

Posted by Vic Rubba at 6:49 PM Comments

Monday - February 18, 2008
Working With BlazeDS Beta 1



Last week we successfully ported an AIR application from amfphp to BlazeDS. The code for this application was almost completely generated by a new generator we're working on (coming soon!). With the announcement of BlazeDS, we kinda shelved our php generator and redirected our efforts in doing the same thing for BlazeDS. In the process, we put together our own version of the blazeds.war file that ships with BlazeDS beta 1, which we use as the starting point for all our BlazeDS projects. Here's a list of the changes we've made:

  • Modified the context.xml found in the META-INF folder - the packaged one was producing Valve Errors
  • Added the missing my-streaming-amf channel to services-config.xml, which I found in the BlazeDS samples war's config file
  • Incorporated the latest Flex 3 Compiler Module files to allow server-side compilation of mxml files
  • Created a very simple java class and a corresponding destination which will verify Blaze backend functionality
  • Created a very simple Flex application that calls the above java class function test(string)
  • Added 2 jars to WEB-INF, one is crazedTemplate.jar, which our new codegenerator (coming soon) uses, the other is sharpertools.jar, which the jar requires.
You can choose to go ahead and just use the application as is. It's only been tested on Tomcat / Win / OSX 10.5.2. If you don't intend on using our generator (coming soon!) to generate your java and AS3 Classes then you can go ahead and delete the 2 jars mentioned above. I really like this separation of compiler and essentially what was FDS. When FDS was originally released, it did both runtime compiles as well as Remoting, Messaging, Proxy and Managed Data Services. In our case, we never deployed anything that required runtime compilation AND furthermore, with each subsequent Flex release (2.01, Hotfix 1, 2 and 3), converting FDS projects that were set to compile on the server wasn't trivial. So we stopped using it. If I was super Java savvy I might have been able to figure out what parts I could yank out of my FDS application, but generally it seemed better to just leave it alone.

Now, with Blaze and the compiler war being separate, I've gone through the web.xml in this project and put comments to show which pieces are required by the compiler module and which pieces are required by Blaze. To get this back to being a pure Blaze non-Flex 3 Compiler Module, you'd just need to remove the appropriately marked sections from the web.xml and then remove all folders and files from WEB-INF/flex with the exception of:
  • services-config.xml
  • remoting-config.xml
  • proxy-config.xml
  • messaging-config.xml
Some of our clients have asked what the differences exactly are between BlazeDS and LCDS (prev. known as FDS). If you do enough research on the web, you can find several answers. From what I've seen, here's some differences I've found so far:
  • BlazeDS does not support the RTMP Channel typically used by LCDS for data push (RTMP typically means firewall port challenges all around anyway!)
  • BlazeDS does support AMF Streaming which offers data push like RTMP, however not nearly as scalable (100's vs 10000's of concurrent users)
  • BlazeDS does support proxy so you can bypass the all too familiar sandbox issues when accessing remote data where no crossdomain.xml is present
  • BlazeDS does not come packaged with the Compiler Module
  • BlazeDS does not have managed dataservices. This means that you don't need the fds.swc (DataService & [Managed]) in your flex projects.. you will use either Consumer, Producer or RemoteObject Classes
  • BlazeDS does support AMF3, RemoteClasses & Messaging with a "lite" version of push via amf streaming
To download the blazeBlank application click here. (as new builds of Flex 3 and BlazeDS are released I'll try to keep this application updated). This application currently uses Flex 3 Beta 3 and BlazeDS Beta 1. Be sure to visit the url /{context}/TestApp/Main.mxml to ensure that the application is working properly. (i.e. http://localhost:8600/blazeBlank/TestApp/Main.mxml)

Posted by Vic Rubba at 12:28 AM Comments

Friday - January 18, 2008
Flex 3 (Beta 3) Badge.swf don't like spaces!



We just recently were challenged with trying to update to the latest Flex beta, and there have been a few changes to the way the seamless install badge.swf works. For one thing, this program now goes out and talks to an air.swf hosted by Adobe. The second, and far more annoying "feature" was that if you had an AIR file name like "Sample Application.air" and tried to publish that using the sample batch.swf provided in the SDK, the AIR Installer would fail, choking on the space.

I've hacked the badge.fla file using regex to put replace spaces with %20, and this seems to have fixed the problem for now. I also downloaded a copy of the air.swf from the Adobe site, threw it in the same folder as my badge.swf and changed the code to use that one instead.

You can get the whole bag of goodies here. I've included all the source and a ready to use badge.swf, as well as a working sample.

Posted by Vic Rubba at 9:02 AM Comments

Saturday - January 05, 2008
amfphp/flex/cairngorm Codegen - Source Available on Google Code



I've had quite a few people ask if they could get their hands on the php source for the code generator tool I published back in October here. My intention has always been to eventually get this out to the community, however the last couple months have been just crazy, with one release after another getting pushed out the door. So much demand for AIR and Flex applications, so little time...

Anyway, we finally had some time to get this thing cleaned up and out on Google code... you can find the source files at http://code.google.com/p/flexamfphpcairngormgenerator/source

Posted by Vic Rubba at 12:34 PM Comments

Friday - December 14, 2007
DataServiceTransaction & LCDS



Just a quick blog note on something that I've now wasted a good day on twice, only because I never blogged it last time. The challenge is say you need to make changes to data in a database, maybe across multiple tables, and using DataServices just doesn't make sense. For example, cloning x number of records. It's easy enough to create your Java remote objects and call them from Flex, but then in an FDS/LCDS implementation how do you push those changes out to Flex clients?

There's some documentation on this, scattered vaguely across the web, and there's a good chance that perhaps this has already been blogged - but I just couldn't find it. The trick is that there are 2 sides to this story, one, you must perform your operations on the database directly, and then two, you must INFORM FDS that changes have occurred. So say I want to create a new Author record, this is what that might look like:

public void createAuthor(){  
DataServiceTransaction dtx = DataServiceTransaction.begin(false);
//create record and save:
Author auth = new Author();
auth.setFirstName("Ernest");
auth.setLastName("Hemingway");
AuthorDAO dao = new AuthorDAO();
dao.create(auth);
//let LCDS know:
dtx.createItem("author", auth);
dtx.commit();
}
So I just do my regular db insert, then I use a DataServiceTransaction to let FDS know that I've created an Item. Alternatively, I could use this approach:
public void createFDSItem(){
DataServiceTransaction dtx = DataServiceTransaction.begin(false);
Author auth = new Author();
auth.setFirstName("victor");
auth.setLastName("javarubba");
AuthorDAO dao = new AuthorDAO();
dao.create(auth);
dtx.refreshFill("author", null);
dtx.commit();
}
This approach might be a bit of overkill and might be better suited when doing mass updates across many records. I did a little bit of testing and it seemed that for the most part calling CreateItem() was faster that the refreshFill() in pushing the new record to the Flex Client.

What cost me so much grief is that I was falsely led down the garden path to believe that calling dtx.createItem("author", auth) would not only inform FDS but also actually create the item. This is not the case. There! Officially blogged!

Posted by Vic Rubba at 12:25 AM Comments

Tuesday - November 13, 2007
Losing the RollOverColor in TileList



In one of our projects we have a custom effect that plays over each tile as a user mouses over the items in a tilelist. Not getting too much into details, I basically overlay a canvas that appears and disappears as the mouse moves over the tile, giving the illusion that each tile sort of explodes. So the one thing I don't need is the rollOverColor effect, which defaults to a nasty baby blue. Usually I just set the rollOverColor to the same color as the background but that's not working so well on this project, since the background can be an assortment of wallpapers.

Unfortunately there doesn't seem to be any way to disable the rollOverColor, and maybe someone can shed some light on an easier solution. I ended up extending TileList with my own mxml component and overriding the drawitem function, as follows:

<?xml version="1.0" encoding="utf-8"?>
<mx:TileList xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.listClasses.IListItemRenderer;

protected override function drawItem(item:IListItemRenderer,
selected:Boolean = false,
highlighted:Boolean = false,
caret:Boolean = false,
transition:Boolean = false):void{

super.drawItem(item,false,false,caret,transition)
}
]]>
</mx:Script>
</mx:TileList>

As you can see, I override the selected and highlighted parameters with false, thereby eliminating the selected and roll over effect. Seems to work quite well. I now use this mxml component instead of TileList throughout my applications.

Posted by Vic Rubba at 9:26 PM Comments

Friday - November 09, 2007
Where or where has my intellisense gone?



I'm working on a flex 3 app using the latest flexbuilder 3 beta, both the plugin and standalone versions. For some reason, in some mxml files my intellisense just seems to not work at all. While in other mxml files the intellisense works fine. Turns out that in this latest beta release, Flexbuilder gets cranky if you use double quotations in Metadata Event tags:

[Event("forward", type="mx.events.Event")] will kill your intellisense and your control clicks. You will feel very lonely.

[Event('forward', type='mx.events.Event')] will make everything right again, blue coding skies ahead.

On a side note, the single quote is actually only necessary on the type attribute, intellisense seems to work fine if you use double quotes on the Event name itself.

Hopefully this will be fixed in the next release.

Posted by Vic Rubba at 9:03 AM Comments

Thursday - November 01, 2007
Using floating IFrames in Flex 3 Beta: wmode buh-bye?



Just a quick one today... we're porting some work to Flex 3 where we do the floating Iframe thing, and noticed some strange behaviour changes. In Firefox, the floating Iframe would briefly flash into view and then disappear, while in IE the Iframe would appear, however if we clicked into the IFrame embedded html page and then clicked outside it somewhere on the flex app, the IFrame would disappear from view.

Took a little bit of sniffing around but in the end the culprit was the html-template\index.template.html file. For some reason, and it might well be a very good reason, the property wmode is no longer included in the flash player tags ("wmode", "opaque" in AC_FL_RunContent() && wmode="opaque" in <EMBED>) in FlexBuilder 3. Once we added those back in, the floating IFrame started working again.

Posted by Vic Rubba at 5:26 PM Comments

Friday - October 26, 2007
Not another Flex, AmfPHP, Cairngorm CodeGen! MAKE IT STOP!



Haven't blogged in quite some time and this is a project that's been half done for far too long. Like everyone else we decided to build our own code generator, just something fairly straightforward that would generate all the DAO code, the Cairngorm code, and a nice little interface to test all the main CRUD and DAD functions we have come to know and love. Lately we've been busy souping up the generated UI, not so much in terms of style... beauty does not live here... functionality however does.

You can get all the gory details by clicking on this link:

http://www.crazedcoders.com/php/codegen.php

We built this code to use AMFPHP, Cairngorm, PHP and Flex 2.01. We've put in place validators, datepickers, checkboxes and textinputs on our forms and generated full Command/Event/Model/Controller classes. We've implemented binding on the generated view form fields. Our code generator will detect relationships between tables and render comboboxes accordingly, for example, if there's a foreign key on a customer table linked to a country table, the customer view will have a combobox linked to the model.countries collection. But I must stop, I'm getting too technical...

Basically, if the generator runs successfully, you're a few clicks away from being able to manage the data in your database from Flex. The generated code is zipped up for you to download. Inside the zip you will find a complete and ready to import Flexbuilder Project and the php packages ready to copy into your amfphp services folder. Further details can be found by clicking on the link.

Posted by Vic Rubba at 12:56 AM Comments

Wednesday - May 30, 2007
Flash.media.Sound & Memory Issues in Flex



Taking a short break from my module woes, I've been working with audio in Flex. In my app I was building a preview intro scan of my listed mp3's. What I noticed is that as the list of mp3's got longer, the memory that my browser was eating up got larger. I haven't really found any articles addressing best practices regarding handling audio in Flex, however I would venture a guess that this has been addressed many times in the past by Flash Developers.

I'm pretty tired so I'll keep this simple. Best way I have found to ensure that an audio stream is destroyed and the memory returned when you stop it:


private var mySound:Sound = new Sound();
private var audio:SoundChannel = new SoundChannel();

private function startPlaying():void{
mySound = new Sound(new URLRequest("music/sample.mp3"));
mySound.addEventListener(Event.COMPLETE, completeSound);
audio = mySound.play();
}

private function stopPlaying():void{
audio.stop();
mySound.removeEventListener(Event.COMPLETE,completeSound);
mySound = null;
}
Trick is to declare the variables outside the function, ensure you configure a sound channel (audio) for your sound, and make sure you that you can reference both from the stop function. Then you need to stop the audio, remove any event listeners, and set sound to null. I found it's also a good idea to do your URLRequest inline, as it seems to get destroyed at the same time as mySound.

Short, simple.

Posted by Vic Rubba at 8:39 AM Comments

Sunday - May 13, 2007
Can Cairngorm and Modules play nice? Sample App



First I'd like to say thanks to those of you that commented on my previous blog entry. I was inspired to go back and take another look at ApplicationDomain. To be honest, I can't get it to work for me. So I'm just going to put up my prototype application with source code and let you play with it. There is a shell application and 3 very simple modules. The challenge is to have a controller in the shell and still have the modules all work independently of each other. The sample app as it sits on the server works because it's essentially Cairngorm free. Good luck!

Source can be found here. Demo can be viewed here.

Posted by Vic Rubba at 7:36 AM Comments

Saturday - May 12, 2007
Can Cairngorm and Modules play nice?



Let me say, first off, that my wife gave birth to a beautiful baby girl on Wednesday morning, and they are doing just fine. I've been relocated to the spare bedroom so that I can actually function during the day, however I'm missing about 30 hours of sleep this week that I'll never get back. Having said that, I am blogging today because even though I've sort of fixed my latest issues, I'm not entirely sure I've used the best approach.

This is really a sequel to my previous blog... I am still fighting with getting modules to load properly and independently of each other and the shell flex application. Here's the deal...

I have one complex flex module that is built on the Cairngorm 2.2 framework. In itself, the module works fine, and after the progress from the other day, loading multiple instances of the module into a simple shell works fine too. However, when I tried loading multiple instances of the module into the actual application, things died. Why? Because the shell is built on the Cairngorm framework as well. The minute I add in the <services:AppController id="appController"> line to my shell app, subsequent instances of the module don't load properly. I determined that the shell needed to use a different controller than the module, but that wasn't enough (though still necessary). There were funky things happening again when events were triggered - weird casting errors, events firing across multiple module instances, shared models, etc.

A couple of observations:
CairngormEventDispatcher basically returns a singleton. If the shell app gets an instance of this class, then any Modules that load will use the same instance. So, adding the appcontroller to the application will in fact get an instance of the dispatcher. Running through the debugger, I noticed that as I loaded each new instance of the same module, event listeners were added to the singleton's eventDispatcher. So, say your module was listening for the ContactEvent.LOAD_CONTACT event. If you loaded 3 instances of that module, your controller would execute 3 commands, once for each module.

When an event is received by a command, and you try to cast that event back to its origin, i.e. ContactEvent(event), it will only work in the module that actually originated the event. The other modules will throw the following exception:
" cannot convert com.crazedCoders.moduleTest.event::ContactEvent@4b23281 to com.crazedCoders.moduleTest.event.ContactEvent." Trying to test for it, i.e. if(event is ContactEvent) doesn't work since the event is in fact a ContactEvent. Very frustrating.

If you do not use any Caingorm in your shell application, you will not run into these issues, so for some that might be the quick solution. Sadly I was not afforded that luxury, so I had to find another way.

Since I was trying to treat each Module as an autonomous mini-application, I decided that I needed a CairngormEventDispatcher specifically for each Module and the Application. I created a Factory Class that would do just that. Here's the code:

package com.adobe.cairngorm.control{
import mx.modules.ModuleManager;
public class CairngormEventDispatcherFactory
{
private static var instances : Array = new Array;
public static function getDispatcher(obj:Object) : CairngormEventDispatcher
{
// in order for each module developed using cairngorm to be able
// to work independently of the shell and other modules,
// we need to create a hash map of cairngormeventdispatchers
// that are keyed on module instance or application.
// This prevents cross module listening for events,
// which is beneficial especially when loading multiple instances
// of the same module
var ed:Object = ModuleManager.getAssociatedFactory(obj);
var parent:String = "application";
if(ed != null){
trace(ed.name);
parent = ed.name;
}
if(instances[parent] == null){
var cgDispatcher:CairngormEventDispatcher = new CairngormEventDispatcher();
instances[parent] = cgDispatcher;
return cgDispatcher;
}
else{
return instances[parent];
}
}
}
}
It took me a while, but eventually I stumbled upon ModuleManager.getAssociatedFactory(object). This function *seems* to be able to figure out within the context of which Module (if any) the object was instantiated. If an object belongs to the shell, it returns null, if not, then it returns a ton of information, including a name property that contains a unique name i.e. instance77 for the loaded module. I create a new instance of the CairngormEventDispatcher for each instance and stuff it in the static associative array, then I replace the usual CairngormEventDispatcher.getInstance().dispatchEvent(...) with
CairngormEventDispatcherFactory.getDispatcher(this).dispatchEvent(...));
Now the application shell and each module gets it's own singleton, and the overlap seems to be taken care of.

Again, I welcome any feedback. I'm not particularily fond of this solution, and I hope someone out there can offer a better one.

Posted by Vic Rubba at 10:18 PM Comments

Tuesday - May 08, 2007
Loading Multiple Independent Instances of a Module



So, it's Monday night... my wife's contractions are 13 minutes apart, and it seems I have nothing better to do than blog. Of course, this is more akin to the calm before the storm that will be the next 24 hours and probably the next six months. Eventually I will once again emerge from the dark precipice that lies ominously before me. But on to modules.

I love Cairngorm... I just upgraded all my projects 2.2 and it was painless, nothing like child labor, I'm told. I am working on a project where we have to build all these pretty much independent modules, and in these modules we stick to Cairngorm as well.

The first problem we ran into occurred when attempting to load 2 instances of the same module. ModuleManager, as it turns out, keys modules by url. So if you try to load the same module twice, you're just getting a reference to the same one. There is no way around this (or so I thought) This has a number of repercussions:

  • Only one ServiceLocator instance can be instantiated - this wonderful little Error message pops up the minute you load a second instance of the module. Quick workaround is to declare the system locator code much like you do model:
    private var dataServices:ServiceLocator = ServiceLocator.getInstance();
    and abstain from using the mxml format:
    <business:Services id="dataServices" />
  • All your module instances will share the same model... so if you say do a search, get a searchresult back and stick that in your model, all your modules will display the same search results, which defeats the purpose of having separate file/image search browsers (for example).

Here's a couple other funky things I tried:

  • Created 2 modules pretty much identical, Mod1.swf and Mod 2.swf. I loaded them up and they both worked fine and independently
  • Created a copy of Mod1.swf and called it Mod1a.swf. I loaded them up and they both worked fine.
  • Tried loading two Mod1.swf and suddenly no independence, plus the ServiceLocator error.

I tried wiring up my own ModuleManager, but after a good couple hours I gave up... I was getting all sorts of weird behaviour. I figured out that everything is based around the url that you pass to ModuleManager or ModuleLoader. I was pretty much ready to give up when I had this really silly notion, I did this:

private var count:int;
private var spaces:String = "";
private function LoadModule():void{
for (var x:int; x < count; x++) spaces += " ";
var info:IModuleInfo = ModuleManager.getModule("mod1.swf" + spaces);
info.addEventListener(ModuleEvent.READY, done);
info.load();
count ++;
}
private function done(event:ModuleEvent):void{
var visual:DisplayObject = event.module.factory.create() as DisplayObject;
tabber.addChild(visual);
}
Much to my surprise, this hack worked. The modules loaded successfully and ran independently. Of course, I probably need to test this some more, but I figured I'd blog it quick before the trauma of childbirth hopefully graces me with some convenient and kind short term memory loss.

Posted by Vic Rubba at 6:01 AM Comments

Friday - April 27, 2007
Mapping VO's from Flex to PHP using AMFPHP



I sometimes wonder why it is that I never seem to blog till shortly after the midnight hour... oh well... life just gets too crazy when the sun is up. So as it happens, one of my minions spent the better part of today putting together php classes, using a nifty code generator found called DAO Generator by the guys over at Titantic Linux. It seems to do a pretty decent job of generating the sql necessary to create the db table, and then builds three additional files, the VO, a datasource file, and then finally a DAO file that has a ton of functions in it. (and I mean a ton!)

Going to take a moment here to give credit where credit is due... Michael Ramirez's tutorial on Using Amfphp 1.9 with the Adobe Flex 2 SDK is what really got us started in the right direction, it's pretty detailed and yet easy to follow. We quickly were able to get our AMFPHP up and running with the tutorial files as outlined by Michael. Tickled pink by the code generator we figured we could easily start building our own php gateway. But enough background... on to the thick of things.

Passing VO's from PHP seems to be very well covered in numerous articles on the web, and it involves mainly adding a var $_explicitType="tutorials.Person" to the php VO, with a value that corresponds to the [RemoteClass(alias="tutorials.Person")] in the Flex VO. Pretty straightforward and foolproof. But no one seems to spend any time talking about going back the other way.

Generally when a VO is passed from Flex to AMFPHP, it is treated as an Associative Array. In Michael's examples, he treats the ValueObject that is passed back to Save function as just that $valueObject["lastName"]. But we were pretty keen on using the generated code, which actually uses the syntax $valueObject->getLastName(). And this of course, failed, because the $valueObject being passed to PHP from Flex was not in fact being mapped back to the right VO, or any php VO for that matter.

Turns out, after much googling, that only under certain conditions will AMFPHP successfully map an incoming Flex VO to the corresponding PHP VO. In the globals.php, found at the root of the AMFPHP folder structure, you'll find the following line:

$voPath = "services/vo/";

Meanwhile we had been placing our VO in the same folder as our Datasource and DAO files, something like com/crazedCoders/testapp, and this was off the services/ folder, not the services/vo folder. In fact we didn't even have a /vo folder. I found this little tidbit of information: "As for incoming class mapping, remember that if amfphp doesn't find the class to be mapped in the services/vo folder, it will simply deserialize the object as though it were untyped, that is, as an associative array. " in this blog.

It took a little bit of playing around but ultimately, without making any changes to the core AMFPHP files, I was able to get the reverse mapping working successfully. This is what that looked like:

//file: src/tutorials/Person.as
package tutorials{
[RemoteClass(alias="tutorials.Person")]
[Bindable]
public class Person {
public var firstName:String;
public var lastName:String;
public var phone:String;
public var email:String;
}}
and then in php:
<?php
//file: services/vo/tutorials/Person.php
class Person {
var $firstName;
var $lastName;
var $phone;
var $email;
// explicit actionscript package
var $_explicitType = "tutorials.Person";}
function formatLastName(){
$lastName = strtolower($lastName); }
?>
To test the mapping I added the following function to a PersonService.php file:
//file: services/tutorials/PersonService.php
function modify($person){
//this will call a function on person and return it
$person->formatLastName();
return $person;
}
Only if the valueobject was mapped correctly would it be able to call the function on the PHP VO. In Flex I just created a Person object, passed it in to the remoteobject call, and observed the formatting of the last name on the Person object that was returned.

Again, I hope this will save others the time that it took me to figure this out. Enjoy!

Posted by Vic Rubba at 8:33 AM Comments

« Previous   1   2   Next »


Entries 120 out of 255, 10, or 20 per page