ActionScript Library Project vs. Flex Library Project - actionscript-3

I've got couple of issues from the nature of inconsistency between FlexLib Project and AS3 Lib Project in Flash Builder 4.7, AIR SDK 15, 16 and 17, Flex SDK 4.6.
Common thing for these is that FlexLib does not allow (syntax error highlighted) to build/compile pieces of code that are allowed in regular AS3Lib Project.
Please note that examples bellow are simplified, and there are real life use cases even if it's against good practices.
Internal classes above package
internal class Before
{
public function Before(){}
}
package
{
public class Main
{
public function Main()
{
}
}
}
In Flex Library Project this code causes:
1083: Syntax error: package is unexpected.
In regular ActionScript Library project it works perfectly fine, without a single warning.
Array key type greediness
var array:Array = [Boolean, Number, XML];
for(var c:Class in array)
{
if(c is Object) { trace('test') }
}
In Flex Library Project this code causes:
1067: Implicit coercion of a value of type String to an unrelated type
Class.
In regular ActionScript Library project it works perfectly fine, without a single warning.
Constant defined class
public static const FileClass:Class = String;
public function main():void
{
if('test' is Vector.<FileClass>)
{
trace('what?');
}
}
In Flex Library Project this code causes:
1120: Access of undefined property FileClass.
In regular ActionScript Library project it works perfectly fine, without a single warning.
I'd be very thankful if someone could say a word why is this happening or could give me a clue where to look for solution.

According to this, there are two different compilers involved:
Use Legacy Compiler
For ActionScript projects, Flash Builder uses the ActionScript Compiler (ASC) by default. If you are using Adobe Flex SDK 4.6 or an earlier version of the Flex SDK, select Use Legacy Compiler to use the older compiler.
I guess that explains the difference.
The following is an attempt to work around the problem.
I'm not too much into library projects.
From what I found in resources (the link above), these projects result in a .swc file.
I'm not too much into flex either.
Flex is "just" a framework written in actionscript.
Whether your library is an actionscript library or a flex library is not really a choice of the user, but what your code does.
If your library includes some flex components, I'd say it's a flex library project.
But if it is plain old actionscript, it is an actionscript library.
Let's say your library is an actionscript library.
You compile your library into an .swc file and be done with it.
Your are the one doing that compilation step, not the user of your library. I don't think it's their concern if they could perform this compilation.
What actually concerns them is whether their project that includes your library (the .swc file) compiles. And I guess that this will be the case, because the .swc will be used, not compiled.
After all, there's no choice to be made, if it is an actionscript library, because every flex project is an actionscript project. (but every actionscript project is a flex project)
Build your library project (whatever compiler works) and see if you can use the resulting .swc file in both an actionscript and a flex project.

Related

How do I avoid conflicts between haxe Type class and C# Type class?

I am developing Haxe code that I convert in C# and insert into a Unity project.
The conversion works fine and I am able to use the generated class when I import it alone in Unity.
To make it work, I have to bring in Unity the whole generated src folder, including the Type.cs file.
However, when I import the "Post Processing Stack" (a basic Unity extension) I get errors due to name Conflicts. The Type class is also a basic C# class and It is used by the Post Processing scripts.
The haxe-Type takes priority and breaks the compilation:
Assets/PostProcessing/Runtime/PostProcessingBehaviour.cs(406,30): error CS1502: The best overloaded method match for `System.Collections.Generic.Dictionary<Type,System.Collections.Generic.KeyValuePair<UnityEngine.Rendering.CameraEvent,UnityEngine.Rendering.CommandBuffer>>.Add(Type, System.Collections.Generic.KeyValuePair<UnityEngine.Rendering.CameraEvent,UnityEngine.Rendering.CommandBuffer>)' has some invalid arguments
Assets/PostProcessing/Runtime/PostProcessingBehaviour.cs(406,34): error CS1503: Argument `#1' cannot convert `System.Type' expression to type `Type'
I don't know if it is possible to solve this issue by playing around with C#/Unity/Mono search paths.
I as wondering wether it is more appropriate to (optionally) wrap all haxe top-level classes into the haxe namespace, or a special haxe-defaultnamespace, or prefix them for example to class HType.
Name conflicts for this basic types are likely to emerge in many other contexts, not only in Unity.
I found the solution in the Haxe documentation for C#:
https://github.com/HaxeFoundation/HaxeManual/wiki/Haxe-C%23
-D no-root generate package-less haxe types in the haxe.root namespace to avoid conflicts with other types in the root namespace
This way, all the classes that were at global level will be generated under namespace haxe.root.

