I'm playing around a bit with ActionScript. What I want is that I can display a mathematical function from a string.
E.g. in my working python script I do something like that:
formula = 'x**2 + 3*x'
for x in range( 0, 100 ):
y = eval( formula )
graph.display( x, y )
I want to port this to ActionScript, but it seems like there is no more eval since version 3. How can I compute my function values anyway?
Something that might also work in your case, is using Javascript eval instead. You can use something like:
var result = ExternalInterface.call(myEvalFunctionInJS,formula)
to evaluate math functions.
This is an somewhat easy and useful workaround as javascript is quite close to actionscript.
If you put the ExternalInterface call inside an loop, it may become sluggish. To avoid that, you can write the loop in javascript. (You can even write the entire javascript inside as3, so that you do not need to touch the actual html page.)
edit:
Here's an link for that.
http://www.actionscript.org/resources/articles/745/2/JavaScript-and-VBScript-Injection-in-ActionScript-3/Page2.html
You will have to write an eval yourself. You will have to parse the string and invoke the right operators.
Here's a link to get you started.
The Tamarin project has a ECMAScript parser written in ES4. Try this as well.
"You can even write the entire javascript inside as3, so that you do not need to touch the actual html page." Do you have links / tutorials? – okoman
Both AS and JS are based on the same ECMAScript standard. So, if you pass a string of AS3 to a container, and use JS's eval on this string, it should work just fine.
Just noticed this question and realized I answered almost the exact same thing here: https://stackoverflow.com/a/11460839/1449525
To paraphrase myself, you can definitely use D.eval, AS3Eval, or ExternalInterface (as seen in the currently chosen answer) assuming you're running in a web page. However, all it seems like you really need is something like this simple MathParser (More info about the MathParser)
Here's how you'd use the MathParser:
package {
import bkde.as3.parsers.*;
import flash.display.Sprite;
public class MathTest extends Sprite {
public function MathTest() {
var parser:MathParser = new MathParser([]);
var compiledObj:CompiledObject = parser.doCompile("(10/3)*4+10");
var answer:Number = parser.doEval(compiledObj.PolishArray, []);
var xyParser:MathParser = new MathParser(["x", "y"]);
var xyCompiledObj:CompiledObject = xyParser.doCompile("(x/3)*y+10");
var xyAnswer:Number = xyParser.doEval(xyCompiledObj.PolishArray, [10, 4]);
}
}
}
I'm sure ExternalInterface stuff works just fine, but I have personal reservations about the cross language communication (especially in terms of efficiency and security) as well as just the awkward nature of it. I feel like a wholly-contained, same-language solution is typically preferable in most situations.
A bit late, but for reference, the D.eval library does what you are asking for:
http://www.riaone.com/products/deval/
It is free and works great for me, but doesn't come with source. I found this question looking for an alternative built-in or source-available solution.
There is also a seemingly abandoned project to port Tamarin to Flash itself:
http://eval.hurlant.com/
Would be awesome if more progress was made, but seems like a curiosity for now.
Related
I'm completely new to actionscript (as3, not as2) and am having some problems with some simple functions and variables. Everything is in one .fla using the actions panel.
How do I get functions to execute? Nothing of my shape changes and there is no output.
*I am aware the first change won't be noticeable, I'll add a timer later on.
Here is the code*:
var starBlackWidth = 500;
var starBlackScaleX = 0.5;
function starStretch(){
starBlack.length = starBlackWidth;
trace("Stretched the star.");
}
function starReadjust() {
starBlack.scaleX = starBlackScaleX;
trace("Attempted at readjusting without using the width directly.");
}
As some of the commenters pointed out, yes you need to call the functions you created by adding these two lines of code.
starStretch();
starReadjust();
To expand upon what they said, yes these may be fundamental concepts of programming but if you're new to object oriented programming in as3 and even oop in general this link is extremely helpful at getting you going in as3, its 3 parts and it covers it pretty well!
http://www.untoldentertainment.com/blog/2009/08/25/tutorial-understanding-classes-in-as3-part-1/
I have been looking for a way to code the popup window to perform some action in the parent window here on SO. Somewhere in one of the posts I read a suggestion that the "inspect element" option in browsers is a good way to learn. With this option I got the code for the session timeout popup from my host. Here is the part that I am trying to understand:
function fireTimeoutEvent()
{
__doPostBack('','#####forceSessionTimeout');
}
function __doPostBack(eventTarget, eventArgument)
{
var theform = document.Form1;
theform.__EVENTTARGET.value = eventTarget;
theform.__EVENTARGUMENT.value = eventArgument;
theform.submit();
}
What do the "__" mean in the four lines of the code? Do they have a special significance? Am I correct in thinking this is javascript? I ask because I am not familiar enough with the niceties of javascript, jquery and the rest to be able to recognize the difference.
Also, from this script, is it possible to tell what it is going to do? Though the popup is essentially meant to extend the session, it has some other functions besides this one, but none of the others have any under-scores in them.
Usually library writers use _ or __ to indicate private functions or methods. So this is probably something that the person didn't want people to call directly.
How would someone go about coding a 'window'? I'm starting to make a GUI, and I want to learn how to code one. One that can be skinnable, and one that actually loops and creates itself at runtime. I understand that this might be a bit vague, so I'll add details.
One that actually 'creates' itself. Most GUI tutorials I've looked on depends on an 'image' that just gets added on the screen. I want to be able to use skins in my windows. One where my 'skin' is just a collection of 'borders'. Then when I insert window.create(50,50) where 50,50 is my height, width, It would just create that window, following the skin.
I understand that it probably follows just like when a language draws a rectangle, it just follows a different set of rules (maybe?). However, for all my Google-fu skills I cannot find a tutorial that teaches me this.
Please Help. I didn't include the language I used as you can see, because I believe I just need to know how to create one. Anyway though, I am using Actionscript 3. A tutorial would be just fine, or even A SINGLE CLASS THAT HAS THIS FUNCTIONALITY, I'll just study the code. Or if you know one, maybe a whole book about GUI and programming it :D
Pure As3.0 GUI coding is quite troublesome. I try to Googling, but not come out well. anyway for my case, i generate using a SWC, and Class Mapping and Customizing. but i'm not sure best way. in other way i use a bit101 library. this is gives me want Window, Charts, Componets easily of high abstraction. see the below image.
It can be pretty hard and complicated to do, or very easy, it just depends on how flexible your solution should be. You need firstly to design a structure of your program and approach to the problem.
I like to go from the image of how it should look like from API point of view. I think I would create a GUI element like this:
var wholeGui:MyGUI = new MyGUI();
var window:IGuiElement = new GuiWindow(dataObject, skinObject);
wholeGui.addElement(window);
So what would you need?
1) Object that would manage all GUI elements. Why? Simply because your GUI elements shouldn't be destroyed by themselves if user will click "X" on your little window. The wholeGui object would manage them and listen for any events including those that would destroy them. You may consider creating custom events for interaction between the wholeGui object and your window object if this interaction is going to be complicated.
2) Interface for your GUI objects. Some problem here is that AS3 actually doesn't have interface for Sprite, and you would like to interact with it like with extended Sprite. The workaround here is to have in this interface a declaration like this:
function asSprite():Sprite;
And your implementation in GuiWindow would look like this:
public function asSprite():Sprite {
return this;
}
And your GuiWindow class should extend Sprite of course. Then you would have access to it's Sprite properties and methods by writing for example: window.asSprite.startDrag();
This interface should give you abilities that you need to operate on your GUI element.
3) Class for your GUI element, in this example GuiWindow.
4) Class for your data that would be injected into your element. If you would load data dynamically, and from some location, you would need to deal with the situation when no data can be provided - but that logic would be inside your window.
5) Class for your skin - so you would be able to dynamically create a skin object and use it to create your window in a way you want.
That's just few thoughts to consider.
PS. It may be good idea to fill GuiWindow object with data AFTER creating it, and not in constructor, as you would be able to visualize loading process then.
I have a semi-newbie question. I've been programming for years, but all my early experience was pre-OOP and my brain kind of settled that way. I'm also new to Actionscript. So hopefully this is an easy one for somebody.
I'm using as3svgrendererlib to import SVG. It works great, but I need to be able to serialize the graphics it outputs. But I can't serialize sprites, so I have to go all the way down to the IGraphicsData level to get something that I can. But the library doesn't give me that data. It only gives me sprites. So I need to change that.
Since there are only a handful of drawing methods that it ultimately uses (beginFill, drawRect, etc), my thinking is that if I can hook into those and supplement them with my own code to output IGraphicsData as well, then I'll be in business. Now I know I could do that by using "extends" classes, but that would require substantial modification of the library to change all of those standard calls to my custom ones.
So I'm wondering: Is there a magic OOP way to write methods that will universally intercept calls to existing methods without needing to modify the original calls?
Thanks! :)
EDIT: I need resolution-independence, so it's important that I keep the graphics in vector and not convert them to bitmap.
You cannot do this kind of thing in OOP, you either need to override the class (but that might not be possible in your case) or modify the library directly.
However, in your case, a possible solution would be to:
Draw the SVG to a sprite using the library.
Draw the sprite to a BitmapData.
Finally, get the pixel data using getPixels() and serialize it.
Something like this should work;
var sprite:Sprite = new Sprite();
// Add the child to the stage...
// Draw the SVG to the sprite...
var bmpData:BitmapData = new BitmapData(spriteWidth, spriteHeight);
bmpData.draw(sprite);
var pixelData:ByteArray = bmpData.getPixels(new Rectangle(0, 0, bmpData.width, bmpData.height));
// Here serialize the byte array
In this example, note that spriteWidth/spriteHeight are not necessarily "sprite.width" and "sprite.height" (sprites often report dimensions different from what you would expect). So you need to decide in advance the size of the rendered SVG and use this when building the BitmapData.
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;
}