How to use robotlegs and signals without flex ie. pure as3 - actionscript-3

I'm try to put together a bare bones robotlegs-signals project but all the samples I've seen are flex ie
Index.mxml
<context:SignalCafeContext contextView="{this}"/>
SignalCafeContext.as
public class SignalCafeContext extends SignalContext
{
override public function startup():void
{
injector.mapSingleton.... etc etc
}
}
Is this possible to replace the mxml with another .as file - normally I would pass from the main class
context = new MyContext(this); // where this is DisplayObjectContainer
however super() takes no parameters in SignalContext so I might be missing something.
More Info:
libs:
as3-signals-v0.5.swc
robotlegs-framework-v1.03.swc
signals-extensions-SignalsCommandMap.swc

What you're trying would work in the current RobotLegs v.1 release (v.1.5.2). Context and its subclass SignalContext take optional params. The first param is your context view:
contextView:DisplayObjectContainer = null
Here's the SignalContext class extending Context.
Note, Context in Robotlegs 2 does not take parameters (source).

I imagine you need to start with a actionscript project instead of a flex project in FlashBuilder first.
Yes, your right, you just extend the Context class, as you can see in the basic HelloFlash robotlegs demo

mxml tags are just shorthand for actionscript classes. So I'd imagine you could start by taking a look at the auto-generated actionscript code. There is a flash builder compiler option that will let you see this. Using that as a template, you probably can't go too far wrong.

Related

Need some help getting started with OOD in ActionScript 3

So being new to AS3 but not development in general, during a recent project that I just started I hit an immediate snag where my normal method of OOD is causing errors in AS3.
I created a layer in Adobe Flash called code just to keep everything separate and in frame one under actions I used the following code to get started:
var GameContainerSize:int = 400;
class GameInfo {
var GameID:int;
var HomeTeam:String;
var VisitingTeam:String;
function GameInfo()
{
}
}
This simple code immediately causes an error though
Scene 1, Layer 'Code', Frame 1, Line 4 1131: Classes must not be nested.
And my best guess is this is because the timeline and all code on it exists within a class already. So what should I be doing if I want to develop this program using class objects, or is this even possible in flash?
You can't define classes on the timeline. Each timeline is exported as a class, var and function declarations become members of the class, and frame code is moved to its own frame functions which are called when the timeline reaches that frame. Thus the error is saying "you can't put a class in a class" because the timeline already is a class.
To define classes you must use external .as files with package blocks:
// GameInfo.as
package {
public class GameInfo {
public var GameID:int;
public var HomeTeam:String;
public var VisitingTeam:String;
public function GameInfo(){ }
}
}
In Flash Pro you can link a class to a timeline (document or symbols). Such a class must extend Sprite or MovieClip.
You can also refer to any of your classes from any frame script. For example, you could put on frame 1 of your main timeline:
var gameInfo:GameInfo = new GameInfo();
Typical OOP would involve using external .as class files for almost everything, with only minimal function calls on your timeline frames, like stop() at the end of a timeline or calling a custom function you've added to the class linked to the timeline.
I created a layer
That's not ideal. The problem is that it will not get you any closer to understanding the code, because it isn't code. It's a feature of the flash authoring environment. You might as well spend a day with the drawing tool drawing something.
to keep everything separate and in frame one under actions
Organisation is important, but layers aren't the way to go. As each class definition goes into its own external file, you have to create additional files anyway if you want to create more classes. And you want to create more classes because having only one is horrible object oriented design. Being consistent here is important. That's why people in the comments suggested to use a document class and have no code on any frames. All code is organised in classes. No exceptions1.
Having said all that, I highly advice against using Adobe Flash to learn As3. There's too much obfuscation going on behind the scenes. If you want to learn how to code As3, use a code editor. (or plain text editor + compiler if you prefer). Learning what settings dialog has to be adjusted in order to get what you want is not going to get you any closer to understanding OOD in As3.
I also see package, is this kind of like a namespace and does it need to be named, if not what is its purpose?
No, packages are packages and namespaces are namespaces. Apples and oranges.
Packages are used to organize classes just like a structure of
folders is used to organize the .as fiels of those classes. In fact,
the package is pretty much exactly that folder structure, for example:
flash.display is for all display related classes
flash.events is for events
A namespace allows you to control access to members of a class. Namespaces are very rarely used in As3. Here's an article from grant skinner about namespaces. Personally, I never needed to use namespaces. If you are jsut getting started, you can very well ignore them for now.
That sounds perfect! except I cannot get it to launch on my Win10 machine. I may just end up outsourcing this at this ratio
flash develop is the alternative editor. It's free, fast and lightweight.
my normal method of OOD
You want to extend your definition of normal with
always explicitly specify the access control modifiers
member names start with small letters
public class GameInfo {
private var gameID:int;
private var homeTeam:String;
private var visitingTeam:String;
function GameInfo()
{
}
}
1admittedly, there are top level functions that are pretty much free floating functions without a class. If you want to do oop, this is not what you want. It's for the occasional independent utility function. Stick to classes for now.

Actionscript 3 getDefinitionByName not seeing classes