Type was not found or was not a compile-time constant: Custom Class after switching IDEs

It seems that this is a fairly common error, but I was not able to find a solution for my exact problem. I was originally working in FlashBuilder, but my free trial expired and so I am attempting to switch to flashDevelop. Everything would build just fine in FlashBuilder, but I keep getting errors in FlashDevelop I have a custom class called MyCustomClass which extends EventDispatcher. I'm not allowed to be too specific with code, as this is for work, but I have something similar to this:
package myPackage{
import myPackage.MyCustomClass;
public class SecondClass extends EventDispatcher{
private var _fields:Vector.<MyCustomClass>;
[Bindable("fieldsChanged")]
public function get fields(): Vector.<MyCustomClass> { return _fields.slice(); }
}
}
I get the error Type was not found or was not a compile-time constant: MyCustomClass
on the fourth line of code. Any ideas?
Probably your source path is not setup in Flash Develop. In the project panel (View > Project Manager) select your source root directory (probably "src" since that is what Flash Builder creates by default) and right click and choose "Add Source Path". You can also setup your source paths in Project > Properties.. > Classpaths.

Static function in base class not wanting to call member functions on subclasses if using Flash Builder 4.7, instead of 4.6

Since yesterday, I've been trying to port an ActionScript Mobile project from Flash Builder 4.6 to Flash Builder 4.7, and I've run into a little bit of a problem that's probably a compiler bug. In FB 4.6, this works:
Temp.as:
package
{
import flash.display.Sprite;
public class Temp extends Sprite
{
public function Temp()
{
new StartMenu();
}
}
}
Screen1.as:
package
{
import flash.display.*;
internal class Screen1 extends Sprite
{
private static var m_vScreens:Vector.<Screen1> = new Vector.<Screen1>();
public function Screen1()
{
m_vScreens.push(this);
onScreenSizeDetermined();return;
var strFunction:String = "useSmallPortraitLayout";
for each (var screen:Screen1 in m_vScreens)
{
trace(1)
screen[strFunction]();
}
}
protected function useSmallPortraitLayout():void
{
}
private static function onScreenSizeDetermined():void
{
var strFunction:String = "useSmallPortraitLayout";
for each (var screen:Screen1 in m_vScreens)
{
trace(2)
screen[strFunction](); // Error thrown here in 4.7.
}
}
}
}
StartMenu.as:
package
{
public final class StartMenu extends Screen1
{
override protected function useSmallPortraitLayout():void
{
}
}
}
But in 4.7, it doesn't work. The error I get back is this:
ReferenceError: Error #1069: Property useSmallPortraitLayout not found on StartMenu and
there is no default value.
Now that being said, this can be fixed in one of at least two ways:
Use Flash Builder 4.6
Comment out onScreenSizeDetermined();return;, thereby using a member function to call useSmallPortraitLayout(), instead of a static function. This doesn't require using the constructor; it works just fine, as long as Screen1 is calling useSmallPortraitLayout() from pretty much any non-static method.
Unfortunately the static method will fail, even when it's called from outside the constructor and/or from a timed delay. One thing I don't specifically remember in 4.6, but I am seeing it in at least 4.7, is that using an unrelated class to call a static method directly through an instance won't compile - it has to be done in a staticky way in unrelated classes. Not that I do things like that in real code, but it does make me wonder if the relationship between static and non-static has intentionally changed.
This is probably just some trivial compiler bug specific to FB 4.7, and I would just go right back to 4.6, but pure ActionScript library projects are directly supported only in 4.7. (This is a mobile project, but I was going to add a library project to the solution.)
One thing to note is the code will not compile in FB 4.7 if the static function calls useSmallPortraitLayout this way:
screen.useSmallPortraitLayout();
It has to call it dynamically for it to even compile.
Is there an easy-enough fix for this? Has there been a little bit of syntactical weirdness that 4.6 has simply been overlooking this whole time? What's wrong, and what's a good solution/work-around?
UPDATE
If worst comes to worst, it does seem to work to partially replace the Vector.<Screen1> with a Vector.<Function>, and then just make calls to the members of the function vector, instead of to functions of the members of the Screen1 vector. (This is simplified from production code.) But that's just a fallback.
Also, something I wasn't paying a lot of attention to previously (specifically as far as this one problem goes), but BotMaster kind of brought it to my attention, is that in the process of going from FB 4.6 to FB 4.7, I also went from AIR 3.1 to AIR 3.4.
This is more a scope issue imo. Protected method can only be called within the instance scope and not within a static scope. Of course changing the modifier to public fixes the issue here. PO might argue that protected is wanted here but in reality if there is intention of directly calling a method on an instance outside the scope of that instance then logically that method needs to be public.
Btw FB 4.6 compiler is provided by the used AIR/FLEX SDK and so cannot behave differently from FB 4.7 using the same SDK.
Flash Builder 4.7 uses ASC 2.0 to compile ActionScript projects. From the release notes, emphasis added:
ASC 2.0 is a new compiler for ActionScript® 3.0 (AS3). It has stricter
adherence to the AS3 language specification, includes compilation
performance improvements, is more stable under memory pressure, and
contains some demonstration optimizations that can be optionally
enabled (in-lining, dead code elimination).
I suspect that the compiler sees useSmallPortraitLayout() is not referenced in your original code, and is eliminated from the ABC output.

