AssetLibrary.loadFromFile error - [File not found]

#1

Hello!
Please, help me deal with my problem.
I use your example for load asset library from file

package;

import openfl.display.Sprite;
import openfl.utils.AssetLibrary;

class Main extends Sprite
{
    public function new() {
        super();

        var future = AssetLibrary.loadFromFile ("assets/Test.bundle");
        future.onError (this.library_onError);
        future.onComplete (this.library_onComplete);
    }

    private function library_onError (err:Dynamic):Void {
        trace ("ERR " + err);
    }

    private function library_onComplete (library:AssetLibrary):Void {
        trace ("Bundle Loaded");
        var clip = library.getMovieClip ("");
        this.addChild (clip);

    }
}

project.xml

 <?xml version="1.0" encoding="utf-8"?>
 <project>

     <meta title="HaxeTest" package="com.sample.haxetest" version="1.0.0" company="Company Name"/>

     <app main="Main" path="Export" file="HaxeTest"/>

     <source path="Source"/>

     <haxelib name="openfl"/>

     <assets path="Assets" rename="assets" embed="false"/>

 </project>

When I trying upload bundles, an error occurs:

GET /assets/Test.bundle/assets/Test.bundle/swflite.bin?458557
Error (404): "Not found"

But file swflite.bin has path “/assets/Test.bundle/swflite.bin”.
Why the file path looks like this: “/assets/Test.bundle/assets/Test.bundle/”?
Also, In file “Export/html5/bin/assets/Test.bundle/library.json” rootPath=“assets/Test.bundle”.

0 Likes

#2

Do you need to load the SWF file at runtime in this way? Could you use the <library /> tag instead?

<library path="Assets/test.swf" preload="true" />

Then:

var mc = Assets.getMovieClip ("test:");

It looks like there might be an issue here with using “assets/Test.bundle” as the rootPath. I think the rootPath probably should be blank. There might be a bug here, if you could share an example project?

Go ahead and look at openfl create NyanCat, however, as a simple example of including SWF assets. The <library /> tag is the standard/easy way to include SWF assets, using openfl process in advance and loading SWF assets at runtime is a more advanced feature that may still have some problems in corner cases, so I appreciate feedback, but it may also be easiest to try a slightly different approach :wink:

0 Likes

#3

I can confirm this is a bug. Trying to load a pre-processed swf bundle at runtime, it gives the exact same error. In the final exported library.json, there is a path on the “root” parameter, and as you say Joshua, it must be blank for this to work.

We manually remove root content ("") each time we compile, and it works. It is a bit inconvenient to have to edit the file every time we compile, but we expect a solution in next versions.

Question: Is there any way to remove loaded contents, if we load with AssetLibrary.loadFromFile ?

Thanks

1 Like

#4

So openfl process not setting the root parameter in the JSON would fix the problem?

I believe you can Assets.unloadLibrary using the same path

0 Likes

#5

The problem is not in the process to convert a swf to swflite (openfl process …). When this process is launched, if we look at the generated library.json: “rootPath”: null (it is correct and it works)

The problem is in the final compilation of the project in the definitive folder, provided that we specify the assets swf bundle in project.xml. For example, I have this:

<assets path = “assets/swf” rename = “swf” embed = “false” />

With this the swf.bundle files of that folder are automatically copied to the final compilation folder. But in the process, “rootPath” its modified and set to the value of the relative path; “rootPath”:“swf/assets_en_multi.bundle”.

So when you indicate AssetLibrary.loadFromFile (“swf/assets_en_multi.bundle”) it is as if the path is duplicated: “swf/assets_en_multi.bundle/swf/assets_en_multi.bundle”

I am complicating myself with the explanation … I hope it is understood.

If we do not specify the assets swf in project.xml, you can copy by hand the original created swf.bundle files (with rootPath null) to the final folder, so it’s not that bad.

On the other hand, AssetLibrary (openfl.utils.AssetLibrary) does not have an unloadLibrary method. I do not know if there is another AssetLibrary that can also work with swf at runtime.

1 Like

#6

Thanks for the extra information. I think I understand now!

Does this work?

<assets path="assets/swf" rename="swf" embed="false" />
var library = Assets.loadLibrary ("swf/assets_en_multi.bundle");

You can then try this code to unload later:

Assets.unloadLibrary ("swf/assets_en_multi.bundle");
0 Likes

#7

I was quite confused with the operation of AssetLibrary and Assets … I thought you had to use either one or the other. But I think I already have it!

The problem in part was the types. I did not understand what types to assign to each part of the load. And I needed an onComplete event.

The imports with the appropriate classes:

import openfl.utils.AssetLibrary;
import openfl.utils.Assets;
import openfl.utils.Future;

Variables:

private var futureContent: Future <AssetLibrary>;
private var contentLibrary: AssetLibrary;
public var contentLoaded: Bool;

Methods:

private function loadExtraContent (swfContentFile: String = ""): Void
{
  if (! contentLoaded)
  {
    futureContent = Assets.loadLibrary (swfContentFile);
    futureContent.onComplete (library_onComplete);
   }
}

private function library_onComplete (library: AssetLibrary): Void
{
  contentLibrary = library;
  trace ("library_onComplete:" + contentLibrary);
  var contentMovieClip = contentLibrary .getMovieClip ("Multi0ScreenAssets");
  addChild (contentMovieClip );
  contentLoaded = true;
}

Use:

loadExtraContent ("swf / assets_en_multi.bundle");

So now I can unload the file with: Assets.unloadLibrary(swfContentFile);

I have to look at it in more depth but I think it works. Thank you!

P.D.: I still do not know how to paste code in the forum correctly :joy:

0 Likes

#8

Mmmm, what exactly does Assets.unloadLibrary ?. Deletes files loaded from the browser cache ?.

If I do unloadLibrary from swf content of movieclips that I have on screen (addChild), they continue to show … I could eliminate them with removeChild, but I am not clear if unloadLibrary actually frees memory from the application.

0 Likes

#9

First, once you load a library, you can access it from the loaded library, or just use the Assets class. Using Assets lets you use the cache system as well.

Assets.loadLibrary ("swf/assets_en_multi.bundle").onComplete (function (_) {
    var clip = Assets.getMovieClip ("swf/assets_en_multi.bundle:");
    addChild (clip);
});

// or

Assets.loadLibrary ("swf/assets_en_multi.bundle").onComplete (function (library) {
    var clip = library.getMovieClip ("");
    addChild (clip);
});

Using Assets requires a <lib name>: prefix to each of the calls

Second, unloadLibrary removes any of the internal cache references. It does not remove anything you are still actively referencing or using. It is your responsibility to remove any references you have to the content for it be garbage collected

0 Likes

#10

Ok, thanks Joshua,

So I need the second method call because I need to access specific MovieClip containers from the loaded library.

What type is the “library” parameter on the onComplete callback?. openfl.utils.Assets? or openfl.utils.AssetLibrary?

With AssetLibrary (as in my code) <lib name>: prefix, is not needed (I think it doesnt work). But with Assets I understand is always needed.

0 Likes

#11

Here is Assets.loadLibrary in the API docs:

https://api.openfl.org/openfl/utils/Assets.html#loadLibrary

It returns a Future<AssetLibrary>, which means that your onComplete handler will be an openfl.utils.AssetLibrary

Yep, the <lib name>: prefix is for the Assets class. With no prefix is the same as adding default: before each call, like Assets.getBitmapData ("default:image.png")

0 Likes