I've worked around this with a hack for now, but would rather know if there's a right way to do it. I have a function that churns out MovieClips, which are tiles for a map that I then attach to the stage. It determines which class of tile to use based on a string variable, like this:
// symbolID holds our class name, determined by logic above
var newClass:Class = getDefinitionByName(symbolID) as Class;
var newtile:MovieClip = new newClass();
This works, but only if an instance of the class already exists somewhere else in the code. It could be anywhere-- in the document class, in some buried function of a helper class, it doesn't seem to matter. If not, Flashdevelop throws error 1065, "Variable (the variable) is not defined". I mention that I'm using Flashdevelop because it seems like it might be compiler-specific, but I'm not sure.
My hack fix is to do this:
var a:baseTile;
a as anotherTile;
a as aThirdTile;
and so on, which works, but definitely isn't ideal if I'm going to have hundreds of these tile classes eventually.
Edit: I should add that these movieclips are coming from a .swc file, which comes from Flash Professional.
You have to use the 'hack'.
getDefinitionByName() can only work with classes that exist at runtime. Unfortunately, if you don't make use of a class, it won't be compiled and won't exist at runtime.
Library symbols make getting around this a little easier. If you check the box that has them available automatically at a given frame, you can just make sure your getDefinitionByName() calls are done during or after that frame.
While SWC libraries can include specific classes to include in the build path, Flash compiler will not link unreferenced classes to a SWF; therefore, requires a linkage library.
Example linkage to retain classes:
/** linkage library */
private static const classA:ClassA;
private static const classB:ClassB;
private static const classC:ClassC;
Another option would be to load the classes from a RSL (Runtime Shared Library).
Basically yes, you need to have a strict reference of that class somewhere in your code. You can even make that reference "unreferenced" elsewhere. I have a hundred of classes like this, and I had to make a single Array of these classes, located somewhere inside the project. I have placed it aside the function that calls getDefinitionByName() to make sure the classes are available in that function.
private static const dummy:Array=[Rock01, Rock02,...,Gem01,Gem02,...];
So you can use such an Array listing all your tiles that you have in your project and want to be accessible by getDefinitionByName().

dynamic class in AS3 : listening to property creation?

I'm currently working on a project that involve a re-implementation of the Array class.
This object needs to be an Array for compatibility reasons, while I also need to keep control of what is written in.
I cannot seem to find any way to check property creation inside of a dynamic object in AS3. Something that would work like the Event.ADDED_TO_STAGE but, like, ClassEvent.PROPERTY_ADDED.
I override methods like push, splice etc, but I cannot control direct assignation : MyArray[i] = ...
Is such a thing even possible ?
Of course, I could make some kind of validations elsewhere, but this would involve accessing a part of the code I cannot modify.
Thanks for your time !
I'm not sure I follow you entirely but you may be looking for the Proxy class:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/Proxy.html
An example at the bottom shows you how you can override direct assignment:
override flash_proxy function setProperty(name:*, value:*):void {
_item[name] = value;
}
Using this you would be able to dispatch a custom event that would be fired any time an item was added to your ProxyArray

What is the data type from the source of an image

another flashbuilder brainbreaker for me...
I have a class with a contstructor that should only change the source of an image.
[Bindable]
[Embed(source='../pictures/test.jpg')]
private var _picture:Class;
public function Test(newSource:*****)
{
_picture.source = newSource;
}
(the image is not an image, but a class, I am aware of this, it is meant to be so :-) )
The problem is that when I call the constructor, let's say:
var test:Test = new Test(pictureAtStage.source);
Flashbuilder will give an error, becouse I can't tell the compiler what data type "newSource" at the constructor will have...
*edit:
When i use _picture.source, the embedded source does not seem to be changed...?
Anyone knows an answer?
Are we talking about mx.controls.Image? if so, then the source of an image can be: a Class, a Bitmap (not a BitmapData), a String (in which case it is assumed that you wanted to load it instead of using an embedded one). If you want to find a common denominator for all these, then Object is that class, however, I would rather limit it to something particular to your use case.
However, if I may advise anything... don't use mx.controls.Image, it's too bloated, even for Flex framework. If it must be a UIComponent - extend UIComponent and let the source be of type BitmapData - this way you will be able to manage resources better - you could reuse the same actual image for example. You could then use graphics property of the control to display the image.
Another advise, if you are still here :) Don't use [Bindable], especially the short version of it, especially not on a private variable - you will save yourself the frustration of countless hours of debugging it... Besides, in your case you aren't going to change the value of that variable anyway...
Are you still here? Well, don't use [Embed] on variables, use it on class definition - slightly more work for you, but this will, potentially, make your code more portable. If you embed on class the compiler will not generate a silly "something-something-Asset" class, it will use Bitmap or BitmapData - whichever your class extends. Thus, you will not introduce a dependency on Flex framework, and, in general, you will have more control over your code.
EDIT: the above was written assuming that _picture (class) variable and _picture (some variable used in a function) are not the same thing. But if they are the same thing, then Class class is dynamic, which means that you can add to it properties at runtime (don't know why, it's a design decision by Adobe...), however, the compiler will act as if it's not possible, so you would work around that by adding the property through reflection:
var _picture:Class = Sprite;
_picture["source"] = whatever;
trace(Sprite["source"]);
This is indeed slightly confusing, It will be of the type BitmapAsset which extends Bitmap. So any of those will work.
Since I'm very new to flashbuilder I didn't see the obvious solutions...
The solution for the first part of my question (before the edit):
Setting the data type to Object did the trick:
[Bindable]
[Embed(source='../pictures/test.jpg')]
private var _picture:Class;
public function Test(newSource:Object)
{
_pucture.source = newSource;
}

Possible to add an EventListener to a function for Actionscript 3?

I'm trying to setup something like Aspect Oriented Programming in Actionscript 3, basically the only thing I need to be able to do is something like this:
SomeClass.getMethod("methodName").addEventListener(afterMethodExecuted, function() {
//run code
});
This way I can run code after (or before) any method in any class has run, allowing numerous new possibilities.
How should I implement this?
You can write a wrapper on a method. The BindUtils class of the Flex library does just that using the ChangeWatcher. It does so by wrapping a property but in ActionScript a method is just a property.
I suggest reading the code for those methods ($FLEX_ROOT/sdks/4.0.0/frameworks/projects/framework/src/) to get an idea of how you can do the same.
You might also be interested in the FunctionReturnWatcher.