0

I have a Scaleform movie that I want to serve as the container for my game's user interface. I want it to be able to load and unload other swf files that will serve as different HUDs and menus. And when I load a swf, I need Actionscript to register the name of the DisplayObject, so the game will know which "view" (i.e., HUD, pause menu, shop menu, etc.) just loaded.

I am able to load other swfs using Loader.load(), but for some reason I can't change their names. I keep getting error 1074.

[Edit: Adding more info on the error. "Error #1074: Illegal write to read-only property." Apparently I'm trying to write to a read-only property. So how do I make that property not-read-only? name isn't read-only in any other UIComponents I'm loading.]

    public function loadView(viewName:String, movieFileName:String):void
    {
        var loader:Loader = new Loader();
        var url:URLRequest = new URLRequest(movieFileName);
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderComplete);
        loader.name = viewName;
        loader.load(url);
    }
    
    private function loaderComplete(e:Event):void
    {
        var loader:Loader = e.currentTarget.loader as Loader;
        var content:DisplayObject = LoaderInfo(e.target).content; // This returns the content I'm looking for, but I always get error 1074 if I try changing its name
        // var content:DisplayObject = loader.getChildAt(0); // This also returns the content I'm looking for, but it also gives me error 1074 if I try changing its name
        
        // content.name = loader.name; // This line always gives me error 1074
        
        // var newView:View = View(content); // Even if I try casting the content as a custom .as class...
        // newView.setName(loader.name); // public function setName(newName:String):void { this.name = newName; } // ...I still get error 1074
        
        addChild(content);
    }

Am I just not allowed to change the name property of swf movies that get returned? Can I set the name in the document class of the swf? I tried that too, but no matter where I change the name inside the document class (their class extends scaleform.clik.core.UIComponent, and I try setting the name in the constructor and in configUI), it always seems to get overwritten when I addChild().

[And another edit. Apparently there is some confusion over the "name" property. Here's how it works...]

I start off with this code. I just put it in frame 1 of my movie.

import TestUIComponent;
var testUIComponent:TestUIComponent = new TestUIComponent();
testUIComponent.name = "Something something";
trace("This is the testUIComponent's name: " + testUIComponent.name);
addChild(testUIComponent);

This is the class TestUIComponent:

package  {
    import scaleform.clik.core.UIComponent;
        
    public class TestUIComponent extends UIComponent {
        
        public function TestUIComponent() {
        }

        override protected function configUI():void {   
            super.configUI();
            enableInitCallback = true;
        }
    }
}

Nothing fancy there. It's just an Actionscript 3 scaleform.clik.core.UIComponent (need to specify that because I think there are at least 3 different UIComponents in different packages). enableInitCallback is a property that used to be visible in Flash's properties panel, but now in AS 3, it seems you can only change it in code.

So I run that code, and this is what I see:

This is the testUIComponent's name: Something something
CLIK Load: root.Something something

If I comment out the line

// testUIComponent.name = "Something something";

and then run the code, this is what I see:

This is the testUIComponent's name: instance1
CLIK Load: root.instance1

Going back to my original problem, the text that comes after "CLIK Load:" is the name that is getting sent from the UI to the game. I need that name to be something meaningful so the game knows what just got loaded. The swf files I am trying to load have Document Classes that are children of scaleform.clik.core.UIComponent, so I thought their name properties would work the same way as the TestUIComponent above. Apparently it doesn't. And as you can see all the way back up at the top, I even cast the loader.content as a View (which is a child of UIComponent), and I still can't change the name.

Nathaniel
  • 540
  • 1
  • 7
  • 17
  • It is a good idea to research what **Error 1074** or at least quote its full description. It is what you **can** and **should** do to explain your problem thoroughly. Please "edit" your question to do so. – Organis May 06 '21 at 20:40
  • **(1)** `loader` is already the name of your **Loader** data type. Why do you need a second name added for its identity? Can a Loader even have a `.name` attached? Try immediately tracing the Loader's name after you set it in your first function. **(2)** A var created inside some function only exists in that function, so you say `content.name = loader.name;` but there is no `loader.name` set in your function. Where is it coming from (non-exist)? **(3)** Why not just have a **public** String that holds your expected name and then later used as _eg:_ `content.name = myString;`? – VC.One May 07 '21 at 00:00
  • Added information on Error 1074 and I added more explanation for how `name` works. Specifically regarding loader and its content, if I don't set loader's name, it's always "instance1," or if I'm experimenting with the code and making multiple loaders, then they're instance2, instance3, etc. – Nathaniel May 08 '21 at 06:38
  • 2
    I poked it a bit. **№1**. You cannot change the **name** property of the **root** object (**Loader.content** points to the **root** object of the loaded movie). You just cannot, there's no difference if that a loaded movie or not. If your goal indeed is "*I need Actionscript to register the name of the DisplayObject, so the game will know which "view" just loaded.*" just (per *VC.One* suggestion) work with **Loader** (as the loaded content container) and its properties, not **Loader.content** directly. **№2**. Don't **Loader.unload()** what you just loaded. – Organis May 08 '21 at 14:58
  • @Nathaniel so does using a universal string to set `content.name = myString` solve your problem? – VC.One May 17 '21 at 13:27

1 Answers1

0

This is what I meant in the comments. Try something like this:

//... where you declare your variables, make them public to use in other functions...
public var myString = "";


//... later where you declare functions...
public function loadView(viewName:String, movieFileName:String):void
{
    var loader:Loader = new Loader();
    var url:URLRequest = new URLRequest(movieFileName);
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderComplete);
    //loader.name = viewName;
    myString = viewName; //# 1) update String here to re-access in next function...
    loader.load(url);
}

private function loaderComplete(e:Event):void
{
    var content:DisplayObject = LoaderInfo(e.target).content; // This returns the content I'm looking for, but I always get error 1074 if I try changing its name
    
    // content.name = loader.name; // This line always gives me error 1074
    content.name = myString; //# 2) set content name to whatever myString holds (ie the viewName)...
    
    addChild(content);
}
VC.One
  • 14,790
  • 4
  • 25
  • 57
  • Thanks, but no. The issue isn't accessing loader.name (which you replaced with myString). The issue is changing content.name, which Organis discovered is the root of the object I'm loading. You can't change the name of root. – Nathaniel May 18 '21 at 15:13