Connecting two swf when using same library


#1

Hello. I use the same library in two projects, but the objects made from the classes of that library in different projects are not considered the same type.

SWF A:

public class Main extends Sprite
{
    public function Main()
	{
		trace('A');
		var item:Item = new Item();
		item.init('A');
	}
	
	public function setItem(item:Item):void
	{
		trace('setItem');
		item.init('A2');
	}
}

SWF B:

public class Main extends Sprite
{
    public function Main()
    {
		trace('B');
		
		var loader:Loader = new Loader();
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
		//loader.load(new URLRequest('A.swf'));
		loader.load(new URLRequest('A.swf'));
	
		function loaded(e:Event)
		{
			trace('loaded');
			var item:Item = new Item();
			item.init('B');
			Object(loader.content).setItem(item);
		}
    }
}

LIBRARY:

public class Item
{
	public function Item()
	{
	}
	
	public function init(str:String = null):void
	{
		trace('init', str);
	}
}

OUTPUT:

[trace] B
[trace] A
[trace] init A
[trace] loaded
[trace] init B
[Fault] exception, information=TypeError: Error #1034: Type Coercion failed: cannot convert Item@41e6e61 to Item.

#2

Yes that’s normal

first rule, when you define something in ActionScript
this definition is like a constant, you can not override it

so what happen in your case

  • SWF A compile the definition of class Item
  • SWF B compile the definition of class Item
  • when SWF B try to load SWF A
    • SWF B definition of class Item is already loaded in memory
      and is like a constant, eg. you can not redefine it
    • by loading SWF A the code try to define class Item
      or more exactly try to REdefine class Item

see Adobe Air android with 2 swfs questions for the longer explanation of the difference between -library-path and -external-library-path

in short,

  • by using -external-library-path you compile against definitions
    but you do not embed them into the final SWF
  • by using -library-path you compile against definitions
    and you do embed them into the final SWF
    also known as “merged into code”

and that’s the second rule, know your compiler options to know what end up in your SWF (or binary)

But it can get more complicated than that, depends f your context and what you try to do, here few scenarios

  1. You can embed the class Item definition in both SWF
    but then when you dynamically load an external SWF
    you use the ApplicationDomain to isolate the definitions

  2. You use an interface as your type instead of the class definition
    If I remember well AIR/Flash is smart enough to not throw an error
    on the same interface even if the definition of the interface is embedded multiple times

  3. You control how you compile things, the main SWF embed all definitions
    and any external SWF which need to be loaded is compiled against those definitions
    but do not embed them eg. -external-library-path

  4. Ideally you separate anything that is “shared” into a SWC eg. shared.swc
    and with the main SWF you use -library-path shared.swc
    and any other SWF you use -external-library-path shared.swc

That said, if you do that on AIR mobile you may end up in a world of hurts, less on desktop.
So I would ask, why in the first place do you load an external SWF, what are you trying to do?


#3

Thank you a lot. :slightly_smiling_face:
I have an application that has a lot of modules. For example, a photo editing module, a sound module, a module for working with a sprite sheet, and so on. Each module is written individually and injected into the program. Each user has some modules, depending on which accesses it has. In order to be able to update without having to replace the entire program, I decided that each module would be a separate swf.
Modules are written at different times and by multiple people. When I use personal libraries or Starling, I’m having this problem.
If there is another way, I do not have to use this model to be able to separate parts of the program in isolation.


#4

well… it depends, where are you publishing the app?


#5

A desktop application that will be published through its website.
And in the future it’s Android version. Previously, I made a very simple version. Which was only used in my team. But we also had problems with updates, and we are going to publish them to others as well.


#6

OK, so I think you complicate your life based on a false assumption

eg.

it is cheaper/faster to include all your module into 1 SWF and only enable some of them depending on a user license of some kind.

Now yes it is possible to do multiple module and load them dynamically
but then you’re looking at a world of hurts

case where

main app
      |_ module 1
      |       |_ module A
      |       |_ module C
      |
      |_ module 2
              |_ module B
              |_ module C

I worked on something like that with a main SWF app and about 20+ modules
in fact I got hired to do that specific task before many dev before “failed” to make it work for ~1,5 year

I had to publish a global interface containing other interfaces as a public API
so other dev could test/use this API without having access to the implementation
but then when loaded online the API would work

and the basis of the thing is basically the interface define an API per module
the SWF compiled against the interface implement the API

not only you have to define things like shared.swc so all dev can share common reusable code

but you have also to use ApplicationDomain to isolate each module from one another
case where module A want to use libXYZ v1.0 and module B want to use libXYZ v2.0
and so with that modules can communicate with each other only through the API

and then to organise all that you need a solid automated build
because you will want things like module E compiled before module F but after module C
I called mine “metabuild” and it took me a good month to setup with all the details

my point is separating modules in different SWF not necessarily gonna simplify your dev life
and other dev in your team, it gonna be quite the opposite

in my case, we did not have the optino to embed everything into 1 SWF
because gameloader dynamically load game, and then game access a public API
and there were 100s of different games

but here in your case where you have different modules photo/sound/spritesheet/etc.
those probably need to cooperate with each others

if you want to use many SWF to easily updates
just make a main SWF (a shim) that load the app SWF and update that app SWF
but honestly just updating the whole exe is imho more efficient

if you want to split the SWF for security reasons
“oh your license does not allow you to use the photo editor, you don’t have the SWF so you can’t use it”
loading a remote SWF based on a license will more easily configure what the user can do or not

On the desktop or even on mobile the SWF size of your main app does not matters,
long time ago I tested 800MB+ SWF and it was loading fine

What I’m saying is separating all in SWF module is not worth the effort unless you really have no choice, it’s like saying “oh I gonna run a marathon but it is too easy to run with sneakers I will use nails under my toes to make it more interesting”.


#7

I am thankful with your guidance.
I’m convinced that the use of separate files is more troublesome. :roll_eyes:
However, if there was a simple way in which all classes would refer to a single definition, I would not take that decision
Thank you again. And forgive for the poor English translation of Google!

دمت گرم
مخلص داداش