pass class as parameter, then instantiate from class - actionscript-3

I've done this before, but i can't quite remember the syntax.
What i've got (simplified):
function createText(clazz:Class)
{
var font:Font = new clazz(); //throws Instantiation attempted on a non-constructor.
}
I believe this can be done without using getQualifiedClassName, but its been a long time. Any help appreciated.

You are probably passing null to the function.
package
{
import flash.display.Sprite;
public class ClassTest extends Sprite
{
function ClassTest()
{
makeObject(Object);
makeObject(Sprite);
makeObject(null);
}
private function makeObject(type:Class):void
{
trace(typeof type);
var obj:* = new type();
trace(typeof obj);
trace("");
}
}
}
This outputs:
object
object
object
object
object
TypeError: Error #1007: Instantiation attempted on a non-constructor.
at ClassTest/makeObject()
at ClassTest()

how are you passing the class to the function ?
the calling line should have trown an error in the first place if the wanted class wasn't available, this is weird.
can you post the real code ?
here a trick for loading a class compiled in an external swf
var clazz:Class = this.yourLoader.contentLoaderInfo.applicationDomain.getDefinition("yourClassName") as Class;

Turns out I hadn't given the font a class name in CS3. So yes,I was passing null.

Related

why cant I access a public method?

When I'm using from Main.as:
appleObject.setX(50);
to call the function which is in Floater.as:
public function setX(positionX):void {
trace("hello");
}
from Floater.as, but I get the error 1120: Access of undefined property appleObject.
Main.as: http://pastebin.com/CHMdYM8r
Floater.as: http://pastebin.com/BV4PbfXe
To elaborate on what has been said in the comments:
In AS3 class files, all functional code needs to be wrapped in a method (function).
So when the compiler sees this line:
appleObject.setX(50);
It is expecting it to be either a variable declaration, or a function declaration. Move that line inside a function, and the compiler error should go away. As suggested by #DodgerThud in a comment, putting it in the constructor would make a lot of sense:
public function Main():void {
score.text = "hello";
addChild(bananaObject);
addChild(appleObject);
appleObject.setX(50);
//...rest of code
As an aside, it's also a good practice to not instantiate complex objects in the class scope. So this would be even better:
private var appleObject:Floater;
public function Main():void {
score.text = "hello";
addChild(bananaObject);
appleObject = new Floater();
addChild(appleObject);
appleObject.setX(50)

How AS3 class files.as work together with FLA file?

I have two questions: Can i write app using just *.as files, and then compile them somehow in SWF? (i am making myself a webpage now)
Secondly, please look at the code, my problem is the same - I can't render text field onto stage, to be visible.
Flash say's 'undefined method addChild.' and 'Access of undefined property tekstuKaste through a reference with static type Class.'
This is a constructor type class inic which kinda serves for initialization, cos all i do is, I make an instance OF THIS class in FLA file by ActionScript, and expect, all application to work.
package {
import pacinas.visuals.*;
import pacinas.visuals.AE_kanva;
public class inic {
public function inic() {
trace("===========");
trace("inicializēt un izsaukt visu no Kanvas klases");
trace("===========");
trace(" ");
var kanvas:AE_kanva = new AE_kanva();
trace(" ");
kanvas.varis();
trace(" ");
trace("===========");
trace("inicializēt un izsaukt visu no Lauki klases");
trace("===========");
trace(" ");
var laukiTxt:BE_tekstaLaukiPrimitive = new BE_tekstaLaukiPrimitive();
trace("");
laukiTxt.simpleText();
addChild(BE_tekstaLaukiPrimitive.tekstuKaste);
}
}
}
There is another EXTERNAL CLASS By whom i hoped to place a rectangles - that does not work too. Example:
package pacinas.visuals
{
import flash.display.Sprite;
public class AE_kanva extends Sprite
{
public function AE_kanva()
{
var kvad:Shape = new Shape();
kvad.graphics.beginFill(0xFF0000);
kvad.graphics.drawRect(0, 0, 100,100);
kvad.graphics.endFill();
addChild(kvad);
trace("konstruktors - zīmē kanvu");
}
public function varis()
{
trace("te glabaas variaabljus");
var ff:int = 4;
var dd:int = 8;
}
}
}
And here is class i hoped will make text box for me (to fill it with XML later)
package pacinas.visuals
{
import flash.text.*;
import flash.display.Sprite;
public class BE_tekstaLaukiPrimitive extends Sprite
{
public var tekstuKaste:TextField = new TextField();
private var kontinents:String = new String ("XML SATURU CMON! a123");
public function BE_tekstaLaukiPrimitive():void
{
trace("teksta rāmis = konstruktora klase");
addChild(tekstuKaste); <--CAN'T GET THIS TO WORK!!!
tekstuKaste.text = kontinents;
}
public function simpleText()
{
trace("nekonstruktora f-cija no Teksta lauki");
}
}}
p.s. I do not use document Class. Ok I will if it's needed. But how?
Can I write app using just *.as files, and then compile them somehow into a SWF?
Yes - using the Flex SDK you can write pure ActionScript and compile it down into a working SWF. FlashDevelop is a good IDE that takes advantage of this.
You will however need to understand how the document class works.
Flash says undefined method addChild. and Access of undefined property tekstuKaste through a reference with static type Class.
In your code, this line is causing your issue:
addChild(BE_tekstaLaukiPrimitive.tekstuKaste);
The first error undefined method addChild is because your class inic does not extend a class that implements the method addChild(). DisplayObjectContainer defines this method, so you'll want to extend that as a minimum, like this:
public class inic extends DisplayObjectContainer
The second error is because you're attempting to access a property of the class BE_tekstaLaukiPrimitive as if it were static. I suspect what you actually wanted to do was this:
addChild(laukiTxt); // laukiTxt is the instance you created.

AS3 Access stage object in singleton returns null

I know singletons are sensitive subjects, but I really don't want to hear anything about that, or what you think about this implementation. This question is not about that.
So, I have implemented a singleton using a static var with the instance.
private static var instance:SomeClass = new SomeClass();
public static function getInstance():SomeClass {
return instance;
}
SomeClass is a class in the library, and inside that one there some instance called someSymbol.
For some reason, when I use SomeClass as a singleton, every time I want to access someSymbol I get Cannot access a property or method of a null object reference. But if I implement SomeClass with regular instantiation the error disappears.
I've tried accessing someSymbol in different ways but I always get the error.
someSymbol.rotation = 0;
and also
var aSymbol = getChildByName("someSymbol");
aSymbol.rotation = 0;
and also
trace(someSymbol); // null
trace(this['someSymbol']); // null
trace(SomeClass.instance.someSymbol); // throws error
So why do I get null when using this singleton implementation, and not when instantiating the class as usual?
Edit:
Thanks to #Marty Wallace answer, I changed my singleton implementation and now it works.
So, instead of instantiating the instance this way:
private static var instance:SomeClass = new SomeClass();
I instead instantiate it the first time getInstance() is called, as #Marty does it.
I don't know exactly what is going on behind the curtains, but it seems as if SomeClass wasn't fully exported when instantiating before the document class is running.
Your example is working fine for me:
public class Singleton
{
private static var _instance:TestClip;
public static function get instance():TestClip
{
if(_instance === null) _instance = new TestClip();
return _instance;
}
}
And TestClip has an inner MovieClip with the instance name inner:
trace(Singleton.instance.inner); // [object MovieClip]
Do you have any luck if you make a class for SomeClass and make a getter for someSymbol like this?
public function get someSymbol():MovieClip
{
return this["someSymbol"];
}

As3 Vector<T> parametric TYPE

I have one vector instance and I'm exporting swf with Flash Player 10/10.1.
I want initialise it with a parametric type. I tried as follow:
var someType:Class = MyCustomClass;
var v:Vector.<someType> = new Vector.<someType>();
But it doesn't work!!
There is a way to do this?
I hope question is clear :-)
Thanks in advance!
someType is the instance of the class type; whereas Vector is a container of that type.
This should be:
var v:Vector.<MyCustomClass> = new Vector.<MyCustomClass>();
Otherwise, I've noticed Haxe would compile this as:
var v:Vector.<Object> = new Vector.<Object>();
Flash polymorphism is lacking, if you had class A and class B, and attempted to push them to a vector of type Class you would receive an error:
Example
package
{
import flash.display.Sprite;
public class test extends Sprite
{
public function test()
{
var v:Vector.<Class> = new Vector.<Class>();
var a:A = new A();
var b:B = new B();
v.push(a);
v.push(b);
}
}
}
Error:
TypeError: Error #1034: Type Coercion failed: cannot convert A#43a2ff1 to Class.
Jason's right. You can't do this. I'm sorry. I ran into the same problem a while back.
Dynamically instantiate a typed Vector from function argument?
Sucks, doesn't it? :-)

Re-defining named functions at runtime

What I am trying to do is kind of odd, but I am wondering if anyone can come up with a clever way to do what I want to do. Basically, I want to re-define a named function at runtime. I can do this with anonymous functions, but I can't figure out a way to do it for named functions. I want to do this so that I can implement a "spy" functionality on an object for a testing framework (a port of Jasmine to Flex).
Take, for instance, this class:
public class TestClass
{
public var anonymous:Function = function():void {
trace("original anonymous");
};
public function named():void {
trace("original named");
}
}
I can easily re-define the anonymous function because it is just a variable. Javascript uses this idiom a lot.
var testClass:TestClass = new TestClass();
testClass.anonymous = function():void { trace("overridden anonymous"); }
BUT, when I do the same thing for named functions, you get a compile-time error:
// Does not compile
testClass.named = function():void { trace("overridden named"); }
I tried to make it a bit more "squishy" but this leads to a runtime failure "Cannot assign to a method named on TestClass".
// Compiles with runtime failure
testClass["named"] = function():void { trace("overridden named"); }
Can anyone more clever than I come up with a way to hack this? Can the bytecode be hijacked? Something?
I want to modify an object, not a
class
But object doesn't contain functions, only non-static variables. I tried to use prototype property and replace method there, but original method still gets called instead of injected one.
About "hack" bytecode, do you mean "hack" already loaded SWF in runtime? I think it's not possible. I'm sure, though, you can parse SWF with something like as3swf, find method in bytecode, replace it and save result in new SWF.
I had an idea bout making a function "cache" . This might work with what you need.
Let's say you have a class "Car" with a method you need to redefine at runtime:
public class Car extends Sprite
{
private var functionCache:Function;
public function Car()
{
super();
}
public function flexibleFunction(functionBody:*=null):void{
if(functionBody is Function){
functionBody.call();
functionCache=functionBody;
} else {
functionCache(functionBody);
}
}
}
Usage:
public class Main extends Sprite
{
private var car:Car;
public function Main()
{
car = new Car();
car.flexibleFunction(function(){trace("redefine test #1")});
car.flexibleFunction();
car.flexibleFunction(function(doParametersWork:String="let's see"){trace("redefine test #2: " + doParametersWork);});
car.flexibleFunction("yes they do");
car.flexibleFunction();
}
}
an easy way to accomplish what you want is to simply pass a new function to the original function and execute it from there:
package
{
//Imports
import flash.display.Sprite;
//Class
public class RedefineFunction extends Sprite
{
//Constructor
public function RedefineFunction()
{
originalFunction();
originalFunction(redefinedFunction);
}
//Original Function
public function originalFunction(redefinition:Function = null):void
{
if (redefinition != null)
redefinition();
else
trace("Original Function Definition");
}
//Redefined Function
private function redefinedFunction():void
{
trace("Redefined Function Definition")
}
}
}
traces:
Original Function Definition
Redefined Function Definition