AS3 internal and custom namespaces - actionscript-3

I have the following packages:
spark
spark.engine
Within spark I have a class SeCore; and within spark.engine I have SeStepper and SeKeyboard.
What I'm trying to achieve is have SeCore as being the only class that can create an instance of SeStepper or SeKeyboard. This can be achieved by moving SeCore into the spark.engine package and making the other two classes internal, but I'd like to have SeCore in the spark package if possible.
I've tried making my own namespace to handle this, like so:
package spark.engine
{
import spark.namespaces.spark_core;
use namespace spark_core;
spark_core class SeStepper extends SeObject
{
//
}
}
However I get the error:
1116: A user-defined namespace attribute can only be used at the top
level of a class definition.
Are there any other approaches I can take to achieve what I'm after?

99% of the time, marking anything as 'internal' is a bad idea. It's better to have a naming convention for 'off-limits' classes and members, and allow developers to go there at their own risk. Marking things as 'internal' or 'private' is something that should only be done rarely, and with great forethought.
However, you could enforce this behavior at run time by using a read-only property in SeCore and checking its value from SeStepper and SeKeyboard.
Following is pseudocode, haven't used AS3 in a while.
In SeCore
private var _createAuthorized = false;
public function get CreateAuthorized():boolean {return _createAuthorized;}
private function createSeStepper(){
_createAuthorized = true;
var obj = new SeStepper(this)
_createAuthorized = false;
return obj;
}
in SeStepper
public function SeStepper(core:SeCore){
if (!core.CreateAuthorized) throw new Error("Only SeCore can do this");
}

I can't agree with the answer, i mean making things public is way to invite hackers. I can execute any public functions in any flash running on my computer in any context i want, i can even override their execution in memory since they are easy to find, whereas doing something like that with private/internal functions is almost impossible.

Related

When using the 'Class' datatype, how can I specify the type so I only accept subclass of a specific class?

I've got a method that accepts a parameter of type Class, and I want to only accept classes that extend SuperClass. Right now, all I can figure out to do is this, which does a run-time check on an instance:
public function careless(SomeClass:Class):void {
var instance:SomeClass = new SomeClass();
if (instance as SuperClass) {
// great, i guess
} else {
// damn, wish i'd have known this at compile time
}
}
Is there any way to do something like this, so I can be assured that a Class instance extends some super class?
public function careful(SomeClass:[Class extends SuperClass]):void {
var instance:SuperClass = new SomeClass();
// all is good
}
If you are going to instantiate it anyway, why not accept an object instead which allows you to type it to :SuperClass?
careless(SomeClass);
//vs.
careless(new SomeClass);
Not too much of a problem there as far as your code goes.
There are a few differences though:
The object has to be created, because an object is required. If your function does not instantiate the class under some circumstances, this can be a problem. Additional logic to pass either an object or null can bloat the function call.
If you cannot call the constructor outside that function, it won't
work either.
All that is solved by the factory pattern. Pass a factory as the parameter that produces SuperClass objects.
function careful(factory:SuperClassFactory)
Your requirements:
I want to only accept classes that extend SuperClass
and
I need to pass in a Class so that it can be instantiated many times
by other objects later
Can be met by passing in an instance of the class you need, and using the Object.constructor() method.
public function careful(someInstance:SuperClass):void {
//you probably want to store classRef in a member variable
var classRef: Class = someInstance.constructor();
//the following is guaranteed to cast correctly,
//since someInstance will always be a descendant of SuperClass
var myInst:SuperClass = new classRef() as SuperClass;
}
More reading here.
You can't do that in ActionScript 3. In languages like C# you can do something like (forgive me if the syntax is off):
public void Careless<T>() where T : SuperClass
But AS3 does not have 'generics'. Unfortunately the only way I know how to do what you want is the way you have already done.
A pattern that might be more suitable for your use case might be something like:
class SuperClass
{
public static function careless():void
{
var instance:SuperClass = new SuperClass();
// ...
}
}
The only way to have static type checking in ActionScript 3 is to provide an instance of a class.
It is possible but it's expensive. You can use on a Class (not instance) the:
flash.utils.describeType
You then get an XML with a bunch of information including inheritance for that class. Like I said it's an expensive process and probably creating an instance and checking it will be in most cases faster.

