Hi,
I have this problem with cross-flash communication. To simplify the problem, I'll say I have two plugins.
One is a interface that uses a xml with all panorama id's stored (and lots of other information about that location), let's call this plugin the Control Center, because everything a user does, goes via this plugin. When a hotspot is pressed, it fires a flash function with a id in it. It then does some voodoo all based on that id. It matches the id it gets with an id thats stored in special xml file (not krpano's). Then it loads the next panorama based on this, and fires several events (open/close the map, color a hotspot so it looks active etc). This Control Center, once completed, will never be changed unless it's a bug and the same for every client.
The other plugin can be any other plugin, but let's say it's a flashtextfield. This is a plugin a client can order. The plugin alsoo needs the id of the panorama thats being loaded (or is loaded). So in this case it needs the panorama id to match it with an id in the xml, so it can load the appropiate text file.
Now this is where I am stuck. Somehow I need this panorama id. I tried several things. Some dont work, others just partly. Let me brief you through:
1) I tried to fetch the function the hotspot fires. This failed. Apperently when you call a flash function within krpano. It stops as soon as it gets received. And the control center already received it.
2) I tried to dispatch an event after the controlcenter is done. The event is received by the other plugin. But an event isn't an id. So I tried to create my own custom event that can carry a string:
import flash.events.Event;
public class PlayerEvent extends Event
{
public var property:*;
public static const CHANGELOCATION_EVENT:String = "changelocationevent";
public function PlayerEvent(type:String, property:*) {
this.property = property;
super(type, property);
}
override public function clone():Event {
return new PlayerEvent(type, property);
}
}
Display More
I import this class in both my plugins, but then I get a error that the dispatch event doesnt match the listener because although its the same class. It are different instances.
3) I made a localconnection class. The controlcenter sends the id through a channel and the plugin listens to it.
import flash.net.LocalConnection;
import flash.events.StatusEvent;
import krpano_as3_interface;
public class LocalConnect extends LocalConnection
{
public var outgoing_lc:LocalConnection = new LocalConnection();
public var krpano:krpano_as3_interface = null;
public function LocalConnect()
{
krpano = krpano_as3_interface.getInstance();
}
public function Send(_channel:String, _method:String, _param:String)
{
outgoing_lc = new LocalConnection();
outgoing_lc.addEventListener(StatusEvent.STATUS, onStatus);
outgoing_lc.send(_channel, _method, _param);
}
private function onStatus(event:StatusEvent):void
{
switch (event.level) {
case "status":
krpano.trace(0, "LocalConnection.send() succeeded");
break;
case "error":
krpano.trace(0, "LocalConnect.Send() But no one is listening. No Connection Made");
break;
}
}
Display More
This works. BUT when you have multiple plugins all needing the id, you have to make a different channel for every plugin, thus have to update the controlcenter each time you add a plugin (or have to create a large amount of channels sending the same id, which doent help performance wise. Alsoo Localconnection is limited to 44kb of information. This isnt a problem now. But still I dont like the limit. This option is what I currently use, and Im not really happy with it.
Then I pondered. What if I, instead of putting the location id in a seperate xml file, put it alsoo in the krpano xml file. Then when the panorama gets changed by the control center, a event will fire (onviewchange or wait(blend) by krpano). The textfield plugin will then read the unique panorama id from the krpano xml thats currently loaded.
This raises the following questions:
Will this work?
How do I store a custom variable in krpano xml (I've read it somewhere but can't find the docu about it).
How do I listen to onviewchange or wait(blend) from within the textfield plugin? Does it need a timer event or is there a better way? Because if you have 10, 20 ,30 plugins all having a timer event, listening whenever the panorama gets updates, won't help you perfomance wise :p
Another possible solution pops in my mind, a solution concerning javascript.
hotspot -> Controlcenter -> send javascript call - javascript -> textfield externalinterface.addcallback -> textfield updated.
Controlcenter
var url:URLRequest = new URLRequest("javascript:changeText(" + id + ")" );
navigateToURL(url, "_self");
Javascript
no clue??? :(
function changeText(id)
{
sendvariable to otherflash function
}
textfield
import flash.external.ExternalInterface;
ExternalInterface.addCallback("changeText", changeTheText);
function changeTheText(t:String):void {
txtText.text = t;
}
Although im not sure how I can avoid page refreshes or if it sends the var to multiple plugins.
Sorry, a very big post. But it's a problem I'm facing alot. Im trying to find the best solution, performance wise and maintence wise (leaving controlcenter as much untouched as possible and with the least amount of xml). Hope you can clear the water for me?
Thanks!
and btw. If you're curious about the Controlcenter and such. Go to the link in my signature. It's an old bloggy version of it. I've rewritten it completely to classes now. When you click on a hotspot. the textfield gets updated (on the right) most texts are the same, so it won't update always. And while you're in the tour, press the "i' you see near houses.