getDefinitionByName "Variable Not defined" workaround

Ok so I have game data parser that creates a game out of data file basically, it is using extensively getDefinitionByName which has one problem if the class is not loading somewhere else it throw variable not defined error information=ReferenceError: Error #1065: Variable {MyClass} is not defined. to workaround it I am using a class that holds all the list of components and instantiate it to make these classes available to the compiler.
Ok the question part is there any more efficient way to do that or playing with compiler argument or something ?
Is there something like export in first frame in flash professional as a compiler argument ?
I think what you want is to have a library project with all those "callable" classes, and then reference that library project in your game.
In flash builder, for a library project, you can check which classes are compiled (and so available to getDefinitionByName). (info here)

Actionscript-3 prototype inheritance

Basically, I want to modify the constructor of the Object
class. Since every class extends Object, I hope whenever any
object of any class is instantiated, the modified function will
be called.
So I did this :
Object.prototype.constructor = function (){
trace("it was called;");
};
and put a breakpoint on the trace statement.
But it didn't stop there.
The trace statement did not get executed also.
Any solutions/suggestions?
In which context are you coding?
If you're using the Flex Compiler MXMLC (default, if you're in FlashBuilder), than you could add the compiler option -es. This should make AS3 feel more like AS2 and JS and support the prototype chain inheritance.
-compiler.es alias -es
"use the ECMAScript edition 3 prototype based object model to allow dynamic overriding of prototype properties. In the prototype based object model built-in functions are implemented as dynamic properties of prototype objects. (advanced)"
I don't know, if this plays well with all the extensions Adobe added to the ECMA Script standard, like packages, namespaces and classes. But you could give it a try.
I don't think it's possible in AS-3, but it was in AS-2.