Migrating a simple Robotlegs application (form 1.5 to 2)

I'm new to Robotlegs, and somewhat struggling with the first steps.
To learn the ropes I followed the first part of Joel Hooks' introduction and am now trying to create the same in RL2.
My current questions/problems are:
Which method has replaced the startup() in the Context
In the Context I can no longer just use "mediatorMap"; Do I need to create a MediatorMap Instance for this?
In the few RL2 example out there, many devs use the IConfig to configure their main Context; is this required, a good convention or optional.
..and in which way, is the Context 'configured' through this?
I spent the best part of the day looking for solutions. I apologize if I missed the obvious.
Thanks in advance for any incite.
part of the main class (mxml)
xmlns:context="contexts.*"
<fx:Declarations>
<rl:ContextBuilder>
<context:HelloWorldContext/>
</rl:ContextBuilder>
</fx:Declarations>
and the (non-compling) context .as
public class HelloWorldContext extends Context
{
public function HelloWorldContext()
{
this.install(MVCSBundle);
this.configure(HelloWorldConfig);
mediatorMap.map(ButtonView).toMediator(ButtonMediator); // Error: mediatorMap not defined
}
}
Which method has replaced the startup() in the Context In the Context
use context.install to install extension that you want to use.
most common one is MVCSBundle.
use context.configure with (new ContextView) argument will start your context initialization.
I can no longer just use "mediatorMap"; Do I need to create a
MediatorMap Instance for this?
you can inject IMediatorMap anywhere you need it, like in config
[Inject]
public var injector:IInjector;
[Inject]
public var mediatorMap:IMediatorMap;
[Inject]
public var commandMap:ISignalCommandMap;
In the few RL2 example out there, many
devs use the IConfig to configure their main Context; is this
required, a good convention or optional. ..and in which way, is the
Context 'configured' through this?
you can create your own config. Usually, in there you will map your commands, mediators and injections. You create one [PostConstruct] method which will call all theese stuff:
If you implement IConfig inside config, you dont need [PostConstruct] tag, because robotlegs will call configure function automatically once the dependencies have been injected.
[PostConstruct]
public function init():void {
context.logLevel = LogLevel.DEBUG;
// injector.fallbackProvider = new DefaultFallbackProvider();
mapSignalCommands();
mapMediators();
mapInjection();
context.afterInitializing(afterInit);
}
in your case you will have
_context:IContext;
public function MainApp()
{
_context = new Context();
_context.install(MVCSBundle);
_context.configure(HelloWorldConfig,new ContextView(this));
}
mediator thing goes to config on mapMediators();

Robotlegs wiring up dependencies that belong to a base class

I'm using robot legs, I've got a bunch of ServiceResponses that extends a base class and have a dependency on a Parser, IParser. I need to wire in a parser specific to the subclass. Here's an example:
ModuleConfigResponse extends SimpleServiceResponse and implements IServiceResponse.
The initial part is easy to wire in the context, here's an example:
injector.mapClass(IServiceResponse, ModuleConfigResponse);
injector.mapClass(IServiceResponse, SimpleServiceResponse, "roomconfig");
..etc
Each Response uses a parser that is used by the baseclass:
injector.mapValue(IParser, ModuleConfigParser, "moduleconfig");
injector.mapValue(IParser, RoomConfigParser, "roomconfig");
The question is how to tie these together. The base class could have:
[Inject]
public var parser : IParser
But I can't define the type ahead of time. Im wondering if there a nice way of wiring this in the context. For the moment I've decided to wire this up by instanciating responses in a ResponseFactory instead so that I pay pass the parser manually in the constructor.
injector.mapValue(IParser, ModuleConfigParser, "moduleconfig");
I realised that not everything can be mapped in the context, RL trapped me into this way of thinking. But I've realised that its far better to map a factory to produce these objects which have very specific dependencies, than littler the codebase with marker interfaces or strings :)
one solution is to have the following in your base class:
protected var _parser : IParser
Then for instance in ModuleConfigResponse
[Inject(name='moduleconfig')]
public function set parser( value : IParser ) : void{
_parser = value;
}
But TBH, using named injections is STRONGLY discouraged, you might as well use a marker interface:
public interface IModuleConfigParser extends IParser{}
the base class stays the same, but ModuleConfigResponse would then use:
[Inject]
public function set parser( value : IModuleConfigParser ) : void{
_parser = value;
}

How can I create a subclass that takes in different parameters for the same function name?

So I have made this simple interface:
package{
public interface GraphADT{
function addNode(newNode:Node):Boolean;
}
}
I have also created a simple class Graph:
package{
public class Graph implements GraphADT{
protected var nodes:LinkedList;
public function Graph(){
nodes = new LinkedList();
}
public function addNode (newNode:Node):Boolean{
return nodes.add(newNode);
}
}
last but not least I have created another simple class AdjacancyListGraph:
package{
public class AdjacancyListGraph extends Graph{
public function AdjacancyListGraph(){
super();
}
override public function addNode(newNode:AwareNode):Boolean{
return nodes.add(newNode);
}
}
Having this setup here is giving me errors, namely:
1144: Interface method addNode in namespace GraphADT is implemented with an incompatible signature in class AdjacancyListGraph.
Upon closer inspection it was apparent that AS3 doesn't like the different parameter types from the different Graph classes newNode:Node from Graph , and newNode:AwareNode from AdjacancyListGraph
However I don't understand why that would be a problem since AwareNode is a subClass of Node.
Is there any way I can make my code work, while keeping the integrity of the code?
Simple answer:
If you don't really, really need your 'addNode()' function to accept only an AwareNode, you can just change the parameter type to Node. Since AwareNode extends Node, you can pass in an AwareNode without problems. You could check for type correctness within the function body :
subclass... {
override public function addNode (node:Node ) : Boolean {
if (node is AwareNode) return nodes.add(node);
return false;
}
}
Longer answer:
I agree with #32bitkid that your are getting an error, because the parameter type defined for addNode() in your interface differs from the type in your subclass.
However, the main problem at hand is that ActionScript generally does not allow function overloading (having more than one method of the same name, but with different parameters or return values), because each function is treated like a generic class member - the same way a variable is. You might call a function like this:
myClass.addNode (node);
but you might also call it like this:
myClass["addNode"](node);
Each member is stored by name - and you can always use that name to access it. Unfortunately, this means that you are only allowed to use each function name once within a class, regardless of how many parameters of which type it takes - nothing comes without a price: You gain flexibility in one regard, you lose some comfort in another.
Hence, you are only allowed to override methods with the exact same signature - it's a way to make you stick to what you decided upon when you wrote the base class. While you could obviously argue that this is a bad idea, and that it makes more sense to use overloading or allow different signatures in subclasses, there are some advantages to the way that AS handles functions, which will eventually help you solve your problem: You can use a type-checking function, or even pass one on as a parameter!
Consider this:
class... {
protected function check (node:Node) : Boolean {
return node is Node;
}
public function addNode (node:Node) : Boolean {
if (check(node)) return nodes.add(node);
return false;
}
}
In this example, you could override check (node:Node):
subclass... {
override protected function check (node:Node) : Boolean {
return node is AwareNode;
}
}
and achieve the exact same effect you desired, without breaking the interface contract - except, in your example, the compiler would throw an error if you passed in the wrong type, while in this one, the mistake would only be visible at runtime (a false return value).
You can also make this even more dynamic:
class... {
public function addNode (node:Node, check : Function ) : Boolean {
if (check(node)) return nodes.add(node);
return false;
}
}
Note that this addNode function accepts a Function as a parameter, and that we call that function instead of a class method:
var f:Function = function (node:Node) : Boolean {
return node is AwareNode;
}
addNode (node, f);
This would allow you to become very flexible with your implementation - you can even do plausibility checks in the anonymous function, such as verifying the node's content. And you wouldn't even have to extend your class, unless you were going to add other functionality than just type correctness.
Having an interface will also allow you to create implementations that don't inherit from the original base class - you can write a whole different class hierarchy, it only has to implement the interface, and all your previous code will remain valid.
I guess the question is really this: What are you trying to accomplish?
As to why you are getting an error, consider this:
public class AnotherNode extends Node { }
and then:
var alGraph:AdjacancyListGraph = new AdjacancyListGraph();
alGraph.addNode(new AnotherNode());
// Wont work. AnotherNode isn't compatable with the signature
// for addNode(node:AwareNode)
// but what about the contract?
var igraphADT:GraphADT = GraphADT(alGraph);
igraphADT.addNode(new AnotherNode()); // WTF?
According to the interface this should be fine. But your implemenation says otherwise, your implemenation says that it will only accept a AwareNode. There is an obvious mismatch. If you are going to have an interface, a contract that your object should follow, then you might as well follow it. Otherwise, whats the point of the interface in the first place.
I submit that architecture messed up somewhere if you are trying to do this. Even if the language were to support it, I would say that its a "Bad Idea™"
There's an easier way, then suggested above, but less safe:
public class Parent {
public function get foo():Function { return this._foo; }
protected var _foo:Function = function(node:Node):void { ... }}
public class Child extends Parent {
public function Child() {
super();
this._foo = function(node:AnotherNode):void { ... }}}
Of course _foo needs not be declared in place, the syntax used is for shortness and demonstration purposes only.
You will loose the ability of the compiler to check types, but the runtime type matching will still apply.
Yet another way to go about it - don't declare methods in the classes they specialize on, rather make them static, then you will not inherit them automatically:
public class Parent {
public static function foo(parent:Parent, node:Node):Function { ... }}
public class Child extends Parent {
public static function foo(parent:Child, node:Node):Function { ... }}
Note that in second case protected fields are accessible inside the static method, so you can achieve certain encapsulation. Besides, if you have a lot of Parent or Child instances, you will save on individual instance memory footprint (as static methods therefore static there exists only one copy of them, but instance methods would be copied for each instance). The disadvantage is that you won't be able to use interfaces (can be actually an improvement... depends on your personal preferences).

Actionscript 3.0 Best Option for Subclassing Vector Class (Flash Player 10)

I would like to take advantage of all the goodness of the newer Vector class for FP10, but it seems it is marked as final.
I am doing some intensive mathematical processing in Actionscript, and repeatedly process arrays of Numbers. I have previously been using my own subclass of Array(I call it NumericArray), with added functions such as sum(), mean(), add(), multiply(), etc. This works very well and allows for some clean OO code. However, I am finding through profiling that about 95% of my processing time occurs in the functions of these objects. I need more performance out of these arrays.
I want to use a Vector, as it provides some performance enhancements. I want to specifically use a Vector.<Number>. Unfortunately, I cannot subclass Vector as it is marked final.
What is the best and cleanest way to imitate what I was previously doing with a subclass of Array, to a Vector.<Number>?
I have thought about passing around Vector.<Number> variables instead of my custom class and just using utility functions to manipulate, but this is not good OO design and will be a pain to use, not to mention ugly.
If adding your additional functionality doesn't require access to protected properties/methods of Vector, you could create a wrapper class for the Vector. Something along these lines?
import flash.utils.Proxy;
import flash.utils.flash_proxy;
use namespace flash_proxy;
public class NumericVector extends Proxy
{
private var vector:Vector.<Number>;
public function NumericVector(vector:Vector.<Number> = null)
{
if(vector == null)
{
this.vector = new Vector.<Number>();
}
else
{
this.vector = vector;
}
}
override flash_proxy function nextName(index:int):String
{
return vector[index - 1].toString();
}
override flash_proxy function nextNameIndex(index:int):int
{
// implementation
}
public function sum():Number
{
// do whatever you intend to do
}
...
}
A way to sidestep this issue might be to use the as3ds (short for actionscript 3 data structures). Whether they can be faster than using Vector, I'm not sure.
How come on this page
http://help.adobe.com/en_US/AS3LCR/Flash_10.0/Vector.html
it says:
"Note: To override this method in a subclass of Vector, use ...args for the parameters, as this example shows:"
??
doesn't that imply that you can subclass a Vector?
James